Skip to content

Commit c940ff0

Browse files
committed
Merge branch 'release/0.1.3'
2 parents 8b9ae84 + 5dad56e commit c940ff0

File tree

5 files changed

+136
-43
lines changed

5 files changed

+136
-43
lines changed

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,71 @@ taskiq_aiohttp.init(broker, "project.module:app")
2626
It adds startup functions to the broker, so it imports your aiohttp application and creates a single worker-wide Request and Application objects that you can depend on.
2727

2828
THIS REQUEST IS NOT RELATED TO THE ACTUAL REQUESTS IN AioHTTP! This request won't have actual data about the request you were handling while sending a task.
29+
30+
31+
## Manual context updates
32+
33+
Sometimes it's required to update context manually. For example, for tests.
34+
If you need to add context in your broker by hand, please use function populate_context.
35+
36+
Imagine, you want to use InMemoryBroker for testing and your broker file looks like this:
37+
38+
```python
39+
broker = MyBroker()
40+
41+
if env == "pytest":
42+
broker = InMemoryBroker()
43+
```
44+
45+
In this case your context won't be updated, because inmemory brokers cannot run as workers.
46+
To solve this issue, we have a populate context function. It's a bit complex and takes lots of
47+
parmeters. But here's a fixture that creates aiohttp test client and populates context of inmemory broker.
48+
49+
```python
50+
import asyncio
51+
from typing import AsyncGenerator
52+
53+
import pytest
54+
from aiohttp import web
55+
from aiohttp.test_utils import BaseTestServer, TestClient, TestServer
56+
from taskiq_aiohttp import populate_context
57+
58+
59+
@pytest.fixture
60+
async def test_client(
61+
app: web.Application,
62+
) -> AsyncGenerator[TestClient, None]:
63+
"""
64+
Create a test client.
65+
66+
This function creates a TestServer
67+
and a test client for the application.
68+
69+
Also this fixture populates context
70+
with needed variables.
71+
72+
:param app: current application.
73+
:yield: ready to use client.
74+
"""
75+
loop = asyncio.get_running_loop()
76+
server = TestServer(app)
77+
client = TestClient(server, loop=loop)
78+
79+
await client.start_server()
80+
81+
# This is important part.
82+
# Since InMemoryBroker doesn't
83+
# run in worker_process, we have to populate
84+
# broker's context manually.
85+
populate_context(
86+
broker=broker,
87+
server=server.runner.server,
88+
app=app,
89+
loop=None,
90+
)
91+
92+
yield client
93+
94+
await client.close()
95+
96+
```

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "taskiq-aiohttp"
33
description = "Taskiq integration with AioHTTP framework"
44
authors = ["Taskiq team <taskiq@no-reply.com>"]
55
maintainers = ["Taskiq team <taskiq@no-reply.com>"]
6-
version = "0.1.2"
6+
version = "0.1.3"
77
readme = "README.md"
88
license = "LICENSE"
99
classifiers = [

taskiq_aiohttp/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Project was generated using taskiq."""
2-
from taskiq_aiohttp.initializer import init
2+
from taskiq_aiohttp.initializer import init, populate_context
33

4-
__all__ = ["init"]
4+
__all__ = ["init", "populate_context"]

taskiq_aiohttp/initializer.py

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,64 @@
1313
from taskiq.cli.utils import import_object
1414

1515

16+
def populate_context(
17+
broker: AsyncBroker,
18+
server: web.Server,
19+
app: web.Application,
20+
loop: asyncio.AbstractEventLoop,
21+
) -> None:
22+
"""
23+
Function to add dependency context.
24+
25+
This function adds base dependency,
26+
that you may need while working with AioHTTP application.
27+
28+
:param broker: current broker.
29+
:param server: current server that handles requests.
30+
:param app: your application.
31+
:param loop: current event loop.
32+
"""
33+
handler = RequestHandler(server, loop=loop)
34+
handler.transport = asyncio.Transport()
35+
request = web.Request(
36+
RawRequestMessage(
37+
"GET",
38+
"/",
39+
HttpVersion10,
40+
headers=CIMultiDictProxy(CIMultiDict()),
41+
raw_headers=(),
42+
should_close=False,
43+
upgrade=False,
44+
chunked=False,
45+
compression=None,
46+
url=yarl.URL.build(
47+
scheme="https",
48+
host="test.com",
49+
path="/",
50+
),
51+
),
52+
None,
53+
handler,
54+
None,
55+
None,
56+
None,
57+
)
58+
59+
request._match_info = UrlMappingMatchInfo(
60+
match_dict={},
61+
route=SystemRoute(web.HTTPBadRequest()),
62+
)
63+
request._match_info._apps = app._subapps
64+
request._match_info._current_app = app
65+
66+
broker.add_dependency_context(
67+
{
68+
web.Application: app,
69+
web.Request: request,
70+
},
71+
)
72+
73+
1674
def startup_event_generator(
1775
broker: AsyncBroker,
1876
app_path: str,
@@ -35,8 +93,6 @@ def startup_event_generator(
3593
"""
3694

3795
async def startup(state: TaskiqState) -> None:
38-
loop = asyncio.get_event_loop()
39-
4096
local_app = app
4197

4298
if not isinstance(local_app, web.Application):
@@ -54,47 +110,16 @@ async def startup(state: TaskiqState) -> None:
54110
if app_runner.server is None:
55111
raise ValueError("Cannot construct aiohttp app to mock requests")
56112

57-
# Creating mocked request
58-
handler = RequestHandler(app_runner.server, loop=loop)
59-
handler.transport = asyncio.Transport()
60-
request = web.Request(
61-
RawRequestMessage(
62-
"GET",
63-
"/",
64-
HttpVersion10,
65-
headers=CIMultiDictProxy(CIMultiDict()),
66-
raw_headers=(),
67-
should_close=False,
68-
upgrade=False,
69-
chunked=False,
70-
compression=None,
71-
url=yarl.URL.build(
72-
scheme="https",
73-
host="test.com",
74-
path="/",
75-
),
76-
),
77-
None,
78-
handler,
79-
None,
80-
None,
81-
None,
82-
)
113+
loop = asyncio.get_running_loop()
83114

84-
request._match_info = UrlMappingMatchInfo(
85-
match_dict={},
86-
route=SystemRoute(web.HTTPBadRequest()),
87-
)
88-
request._match_info._apps = local_app._subapps
89-
request._match_info._current_app = local_app
90-
91-
broker.add_dependency_context(
92-
{
93-
web.Application: local_app,
94-
web.Request: request,
95-
},
115+
populate_context(
116+
broker=broker,
117+
server=app_runner.server,
118+
app=local_app,
119+
loop=loop,
96120
)
97121

122+
# Creating mocked request
98123
state.aiohttp_runner = app_runner
99124
local_app.router._resources = []
100125

taskiq_aiohttp/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)