Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Aeterna DI

aeterna-di is an explicit, annotation-driven asynchronous dependency-injection container. Applications compose a ServiceCollection, build a provider, and resolve services through that provider or an explicit scope.

Features

  • Register existing instances, implementation types, and synchronous or asynchronous factories.
  • Resolve constructor dependencies from type annotations.
  • Choose singleton, scoped, or transient lifetimes.
  • Validate duplicate registrations, missing services, dependency cycles, constructor annotations, and singleton graphs that capture scoped services.
  • Opt into ownership and close supported resources in reverse acquisition order.
  • Detect cross-task singleton cycles and report cleanup cancellation as a framework error.

Requirements

  • Python 3.12 or later.
  • No runtime dependencies outside the Python standard library.

Installation

With pip:

pip install aeterna-di

With uv:

uv add aeterna-di

Basic usage

Constructor dependencies must have resolvable type annotations. Resolution and provider cleanup are asynchronous.

import asyncio

from aeterna.di import ServiceCollection, ServiceLifetime


class Clock:
    def now(self) -> str:
        return "12:00"


class GreetingService:
    def __init__(self, clock: Clock) -> None:
        self._clock = clock

    def greet(self) -> str:
        return f"Hello at {self._clock.now()}"


async def main() -> None:
    services = ServiceCollection()
    services.add_type(Clock, lifetime=ServiceLifetime.SINGLETON)
    services.add_type(GreetingService)

    async with services.build_provider() as provider:
        greeting = await provider.get(GreetingService)
        print(greeting.greet())  # Hello at 12:00


asyncio.run(main())

Registration, scopes, and ownership

add_type() creates instances from annotated constructor dependencies. add_factory() and add_async_factory() receive a ServiceResolver; their optional dependencies=(...) sequence enables build-time validation of services the factory will resolve. Without that declaration, factory resolution failures are deferred until first use.

add_instance() registers an existing singleton. add_type() and factory registrations accept lifetime and owns_instance; ownership is opt-in. Owned singleton resources belong to the provider, owned scoped resources belong to their scope, and transient services may not be owned. Supported cleanup includes sync/async context management, close(), and aclose().

Scoped services require an explicit scope:

async with provider.create_scope() as scope:
    service = await scope.get(RequestService)

ServiceCollection is immutable after build_provider(). Provider and scope closing is idempotent and prevents new resolutions.

Public API

Classes, protocol, and enum:

  • ServiceCollection: mutable registration builder.
  • ServiceDescriptor: immutable description of one registration.
  • ServiceLifetime: SINGLETON, SCOPED, and TRANSIENT lifetime policies.
  • ServiceProvider: root resolver and singleton ownership boundary.
  • ServiceScope: scoped resolver and scoped ownership boundary.
  • ServiceResolver: protocol providing asynchronous get() and try_get() methods.

Exceptions:

  • ResolutionError: base class for service-resolution failures.
  • RegistrationError: an invalid registration or mutation after build.
  • MissingRegistrationError: no registration exists for a required service.
  • AmbiguousRegistrationError: more than one registration uses the same key.
  • CircularDependencyError: the dependency graph contains a cycle.
  • CaptiveDependencyError: a singleton graph depends on a scoped service.
  • ActivationError: a registered service could not be created.
  • ScopeClosedError: a provider or scope was used after it closed.
  • ServiceCancellationError: cleanup could not complete normally after cancellation.

Tests

From the repository root:

uv sync --locked
uv run pytest tests/test_di.py

Release files for aeterna-di 1.0.0.dev1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aeterna-di 1.0.0.dev1
File Size Uploaded
aeterna_di-1.0.0.dev1.tar.gz 11.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aeterna-di 1.0.0.dev1
File Interpreter ABI Platform
aeterna_di-1.0.0.dev1-py3-none-any.whl Python 3 none any Details

Total release size: 22.8 kB

Release files / aeterna_di-1.0.0.dev1.tar.gz

Download URL aeterna_di-1.0.0.dev1.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
13358882a4d5f25992dbee159ce2f229cac27f87efcab78f128aeb0f7eeea178
BLAKE2b-256 checksum
How to use checksums
baae9108a79acaaf71967d2616d17236d9787ed9c3113e745d85a10fc5353acc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release files / aeterna_di-1.0.0.dev1-py3-none-any.whl

Download URL aeterna_di-1.0.0.dev1-py3-none-any.whl
Size 11.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e12c7c2d9275dbd9373923a8d0faef338c534e98b634d862202c60aafbda28b9
BLAKE2b-256 checksum
How to use checksums
51769424d61ba09afb2abe71998f3f398e087baf509c7f5ba978e2cf72a2cfa8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0.dev1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page