diff --git a/fastapi/__init__.py b/fastapi/__init__.py index 326428564..2ee3cdd2e 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.1.2" +__version__ = "0.1.3" from .applications import FastAPI from .routing import APIRouter diff --git a/fastapi/routing.py b/fastapi/routing.py index 4293f97ff..6349fa9b6 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -1,5 +1,6 @@ import asyncio import inspect +import logging from typing import Any, Callable, List, Optional, Type from fastapi import params @@ -47,21 +48,30 @@ def get_app( is_body_form = body_field and isinstance(body_field.schema, params.Form) async def app(request: Request) -> Response: - body = None - if body_field: - if is_body_form: - raw_body = await request.form() - body = {} - for field, value in raw_body.items(): - if isinstance(value, UploadFile): - body[field] = await value.read() - else: - body[field] = value - else: - body = await request.json() - values, errors = await solve_dependencies( - request=request, dependant=dependant, body=body - ) + try: + body = None + if body_field: + if is_body_form: + raw_body = await request.form() + body = {} + for field, value in raw_body.items(): + if isinstance(value, UploadFile): + body[field] = await value.read() + else: + body[field] = value + else: + body = await request.json() + except Exception: + raise HTTPException( + status_code=400, detail="There was an error parsing the body" + ) + try: + values, errors = await solve_dependencies( + request=request, dependant=dependant, body=body + ) + except Exception as e: + logging.error("Error solving dependencies", e) + raise HTTPException(status_code=400, detail="Error processing request") if errors: errors_out = ValidationError(errors) raise HTTPException( @@ -77,7 +87,10 @@ def get_app( return raw_response if isinstance(raw_response, BaseModel): return content_type( - content=jsonable_encoder(raw_response), status_code=status_code + content=serialize_response( + field=response_field, response=raw_response + ), + status_code=status_code, ) errors = [] try: diff --git a/tests/main.py b/tests/main.py index 697c2e520..5847a6dc7 100644 --- a/tests/main.py +++ b/tests/main.py @@ -67,87 +67,87 @@ def get_path_param_required_id(item_id: str = Path(...)): @app.get("/path/param-minlength/{item_id}") -def get_path_param_min_length(item_id: str = Path(..., min_length = 3)): +def get_path_param_min_length(item_id: str = Path(..., min_length=3)): return item_id @app.get("/path/param-maxlength/{item_id}") -def get_path_param_max_length(item_id: str = Path(..., max_length = 3)): +def get_path_param_max_length(item_id: str = Path(..., max_length=3)): return item_id @app.get("/path/param-min_maxlength/{item_id}") -def get_path_param_min_max_length(item_id: str = Path(..., max_length = 3, min_length = 2)): +def get_path_param_min_max_length(item_id: str = Path(..., max_length=3, min_length=2)): return item_id @app.get("/path/param-gt/{item_id}") -def get_path_param_gt(item_id: float = Path(..., gt = 3)): +def get_path_param_gt(item_id: float = Path(..., gt=3)): return item_id @app.get("/path/param-gt0/{item_id}") -def get_path_param_gt0(item_id: float = Path(..., gt = 0)): +def get_path_param_gt0(item_id: float = Path(..., gt=0)): return item_id @app.get("/path/param-ge/{item_id}") -def get_path_param_ge(item_id: float = Path(..., ge = 3)): +def get_path_param_ge(item_id: float = Path(..., ge=3)): return item_id @app.get("/path/param-lt/{item_id}") -def get_path_param_lt(item_id: float = Path(..., lt = 3)): +def get_path_param_lt(item_id: float = Path(..., lt=3)): return item_id @app.get("/path/param-lt0/{item_id}") -def get_path_param_lt0(item_id: float = Path(..., lt = 0)): +def get_path_param_lt0(item_id: float = Path(..., lt=0)): return item_id @app.get("/path/param-le/{item_id}") -def get_path_param_le(item_id: float = Path(..., le = 3)): +def get_path_param_le(item_id: float = Path(..., le=3)): return item_id @app.get("/path/param-lt-gt/{item_id}") -def get_path_param_lt_gt(item_id: float = Path(..., lt = 3, gt = 1)): +def get_path_param_lt_gt(item_id: float = Path(..., lt=3, gt=1)): return item_id @app.get("/path/param-le-ge/{item_id}") -def get_path_param_le_ge(item_id: float = Path(..., le = 3, ge = 1)): +def get_path_param_le_ge(item_id: float = Path(..., le=3, ge=1)): return item_id @app.get("/path/param-lt-int/{item_id}") -def get_path_param_lt_int(item_id: int = Path(..., lt = 3)): +def get_path_param_lt_int(item_id: int = Path(..., lt=3)): return item_id @app.get("/path/param-gt-int/{item_id}") -def get_path_param_gt_int(item_id: int = Path(..., gt = 3)): +def get_path_param_gt_int(item_id: int = Path(..., gt=3)): return item_id @app.get("/path/param-le-int/{item_id}") -def get_path_param_le_int(item_id: int = Path(..., le = 3)): +def get_path_param_le_int(item_id: int = Path(..., le=3)): return item_id @app.get("/path/param-ge-int/{item_id}") -def get_path_param_ge_int(item_id: int = Path(..., ge = 3)): +def get_path_param_ge_int(item_id: int = Path(..., ge=3)): return item_id @app.get("/path/param-lt-gt-int/{item_id}") -def get_path_param_lt_gt_int(item_id: int = Path(..., lt = 3, gt = 1)): +def get_path_param_lt_gt_int(item_id: int = Path(..., lt=3, gt=1)): return item_id @app.get("/path/param-le-ge-int/{item_id}") -def get_path_param_le_ge_int(item_id: int = Path(..., le = 3, ge = 1)): +def get_path_param_le_ge_int(item_id: int = Path(..., le=3, ge=1)): return item_id diff --git a/tests/test_path.py b/tests/test_path.py index d46604e61..cde7a9d02 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -38,104 +38,124 @@ response_not_valid_float = { ] } -response_at_least_3 = {"detail":[{"loc":["path","item_id"],"msg":"ensure this value has at least 3 characters","type":"value_error.any_str.min_length","ctx":{"limit_value":3}}]} +response_at_least_3 = { + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value has at least 3 characters", + "type": "value_error.any_str.min_length", + "ctx": {"limit_value": 3}, + } + ] +} -response_at_least_2 = {"detail":[{"loc":["path","item_id"],"msg":"ensure this value has at least 2 characters","type":"value_error.any_str.min_length","ctx":{"limit_value":2}}]} +response_at_least_2 = { + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value has at least 2 characters", + "type": "value_error.any_str.min_length", + "ctx": {"limit_value": 2}, + } + ] +} -response_maximum_3 = {"detail":[{"loc":["path","item_id"],"msg":"ensure this value has at most 3 characters","type":"value_error.any_str.max_length","ctx":{"limit_value":3}}]} +response_maximum_3 = { + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value has at most 3 characters", + "type": "value_error.any_str.max_length", + "ctx": {"limit_value": 3}, + } + ] +} response_greater_than_3 = { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "ensure this value is greater than 3", - "type": "value_error.number.not_gt", - "ctx": { - "limit_value": 3 - } - } - ] + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is greater than 3", + "type": "value_error.number.not_gt", + "ctx": {"limit_value": 3}, + } + ] } response_greater_than_0 = { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "ensure this value is greater than 0", - "type": "value_error.number.not_gt", - "ctx": { - "limit_value": 0 - } - } - ] + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is greater than 0", + "type": "value_error.number.not_gt", + "ctx": {"limit_value": 0}, + } + ] } response_greater_than_1 = { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "ensure this value is greater than 1", - "type": "value_error.number.not_gt", - "ctx": { - "limit_value": 1 - } - } - ] + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is greater than 1", + "type": "value_error.number.not_gt", + "ctx": {"limit_value": 1}, + } + ] } -response_greater_than_equal_3 = {"detail":[{"loc":["path","item_id"],"msg":"ensure this value is greater than or equal to 3","type":"value_error.number.not_ge","ctx":{"limit_value":3}}]} +response_greater_than_equal_3 = { + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is greater than or equal to 3", + "type": "value_error.number.not_ge", + "ctx": {"limit_value": 3}, + } + ] +} response_less_than_3 = { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "ensure this value is less than 3", - "type": "value_error.number.not_lt", - "ctx": { - "limit_value": 3 - } - } - ] + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is less than 3", + "type": "value_error.number.not_lt", + "ctx": {"limit_value": 3}, + } + ] } response_less_than_0 = { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "ensure this value is less than 0", - "type": "value_error.number.not_lt", - "ctx": { - "limit_value": 0 - } - } - ] + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is less than 0", + "type": "value_error.number.not_lt", + "ctx": {"limit_value": 0}, + } + ] } -response_less_than_equal_3 = {"detail":[{"loc":["path","item_id"],"msg":"ensure this value is less than or equal to 3","type":"value_error.number.not_le","ctx":{"limit_value":3}}]} +response_less_than_equal_3 = { + "detail": [ + { + "loc": ["path", "item_id"], + "msg": "ensure this value is less than or equal to 3", + "type": "value_error.number.not_le", + "ctx": {"limit_value": 3}, + } + ] +} @pytest.mark.parametrize(