loom.rest.compiler¶
RestInterface compiler.
Validates and compiles RestInterface declarations
into CompiledRoute records at startup. No reflection or validation
occurs after compilation.
Compilation steps per interface:
Validate structural constraints (prefix, routes non-empty if
auto=False).For each
RestRoute: - Verifyuse_casehas a compiledExecutionPlan. - Resolve effective pagination mode (route → interface → global). - Resolve effective profile policy (route → interface → global).Detect and resolve
(method, path)conflicts: custom routes win over duplicates. RaiseInterfaceCompilationErroron ambiguous conflicts within the sameroutestuple.Validate
expose_profilerequires a non-emptyallowed_profiles.
Functions
|
Drop every Python-declared route named by disabled. |
|
Build a collision error, advising to disable-and-redeclare only when it applies. |
|
Render the |
Classes
|
Fully resolved route ready for transport binding. |
|
Compiles RestInterface declarations into CompiledRoute records. |
|
Everything that decides which routes mount, and from which origin. |
|
Which pillar declared a route — the label a collision error names. |
|
A previously compiled route, tracked for collision detection. |
Exceptions
Raised when a RestInterface fails structural validation at startup. |
- class loom.rest.compiler.RouteSources(python=(), config=(), disabled=())[source]¶
Bases:
objectEverything that decides which routes mount, and from which origin.
Groups the three inputs
RestInterfaceCompiler.compile_sources()andcreate_fastapi_app()need — the Python interfaces, the config-declared ones, and the routes disabled between them — into the one value both call sites pass along together.- Parameters:
python (Sequence[type[RestInterface[Any]]]) –
RestInterfacesubclasses declared in code. Compiled first, deterministically.config (Sequence[type[RestInterface[Any]]]) –
RestInterfacesubclasses built fromapp.rest.interfaces(seeloom.rest.config). Compiled after python.disabled (Sequence[tuple[str, str]]) –
(method, full_path)pairs to drop from the routes declared by python — seeRestInterfaceCompiler.compile_sources()for why this never targets config.
- exception loom.rest.compiler.InterfaceCompilationError[source]¶
Bases:
ExceptionRaised when a RestInterface fails structural validation at startup.
- Parameters:
message – Human-readable description of the compilation failure.
Example:
raise InterfaceCompilationError( "UserRestInterface: duplicate route (GET, /{user_id})" )
- class loom.rest.compiler.CompiledRoute(interface_name, route, full_path, effective_pagination_mode, effective_profile_default, effective_allowed_profiles, effective_expose_profile, effective_allow_pagination_override, read_only=False, interface_tags=(), execute_param_types=(), effective_requires_roles=(), effective_max_limit=1000)[source]¶
Bases:
objectFully resolved route ready for transport binding.
Produced by
RestInterfaceCompilerfor each valid route declaration. All policy fields are resolved — no further lookup is needed at request time.- Parameters:
interface_name (str) – Qualified name of the originating
RestInterface.full_path (str) – Absolute HTTP path (
interface.prefix + route.path).effective_pagination_mode (PaginationMode) – Resolved pagination strategy after applying route → interface → global precedence.
effective_profile_default (str) – Resolved default profile name.
effective_allowed_profiles (tuple[str, ...]) – Resolved set of allowed profiles.
effective_expose_profile (bool) – Whether
?profile=...is publicly accepted for this route.effective_allow_pagination_override (bool) – Whether callers may override pagination mode via query parameters for this route.
effective_requires_roles (tuple[str, ...]) – Resolved roles granting access to this route, after applying route → interface precedence. Empty means the route declares no role requirement.
effective_max_limit (int) – Ceiling applied to the
?limit=query parameter of this route.read_only (bool) –
Truefor GET routes — instructs the executor to skip theUnitOfWorktransaction for this request.interface_tags (tuple[str, ...]) – OpenAPI tags inherited from the parent
RestInterface.
- class loom.rest.compiler.RestInterfaceCompiler(use_case_compiler, defaults=None, metrics=None)[source]¶
Bases:
objectCompiles RestInterface declarations into CompiledRoute records.
Validates structure, resolves policies, and caches the result. Designed to run once at startup, driven by
bootstrap_app()or the FastAPI composition root.- Parameters:
use_case_compiler (UseCaseCompiler) – Compiler that holds the cached
ExecutionPlanregistry.defaults (RestApiDefaults | None) – Global REST API defaults applied when interface/route level is unset. Defaults to
RestApiDefaultswith offset pagination.metrics (MetricsAdapter | None) – Optional metrics adapter. Reserved for future use (HTTP metrics are emitted at request time by the router runtime).
Example:
compiler = RestInterfaceCompiler(use_case_compiler) routes = compiler.compile(UserRestInterface)
- compile(interface)[source]¶
Compile
interfaceand return the list ofCompiledRoute.Compilation is idempotent: repeated calls with the same class return the cached result.
- Parameters:
interface (type[RestInterface[Any]]) –
RestInterfacesubclass to compile.- Returns:
Ordered list of compiled routes ready for transport binding.
- Raises:
InterfaceCompilationError – If the interface fails validation.
- Return type:
- compile_sources(sources)[source]¶
Compile interfaces from both origins into one deterministic route set.
Python-declared interfaces compile first.
sources.disabledis then applied to that Python-only set — see_apply_disablement()for why it never targets config-declared routes. Only after disablement doapp.rest.interfacesentries compile and join the result. A(method, path)collision between what remains aborts naming both origins involved — order only decides which origin the message names first, it grants neither side precedence.This sequencing is what makes overriding a route per environment possible: disabling a Python route removes it, and only then does the collision check run, so the config redeclaration mounts cleanly instead of colliding with a route that would otherwise still be considered occupied.
- Parameters:
sources (RouteSources) – Interfaces to compile, grouped by origin, plus the Python routes to drop before the merge.
- Returns:
Compiled routes, Python-declared ones first (minus any disabled), followed by the config-declared ones.
- Raises:
InterfaceCompilationError – On a same- or cross-origin collision, or a
disabledentry matching no Python-declared route.- Return type: