Skip to content

Commit

Permalink
update readme and remove comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan committed Jul 26, 2024
1 parent f95175e commit 118d19e
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 7 deletions.
126 changes: 122 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Injection

![PyPI - Version](https://img.shields.io/pypi/v/deps-injection?label=pypi%20version)
[![GitHub license](https://img.shields.io/github/license/nightblure/injection)](https://github.com/nightblure/injection/blob/main/LICENSE)
![GitHub License](https://img.shields.io/github/license/nightblure/injection?color=012111012)

![PyPI - Python Version](https://img.shields.io/pypi/pyversions/deps-injection)

Expand All @@ -13,14 +13,132 @@

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)
![GitHub Repo stars](https://img.shields.io/github/stars/nightblure/injection)
[![Maintainability](https://api.codeclimate.com/v1/badges/1da49eb0b28eacae4624/maintainability)](https://codeclimate.com/github/nightblure/injection/maintainability)

![PyPI - Month Downloads](https://img.shields.io/pypi/dm/deps-injection?color=102255102)
![GitHub Repo stars](https://img.shields.io/github/stars/nightblure/injection)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/nightblure/injection/total?color=102255102&label=Total%20downloads)
![PyPI - Month Downloads](https://img.shields.io/pypi/dm/deps-injection?color=102255102)

---

## Features
Easy dependency injection for all, works with Python 3.8-3.12. Main features and advantages:
* support **Python 3.8-3.12**;
* works with **FastAPI, Flask, Litestar** and **Django REST Framework**;
* dependency injection via `Annotated` in FastAPI;
* **no third-party dependencies**;
* **multiple containers**;
* **overriding** dependencies for tests without wiring;
* **100%** code coverage and very simple code;
* good [documentation](https://injection.readthedocs.io/latest/).

---

## Installation
```shell
pip install deps-injection
```

## Using example

```python3
import sys

if sys.version_info >= (3, 9):
from typing import Annotated
else:
from typing import Annotated
from unittest.mock import Mock

import pytest
from fastapi import APIRouter, Depends, FastAPI
from fastapi.testclient import TestClient
from injection import DeclarativeContainer, Provide, inject, providers


class Settings:
redis_url: str = "redis://localhost"
redis_port: int = 6379


class Redis:
def __init__(self, *, url: str, port: int):
self.uri = url + ":" + str(port)
self.url = url
self.port = port

def get(self, key):
return key


class Container(DeclarativeContainer):
settings = providers.Singleton(Settings)
redis = providers.Singleton(
Redis,
port=settings.provided.redis_port,
url=settings.provided.redis_url,
)


router = APIRouter(prefix="/api")


def create_app():
app = FastAPI()
app.include_router(router)
return app


RedisDependency = Annotated[Redis, Depends(Provide["redis"])]
RedisDependencyExplicit = Annotated[Redis, Depends(Provide[Container.redis])]


@router.get("/values")
@inject
def some_get_endpoint_handler(redis: RedisDependency):
value = redis.get(299)
return {"detail": value}


@router.post("/values")
@inject
async def some_get_async_endpoint_handler(redis: RedisDependencyExplicit):
value = redis.get(399)
return {"detail": value}


###################### TESTING ######################
@pytest.fixture(scope="session")
def app():
return create_app()


@pytest.fixture(scope="session")
def container():
return Container.instance()


@pytest.fixture()
def test_client(app):
client = TestClient(app)
return client


def test_override_providers(test_client, container):
def mock_get_method(_):
return "mock_get_method"

mock_redis = Mock()
mock_redis.get = mock_get_method

providers_to_override = {"redis": mock_redis}

with container.override_providers(providers_to_override):
response = test_client.get("/api/values")

assert response.status_code == 200
body = response.json()
assert body["detail"] == "mock_get_method"

```

---
3 changes: 0 additions & 3 deletions tests/test_integrations/test_fastapi/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
@asynccontextmanager
async def lifespan_handler(_):
yield
# Container.wire()
# yield
# Container.unwire()


def create_app():
Expand Down

0 comments on commit 118d19e

Please sign in to comment.