PythonInterface.Encoder protocol (AxiomAI v0.1.11)

View Source

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 PythonInterface.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 PythonInterface.Encoder, for: Complex do
  def encode(complex, _encoder) do
    {result, %{}} =
      PythonInterface.eval(
        """
        complex(re, im)
        """,
        %{"re" => complex.re, "im" => complex.im}
      )

    result
  end
end

PythonInterface.encode!(%Complex{re: 1, im: -1})
#=> #PythonInterface.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 PythonInterface.Encoder, for: Explorer.DataFrame do
  def encode(df, _encoder) do
    {result, %{}} =
      PythonInterface.eval(
        """
        try:
          import polars
          result = polars.read_ipc(ipc)
        except ModuleNotFoundError:
          result = None

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

    case PythonInterface.decode(result) do
      %PythonInterface.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 PythonInterface.Object.

Types

t()

@type t() :: term()

All the types that implement this protocol.

Functions

encode(term, encoder)

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

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