From dd3820c62d5c40e2a02fdf796f5cf6d736957cfb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 00:33:24 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20format?= =?UTF-8?q?=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_query_method.patch | 6 +++--- fastapi/routing.py | 9 ++++++--- query_method_patch.py | 15 +++++++++------ test_query_method.py | 14 ++++++++++---- tests/test_query_method.py | 32 +++++++++----------------------- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/add_query_method.patch b/add_query_method.patch index c5ab08bc7..1bbbd4a8b 100644 --- a/add_query_method.patch +++ b/add_query_method.patch @@ -3,7 +3,7 @@ @@ -2581,6 +2581,89 @@ class APIRouter: generate_unique_id_function=generate_unique_id_function, ) - + + def query( + self, + path: Annotated[ @@ -80,10 +80,10 @@ + ) -> 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. -+ ++ + See: https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html + """ + return self.api_route( diff --git a/fastapi/routing.py b/fastapi/routing.py index 04179c8a0..523cb9c42 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -2629,8 +2629,10 @@ class APIRouter(routing.Router): """ ), ] = Default(None), - status_code: Annotated[Optional[int], Doc( - """ + 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. @@ -2638,7 +2640,8 @@ class APIRouter(routing.Router): Read more about it in the [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). """ - )] = None, + ), + ] = None, tags: Annotated[ Optional[List[Union[str, Enum]]], Doc( diff --git a/query_method_patch.py b/query_method_patch.py index ff5071f99..06257431f 100644 --- a/query_method_patch.py +++ b/query_method_patch.py @@ -2,6 +2,7 @@ # This is the method to add to the FastAPI class in applications.py after the post method + def query( self, path: str, @@ -27,21 +28,23 @@ def query( name: Optional[str] = None, callbacks: Optional[List[BaseRoute]] = None, openapi_extra: Optional[Dict[str, Any]] = None, - generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(generate_unique_id), + generate_unique_id_function: Callable[[routing.APIRoute], str] = 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 - + app = FastAPI() - + @app.query("/search/") def search_items(query: SearchQuery): return {"results": [...]} diff --git a/test_query_method.py b/test_query_method.py index 45d7fb786..ea3ba8eff 100644 --- a/test_query_method.py +++ b/test_query_method.py @@ -3,40 +3,46 @@ Test script for the new QUERY method in FastAPI """ +from typing import Any, Dict, List + from fastapi import FastAPI from pydantic import BaseModel -from typing import List, Dict, Any app = FastAPI() + class SearchQuery(BaseModel): terms: List[str] filters: Dict[str, Any] = {} limit: int = 10 + @app.query("/search/") def search_items(query: SearchQuery): """ Search for items using the QUERY method. - + This demonstrates the new QUERY HTTP method that allows complex request bodies for search operations. """ return { "results": [ {"id": 1, "name": "Item 1", "matches": query.terms}, - {"id": 2, "name": "Item 2", "matches": query.terms} + {"id": 2, "name": "Item 2", "matches": query.terms}, ], "query": query.dict(), - "total": 2 + "total": 2, } + @app.get("/") def read_root(): return {"message": "FastAPI with QUERY method support"} + if __name__ == "__main__": import uvicorn + print("Testing FastAPI QUERY method implementation...") print("Visit http://localhost:8000/docs to see the QUERY endpoint in action!") uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/tests/test_query_method.py b/tests/test_query_method.py index b7487634f..d7b152d3d 100644 --- a/tests/test_query_method.py +++ b/tests/test_query_method.py @@ -2,11 +2,11 @@ Tests for the QUERY HTTP method implementation in FastAPI """ -import pytest +from typing import Any, Dict, List + from fastapi import FastAPI from fastapi.testclient import TestClient from pydantic import BaseModel -from typing import List, Dict, Any class SearchQuery(BaseModel): @@ -21,10 +21,7 @@ def test_query_method_basic(): @app.query("/search/") def search_items(query: SearchQuery): - return { - "results": [{"id": 1, "name": "test"}], - "query": query.dict() - } + return {"results": [{"id": 1, "name": "test"}], "query": query.dict()} client = TestClient(app) @@ -35,8 +32,8 @@ def test_query_method_basic(): json={ "terms": ["test", "search"], "filters": {"category": "books"}, - "limit": 5 - } + "limit": 5, + }, ) assert response.status_code == 200 @@ -65,7 +62,7 @@ def test_query_method_validation(): json={ "filters": {"category": "books"} # Missing required 'terms' field - } + }, ) assert response.status_code == 422 # Validation error @@ -111,11 +108,7 @@ def test_query_method_with_dependencies(): client = TestClient(app) - response = client.request( - "QUERY", - "/search/", - json={"terms": ["test"]} - ) + response = client.request("QUERY", "/search/", json={"terms": ["test"]}) assert response.status_code == 200 @@ -130,18 +123,11 @@ def test_query_method_response_model(): @app.query("/search/", response_model=SearchResponse) def search_items(query: SearchQuery): - return { - "results": [{"id": 1, "name": "test"}], - "total": 1 - } + return {"results": [{"id": 1, "name": "test"}], "total": 1} client = TestClient(app) - response = client.request( - "QUERY", - "/search/", - json={"terms": ["test"]} - ) + response = client.request("QUERY", "/search/", json={"terms": ["test"]}) assert response.status_code == 200 data = response.json()