-
Notifications
You must be signed in to change notification settings - Fork 181
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Not quite clear to me if this is a bug or a feature request as I may be doing something out of the ordinary.
Using class based views, my tests return errors using methods (inside cbv) that have multiple path decorators attached to them. When using vanilla FastAPI without cbv the tests pass.
To Reproduce
Credit to @smparekh for the demo below, which I modified slightly to show the issue.
Simple main.py app:
from fastapi import FastAPI, APIRouter
from fastapi_utils.cbv import cbv
router = APIRouter()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@cbv(router)
class RootHandler:
@router.get("/items/?")
@router.get("/items/{item_path:path}")
@router.get("/database/{item_path:path}")
def root(self, item_path: str = None, item_query: str = None):
if item_path:
return {"item_path": item_path}
elif item_query:
return {"item_query": item_query}
else:
return fake_items_db
app = FastAPI()
app.include_router(router)simple test_main.py
from .main import router
from starlette.testclient import TestClient
from .main import fake_items_db
client = TestClient(router)
def test_item_path():
resp = client.get("items/Bar")
assert resp.status_code == 200
assert resp.json() == {"item_path": "Bar"}
def test_item_query():
resp = client.get("items/?item_query=Bar")
assert resp.status_code == 200
assert resp.json() == {"item_query": "Bar"}
def test_list():
resp = client.get("items/")
assert resp.status_code == 200
assert resp.json() == fake_items_db
def test_database():
resp = client.get("database/")
assert resp.status_code == 200
assert resp.json() == fake_items_dbtraceback
traceback from the first test (others are the same)
=================================== FAILURES ===================================
________________________________ test_item_path ________________________________
def test_item_path():
> resp = client.get("items/Bar")
app/test_main_mult_decorators.py:11:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/requests/sessions.py:546: in get
return self.request('GET', url, **kwargs)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/testclient.py:413: in request
return super().request(
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/requests/sessions.py:533: in request
resp = self.send(prep, **send_kwargs)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/requests/sessions.py:646: in send
r = adapter.send(request, **kwargs)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/testclient.py:243: in send
raise exc from None
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/testclient.py:240: in send
loop.run_until_complete(self.app(scope, receive, send))
../../../miniconda3/envs/web-server-eval/lib/python3.8/asyncio/base_events.py:612: in run_until_complete
return future.result()
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/routing.py:550: in __call__
await route.handle(scope, receive, send)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/routing.py:227: in handle
await self.app(scope, receive, send)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/starlette/routing.py:41: in app
response = await func(request)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
request = <starlette.requests.Request object at 0x118cd3670>
async def app(request: Request) -> Response:
try:
body = None
if body_field:
if is_body_form:
body = await request.form()
else:
body_bytes = await request.body()
if body_bytes:
body = await request.json()
except Exception as e:
logger.error(f"Error getting request body: {e}")
raise HTTPException(
status_code=400, detail="There was an error parsing the body"
) from e
solved_result = await solve_dependencies(
request=request,
dependant=dependant,
body=body,
dependency_overrides_provider=dependency_overrides_provider,
)
values, errors, background_tasks, sub_response, _ = solved_result
if errors:
> raise RequestValidationError(errors, body=body)
E fastapi.exceptions.RequestValidationError: 1 validation error for Request
E query -> self
E field required (type=value_error.missing)
../../../miniconda3/envs/web-server-eval/lib/python3.8/site-packages/fastapi/routing.py:145: RequestValidationErrorExpected behavior
Ideally tests work as in vanilla FastAPI without cbv.
Environment:
- OS: tested on macOS and Linux
>>> import fastapi_utils
>>> import fastapi
>>> import pydantic.utils
>>> import pytest
>>>
>>> print(fastapi_utils.__version__)
0.2.0
>>> print(fastapi.__version__)
0.52.0
>>> print(pydantic.utils.version_info())
pydantic version: 1.4
pydantic compiled: False
install path: /Users/bfalk/miniconda3/envs/web-server-eval/lib/python3.8/site-packages/pydantic
python version: 3.8.1 (default, Jan 8 2020, 16:15:59) [Clang 4.0.1 (tags/RELEASE_401/final)]
platform: macOS-10.14.6-x86_64-i386-64bit
optional deps. installed: ['typing-extensions']
>>> print(pytest.__version__)
5.3.5Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working