Skip to content

Command scope

The framework-free seam the Click and Typer integrations specialise. See the command and message hosts for which module to install.

install

install(
    ctx: C,
    container: FrozenContainer,
    *,
    seed: ScopeSeeder[C] | None = None,
) -> ScopeFrame

Open one depin scope bound to a command context's lifetime.

Called from the callback of a command or a group. The container is published to the invocation's context for the duration of the scope, so depin.hosted_container() reaches it from anywhere the command calls into. The scope's teardowns run when the command context closes, including when the command body ends by raising, and the publication is undone after them.

Installing on a group and again on one of its commands is safe but redundant: the inner scope becomes a child of the outer frame, so a key already cached there is what the inner scope resolves.

Parameters:

Name Type Description Default
ctx C

The command context that will own the scope. It ends the scope when it closes, so the scope lasts exactly as long as the invocation the framework opened it for.

required
container FrozenContainer

The frozen container to host for that invocation.

required
seed ScopeSeeder[C] | None

Called once, before this function returns, to produce the key and value to place into the fresh scope frame. It receives ctx. Returning None seeds nothing. Omitting it seeds nothing either.

None

Returns:

Type Description
ScopeFrame

The scope's frame, so the caller can place its own values into it with

ScopeFrame

depin.ScopeFrame.provide — a tenant, a correlation id read off an

ScopeFrame

option — before anything resolves.

Raises:

Type Description
TeardownError

An async provider left a teardown in the invocation's synchronous scope. Raised when the command context closes: a command callback cannot await, so an async provider has no place in one.

ExceptionGroup

One or more teardowns failed when the invocation's scope closed. Every failure is included; one does not hide another.

Example

Install once, in the callback the framework runs before the command body, and let the framework's own context own the scope::

@app.callback()
def main(ctx: typer.Context) -> None:
    install(ctx, di)

CommandContext

Bases: Protocol

A command framework's context: anything that can own a resource for its own lifetime.