Skip to main content

Python Dependency Injection Framework

A lightweight, type-safe dependency injection framework for Python that supports singleton, lazy singleton, and factory registrations, with scoped overrides and flexible parameter injection.

Features

  • Registry-based DI: Register services and resolve them by type and optional tags.
  • Scoped overrides: Create temporary overrides using context managers.
  • Injection decorator: Automatically inject dependencies into functions, methods, or constructors.
  • Multiple registration modes:
    • SINGLETON: Single instance shared globally.
    • LAZY_SINGLETON: Created on first access and then cached.
    • FACTORY: New instance created on every resolution.
  • Tag-based resolution: Support multiple implementations of the same interface.
  • Type-safe: Uses Python type annotations for automatic injection.
  • Supports instance, class, and static methods.

Usage

Using the Global Locator

The package provides a pre-created global locator available from the module:

from di import locator, inject, RegistrationMode, NotRegisteredError

You can register services directly in the global locator:

from di import locator, RegistrationMode

class Service:
    pass

locator.register(Service, lambda: Service(), RegistrationMode.SINGLETON)
locator.register(int, lambda: 42, RegistrationMode.SINGLETON, tag="answer")

Resolve dependencies manually:

service_instance = locator.resolve(Service)
number = locator.resolve(int, tag="answer")

Function and Method Injection with the Global Locator

from di import locator, inject

@inject(locator, params=["service", "num:answer"])
def process(service: Service, num: int):
    return service, num

s, n = process()

Supports injection into:

  • Instance methods:

    class MyClass:
      @inject(locator, params=["service"])
      def method(self, service: Service):
          return service
    
  • Class methods:

    class MyClass:
      @classmethod
      @inject(locator, params=["service"])
      def method(cls, service: Service):
          return service, cls
    
  • Static methods:

    class MyClass:
      @staticmethod
      @inject(locator, params=["service"])
      def method(service: Service):
          return service
    
  • Constructors:

    class MyClass:
      @inject(locator, params=["service"])
      def __init__(self, service: Service):
          self.service = service
    

Scoped Overrides

with locator.override():
    locator.register(Service, lambda: CustomService(), RegistrationMode.SINGLETON)
    instance = locator.resolve(Service)  # Returns CustomService
# Outside override, original registration restored
instance = locator.resolve(Service)  # Returns Service

Registration Modes

Mode Behavior
SINGLETON Single instance created at registration and reused for all resolutions.
LAZY_SINGLETON Instance created on first resolution, then cached for subsequent calls.
FACTORY Factory function called on every resolution to return a new instance.

Error Handling

  • NotRegisteredError: Raised when a requested type or tag is not registered.
  • RootScopeCloseError: Raised when attempting to close the root scope of a Locator.

Advanced Usage

While the global locator is sufficient for most cases, you can create custom locators or registries if you need isolated scopes or multiple independent DI containers:

from di import Locator, Registry

my_locator = Locator()
my_registry = Registry()

Metadata

Release files for pydi-framework 1.0.0

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

Source distribution (sdist)

Source distribution for pydi-framework 1.0.0
File Size Uploaded
pydi_framework-1.0.0.tar.gz 7.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydi-framework 1.0.0
File Interpreter ABI Platform
pydi_framework-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.3 kB

Release files / pydi_framework-1.0.0.tar.gz

Download URL pydi_framework-1.0.0.tar.gz
Size 7.7 kB
Tags Source
SHA-256 checksum
How to use checksums
95b9534af93ce04416a88f852a9a8aa0af450a5cff029c5c80a23a45df99ad43
BLAKE2b-256 checksum
How to use checksums
41ba56b9728a95d0ad91f66d497c8f4710ec81e7f3b147bc704ce3f66d25a3f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Apr 1, 2026.

Transparency log

Release files / pydi_framework-1.0.0-py3-none-any.whl

Download URL pydi_framework-1.0.0-py3-none-any.whl
Size 6.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0fb2ae55e97d6763ab5eb70e9483e03f89ce363fc42009809aa6e26d76dee803
BLAKE2b-256 checksum
How to use checksums
a8e4625882ed06b4a65157fa3b0a8001c8810f234022eac8a399ec80aff5889e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Apr 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 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