Skip to content

Commit fc587ed

Browse files
authored
Merge pull request #108 from kouk/async-support
Support async views. Fixes #91
2 parents 7b941cc + ef87a0d commit fc587ed

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ Feature requests and pull requests are welcome. For major changes, please open a
335335
python3 -m venv venv
336336
source venv/bin/activate
337337
```
338+
- install runtime dependencies
339+
```bash
340+
python3 -m pip install -e .
341+
```
338342
- install development requirements
339343
```bash
340344
python3 -m pip install -r requirements/test.txt

flask_pydantic/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def wrapper(*args, **kwargs):
282282
return make_response(
283283
jsonify({"validation_error": err}), status_code
284284
)
285-
res = func(*args, **kwargs)
285+
res = current_app.ensure_sync(func)(*args, **kwargs)
286286

287287
if response_many:
288288
if is_iterable_of_models(res):

requirements/test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ pytest-flask
33
pytest-coverage
44
pytest-mock
55
pytest-ruff
6+
Flask[async]

tests/func/test_app.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import re
23
from typing import List, Optional
34

@@ -147,6 +148,21 @@ def compute(query: RequestModel):
147148
)
148149

149150

151+
@pytest.fixture
152+
def app_with_async_route(app):
153+
class RequestModel(BaseModel):
154+
n: int
155+
156+
class ResultModel(BaseModel):
157+
result: int
158+
159+
@app.route("/compute", methods=["POST"])
160+
@validate()
161+
async def compute(body: RequestModel):
162+
await asyncio.sleep(0.1)
163+
return ResultModel(result=2 * body.n)
164+
165+
150166
test_cases = [
151167
pytest.param(
152168
"?limit=limit",
@@ -469,3 +485,34 @@ def test_silent(self, client):
469485
response.json["body"],
470486
)
471487
assert response.status_code == 422
488+
489+
490+
@pytest.mark.usefixtures("app_with_async_route")
491+
class TestAsyncRoute:
492+
def test_fails(self, client):
493+
response = client.post("/compute", json={})
494+
495+
assert_matches(
496+
{
497+
"validation_error": {
498+
"body_params": [
499+
{
500+
"input": {},
501+
"loc": ["n"],
502+
"msg": "Field required",
503+
"type": "missing",
504+
"url": re.compile(
505+
r"https://errors\.pydantic\.dev/.*/v/missing"
506+
),
507+
}
508+
]
509+
}
510+
},
511+
response.json,
512+
)
513+
514+
def test_succeeds(self, client):
515+
expected_response = {"result": 2}
516+
response = client.post("/compute", json={"n": 1})
517+
518+
assert_matches(expected_response, response.json)

0 commit comments

Comments
 (0)