yggsdrasyl
Simplistic, but totally explicit dependency injection tool. Main goal is to provide simple, but powerful API for registering dependencies by type and their extensible resolution mechanism in functions.
Why
yggdrasyl? This is misspelling ofyggdrasil- the ancient tree of life in Nordic / Scandinavian mythologies, that connects all the worlds, like DI Framework connects dependencies.
Usage
Main entry point to dependency management is class Dependencies. You can create your
own instance, or use predefined global one - deps.
Dependency Registration
To register a dependency invoke method Dependencies.register:
from yggdrasyl import deps
deps.register(UserServiceConfig, lambda d: UserServiceConfig())
deps.register(UserService, lambda d: UserService(config=d.resolve(UserServiceConfig)))
Dependencies.register accepts accepts 2 required arguments:
- dependency type - identifier for dependency resolution
- factory function - function that accepts
Dependenciesobject and returns dependency instance
Also there are multiple optional keyword-only arguments:
cached- ifTruethan dependency object is reused across all resolutions,Trueby defaultmanaged- ifTruethan dependency object is managed by context manager and can be initialized with all the other dependenciesoverride- ifTruethan existing dependency with same type is overridden,Falseby default
For simplification of registering objects from instances one can use from_instance
utility function. If one has factory function (for example class constructor) use
from_factory.
from yggdrasyl import deps, from_instance, from_factory
deps.register(int, from_instance(1))
deps.register(IService, from_factory(Service))
If dependency type is already registered, then TypeAlreadyRegisteredError is raised.
Dependency Resolution
To resolve dependency invoke Dependencies.resolve method with single desired type
argument:
from yggdrasyl import deps
user_service = deps.resolve(UserService)
If type is not registered, then TypeNotRegisteredError is raised.
Context Manager Dependencies
Some dependencies require being initialized on application startup. In order not to
forget one and rule management from single place there is a managed parameter, that
indicates that this dependency should be resolved on startup and is sync or async
context manager, that should be initialized. By default it takes False meaning, that
one must explicitly tell, that dependency is managed.
After marking only dependencies as managed just open Dependencies.initialize context
and all the dependencies will be initialized at once. Basically this method should be
used as lifespan for ASGI applications (for example).
from contextlib import asynccontextmanager
from fastapi import FastAPI
from yggdrasyl import deps
@asynccontextmanager
async def _lifespan(app: FastAPI):
async with deps.initialize():
yield
Dependency Wiring
In order not to call Dependencies.resolve manually for each dependency, there is a way to tell that some callable requires some dependencies via Dependencies.wire decorator:
from yggdrasyl import deps, Injected
@deps.wire
async def _handle_register_user(
action: RegisterUser,
user_service: UserService = Injected[UserService]
) -> UserID:
...
To mark argument to be injected from DI container one should use Injected object with
wanted type in [].
Metadata
Release files for yggdrasyl 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| yggdrasyl-0.1.0.tar.gz | 24.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yggdrasyl-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.5 kB
Release files / yggdrasyl-0.1.0.tar.gz
| Download URL | yggdrasyl-0.1.0.tar.gz |
|---|---|
| Size | 24.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9139948d81523700a5a9bf244eeb512539d968b312a889b81d2d9436ad16ab0a
|
|
BLAKE2b-256 checksum How to use checksums |
0928f51ed86191a5643f7912d7f0196101b2ea433323b641b8a66b9e81e651fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / yggdrasyl-0.1.0-py3-none-any.whl
| Download URL | yggdrasyl-0.1.0-py3-none-any.whl |
|---|---|
| Size | 5.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a10e0642e9c30b52fff35e214a84ae57fb5b6be7c8b19c3f42a93912490abd9b
|
|
BLAKE2b-256 checksum How to use checksums |
435cacc2e216eb33aa97914e970724ef89fee6ab1a6a62c72175884b0be89bdd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|