Skip to content

API Reference

Full API reference, generated from docstrings.

Public API

Decorator

django_autowired.registry.injectable

injectable(scope=Scope.SINGLETON, bind_to=None)

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 @injectable classes.

required
backend BackendName | AbstractBackend | str

Backend name string or a pre-instantiated AbstractBackend.

'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 reset() first.

False

Returns:

Type Description
AbstractBackend

The initialized backend instance.

Raises:

Type Description
ContainerAlreadyInitializedError

If already initialized and allow_override is False.

django_autowired.container.get

get(cls)

Resolve a type from the container.

Raises:

Type Description
ContainerNotInitializedError

If the container has not been initialized.

django_autowired.container.override

override(bindings)

Override bindings in the current container.

Raises:

Type Description
ContainerNotInitializedError

If the container has not been initialized.

django_autowired.container.reset

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

is_initialized()

Return whether the container has been initialized.

django_autowired.container.get_backend_instance

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

ContainerNotInitializedError()

Bases: AutowiredError

Raised when the container is accessed before initialize() is called.

django_autowired.exceptions.ContainerAlreadyInitializedError

ContainerAlreadyInitializedError()

Bases: AutowiredError

Raised when initialize() is called twice without reset().

django_autowired.exceptions.DuplicateBindingError

DuplicateBindingError(interface, existing_cls, new_cls)

Bases: AutowiredError

Raised when two different classes bind to the same interface.

django_autowired.exceptions.BackendNotInstalledError

BackendNotInstalledError(backend_name, package)

Bases: AutowiredError

Raised when the selected backend package is not installed.

django_autowired.exceptions.UnresolvableTypeError

UnresolvableTypeError(cls, reason)

Bases: AutowiredError

Raised when the container cannot satisfy a type.

Registry

django_autowired.registry.Registration dataclass

Registration(cls, scope, bind_to=None)

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.

target property

target

The type key used for container binding — bind_to if set, else cls.

Backends

django_autowired.backends.base.AbstractBackend

Bases: ABC

Backend contract that all DI library adapters must implement.

build abstractmethod

build(registrations, extra_modules=None)

Configure the native container from the registration list.

get abstractmethod

get(cls)

Resolve an instance of cls from the native container.

name abstractmethod classmethod

name()

Return the canonical backend name.

override abstractmethod

override(bindings)

Apply replacement bindings to the container.

raw abstractmethod

raw()

Return the underlying native container for advanced use.

django_autowired.backends.injector_.InjectorBackend

InjectorBackend()

Bases: AbstractBackend

Backend adapter for the injector library.

create_child

create_child(extra_modules=None)

Create a child injector for request-scoped containers.

raw

raw()

Return the underlying injector.Injector.

django_autowired.backends.lagom_.LagomBackend

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.

override

override(bindings)

Apply overrides via a per-instance dict.

Lagom's define raises on duplicate bindings, so overrides are stored in a dict and consulted before delegating to the container.

raw

raw()

Return the underlying lagom.Container.

django_autowired.backends.wireup_.WireupBackend

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.

raw

raw()

Return the underlying wireup.SyncContainer.

django_autowired.backends.dishka_.DishkaBackend

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.

raw

raw()

Return the underlying dishka Container.

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 @injectable classes.

autowired_backend str

Backend name (default: "injector").

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

autowired_lifespan(
    app,
    packages,
    backend="injector",
    extra_modules=None,
    exclude_patterns=None,
)

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

Provide(cls)

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

init_app(
    app,
    packages=None,
    backend=None,
    extra_modules=None,
    exclude_patterns=None,
)

Initialize the extension with a Flask app.

Args passed here take precedence over constructor args.

django_autowired.integrations.flask.extension.inject_dep

inject_dep(cls)

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

BindingReport(
    interface,
    implementation,
    scope,
    kind,
    source_module,
    dependencies=list(),
)

A single row in the binding report.

Attributes:

Name Type Description
interface str

The type used as a resolution key (bind_to if set, else the class).

implementation str

The concrete class that will be constructed.

scope str

Lifecycle scope.

kind str

"concrete" if interface is implementation, else "interface".

source_module str

Dotted module path where the implementation was declared.

dependencies list[str]

Types consumed by the implementation's __init__, in order.

django_autowired.inspect.scan

scan(*packages, exclude_patterns=None)

Populate the registry by scanning packages, without building a container.

django_autowired.inspect.report

report()

Build a report from the current registry.

Does not require a running container — reads registrations directly.

django_autowired.inspect.render_table

render_table(rows)

Render the report as a plain-text, aligned table.

django_autowired.inspect.render_tree

render_tree(rows)

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_json

render_json(rows)

Render the report as a JSON array.

django_autowired.inspect.render_mermaid

render_mermaid(rows)

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

autowired_container(request)

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

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

container_context(
    packages=None,
    backend="injector",
    overrides=None,
    extra_modules=None,
)

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

InMemoryOverrideModule(overrides)

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})],
)