nodnod integration for Litestar — declare dependency lifetimes on nodes, inject into handlers by type
Project description
nodstar
nodnod integration for Litestar. Declare dependency lifetimes on nodes, inject into handlers by type.
Install
uv add nodstar
Requires Python 3.14+.
Usage
from nodnod import scalar_node
from litestar import Litestar, get
from nodstar import NodstarPlugin, Node, global_node, request
Define nodes
Decorate with a lifetime (@global_node, @request, @per_call) and @scalar_node:
@global_node
@scalar_node
class DatabasePool:
@classmethod
async def __compose__(cls) -> AsyncEngine:
engine = create_async_engine(DATABASE_URL)
yield engine
await engine.dispose()
@request
@scalar_node
class DbSession:
@classmethod
async def __compose__(cls, pool: DatabasePool) -> AsyncSession:
async with AsyncSession(pool) as session:
yield session
Inject into handlers
Use Node[T] in handler signature — nodnod resolves the dependency graph, Litestar injects the value:
@get("/users")
async def get_users(db_session: Node[DbSession]) -> list[User]:
return await db_session.scalars(select(User))
db_session is fully typed as AsyncSession by the type checker.
Wire up
app = Litestar(
route_handlers=[get_users],
plugins=[NodstarPlugin()],
)
That's it. No dependencies={...}, no manual Provide(), no container configuration.
Lifetimes
| Decorator | Scope | Created | Destroyed |
|---|---|---|---|
@global_node |
App | On startup | On shutdown |
@request |
Request | Per HTTP request | After response |
@per_call |
Call | Per handler invocation | After handler |
Nodes declare their own lifetime. The dependency graph is resolved automatically — a @request node can depend on a @global_node, and nodnod will pull the value from the parent scope.
How it works
- Lifetime decorators register nodes in a global registry
NodstarPlugincollects all registered nodes on app init- On startup,
@global_nodenodes are composed into an app-wide scope - Per request, a child scope is created and
@request/@per_callnodes are composed Node[T]is a type-level alias that resolves toTfor type checkers, and at runtime producesAnnotated[T, Dependency(skip_validation=True)]so Litestar skips msgspec validation and pulls the value from the nodnod scope
Generator lifecycle
Use yield in __compose__ for setup/teardown:
@request
@scalar_node
class DbSession:
@classmethod
async def __compose__(cls, pool: DatabasePool) -> AsyncSession:
async with AsyncSession(pool) as session:
yield session
# teardown runs when request scope closes
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nodstar-0.1.0.tar.gz.
File metadata
- Download URL: nodstar-0.1.0.tar.gz
- Upload date:
- Size: 22.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5da170ee950f5338c6c55fbac49402cadf08a08e06d8594c798f07b0ec18e892
|
|
| MD5 |
913df979179c7f0d24015f773e94531a
|
|
| BLAKE2b-256 |
69a4b4081133d197fbec37a766c8a69700193fdbd0301afb188e297b72bc3832
|
File details
Details for the file nodstar-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nodstar-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50b167f28b014a0670df7832142d5929b8e994d3b0384de8f60cf263299c9f87
|
|
| MD5 |
ed848e2c713389859a830875a98b369a
|
|
| BLAKE2b-256 |
a17f67aadfb346e58da3c906049d04466cd1d8d80e10a106a56ec2723c8cae3d
|