Import and Path Registry
View SourceThe 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.pathin 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