Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upd tests and docs about using with litestar #21

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pip install deps-injection
| [FastAPI](https://github.com/fastapi/fastapi) | ✅ | ✅ | ➖ |
| [Flask](https://github.com/pallets/flask) | ✅ | ✅ | ✅ |
| [Django REST Framework](https://github.com/encode/django-rest-framework) | ✅ | ✅ | ✅ |
| [Litestar](https://github.com/litestar-org/litestar) | ✅ | ⚠️ | ➖ | ➖ |
| [Litestar](https://github.com/litestar-org/litestar) | ✅ | | ➖ | ➖ |


## Using example with FastAPI
Expand Down
37 changes: 29 additions & 8 deletions docs/integration-with-web-frameworks/litestar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

In order to successfully inject dependencies into Litestar request handlers,
make sure that the following points are completed:
1. use **@inject** decorator **before** http-method Litestar decorator;
1. use `@inject` decorator **before** http-method `Litestar` decorator;

2. ⚠️ added for each injected parameter to the request handler a typing of the form
`Union[<your type>, Any]` for Python versions below 3.10 or `<your type> | Any`;
2. added for each injected parameter to the request handler a typing of the form
`Annotated[<your type>, Dependency(skip_validation=True)]`. `Dependency` is object from `litestar.params`;

3. use the `Provide` marker from the `injection` (not from Litestar) package indicating the provider

Expand All @@ -14,10 +14,17 @@ make sure that the following points are completed:
## Example

```python3
from typing import Any, Union
from functools import partial
from unittest.mock import Mock
from typing import Annotated

from litestar import Litestar, get
from injection import Provide, inject, DeclarativeContainer, providers
from litestar import Litestar, get
from litestar.params import Dependency
from litestar.testing import TestClient


_NoValidationDependency = partial(Dependency, skip_validation=True)


class Redis:
Expand Down Expand Up @@ -45,8 +52,8 @@ class Container(DeclarativeContainer):
)
@inject
async def litestar_endpoint(
redis: Union[Redis, Any] = Provide[Container.redis],
num: Union[int, Any] = Provide[Container.num],
num: Annotated[int, _NoValidationDependency()] = Provide[Container.num],
redis: Annotated[Redis, _NoValidationDependency()] = Provide[Container.redis],
) -> dict:
value = redis.get(800)
return {"detail": value, "num2": num}
Expand All @@ -58,7 +65,7 @@ async def litestar_endpoint(
)
@inject
async def litestar_endpoint_object_provider(
num: Union[int, Any] = Provide[Container.num],
num: Annotated[int, _NoValidationDependency()] = Provide[Container.num],
) -> dict:
return {"detail": num}

Expand All @@ -69,4 +76,18 @@ _handlers = [
]

app = Litestar(route_handlers=_handlers)

# Testing

def test_litestar_overriding():
mock_instance = Mock(get=lambda _: 192342526)
override_providers = {"redis": mock_instance, "num": -2999999999}

with TestClient(app=app) as client:
with Container.override_providers(override_providers):
response = client.get("/some_resource")

assert response.status_code == 200
assert response.json() == {"detail": 192342526, "num2": -2999999999}

```
18 changes: 14 additions & 4 deletions tests/integration/test_litestar/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
import sys
from functools import partial
from typing import Any, Union
from unittest.mock import Mock

import pytest
from litestar import Controller, Litestar, get
from litestar.params import Dependency
from litestar.testing import TestClient

from injection import Provide, inject
from tests.container_objects import Container, Redis

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

_NoValidationDependency = partial(Dependency, skip_validation=True)


@get(
"/some_resource",
status_code=200,
)
@inject
async def litestar_endpoint(
redis: Union[Redis, Any] = Provide[Container.redis],
num: Union[int, Any] = Provide[Container.num2],
redis: Annotated[Redis, _NoValidationDependency()] = Provide[Container.redis],
num: Annotated[int, _NoValidationDependency()] = Provide[Container.num2],
) -> dict:
value = redis.get(800)
return {"detail": value, "num2": num}
Expand All @@ -41,8 +51,8 @@ class LitestarController(Controller):
async def controller_endpoint(
self,
redis_key: int,
redis: Union[Redis, Any] = Provide[Container.redis],
num: Union[int, Any] = Provide[Container.num2],
redis: Annotated[Redis, _NoValidationDependency()] = Provide[Container.redis],
num: Annotated[int, _NoValidationDependency()] = Provide[Container.num2],
) -> dict:
value = redis.get(redis_key)
return {"detail": value, "num2": num}
Expand Down