Skip to content

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.

mount_static_component(*, path: str, stem: Path, template: str,
                       meta: Mapping[str, str]) -> Router

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

python -m situ.check ROOT [--from-dir DIR]... [--kit]

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.