API Reference¶
Full API reference, generated from docstrings.
Public API¶
Decorator¶
django_autowired.registry.injectable ¶
Decorator that registers a class for autowiring.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scope
|
Scope
|
Lifecycle scope (default: SINGLETON). |
SINGLETON
|
bind_to
|
type | None
|
Optional interface type to bind this implementation to. |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
The original class, unmodified. |
Example::
@injectable()
class MyService:
...
@injectable(bind_to=IRepository, scope=Scope.TRANSIENT)
class SqlRepository:
...
Scope¶
django_autowired.scopes.Scope ¶
Bases: StrEnum
Controls how often a new instance is created.
Attributes:
| Name | Type | Description |
|---|---|---|
SINGLETON |
One instance per container lifetime (default). |
|
TRANSIENT |
New instance on every resolution. |
|
THREAD |
One instance per thread (useful for request-scoped objects in threaded WSGI). |
Container¶
django_autowired.container.initialize ¶
initialize(
packages,
backend="injector",
extra_modules=None,
exclude_patterns=None,
allow_override=False,
)
Initialize the global container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
packages
|
list[str]
|
Dotted package paths to scan for |
required |
backend
|
BackendName | AbstractBackend | str
|
Backend name string or a pre-instantiated |
'injector'
|
extra_modules
|
list[Any] | None
|
Backend-specific module objects for manual bindings. |
None
|
exclude_patterns
|
set[str] | None
|
Additional module name segments to skip during scanning. |
None
|
allow_override
|
bool
|
If True, re-initialization is allowed without calling |
False
|
Returns:
| Type | Description |
|---|---|
AbstractBackend
|
The initialized backend instance. |
Raises:
| Type | Description |
|---|---|
ContainerAlreadyInitializedError
|
If already initialized and |
django_autowired.container.get ¶
Resolve a type from the container.
Raises:
| Type | Description |
|---|---|
ContainerNotInitializedError
|
If the container has not been initialized. |
django_autowired.container.override ¶
Override bindings in the current container.
Raises:
| Type | Description |
|---|---|
ContainerNotInitializedError
|
If the container has not been initialized. |
django_autowired.container.reset ¶
Tear down the container. For tests only.
Does not clear the registry — registrations from already-imported
modules are preserved so that initialize() can rebuild the container
without relying on re-scanning (which is a no-op once modules are
cached in sys.modules). Use registry.clear_registry() directly
if you need a full wipe (typically only needed by the library's own
test suite when it creates @injectable classes inside test bodies).
django_autowired.container.is_initialized ¶
Return whether the container has been initialized.
django_autowired.container.get_backend_instance ¶
Return the current backend instance.
Raises:
| Type | Description |
|---|---|
ContainerNotInitializedError
|
If the container has not been initialized. |
Exceptions¶
django_autowired.exceptions.AutowiredError ¶
Bases: Exception
Base exception for all django-autowired errors.
django_autowired.exceptions.ContainerNotInitializedError ¶
django_autowired.exceptions.ContainerAlreadyInitializedError ¶
django_autowired.exceptions.DuplicateBindingError ¶
django_autowired.exceptions.BackendNotInstalledError ¶
django_autowired.exceptions.UnresolvableTypeError ¶
Registry¶
django_autowired.registry.Registration
dataclass
¶
A single injectable registration.
Attributes:
| Name | Type | Description |
|---|---|---|
cls |
type
|
The concrete implementation class. |
scope |
Scope
|
The lifecycle scope for this registration. |
bind_to |
type | None
|
Optional interface/ABC this class implements. |
Backends¶
django_autowired.backends.base.AbstractBackend ¶
Bases: ABC
Backend contract that all DI library adapters must implement.
build
abstractmethod
¶
Configure the native container from the registration list.
django_autowired.backends.injector_.InjectorBackend ¶
Bases: AbstractBackend
Backend adapter for the injector library.
django_autowired.backends.lagom_.LagomBackend ¶
Bases: AbstractBackend
Backend adapter for the lagom library.
Lagom resolves concrete classes automatically from type hints, so only interface bindings and singleton scopes need explicit registration.
Note
The @inject decorator from the injector library is not used
or needed with this backend.
django_autowired.backends.wireup_.WireupBackend ¶
Bases: AbstractBackend
Backend adapter for the wireup library.
Note
Scope.THREAD falls back to SINGLETON because wireup does not
support thread-local scoping, and transient resolution from the root
container requires explicit scope entry — which breaks the simple
container.get() contract. Scope.TRANSIENT is still honored,
but consumers must enter a scope to resolve transient injectables.
django_autowired.backends.dishka_.DishkaBackend ¶
Bases: AbstractBackend
Backend adapter for the dishka library.
Note
Dishka's scope model differs from other backends — SINGLETON,
TRANSIENT, and THREAD all map to DishkaScope.APP because
the top-level container is APP-scoped. Use cache=False semantics
via a REQUEST scope for true transient behavior if needed.
Integrations¶
django_autowired.integrations.django.apps.AutowiredAppConfig ¶
Bases: AppConfig
Base AppConfig that initializes the autowired container in ready().
Subclass this and set the class attributes to configure scanning::
class MyAppConfig(AutowiredAppConfig):
name = "myapp"
autowired_packages = ["myapp.services", "myapp.adapters"]
autowired_backend = "injector"
Attributes:
| Name | Type | Description |
|---|---|---|
autowired_packages |
list[str]
|
Package paths to scan for |
autowired_backend |
str
|
Backend name (default: |
autowired_extra_modules |
list[Any]
|
Backend-specific modules for manual bindings. |
autowired_exclude_patterns |
set[str]
|
Additional module segments to skip during scanning. |
django_autowired.integrations.fastapi.lifespan.autowired_lifespan
async
¶
Async context manager for FastAPI lifespan that initializes the container.
Usage::
from functools import partial
app = FastAPI(
lifespan=partial(
autowired_lifespan,
packages=["myapp.services"],
)
)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Any
|
The FastAPI application instance. |
required |
packages
|
list[str]
|
Package paths to scan. |
required |
backend
|
BackendName | str
|
Backend name. |
'injector'
|
extra_modules
|
list[Any] | None
|
Backend-specific module objects. |
None
|
exclude_patterns
|
set[str] | None
|
Module name segments to skip during scanning. |
None
|
django_autowired.integrations.fastapi.lifespan.Provide ¶
Bases: Generic[T]
Callable that resolves a type from the container.
Use with FastAPI's Depends::
@app.get("/")
async def index(svc: MyService = Depends(Provide(MyService))):
...
django_autowired.integrations.flask.extension.Autowired ¶
Autowired(
app=None,
packages=None,
backend="injector",
extra_modules=None,
exclude_patterns=None,
)
Flask extension that initializes the autowired container.
Supports both direct init and the init_app() factory pattern::
# Direct
app = Flask(__name__)
Autowired(app, packages=["myapp.services"])
# Factory
autowired = Autowired(packages=["myapp.services"])
autowired.init_app(app)
Args passed to init_app() take precedence over constructor args.
init_app ¶
Initialize the extension with a Flask app.
Args passed here take precedence over constructor args.
django_autowired.integrations.flask.extension.inject_dep ¶
Resolve a type from the container. Use in Flask route handlers.
Example::
@app.route("/")
def index():
svc = inject_dep(MyService)
return svc.do_work()
Inspect¶
django_autowired.inspect.BindingReport
dataclass
¶
A single row in the binding report.
Attributes:
| Name | Type | Description |
|---|---|---|
interface |
str
|
The type used as a resolution key ( |
implementation |
str
|
The concrete class that will be constructed. |
scope |
str
|
Lifecycle scope. |
kind |
str
|
|
source_module |
str
|
Dotted module path where the implementation was declared. |
dependencies |
list[str]
|
Types consumed by the implementation's |
django_autowired.inspect.scan ¶
Populate the registry by scanning packages, without building a container.
django_autowired.inspect.report ¶
Build a report from the current registry.
Does not require a running container — reads registrations directly.
django_autowired.inspect.render_table ¶
Render the report as a plain-text, aligned table.
django_autowired.inspect.render_tree ¶
Render the report as an ASCII dependency tree.
Each binding is a top-level node; its __init__ dependencies are
shown as children. Cycles are not drawn (dependencies of dependencies
appear as leaf names only — follow up with another lookup).
django_autowired.inspect.render_mermaid ¶
Render the report as a Mermaid flowchart (graph TD).
Dependency edges point from the consumer to the dependency type. Paste into a Mermaid renderer (GitHub, Mermaid Live) to visualize.
Testing utilities¶
django_autowired.testing.autowired_container ¶
Pytest fixture that initializes the container from markers.
Markers
@pytest.mark.autowired_packages(["pkg1", "pkg2"])
@pytest.mark.autowired_backend("injector")
Yields the initialized backend, then resets on teardown.
django_autowired.testing.build_container ¶
Pytest fixture yielding a ContainerFactory.
The factory calls container.reset() before each build. After the test,
the container is reset.
django_autowired.testing.container_context ¶
Sync context manager that initializes and tears down the container.
Usage::
with container_context(packages=["myapp.services"]) as backend:
svc = container.get(MyService)
django_autowired.testing.ContainerFactory ¶
Callable factory for building containers in tests.
Usage with the build_container fixture::
def test_something(build_container):
backend = build_container(
packages=["myapp.services"],
overrides={IRepo: FakeRepo},
)
svc = container.get(MyService)
django_autowired.testing.InMemoryOverrideModule ¶
Wraps a dict into an injector.Module-compatible callable.
Use with extra_modules when using the injector backend::
container.initialize(
packages=[...],
extra_modules=[InMemoryOverrideModule({IRepo: FakeRepo})],
)