Skip to main content

Python Dependency Injection Library

Project description

Wireup

Modern Dependency Injection for Python.

GitHub GitHub Workflow Status (with event) Code Climate maintainability Coverage PyPI - Python Version PyPI - Version

Wireup is a performant, concise, and easy-to-use dependency injection container for Python 3.8+.


⚡ Key Features

  • Inject services and configuration.
  • Support for interfaces and abstract classes.
  • Factory pattern.
  • Singleton and transient dependencies.
  • Framework-agnostic.
  • Simplified integration with Django, Flask, and FastAPI.

📋 Quickstart

Example showcasing a Redis wrapper and a weather service that calls an external API and caches results as needed.

1. Set up

from wireup import container, initialize_container
def create_app():
    app = ...
    
    # ⬇️ Expose configuration by populating container.params.
    container.params.put("redis_url", os.environ["APP_REDIS_URL"])
    container.params.put("weather_api_key", os.environ["APP_WEATHER_API_KEY"])

    # Bulk update is possible via the "update" method.
    container.params.update(Settings().model_dump())
    
    # Start the container: This registers and initializes services.
    # `service_modules` contains top-level modules containing registrations.
    # ⬇️
    initialize_container(container, service_modules=[services])

    return app

2. Register services

Use a declarative syntax to describe services, and let the container handle the rest.

from wireup import service, Inject

@service # ⬅️ Decorator tells the container this is a service.
class KeyValueStore:
                                           # This tells the container to inject the value
                                           # of the parameter during creation.
                                           # ⬇️ 
    def __init__(self, dsn: Annotated[str, Inject(param="redis_url")]):
        self.client = redis.from_url(dsn)

    def get(self, key: str) -> Any: ...
    def set(self, key: str, value: Any): ...


@service
@dataclass
class WeatherService:
    # Inject the value of the parameter to this field. ⬇️
    api_key: Annotated[str, Inject(param="weather_api_key")]
    kv_store: KeyValueStore # ⬅️ This will be injected automatically without additional metadata.

    def get_forecast(self, lat: float, lon: float) -> WeatherForecast:
        ...

3. Inject

Decorate targets where the library should perform injection.

from wireup import container

@app.get("/weather/forecast")
# ⬇️ Decorating views with autowire enables the container to inject services/parameters.
@container.autowire
def get_weather_forecast_view(weather_service: WeatherService, request):
    return weather_service.get_forecast(request.lat, request.lon)

Installation

# Install using poetry:
poetry add wireup

# Install using pip:
pip install wireup

📑 Documentation

For more information check out the documentation

🎮 Demo application

A demo flask application is available at maldoinc/wireup-demo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wireup-0.8.2.tar.gz (20.3 kB view hashes)

Uploaded Source

Built Distribution

wireup-0.8.2-py3-none-any.whl (24.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page