pyvelm.loader¶
loader ¶
Module discovery, dependency resolution, and install/migrate.
A pyvelm module is a Python package containing a __pyvelm__.py manifest.
Preferred style (velmphp-like fluent builder)::
from pyvelm.manifest import Manifest
manifest = (
Manifest.make("partners")
.version(0, 1, 0)
.depends("base")
.data("views/partner.py")
)
Legacy module-level constants remain supported::
NAME = "partners"
VERSION = (0, 1, 0)
DEPENDS = ["base"]
Optionally:
MODELS_PACKAGE = "myapp.partners.models" # defaults to <pkg>.models
INSTALL_HOOK = "myapp.partners.hooks:install"
# Optional — default: discover seeders/SEEDERS from seeders/__init__.py
SYNC_HOOK = "myapp.partners.hooks:sync" # runs on Apps Sync (re-install path)
WEB_ROUTES = "myapp.partners.web:register_routes" # optional FastAPI routes
MIGRATIONS_PACKAGE = "myapp.partners.migrations" # defaults to <pkg>.migrations
The loader
- discovers manifests under given roots,
- resolves dependency order (topo sort, cycle detection),
- imports each module's models under an active registry,
- runs install/migrate per module inside one transaction,
- records installed versions in
ir_module.
parse_module_roots_env ¶
Parse PYVELM_MODULE_ROOTS — comma- or colon-separated paths.
module_display_name ¶
Readable Apps label. NAME stays the technical id (geo_data).
Source code in pyvelm/loader.py
discover_bootstrap_module_names ¶
Bundled modules auto-installed on a fresh database.
Modules with BOOTSTRAP = False in their manifest (or
Manifest.bootstrap(False)) are discovered but opt-in via Apps.
Source code in pyvelm/loader.py
discover ¶
Walk module roots for directories containing a __pyvelm__.py manifest.
Always scans :data:pyvelm.BUILTIN_MODULE_ROOTS first so bundled modules
such as contacts are visible even when the app only passes custom
addon paths (mirrors pyvelm-cron / CLI behaviour).
Source code in pyvelm/loader.py
resolve_order ¶
Topological sort by DEPENDS; raises on missing deps or cycles.
Source code in pyvelm/loader.py
reload_models ¶
Re-import a module's models package (upgrade / dev reload).
Refreshes Python class definitions on the live registry without requiring a full process restart.
Source code in pyvelm/loader.py
reload_installed_models ¶
Re-import models for every installed module in dependency order.
Reloading a single module overwrites _inherit merges on shared
models (e.g. upgrading base alone drops geo_data fields on
res.country while res.continent still references them).
Source code in pyvelm/loader.py
specs_to_install ¶
specs_to_install(env: Environment, ordered: list[ModuleSpec], *, install_all: bool = False) -> list[ModuleSpec]
Return the subset of ordered specs to load and install on this pass.
By default (app/cron boot): on a fresh database every bundled module in
pyvelm/modules/ (BOOTSTRAP_MODULES) is installed; otherwise only
rows already present in ir_module. Pass install_all=True to also
install discovered addons outside the bundled tree (migrate --all,
demo scripts, integration tests).
Source code in pyvelm/loader.py
install ¶
Install or upgrade each module, in specs order, atomically per
module. Models must already be loaded into env.registry.
Returns one result dict per spec with keys name, schema,
views, menus (human-readable summaries for the Apps UI).
Source code in pyvelm/loader.py
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 | |
load_and_install ¶
load_and_install(roots: list[Path | str], env: Environment, *, install_all: bool = False) -> list[ModuleSpec]
End-to-end: discover, resolve, load models, install/sync.
By default every bundled module under pyvelm/modules/ is installed on
a fresh database; other discovered addons stay available in Apps until
installed. Pass install_all=True to install every discovered module
(used by pyvelm migrate --all and demo scripts). Returns the specs
that were loaded and installed/synced.
Source code in pyvelm/loader.py
register_web_routes ¶
register_web_routes(app, roots: list[Path | str], *, only: set[str] | frozenset[str] | None = None) -> None
Mount each discovered module's WEB_ROUTES registrar on app.
Modules declare WEB_ROUTES = "pkg.web:register_routes" in
__pyvelm__.py. The callable receives the FastAPI app (with
app.state.registry and app.state.pool already set) and should
attach routes, static mounts, or routers. Registrars run in dependency
order after core create_app routes are registered.
Only installed modules register routes — uninstalled addons stay visible in Apps but do not mount HTTP handlers until installed.
Pass only={...} after a live Apps install to mount routes for modules
that were not present in ir_module when the process started. Each
module's registrar runs at most once per process (tracked on
app.state.registered_web_route_modules).
Source code in pyvelm/loader.py
discover_commands ¶
Discover and register console commands from all modules under roots.
Returns a :class:~pyvelm.console.CommandRegistry. Does not require a
database connection unless a command sets requires_db=True.