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 Dependent
s).
The first argument is a Callable
, which is used to find the
sub-dependencies.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
call |
DependencyProviderType[T] | None
|
used to find subdependencies |
None
|
wire |
bool
|
if True then |
True
|
scope |
Scope
|
the Scope for this dependency (see https://www.adriangb.com/di/latest/scopes/) |
None
|
marker |
Marker | None
|
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