Podlet
A minimal, type-safe dependency injection framework for Python, focused on resource management and the Bootstrap pattern.
Installation
pip install podlet
Quick Start
from podlet import Bootstrap, ResourceAbstract
class DatabaseResource(ResourceAbstract):
@classmethod
def kind(cls) -> str:
return "resource"
@classmethod
def identity(cls) -> str:
return "database"
def initialize(self) -> None:
self.connection = f"{self.options().get('host')}:{self.options().get('port')}"
def query(self, sql: str):
return f"Executed: {sql}"
bootstrap = Bootstrap(resources=[Database], options={
"resource": {
"database": {
"host": "localhost",
"port": 5432
}
}
})
db = bootstrap.get_resource("database")
print(db.query("SELECT 1")) # Executed: SELECT 1
Core Concepts
Bootstrap
The central DI container that manages multiple registries and coming default with a ResourceRegistry.
bootstrap = Bootstrap()
assert bootstrap.has_registry(ResourceRegistry)
Resources
Define injectable dependencies by inheriting from ResourceAbstract.
class CacheResource(ResourceAbstract):
@classmethod
def identity(cls) -> str:
return "cache"
def initialize(self) -> None:
self.store = {}
def get(self, key):
return self.store.get(key)
def set(self, key, value):
self.store[key] = value
Registration and Retrieval
Register resources and retrieve them type-safely or by identity.
bootstrap = Bootstrap(resources=[DatabaseResource, CacheResource], options={
"resource": {
"database": {
"enabled": True,
"host": "localhost",
"port": 5432
},
"cache": {
"enabled": True
}
}
})
db: Database = bootstrap.get_resource(Database) # type-safe
db = bootstrap.get_resource("database") # by string
Dependencies
Resources can access other resources via self.registry.
class Service(ResourceAbstract):
@classmethod
def identity(cls) -> str:
return "service"
def initialize(self) -> None:
self.db = self.registry.get("database")
def do_work(self):
return self.db.query("SELECT 1")
Advanced Usage
Structure
Registrar: Manages multipleRegistryinstances.Registry: Manages multipleRegistrantinstances.RegistrantAbstract: Base class for registrable entities (e.g., resources, services, etc.)
Custom Registrars, Registries, and Registrants
Bootstrap is actually built on top of the underlying Registrar -> Registry -> RegistrantAbstract pattern and you're free to construct your own in any compatible way.
from podlet import Registry
class ServiceRegistry(Registry):
@classmethod
def kind(cls) -> str:
return "service"
class DatabaseService(RegistrantAbstract):
@classmethod
def kind(cls) -> str:
return "database"
class MyApp(Registrar):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.register_registry(ServiceRegistry)
def get(name: str):
return self.get_registry("service").get(name)
app = MyApp()
app.get("database")
Direct Registry Access
Interact with registries directly.
bootstrap.has_registry("resource")
registry = bootstrap.get_registry("resource")
bootstrap.register(NewResource)
bootstrap.set_options({"resource": {"new": {"enabled": True}}})
Testing
Mock resources for testing.
import pytest
class MockDBResource(ResourceAbstract):
@classmethod
def identity(cls) -> str:
return "database"
def initialize(self):
self.queries = []
def query(self, sql):
self.queries.append(sql)
return {"result": "mock"}
@pytest.fixture
def bootstrap():
return Bootstrap(resources=[MockDBResource], options={
"resource": {
"database": {
"enabled": True
}
}
})
def test_db(bootstrap):
db = bootstrap.get_resource("database")
result = db.query("SELECT * FROM users")
assert result["result"] == "mock"
assert len(db.queries) == 1
Architecture
- Type Safety: Compile-time guarantees with generics.
- Lifecycle: Lazy initialization, singleton pattern, memory efficient.
- Resolution: Smart polymorphic resolution via
Resolveutility.
Contributing
Contributions welcome! Please open issues or PRs on GitHub.
Acknowledgements
Inspiration for this project was drawn from Zend Framework's plugin architecture.
License
3-Clause BSD License. See LICENSE file.
Metadata
Release files for podlet 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| podlet-1.0.3.tar.gz | 13.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| podlet-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.0 kB
Release files / podlet-1.0.3.tar.gz
| Download URL | podlet-1.0.3.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9730d0b2ce2370bb0e0399395d10656734008de6054a4ddf4ce0bb27a83ea2f
|
|
BLAKE2b-256 checksum How to use checksums |
c1cebea151d28f99beb16a027d8dded8ff36962fe018b52b323d32359c858978
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / podlet-1.0.3-py3-none-any.whl
| Download URL | podlet-1.0.3-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f6511e0aedb8108f77f0d886a512cd63fb1028b8ecd08b902c91bd68e33d3b00
|
|
BLAKE2b-256 checksum How to use checksums |
23f40e7974696d3aacf28ff058c111d1ab22a2365bd70bc2169fe9087e365842
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Security for podlet 1.0.3
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.