View Source Pythonx.Encoder protocol (Pythonx v0.4.4)

A protocol for converting data structures to Python objects.

The protocol has implementation for Elixir built-in data types.

In order to define it for other data structures, you can use Pythonx.eval/2 and pass necessary information as built-in types. For example, imagine we have the following struct representing a complex number:

defmodule Complex do
  defstruct [:re, :im]
end

The protocol implementation could look like this:

defimpl Pythonx.Encoder, for: Complex do
  def encode(complex, _encoder) do
    {result, %{}} =
      Pythonx.eval(
        """
        complex(re, im)
        """,
        %{"re" => complex.re, "im" => complex.im}
      )

    result
  end
end

Pythonx.encode!(%Complex{re: 1, im: -1})
#=> #Pythonx.Object<
#=>   (1-1j)
#=> >

When dealing with more complex data structures, you will want to return an object from a Python package. In that case, it is a good idea to raise a clear error if the package is not installed. For example, here is one possible implementation for Explorer.DataFrame:

defimpl Pythonx.Encoder, for: Explorer.DataFrame do
  def encode(df, _encoder) do
    {result, %{}} =
      Pythonx.eval(
        """
        try:
          import polars
          result = polars.read_ipc(ipc)
        except ModuleNotFoundError:
          result = None

        result
        """,
        %{"ipc" => Explorer.DataFrame.dump_ipc!(df)}
      )

    case Pythonx.decode(result) do
      %Pythonx.Object{} ->
        result

      nil ->
        raise Protocol.UndefinedError,
          protocol: @protocol,
          value: df,
          description:
            "cannot encode Explorer.DataFrame, because the polars Python package is not installed"
    end
  end
end

Summary

Types

t()

All the types that implement this protocol.

Functions

A function invoked to encode the given term to Pythonx.Object.

Types

t()

@type t() :: term()

All the types that implement this protocol.

Functions

encode(term, encoder)

@spec encode(term :: term(), Pythonx.encoder()) :: Pythonx.Object.t()

A function invoked to encode the given term to Pythonx.Object.