API & CLI¶
The public surface, as importable today. Signatures are verbatim from the package.
Site & composition markers — situ¶
Transparent Annotated aliases: the checker sees the payload type; the compiler reads the site from the outer name.
| Marker | To a type checker | To the compiler |
|---|---|---|
Local[T] Url[T] Server[T] Synced[T] |
T |
the signal's site |
Prop[T] |
T |
parent → child input |
Emit[T] |
Callable[[T], None] |
child → parent event |
Provide[T] / Inject[T] |
T |
the hierarchical value channel |
Mount factories — Litestar (situ)¶
The reference mount adapter, over the framework-neutral core (situ.mount.core). These names load lazily, so import situ pulls in no Litestar until you call one.
Pure client: GET / + GET /island.js. No DI, no commands.
mount_component(*, path: str, stem: Path, template: str, meta: Mapping[str, str],
service_type: type[ServiceT],
facade: Callable[..., object] | None = None,
context: Callable[..., Awaitable[Mapping[str, object]]],
children: Mapping[str, Path] | None = None, # deprecated — use components=
components: Context | None = None,
overrides: Mapping[str, Path] | None = None,
unified: bool = False,
live: bool = False,
window_template: str | None = None,
guard: Guard | None = None,
identity: Callable[[Request], str] | None = None,
extra_routes: list | None = None,
exception_handlers: ExceptionHandlersMap | None = None) -> Router
The server seam: adds POST /cmd/{name} (+ /{arg:int}), and with live=True an SSE /feed + /region, with window_template= a /window. service_type is resolved per request from request.state.dishka_container (the Litestar adapter's DI); facade optionally wraps it for the handlers; context builds the template data. guard / identity / extra_routes / exception_handlers are pass-through integration hooks (see mount/factories.py).
mount_tree(*, path: str, root: Path,
children: Mapping[str, Path] | None = None,
components: Context | None = None,
overrides: Mapping[str, Path] | None = None,
template: str, meta: Mapping[str, str]) -> Router
A pure-client component tree: the root plus resolved children, spliced to one island.
Mount adapter — Flask (situ.mount.flask)¶
mount_flask(*, path: str, app_factory: Callable[[str], EmittedApp], template: str,
meta: Mapping[str, str], resolve: Callable[[], object],
context: Callable[[object, Mapping[str, str]], Awaitable[Mapping[str, object]]],
facade: Callable[..., object] | None = None,
page_render: Callable[[str, Mapping[str, object]], str] | None = None) -> Blueprint
Serves a compiled component on Flask (WSGI): the same four routes as mount_component, over a Flask Blueprint. app_factory(cmd_base) returns the compiled EmittedApp (the caller compiles, so the baked-in command URLs match the mount); resolve() supplies the domain service (no Dishka); context(service, view) builds the region data. Commands run the async core via asyncio.run. Ships in situ[flask]; importing it pulls in no Litestar. See examples/flask/.
Neutral mount core — situ.mount.core¶
The portable mechanics both adapters wrap, importing no web framework: dispatch_command(app, *, name, arg, form, facade, make_context) -> CommandResult(html, patch, found), page_data(app, template, ctx, ...) -> (template_name, context_dict), view_from_query(app, query), the compile cache (compile_mount / compile_tree), the wire helpers (parse_id_set / coerce_int), and the live Hub. An adapter reads its framework's request, calls these, and wraps the result in that framework's response.
Component resolution — situ.Context¶
Context.of(mapping: Mapping[str, Path]) -> Context
Context.from_dir(directory: Path, *, aliases: Mapping[str, str] | None = None) -> Context
ctx.merge(other: Context) -> Context
ctx.with_override(tag: str, stem: Path) -> Context
ctx.get(tag) / ctx.tags()
Immutable and value-hashable (usable as a cache key). from_dir derives PascalTag from snake_case.html filenames; aliases covers the exceptions.
Compiler — situ¶
load_front_end(stem: Path) -> FrontEnd # read a .py/.html pair
parse_front_end(template: str, python_src: str) -> FrontEnd
splice_tree(root: FrontEnd, children: dict[str, FrontEnd]) -> FrontEnd
compile_app(front: FrontEnd, cmd_base: str = ...) -> EmittedApp
EmittedApp carries page_template, region_template, island_js, local_init, url_names, set_names, routes, handler_kinds, signal_table, island_loc. CompileError is the one exception type every layer raises.
Paths for wiring: situ.static_dir() (the _rt.js shim), situ.templates_dir() (the default page.html).
Siting contract — situ.siting¶
Site (str-enum: local / url / server / synced), Signal, Signals (projections: local_init(), url_names(), client_init(), table()), and SIGNALS_HEADER = "X-Siting-Signals".
Kit — situ_ui¶
situ_ui.STATIC # Path to ui.css + widgets.js — serve beside situ.static_dir()
situ_ui.component(name: str) -> Path # one component's stem
situ_ui.kit() -> Context # the whole kit as a resolution Context
situ_ui.css_path() -> Path
declui — situ.declui¶
Field(label=None, label_field=False, hidden=False, secret=False, widget=None,
search=False, required=False, filter=False, link=None, in_=None,
visible=None, editable=None, valid=None)
Screen(model: type, zones={}, rules=(), object_editable=None)
zones(**named: Sequence[str]) -> Mapping[str, tuple[str, ...]]
action(func=None, *, visible=None, message=None, bulk=False)
mount_model(*, path: str, screen: Screen, screens: Sequence[str] = ("form",),
rows: Sequence[object] = (), choices: Mapping[str, Any] | None = None,
service_type: type | None = None, facade: Callable[..., Any] | None = None,
context: ... | None = None, template: str = "page.html",
meta: Mapping[str, str] | None = None) -> Router
read_model(cls: type) -> list[FieldSpec]
generate_form / generate_list / generate_master_detail / generate_server_tracker
Infrastructure — situ.infra¶
templating.render_string (the shared Jinja string renderer); behind the [sqlalchemy] extra, infra.db (an async engine helper) and infra.di (a Dishka session provider).
CLI — situ check¶
Statically resolves every PascalCase <Tag/> a component tree reaches — no server boot — and exits non-zero listing every unresolved tag. --from-dir adds a directory context (repeatable); --kit includes situ_ui.kit(). Run it in your lint loop.