PyCall and email get_payload

I am trying to decode email body using PyCall and email Python library. This works in Python:

>>> import email
>>> email_message = email.message_from_string(data[0][1])
>>> email_message.get_payload(decode=True)

The problem in Julia is that email.message_from_string returns a Dict, so calling get_payload is not possible (none of the elements contain the body):

julia> email_message = email.message_from_string(data[1][2])
Dict{Any,Any} with 25 entries:
  "Subject"                    => "Rec...

So, is there a way to call get_payload(decode=True) from Julia?

PyCall.jl tries to automatically convert Python return types back to native Julia types. Since that’s not always what you want (as in this case) you can use the lower-level pycall function, which lets you specify the expected return type. Specifying a return type of PyObject avoids any automatic conversion:

using PyCall
@pyimport email
pymsg = pycall(email.message_from_string, PyObject, data[1][2])
pymsg[:get_payload](decode=true)

See: https://github.com/JuliaPy/PyCall.jl#calling-python

2 Likes

Because @pyimport works so well in general, it seems that I have overlooked pycall(), many thanks!