{"id":7349,"library":"lagom","title":"Lagom Dependency Injection","description":"Lagom is a dependency injection container designed to give you 'just enough' help with building your dependencies. It emphasizes type-based auto-wiring with strong Mypy integration and minimal changes to existing code. It currently supports Python 3.7+ and is actively maintained with frequent releases.","status":"active","version":"2.7.7","language":"en","source_language":"en","source_url":"https://github.com/meadsteve/lagom","tags":["dependency injection","DI","container","mypy","async"],"install":[{"cmd":"pip install lagom","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for loading environment variables via `lagom.environment`.","package":"pydantic","optional":true}],"imports":[{"symbol":"Container","correct":"from lagom import Container"},{"note":"Used with decorators like @bind_to_container to explicitly mark arguments for injection, especially when default values are present.","symbol":"injectable","correct":"from lagom import injectable"},{"note":"Decorator to explicitly register a function as a dependency constructor with the container, especially for async functions or complex build logic.","symbol":"dependency_definition","correct":"from lagom import dependency_definition"},{"note":"Awaitable is part of Python's standard `typing` module, not Lagom. It's crucial for requesting async dependencies from the container.","wrong":"from lagom import Awaitable","symbol":"Awaitable","correct":"from typing import Awaitable"}],"quickstart":{"code":"from lagom import Container, injectable\n\nclass Config:\n    def __init__(self, api_key: str):\n        self.api_key = api_key\n\nclass HttpClient:\n    def __init__(self, config: Config):\n        self.config = config\n\nclass MyService:\n    def __init__(self, http_client: HttpClient):\n        self.http_client = http_client\n\n# Create a container\ncontainer = Container()\n\n# Configure a dependency (e.g., from environment variables)\n# In a real app, this might come from os.environ.get or a settings file\ncontainer[Config] = lambda: Config(api_key=os.environ.get('MY_API_KEY', 'default_api_key'))\n\n# Lagom will auto-wire HttpClient and MyService based on type hints\nservice = container[MyService]\n\nprint(f\"Service created with API Key: {service.http_client.config.api_key}\")\n\n# Example with function binding\nfrom lagom.decorators import bind_to_container\n\n@bind_to_container(container)\ndef process_request(service: MyService, request_data: dict):\n    print(f\"Processing request with API Key: {service.http_client.config.api_key}\")\n    return {\"status\": \"ok\", \"data\": request_data}\n\nprocess_request(request_data={\"id\": 123})\n","lang":"python","description":"This example demonstrates basic auto-wiring with `Container`, explicit dependency configuration, and integrating with functions using `@bind_to_container`. It shows how to provide a `Config` instance and how `HttpClient` and `MyService` are automatically resolved based on their type hints."},"warnings":[{"fix":"Upgrade your Python environment to 3.9+ or use an older version of Lagom compatible with your Python version. Refer to Lagom's `requires_python` metadata for the latest compatibility.","message":"Lagom versions 2.0.0 dropped formal support for Python 3.6, and 2.7.0 dropped formal support for Python 3.8. Using these versions on unsupported Python runtimes may lead to unexpected behavior or compilation issues.","severity":"breaking","affected_versions":">=2.0.0 (Python 3.6), >=2.7.0 (Python 3.8)"},{"fix":"If your dependency `MyAsyncDep` is constructed by an `async def` function, retrieve it as `my_dep = await container[Awaitable[MyAsyncDep]]`. (Fixed a related `RuntimeError` for `Awaitable` singletons in 2.7.6).","message":"Asynchronous dependencies defined with `async def` must be requested from the container as `Awaitable[YourType]` and then awaited. Attempting to directly resolve `YourType` will result in an error or an unawaited `Awaitable` object.","severity":"gotcha","affected_versions":"All versions with async support"},{"fix":"Upgrade Lagom to version 2.7.5 or higher to ensure all request-level singletons are correctly registered and resolved within the FastAPI integration.","message":"When using Lagom's FastAPI integration, versions prior to 1.7.1 and between 2.4.2 and 2.7.5 had a bug where only the last defined request-level singleton would be correctly applied. This could lead to incorrect instances being injected for other request-scoped dependencies.","severity":"gotcha","affected_versions":"<1.7.1, >2.4.2 & <2.7.5"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"If your dependency `MyAsyncDep` is defined by an `async def` constructor, you must request it as `my_dep = await container[Awaitable[MyAsyncDep]]`.","cause":"You are trying to resolve an asynchronous dependency directly as its concrete type (<YourType>) instead of wrapping it in `typing.Awaitable` and awaiting the result.","error":"lagom.exceptions.TypeOnlyAvailableAsAwaitable: Unable to construct type <YourType> as it is only available as an async.Try requesting Awaitable[<YourType>] instead."},{"fix":"Ensure all constructor arguments have explicit type hints. If `YourType` is an abstract base class, provide a concrete implementation using `container[YourAbstractType] = YourConcreteClass`. For complex types, define a factory function: `container[YourType] = lambda c: YourType(c[DependencyA], c[DependencyB])`.","cause":"Lagom could not determine how to construct `YourType` or one of its sub-dependencies. This can happen due to missing type hints, abstract types without concrete bindings, or unconfigured dependencies.","error":"lagom.exceptions.UnresolvableType: Unable to construct dependency of type <YourType> The constructor probably has some unresolvable dependencies"},{"fix":"Identify and break the circular dependency. This often involves introducing an interface, a factory function, or restructuring your classes to decouple their direct dependencies.","cause":"There is a circular dependency in your application's object graph (e.g., A depends on B, and B depends on A), causing infinite recursion during dependency resolution.","error":"lagom.exceptions.RecursiveDefinitionError: When trying to build dependency of type '<YourType>' python hit a recursion limit. This could indicate a circular definition somewhere."}]}