Skip to main content

Simple yet powerful dependency injection framework!

Project description

Pure DI

test pypi python

Source Code: https://github.com/lionsoon/pure_di Features:

  • Lightweight - no external dependencies (only typing_extensions)
  • Based on type hints - no configuration required, less boilerplate
  • Pytest integration - writing unit tests was never so easy!
  • yeild powered - just yeild your component and then write closing steps
  • Async support - sometimes we need await something in build process

Install

pip install pure-di

Example

Let's assume we have following services.py file, witch contains components we want to construct.
For example to be more "real-world" we will use httpx and sqlalchemy packages:

# services.py
import ...

@dataclass
class Settings:
    db_uri: str

@dataclass
class Database:
    engine: AsyncEngine

@dataclass
class Application:
    client: httpx.AsyncClient
    database: Database
    
    async def run(self): ...

The main concept of pure_di is Provider (and AsyncProvider if we need async).
Providers consist of factories - callables that build components. Factories are included to the provider using provider.include_factory method.
All factory arguments should be annotated. And return type should be specified either by return annotation, or by service_type argument (see example below).

Let's create an AsyncProvider for our services in provider.py file:

# provider.py
import httpx
from pure_di import AsyncProvider
from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine

from services import Settings, Database, Application

provider = AsyncProvider()


@provider.include_factory
def provide_settings() -> Settings:
    return Settings(db_uri="sqlite://...")


@provider.include_factory(service_type=AsyncEngine)
async def provide_engine(settings: Settings):
    engine = create_async_engine(settings.db_uri)
    yield engine
    await engine.dispose()


provider.include_factory(Database, service_type=Database)
provider.include_factory(Application, service_type=Application)

Now in main.py we can use provider.build_async method to construct Container. Container is similar to dict, where keys are services types, and values are services. It also contains container.partial_solve method that works similar to functools.partial and solves those arguments whose types it contains.

# main.py
from provider import provider
from services import Database, Application

async def do_some_work(database: Database, some_data):
    ...

async def main():
    async with provider.build_async() as container:
        partial_solved_do_some_work = container.partial_solve(do_some_work)
        await partial_solved_do_some_work(some_data="some_data")
        application = container[Application]
        await application.run()

Test

Let's write some tests using same example and pytest

from pure_di.pytest import pytest_provide_async

from provider import provider
from services import Database
from main import do_some_work


@Provider.from_factory(service_type=Database)
def mock_database():
    return ...


@pytest_provide_async(provider | mock_database)
@pytest.mark.asyncio
async def test_do_some_work(mocked_database: Database, any_usual_fixture):
    await do_some_work(mocked_database, some_data="some_data")
    assert mocked_database.something_to_assert()

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

pure-di-0.0.1.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

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

pure_di-0.0.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file pure-di-0.0.1.tar.gz.

File metadata

  • Download URL: pure-di-0.0.1.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.2

File hashes

Hashes for pure-di-0.0.1.tar.gz
Algorithm Hash digest
SHA256 d55a730478e43424eb1e0a9edac4cee0f846a2e21ba3e80bfe1df255890abfa0
MD5 63bbad8b1adae3a390aca953b6e26c18
BLAKE2b-256 b3afff049792c7078698f0a0510e605b6209fd89291a530bcc36c8ab8b2dec0d

See more details on using hashes here.

File details

Details for the file pure_di-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: pure_di-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.2

File hashes

Hashes for pure_di-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 90b2b0307c445fadfd14b642708364f4e85d815803fb0dc897e883eab5b4a059
MD5 0bb02e50670d2a7e3d2f89cd9c930a23
BLAKE2b-256 9343b4d07b0724e824f42cdc2cd9f772e615cb9d1e85ecdef403349f186ffa4c

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