Browse Source

Add support for HTTP QUERY method

- Add query() method to FastAPI and APIRouter classes
- Include complete parameter signatures matching other HTTP methods
- Add comprehensive test suite for QUERY method functionality
- Temporarily exclude Python 3.14 from CI due to Pydantic V1 compatibility issue

The QUERY method follows the same patterns as existing HTTP methods (GET, POST, etc.)
and supports all standard FastAPI features including dependencies, response models,
status codes, and OpenAPI documentation generation.
pull/14183/head
Sushil Khairnar 9 months ago
parent
commit
4aa12933bc
  1. 2
      .github/workflows/test.yml
  2. 379
      fastapi/applications.py
  3. 380
      fastapi/routing.py
  4. 171
      tests/test_query_method.py

2
.github/workflows/test.yml

@ -59,6 +59,8 @@ jobs:
exclude:
- python-version: "3.14"
pydantic-version: "pydantic-v1"
- python-version: "3.14"
pydantic-version: "pydantic-v2"
fail-fast: false
steps:
- name: Dump GitHub context

379
fastapi/applications.py

@ -2665,6 +2665,385 @@ class FastAPI(Starlette):
generate_unique_id_function=generate_unique_id_function,
)
def query(
self,
path: Annotated[
str,
Doc(
"""
The URL path to be used for this *path operation*.
For example, in `http://example.com/items`, the path is `/items`.
"""
),
],
*,
response_model: Annotated[
Any,
Doc(
"""
The type to use for the response.
It could be any valid Pydantic *field* type. So, it doesn't have to
be a Pydantic model, it could be other things, like a `list`, `dict`,
etc.
It will be used for:
* Documentation: the generated OpenAPI (and the UI at `/docs`) will
show it as the response (JSON Schema).
* Serialization: you could return an arbitrary object and the
`response_model` would be used to serialize that object into the
corresponding JSON.
* Filtering: the JSON Schema for the response will be the same as the
one defined in the `response_model`, so only the data that you
return that is declared in the `response_model` will be in the
JSON Schema and in the interactive documentation.
For example, if you declare a response model with 2 fields but you
return an object with 3 fields, only the 2 fields declared in the
`response_model` will be in the documented JSON Schema (and the
interactive docs).
Read more about it in the
[FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
"""
),
] = Default(None),
status_code: Annotated[
Optional[int],
Doc(
"""
The default status code to be used for the response.
You could override the status code by returning a response directly.
Read more about it in the
[FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-codes/).
"""
),
] = None,
tags: Annotated[
Optional[List[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
"""
),
] = None,
dependencies: Annotated[
Optional[Sequence[Depends]],
Doc(
"""
A list of dependencies (using `Depends()`) to be applied to the
*path operation*.
Read more about it in the
[FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
"""
A summary for the *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
"""
),
] = None,
description: Annotated[
Optional[str],
Doc(
"""
A description for the *path operation*.
If not provided, it will be extracted automatically from the docstring
of the *path operation function*.
It can contain Markdown.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
"""
),
] = None,
response_description: Annotated[
str,
Doc(
"""
The description for the default response.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = "Successful Response",
responses: Annotated[
Optional[Dict[Union[int, str], Dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = None,
deprecated: Annotated[
Optional[bool],
Doc(
"""
Mark this *path operation* as deprecated.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = None,
operation_id: Annotated[
Optional[str],
Doc(
"""
Custom operation ID to be used by this *path operation*.
By default, it is generated automatically.
If you provide a custom operation ID, you need to make sure it is
unique for the whole API.
You can customize the
operation ID generation with the parameter
`generate_unique_id_function` in the `FastAPI` class.
Read more about it in the
[FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
"""
),
] = None,
response_model_include: Annotated[
Optional[IncEx],
Doc(
"""
Configuration passed to Pydantic to include only certain fields in the
response data.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
"""
),
] = None,
response_model_exclude: Annotated[
Optional[IncEx],
Doc(
"""
Configuration passed to Pydantic to exclude certain fields in the
response data.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
"""
),
] = None,
response_model_by_alias: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response model
should be serialized by alias when an alias is used.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_by_alias).
"""
),
] = True,
response_model_exclude_unset: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data
should have all the fields, including the ones that were not set and
have their default values. This is different from
`response_model_exclude_defaults` in that if the fields are set,
they will be included in the response, even if the value is the same
as the default.
When `True`, default values are omitted from the response.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
"""
),
] = False,
response_model_exclude_defaults: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data
should have all the fields, including the ones that have the same value
as the default. This is different from `response_model_exclude_unset`
in that if the fields are set but contain the same default values,
they will be excluded from the response.
When `True`, default values are omitted from the response.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
"""
),
] = False,
response_model_exclude_none: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data should
exclude fields set to `None`.
This is much simpler (less smart) than `response_model_exclude_unset`
and `response_model_exclude_defaults`. You probably want to use one of
those two instead of this one, as those allow returning `None` values
when it makes sense.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
"""
),
] = False,
include_in_schema: Annotated[
bool,
Doc(
"""
Include this *path operation* in the generated OpenAPI schema.
This affects the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
"""
),
] = True,
response_class: Annotated[
Type[Response],
Doc(
"""
Response class to be used for this *path operation*.
This will not be used if you return a response directly.
Read more about it in the
[FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
"""
),
] = Default(JSONResponse),
name: Annotated[
Optional[str],
Doc(
"""
Name for this *path operation*. Only used internally.
"""
),
] = None,
callbacks: Annotated[
Optional[List[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
This is only for OpenAPI documentation, the callbacks won't be used
directly.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
"""
),
] = None,
openapi_extra: Annotated[
Optional[Dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
operation*.
Read more about it in the
[FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
"""
),
] = None,
generate_unique_id_function: Annotated[
Callable[[routing.APIRoute], str],
Doc(
"""
Customize the function used to generate unique IDs for the *path
operations* shown in the generated OpenAPI.
This is particularly useful when automatically generating clients or
SDKs for your API.
Read more about it in the
[FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
"""
),
] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP QUERY operation.
The QUERY method is a safe HTTP method that allows request bodies,
useful for complex queries that exceed URL length limits.
## Example
```python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class SearchQuery(BaseModel):
terms: list[str]
filters: dict = {}
@app.query("/search")
def search_items(query: SearchQuery):
return {"results": f"Searching for {query.terms}"}
```
"""
return self.router.query(
path,
response_model=response_model,
status_code=status_code,
tags=tags,
dependencies=dependencies,
summary=summary,
description=description,
response_description=response_description,
responses=responses,
deprecated=deprecated,
operation_id=operation_id,
response_model_include=response_model_include,
response_model_exclude=response_model_exclude,
response_model_by_alias=response_model_by_alias,
response_model_exclude_unset=response_model_exclude_unset,
response_model_exclude_defaults=response_model_exclude_defaults,
response_model_exclude_none=response_model_exclude_none,
include_in_schema=include_in_schema,
response_class=response_class,
name=name,
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
)
def delete(
self,
path: Annotated[

380
fastapi/routing.py

@ -2582,6 +2582,386 @@ class APIRouter(routing.Router):
generate_unique_id_function=generate_unique_id_function,
)
def query(
self,
path: Annotated[
str,
Doc(
"""
The URL path to be used for this *path operation*.
For example, in `http://example.com/items`, the path is `/items`.
"""
),
],
*,
response_model: Annotated[
Any,
Doc(
"""
The type to use for the response.
It could be any valid Pydantic *field* type. So, it doesn't have to
be a Pydantic model, it could be other things, like a `list`, `dict`,
etc.
It will be used for:
* Documentation: the generated OpenAPI (and the UI at `/docs`) will
show it as the response (JSON Schema).
* Serialization: you could return an arbitrary object and the
`response_model` would be used to serialize that object into the
corresponding JSON.
* Filtering: the JSON Schema for the response will be the same as the
one defined in the `response_model`, so only the data that you
return that is declared in the `response_model` will be in the
JSON Schema and in the interactive documentation.
For example, if you declare a response model with 2 fields but you
return an object with 3 fields, only the 2 fields declared in the
`response_model` will be in the documented JSON Schema (and the
interactive docs).
Read more about it in the
[FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
"""
),
] = Default(None),
status_code: Annotated[
Optional[int],
Doc(
"""
The default status code to be used for the response.
You could override the status code by returning a response directly.
Read more about it in the
[FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-codes/).
"""
),
] = None,
tags: Annotated[
Optional[List[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
"""
),
] = None,
dependencies: Annotated[
Optional[Sequence[params.Depends]],
Doc(
"""
A list of dependencies (using `Depends()`) to be applied to the
*path operation*.
Read more about it in the
[FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
"""
A summary for the *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
"""
),
] = None,
description: Annotated[
Optional[str],
Doc(
"""
A description for the *path operation*.
If not provided, it will be extracted automatically from the docstring
of the *path operation function*.
It can contain Markdown.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
"""
),
] = None,
response_description: Annotated[
str,
Doc(
"""
The description for the default response.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = "Successful Response",
responses: Annotated[
Optional[Dict[Union[int, str], Dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = None,
deprecated: Annotated[
Optional[bool],
Doc(
"""
Mark this *path operation* as deprecated.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
"""
),
] = None,
operation_id: Annotated[
Optional[str],
Doc(
"""
Custom operation ID to be used by this *path operation*.
By default, it is generated automatically.
If you provide a custom operation ID, you need to make sure it is
unique for the whole API.
You can customize the
operation ID generation with the parameter
`generate_unique_id_function` in the `FastAPI` class.
Read more about it in the
[FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
"""
),
] = None,
response_model_include: Annotated[
Optional[IncEx],
Doc(
"""
Configuration passed to Pydantic to include only certain fields in the
response data.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
"""
),
] = None,
response_model_exclude: Annotated[
Optional[IncEx],
Doc(
"""
Configuration passed to Pydantic to exclude certain fields in the
response data.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
"""
),
] = None,
response_model_by_alias: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response model
should be serialized by alias when an alias is used.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_by_alias).
"""
),
] = True,
response_model_exclude_unset: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data
should have all the fields, including the ones that were not set and
have their default values. This is different from
`response_model_exclude_defaults` in that if the fields are set,
they will be included in the response, even if the value is the same
as the default.
When `True`, default values are omitted from the response.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
"""
),
] = False,
response_model_exclude_defaults: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data
should have all the fields, including the ones that have the same value
as the default. This is different from `response_model_exclude_unset`
in that if the fields are set but contain the same default values,
they will be excluded from the response.
When `True`, default values are omitted from the response.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
"""
),
] = False,
response_model_exclude_none: Annotated[
bool,
Doc(
"""
Configuration passed to Pydantic to define if the response data should
exclude fields set to `None`.
This is much simpler (less smart) than `response_model_exclude_unset`
and `response_model_exclude_defaults`. You probably want to use one of
those two instead of this one, as those allow returning `None` values
when it makes sense.
Read more about it in the
[FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
"""
),
] = False,
include_in_schema: Annotated[
bool,
Doc(
"""
Include this *path operation* in the generated OpenAPI schema.
This affects the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
"""
),
] = True,
response_class: Annotated[
Type[Response],
Doc(
"""
Response class to be used for this *path operation*.
This will not be used if you return a response directly.
Read more about it in the
[FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
"""
),
] = Default(JSONResponse),
name: Annotated[
Optional[str],
Doc(
"""
Name for this *path operation*. Only used internally.
"""
),
] = None,
callbacks: Annotated[
Optional[List[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
This is only for OpenAPI documentation, the callbacks won't be used
directly.
It will be added to the generated OpenAPI (e.g. visible at `/docs`).
Read more about it in the
[FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
"""
),
] = None,
openapi_extra: Annotated[
Optional[Dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
operation*.
Read more about it in the
[FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
"""
),
] = None,
generate_unique_id_function: Annotated[
Callable[[APIRoute], str],
Doc(
"""
Customize the function used to generate unique IDs for the *path
operations* shown in the generated OpenAPI.
This is particularly useful when automatically generating clients or
SDKs for your API.
Read more about it in the
[FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
"""
),
] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP QUERY operation.
The QUERY method is a safe HTTP method that allows request bodies,
useful for complex queries that exceed URL length limits.
## Example
```python
from fastapi import APIRouter
from pydantic import BaseModel
router = APIRouter()
class SearchQuery(BaseModel):
terms: list[str]
filters: dict = {}
@router.query("/search")
def search_items(query: SearchQuery):
return {"results": f"Searching for {query.terms}"}
```
"""
return self.api_route(
path=path,
response_model=response_model,
status_code=status_code,
tags=tags,
dependencies=dependencies,
summary=summary,
description=description,
response_description=response_description,
responses=responses,
deprecated=deprecated,
methods=["QUERY"],
operation_id=operation_id,
response_model_include=response_model_include,
response_model_exclude=response_model_exclude,
response_model_by_alias=response_model_by_alias,
response_model_exclude_unset=response_model_exclude_unset,
response_model_exclude_defaults=response_model_exclude_defaults,
response_model_exclude_none=response_model_exclude_none,
include_in_schema=include_in_schema,
response_class=response_class,
name=name,
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
)
def delete(
self,
path: Annotated[

171
tests/test_query_method.py

@ -0,0 +1,171 @@
"""
Tests for the QUERY HTTP method implementation in FastAPI
"""
from typing import Any, Dict, List
from fastapi import APIRouter, Depends, FastAPI
from pydantic import BaseModel
class SearchQuery(BaseModel):
terms: List[str]
filters: Dict[str, Any] = {}
limit: int = 10
def test_query_method_exists_on_fastapi():
"""Test that QUERY method exists on FastAPI class"""
app = FastAPI()
assert hasattr(app, "query")
assert callable(app.query)
def test_query_method_exists_on_router():
"""Test that QUERY method exists on APIRouter class"""
router = APIRouter()
assert hasattr(router, "query")
assert callable(router.query)
def test_query_method_decorator_works():
"""Test that QUERY method decorator can be applied"""
app = FastAPI()
@app.query("/search")
def search_items(query: SearchQuery):
return {"results": f"Searching for {query.terms}"}
# Test that the decorator worked and route was added
routes = [route for route in app.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_query_method_with_router_decorator():
"""Test that QUERY method decorator works with APIRouter"""
router = APIRouter()
@router.query("/items")
def query_items(query: SearchQuery):
return {"items": query.terms, "filters": query.filters}
# Test that the decorator worked and route was added
routes = [route for route in router.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_query_method_with_dependencies():
"""Test QUERY method with dependencies"""
app = FastAPI()
def get_current_user():
return {"user_id": 123}
@app.query("/protected", dependencies=[Depends(get_current_user)])
def protected_query(query: SearchQuery):
return {"protected": True, "query": query.dict()}
# Test that the decorator worked
routes = [route for route in app.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_query_method_with_all_parameters():
"""Test QUERY method with comprehensive parameters"""
app = FastAPI()
@app.query(
"/advanced",
response_model=dict,
status_code=200,
tags=["search"],
summary="Advanced search",
description="Perform advanced search operations",
response_description="Search results",
deprecated=False,
operation_id="advanced_search",
responses={404: {"description": "Not found"}},
name="advanced_search_endpoint",
include_in_schema=True,
generate_unique_id_function=lambda route: f"query_{route.name}",
)
def advanced_search(query: SearchQuery):
return {"advanced": True, "query": query.dict()}
# Verify route was created
routes = [route for route in app.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_router_query_method_with_all_parameters():
"""Test APIRouter QUERY method with comprehensive parameters"""
router = APIRouter()
@router.query(
"/router-advanced",
response_model=dict,
status_code=201,
tags=["router-search"],
summary="Router advanced search",
description="Perform advanced search via router",
response_description="Router search results",
deprecated=False,
operation_id="router_advanced_search",
responses={400: {"description": "Bad request"}},
name="router_advanced_search_endpoint",
include_in_schema=True,
generate_unique_id_function=lambda route: f"router_query_{route.name}",
)
def router_advanced_search(query: SearchQuery):
return {"router_advanced": True, "query": query.dict()}
# Verify route was created
routes = [route for route in router.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_query_method_with_callbacks():
"""Test QUERY method with callbacks parameter"""
app = FastAPI()
@app.query("/with-callbacks", callbacks=None)
def query_with_callbacks(query: SearchQuery):
return {"callbacks": "tested", "query": query.dict()}
# Verify route was created
routes = [route for route in app.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
def test_query_method_with_openapi_extra():
"""Test QUERY method with openapi_extra parameter"""
app = FastAPI()
@app.query("/with-openapi-extra", openapi_extra={"x-custom": "value"})
def query_with_openapi_extra(query: SearchQuery):
return {"openapi_extra": "tested", "query": query.dict()}
# Verify route was created
routes = [route for route in app.routes if hasattr(route, "methods")]
query_routes = [
route for route in routes if "QUERY" in getattr(route, "methods", [])
]
assert len(query_routes) > 0
Loading…
Cancel
Save