Lux.Python (Lux v0.5.0)

View Source

Provides functions for executing Python code with variable bindings.

The ~PY sigil is used to write Python code directly in Elixir files. The content inside ~PY sigils is preserved by the Elixir formatter to maintain proper Python indentation and formatting.

Examples

iex> require Lux.Python
iex> Lux.Python.python variables: %{x: 40, y: 2} do
...>   ~PY'''
...>   x + y
...>   '''
...> end
42

Summary

Functions

Checks if a Python package is available and returns its version information.

Evaluates Python code with optional variable bindings and other options. If code_or_path is a file path, it reads the file content and evaluates it.

Same as eval/2 but raises on error.

Attempts to import a Python package.

Lists all available Python packages and their versions.

Returns a main module path for the Python.

Returns dependant modules path for the Python. Returns nil if it is not ready.

A macro that enables writing Python code directly in Elixir with variable bindings. Python code must be wrapped in ~PY sigil to bypass Elixir syntax checking.

Types

eval_option()

@type eval_option() :: {:variables, map()} | {:timeout, pos_integer()}

eval_options()

@type eval_options() :: [eval_option()]

import_result()

@type import_result() :: %{required(String.t()) => boolean() | String.t()}

package_info()

@type package_info() :: %{available: boolean(), version: String.t() | nil}

Functions

check_package(package_name)

@spec check_package(String.t()) :: {:ok, package_info()} | {:error, String.t()}

Checks if a Python package is available and returns its version information.

Examples

iex> Lux.Python.check_package("pytest")
{:ok, %{available: true, version: "7.4.0"}}

iex> Lux.Python.check_package("nonexistent_package")
{:ok, %{available: false, version: nil}}

eval(code_or_path, opts \\ [])

@spec eval(String.t(), eval_options()) :: {:ok, term()} | {:error, String.t()}

Evaluates Python code with optional variable bindings and other options. If code_or_path is a file path, it reads the file content and evaluates it.

Options

  • :variables - A map of variables to bind in the Python context
  • :timeout - Timeout in milliseconds for Python execution

Examples

iex> Lux.Python.eval("x * 2", variables: %{x: 21})
{:ok, 42}

iex> Lux.Python.eval("os.getenv('TEST')", env: %{"TEST" => "value"})
{:ok, "value"}

eval!(code, opts \\ [])

@spec eval!(String.t(), eval_options()) :: term() | no_return()

Same as eval/2 but raises on error.

Examples

iex> Lux.Python.eval!("x + y", variables: %{x: 1, y: 2})
3

iex> Lux.Python.eval!("undefined_var")
** (RuntimeError) Python execution error: NameError: name 'undefined_var' is not defined

import_package(package_name)

@spec import_package(String.t()) :: {:ok, import_result()} | {:error, String.t()}

Attempts to import a Python package.

Returns information about whether the import was successful. If the import fails, includes the error message.

Examples

iex> Lux.Python.import_package("json")
{:ok, %{success: true, error: nil}}

iex> Lux.Python.import_package("nonexistent_package")
{:ok, %{success: false, error: "No module named 'nonexistent_package'"}}

list_packages()

@spec list_packages() ::
  {:ok, %{required(String.t()) => String.t()}} | {:error, String.t()}

Lists all available Python packages and their versions.

Returns a map where keys are package names and values are version strings.

Examples

iex> Lux.Python.list_packages()
%{
  "pytest" => "7.4.0",
  "requests" => "2.31.0"
}

module_path()

@spec module_path() :: String.t()

Returns a main module path for the Python.

module_path(atom)

@spec module_path(atom()) :: String.t() | nil

Returns dependant modules path for the Python. Returns nil if it is not ready.

python(opts \\ [], list)

(macro)

A macro that enables writing Python code directly in Elixir with variable bindings. Python code must be wrapped in ~PY sigil to bypass Elixir syntax checking.

Options

  • :variables - A map of variables to bind in the Python context
  • :timeout - Timeout in milliseconds for Python execution

Examples

iex> require Lux.Python
iex> Lux.Python.python variables: %{x: 40, y: 2} do
...>   ~PY'''
...>   x + y
...>   '''
...> end
42

iex> require Lux.Python
iex> Lux.Python.python do
...>   ~PY'''
...>   def factorial(n):
...>       if n <= 1:
...>           return 1
...>       return n * factorial(n - 1)
...>   factorial(5)
...>   '''
...> end
120