Skip to main content

Add your description here

Project description

Podlet

PyPI version

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 multiple Registry instances.
    • Registry: Manages multiple Registrant instances.
      • 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 Resolve utility.

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.

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

podlet-1.0.3.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

podlet-1.0.3-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file podlet-1.0.3.tar.gz.

File metadata

  • Download URL: podlet-1.0.3.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for podlet-1.0.3.tar.gz
Algorithm Hash digest
SHA256 c9730d0b2ce2370bb0e0399395d10656734008de6054a4ddf4ce0bb27a83ea2f
MD5 66f980d6c4b2549453768fea7e7d5e0c
BLAKE2b-256 c1cebea151d28f99beb16a027d8dded8ff36962fe018b52b323d32359c858978

See more details on using hashes here.

File details

Details for the file podlet-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: podlet-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for podlet-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f6511e0aedb8108f77f0d886a512cd63fb1028b8ecd08b902c91bd68e33d3b00
MD5 932a02c6c6b752b22d82f6499cf8a3b0
BLAKE2b-256 23f40e7974696d3aacf28ff058c111d1ab22a2365bd70bc2169fe9087e365842

See more details on using hashes here.

Supported by

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