Skip to content

Commit

Permalink
stop multidimensional arrays from breaking FastAPIWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
dantownsend committed Mar 13, 2024
1 parent 957895c commit d341fdb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 17 deletions.
42 changes: 31 additions & 11 deletions piccolo_api/fastapi/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from inspect import Parameter, Signature, isclass

from fastapi import APIRouter, FastAPI, Request, status
from fastapi.params import Query
from fastapi.params import Body, Query
from pydantic import BaseModel as PydanticBaseModel
from pydantic.main import BaseModel

Expand Down Expand Up @@ -120,6 +120,17 @@ def _get_type(type_: t.Type) -> t.Type:
return type_


def _is_multidimensional_array(type_: t.Type) -> bool:
"""
Returns ``True`` if ``_type`` is list[list].
"""
if t.get_origin(type_) is list:
args = t.get_args(type_)
if args and t.get_origin(args[0]) is list:
return True
return False


class FastAPIWrapper:
"""
Wraps ``PiccoloCRUD`` so it can easily be integrated into FastAPI.
Expand Down Expand Up @@ -325,9 +336,9 @@ async def post(request: Request, model):
"""
return await piccolo_crud.root(request=request)

post.__annotations__[
"model"
] = f"ANNOTATIONS['{self.alias}']['ModelIn']"
post.__annotations__["model"] = (
f"ANNOTATIONS['{self.alias}']['ModelIn']"
)

fastapi_app.add_api_route(
path=root_url,
Expand Down Expand Up @@ -386,9 +397,9 @@ async def put(row_id: str, request: Request, model):
"""
return await piccolo_crud.detail(request=request)

put.__annotations__[
"model"
] = f"ANNOTATIONS['{self.alias}']['ModelIn']"
put.__annotations__["model"] = (
f"ANNOTATIONS['{self.alias}']['ModelIn']"
)

fastapi_app.add_api_route(
path=self.join_urls(root_url, "/{row_id:str}/"),
Expand All @@ -410,9 +421,9 @@ async def patch(row_id: str, request: Request, model):
"""
return await piccolo_crud.detail(request=request)

patch.__annotations__[
"model"
] = f"ANNOTATIONS['{self.alias}']['ModelOptional']"
patch.__annotations__["model"] = (
f"ANNOTATIONS['{self.alias}']['ModelOptional']"
)

fastapi_app.add_api_route(
path=self.join_urls(root_url, "/{row_id:str}/"),
Expand Down Expand Up @@ -462,11 +473,20 @@ def modify_signature(
assert annotation is not None
type_ = _get_type(annotation)

# Multidimensional arrays can't be used as query params - only
# body params. For now, we'll use a body param, so it doesn't
# crash, but will explore other options in the future (perhaps a
# string query param with a special query syntax for filtering
# multidimensional arrays).
param_class = (
Body if _is_multidimensional_array(type_=type_) else Query
)

parameters.append(
Parameter(
name=field_name,
kind=Parameter.POSITIONAL_OR_KEYWORD,
default=Query(
default=param_class(
default=None,
description=(f"Filter by the `{field_name}` column."),
),
Expand Down
12 changes: 6 additions & 6 deletions requirements/dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
black==23.7.0
isort==5.12.0
twine==4.0.2
mypy==1.5.1
black==24.2.0
isort==5.13.2
twine==5.0.0
mypy==1.9.0
pip-upgrader==1.4.15
wheel==0.41.2
setuptools==68.2.2
wheel==0.43.0
setuptools==69.2.0
1 change: 1 addition & 0 deletions tests/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Run it from the root of the project using `python -m tests.serve`.
"""

import os

import uvicorn
Expand Down

0 comments on commit d341fdb

Please sign in to comment.