Import and Path Registry

View Source

The py_import module manages a global registry for Python imports and sys.path additions that are automatically applied to all Python interpreters.

Overview

When you call py:call/3 or similar functions, erlang_python needs to import the Python module first. The import registry allows you to:

  • Pre-register modules that should be imported in all interpreters
  • Add paths to sys.path in all interpreters
  • Configure imports and paths via application environment

Registered imports and paths are applied:

  • Immediately to all running interpreters (contexts, event loops, OWN_GIL sessions)
  • Automatically to any new interpreters created later

Configuration

Configure imports and paths in your application environment:

%% sys.config or app.src
{erlang_python, [
    {imports, [
        {json, dumps},
        {json, loads},
        {os, getcwd}
    ]},
    {paths, [
        "/path/to/my/modules",
        "/another/path"
    ]}
]}

API

Import Registry

ensure_imported/1

Register a module for import in all interpreters.

ok = py_import:ensure_imported(json).

ensure_imported/2

Register a module/function pair for import.

ok = py_import:ensure_imported(json, dumps).
ok = py_import:ensure_imported(json, loads).

is_imported/1,2

Check if a module or module/function is registered.

true = py_import:is_imported(json).
true = py_import:is_imported(json, dumps).
false = py_import:is_imported(unknown_module).

all_imports/0

Get all registered imports.

[{<<"json">>, all}, {<<"math">>, <<"sqrt">>}] = py_import:all_imports().

import_list/0

Get imports as a map grouped by module.

{ok, #{<<"json">> => [<<"dumps">>, <<"loads">>],
       <<"math">> => []}} = py_import:import_list().

clear_imports/0

Remove all registered imports. Does not affect already-running interpreters.

ok = py_import:clear_imports().

Path Registry

add_path/1

Add a directory to sys.path in all interpreters.

ok = py_import:add_path("/path/to/my/modules").

add_paths/1

Add multiple directories to sys.path.

ok = py_import:add_paths(["/path/to/lib1", "/path/to/lib2"]).

all_paths/0

Get all registered paths in insertion order.

[<<"/path/to/modules">>] = py_import:all_paths().

is_path_added/1

Check if a path is registered.

true = py_import:is_path_added("/path/to/modules").

clear_paths/0

Remove all registered paths. Does not affect already-running interpreters.

ok = py_import:clear_paths().

Examples

Pre-loading Common Modules

%% At application startup
ok = py_import:ensure_imported(json),
ok = py_import:ensure_imported(os),
ok = py_import:ensure_imported(datetime).

%% Now all py:call invocations skip the import step for these modules
{ok, Json} = py:call(json, dumps, [[{key, value}]]).

Adding Custom Module Paths

%% Add your project's Python modules to sys.path
ok = py_import:add_path("/opt/myapp/python"),
ok = py_import:add_path("/opt/myapp/vendor").

%% Now you can import modules from these directories
{ok, Result} = py:call(mymodule, myfunction, []).

Runtime Configuration

%% Check what's registered
Imports = py_import:all_imports(),
Paths = py_import:all_paths(),
io:format("Registered imports: ~p~n", [Imports]),
io:format("Registered paths: ~p~n", [Paths]).

Notes

  • The __main__ module cannot be cached (returns {error, main_not_cacheable})
  • Clearing registries does not affect already-running interpreters
  • Paths are added in order, maintaining their relative priority in sys.path
  • All module and path values are normalized to binaries internally