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-0.1.0.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

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

podlet-0.1.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for podlet-0.1.0.tar.gz
Algorithm Hash digest
SHA256 acead425620974b38b97b5ea329a1c233adc51ee8ff60ec5ecf94af1862478ed
MD5 f4c1f77ec212473316b70618e1ad8741
BLAKE2b-256 13940b777fd4122846529f2b023978e2ff81f24f3b4009b226277b4f0a174109

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for podlet-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0b8d8d5d5be0d90b4d3b4b8a4dc153eff3d95df75abeafb7ac22857c8685b191
MD5 bcf1b6445ffe79aa072e7906f66a4a1a
BLAKE2b-256 0381c340d02e63c16cf3faa004dae4e0318040b24c72941052f25637a8a78d66

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