Simple dependency injection for Python.
Project description
PyJudo
Overview
PyJudo is a python library to support the dependency injection (DI) pattern. . It facilitates the registration of services, resolves dependencies, and manages the lifecycle of services throughout your application. By decoupling service creation from business logic, PyJudo promotes cleaner, more maintainable, and testable codebases.
Installation
PyJudo is available on PyPi; install using:
pip install pyjudo
Features
-
Service lifetimes:
- Singletons: A single instance created and shared across the application
- Scoped: A single instance created and shared within a scope
- Transient: A new instance is created every time the service is requested.
-
Disposable services:
- Automatically disposes of services that implement the
IDisposable
protocol when a scope ends.
- Automatically disposes of services that implement the
-
Circular dependencies:
- Detects and prevents circular dependencies during service resolution.
-
Thread safety:
- Ensures safe use in multi-threaded environments by managing scopes and service resolutions per thread.
-
Context management
- Supports the use of context managers (i.e.
with ...
) to manage service scopes and their respective service lifetimes.
- Supports the use of context managers (i.e.
Quick Start
1. Define Interfaces and Implementations
Start by defining service interfaces (abstract classes) and their concrete implementations:
from abc import ABC, abstractmethod
from pyjudo import ServiceContainer, ServiceLife
# Define service interfaces
class IDatabaseConnection(ABC):
@abstractmethod
def query(self, sql: str) -> Any: ...
class IDatabaseURIBuilder(ABC):
@abstractmethod
def get_uri(self) -> str: ...
# Implement the services
class DatabaseConnection(IDatabaseConnection):
def __init__(self, uri_builder: IDatabaseURIBuilder, table_name="default"):
self.connection_string = uri_builder.get_uri()
self.table_name = table_name
self.connected = True
print(f"Connected to database: {self.connection_string}")
def query(self, sql: str) -> Any:
if not self.connected:
raise Exception("Not connected to the database.")
print(f"Executing query: {sql} FROM {self.table_name}")
return {"result": "data"}
def dispose(self) -> None:
if self.connected:
self.connected = False
print(f"Disconnected from database: {self.connection_string}")
class TestDatabaseURIBuilder(IDatabaseURIBuilder):
def get_uri(self):
return "connect.to.me"
2. Register Services
Create an instance of the ServiceContainer
and register your services with appropriate lifetimes:
# Create the service container
services = ServiceContainer()
# Register services
services.add_transient(IDatabaseURIBuilder, TestDatabaseURIBuilder)
services.add_scoped(IDatabaseConnection, DatabaseConnection)
3. Resolve Services
Retrieve and utilise services from the ServiceCollection
. When retrieving services from the ServiceContainer
, services referenced in constructors (__init__
) will be automatically resolved.
You can also overwrite any constructor arguments when retrieving services:
with services.create_scope() as service_scope:
db = service_scope[IDatabaseConnection](table_name="foobar")
result = db.query("SELECT *")
print(result)
# Output:
# "Connected to database: connect.to.me"
# "Executing query: SELECT * on foobar"
# "Disconnected from database: connect.to.me"
NOTE: PyJudo will automatically "dispose" scoped services which implement
IDisposable
(i.e. have adispose()
method) by callingdispose()
on them when the service scope exits.
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
Built Distribution
File details
Details for the file pyjudo-0.5.1.tar.gz
.
File metadata
- Download URL: pyjudo-0.5.1.tar.gz
- Upload date:
- Size: 60.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2ca3835a25ed3eb2ec6ebde1f509eca4f6158cbf52559621c8f950828daba114 |
|
MD5 | ba2630b0fe1f63c1f4b4ac58e02a37f5 |
|
BLAKE2b-256 | 9e7fb71dd05e91cbf3a4de324ac3aaa7e4a8a33f54f3192e33b05e73191e5940 |
Provenance
The following attestation bundles were made for pyjudo-0.5.1.tar.gz
:
Publisher:
publish-to-pypi.yml
on NixonInnes/pyjudo
-
Statement type:
https://in-toto.io/Statement/v1
- Predicate type:
https://docs.pypi.org/attestations/publish/v1
- Subject name:
pyjudo-0.5.1.tar.gz
- Subject digest:
2ca3835a25ed3eb2ec6ebde1f509eca4f6158cbf52559621c8f950828daba114
- Sigstore transparency entry: 147990838
- Sigstore integration time:
- Predicate type:
File details
Details for the file pyjudo-0.5.1-py3-none-any.whl
.
File metadata
- Download URL: pyjudo-0.5.1-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 205d17ab7dfccd2d0ac451e6b6fe3a9633cbe6dc4f217939aa29f893ef30d8e2 |
|
MD5 | 330115f0b47a1ff98017a717bb9f848b |
|
BLAKE2b-256 | d950ee8310694fc985a366fe190e24d2da41473d76e0cc49d1d09cc28162e692 |
Provenance
The following attestation bundles were made for pyjudo-0.5.1-py3-none-any.whl
:
Publisher:
publish-to-pypi.yml
on NixonInnes/pyjudo
-
Statement type:
https://in-toto.io/Statement/v1
- Predicate type:
https://docs.pypi.org/attestations/publish/v1
- Subject name:
pyjudo-0.5.1-py3-none-any.whl
- Subject digest:
205d17ab7dfccd2d0ac451e6b6fe3a9633cbe6dc4f217939aa29f893ef30d8e2
- Sigstore transparency entry: 147990839
- Sigstore integration time:
- Predicate type: