Skip to content

API Interface

Classes

di.Container

Solve and execute dependencies.

Generally you will want one Container per application. There is not performance advantage to re-using a container, the only reason to do so is to share binds. For each "thing" you want to wire with di and execute you'll want to call Container.solve() exactly once and then keep a reference to the returned SolvedDependent to pass to Container.execute. Solving is very expensive so avoid doing it in a hot loop.

bind(hook)

Replace a dependency provider with a new one.

This can be used as a function (for a permanent bind, cleared when scope is exited) or as a context manager (the bind will be cleared when the context manager exits).

execute_async(solved, executor, *, state, values=None) async

Execute an already solved dependency.

execute_sync(solved, executor, *, state, values=None)

Execute an already solved dependency. This method is synchronous and uses a synchronous executor, but the executor may still be able to execute async dependencies.

solve(dependency, scopes, scope_resolver=None)

Build the dependency graph.

Should happen once, maybe during startup.

Solving dependencies can be slow.

di.dependent.Marker

A dependency marker holds information about a dependency.

Used to tell di how to construct another class.

For example:

def endpoint(conn: Annotated[DBConn, Marker(inject_db, scope="request")]):
    ...

Building your own Marker can be critical to enable nice functionality. You could for example create a custom Marker "Header" than knows how to construct a str from the headers of a request. Resulting in:

def endpoint(content_type: FromHeader[str]):
    ...

See more in dependency-markers.

register_parameter(param)

Hook to register the parameter this Dependent corresponds to.

This can be used to inferr self.call from a type annotation (autowiring), or to just register the type annotation.

This method can return the same or a new instance of a Dependent to avoid modifying itself.

di.dependent.Dependent

Connect dependencies together.

A Dependent can have sub-dependencies (also Dependents). The first argument is a Callable, which is used to find the sub-dependencies.

Parameters:

Name Type Description Default
call Optional[DependencyProviderType[T]]

used to find subdependencies

None
wire bool

if True then call is introspected to find sub-dependencies.

True
scope Scope

the Scope for this dependency (see https://www.adriangb.com/di/latest/scopes/)

None
marker Optional[Marker]

the Marker from which this Defendant was constructed. This is included only for introspection purposes.

None

get_dependencies()

Collect all of our sub-dependencies as parameters

di.executors.SyncExecutor

An executor that executes only sync dependencies.

Dependencies are executed sequentially. If any async dependencies are encountered a RuntimeError will be raised. If there are no async dependencies, this will be faster than using AsyncExecutor because there is no event loop overhead.

di.executors.AsyncExecutor

An executor that executes sync and async dependencies sequentially.

Functions

di.bind_by_type(provider, dependency, *, covariant=False)

Hook to substitute the matched dependency