Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Key features:
- **Simple** β€” define HTTP requests as decorated async functions, no boilerplate.
- **Typed** β€” full type annotations throughout; validate responses with <a href="https://docs.pydantic.dev/" target="_blank">Pydantic</a> models.
- **Logged** β€” colorful, structured request/response logs with timing, built-in.
- **Complete** β€” GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, GraphQL, and **WebSocket** out of the box.
- **Complete** β€” GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY, GraphQL, and **WebSocket** out of the box.
- **Extensible** β€” middleware, dependency injection, routers, lifespan hooks.
- **Interactive** β€” built-in Swagger UI via `app.web_run()` to browse and execute requests in the browser.
- **HTTP/2** β€” optional HTTP/2 support, with automatic fallback to HTTP/1.1.
Expand Down
23 changes: 22 additions & 1 deletion docs/en/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ app = FastHTTP(
debug: bool = False,
http2: bool = False,
get_request: dict = {},
query_request: dict = {},
post_request: dict = {},
put_request: dict = {},
patch_request: dict = {},
Expand All @@ -34,6 +35,7 @@ app = FastHTTP(
| `debug` | `bool` | `False` | Debug mode |
| `http2` | `bool` | `False` | Use HTTP/2 |
| `get_request` | `dict` | `{}` | GET settings |
| `query_request` | `dict` | `{}` | QUERY settings |
| `post_request` | `dict` | `{}` | POST settings |
| `put_request` | `dict` | `{}` | PUT settings |
| `patch_request` | `dict` | `{}` | PATCH settings |
Expand Down Expand Up @@ -129,6 +131,25 @@ async def lifespan(app):
)
```

### @app.query()

Safe and idempotent like GET, but accepts a `json`/`data` body (like POST). See [HTTP Methods](tutorial/http-methods.md#query-complex-reads-with-a-body).

```python
@app.query(
url: str,
json: dict = None,
data: bytes = None,
params: dict = None,
tags: list = [],
dependencies: list = [],
response_model: type = None,
request_model: type = None,
responses: dict = None,
query_request: dict = None,
)
```

### @app.post()

```python
Expand Down Expand Up @@ -510,7 +531,7 @@ The Route object represents a registered HTTP request. It contains all informati

| Attribute | Type | Description |
|-----------|------|-------------|
| `method` | `str` | HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) |
| `method` | `str` | HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY) |
| `url` | `str` | Full URL of the request |
| `params` | `dict` | Query parameters |
| `json` | `dict` | JSON body sent with request |
Expand Down
2 changes: 1 addition & 1 deletion docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The key features are:
* **Simple**: define HTTP requests as decorated async functions, no boilerplate.
* **Typed**: full type annotations throughout; validate responses with <a href="https://docs.pydantic.dev/" target="_blank">Pydantic</a> models.
* **Logged**: colorful, structured request/response logs with timing, built-in.
* **Complete**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, and GraphQL out of the box.
* **Complete**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY, and GraphQL out of the box.
* **Extensible**: middleware, dependency injection, routers, lifespan hooks.
* **Interactive**: built-in Swagger UI via `app.web_run()` to browse and execute requests in the browser.
* **HTTP/2**: optional HTTP/2 support, with automatic fallback to HTTP/1.1.
Expand Down
21 changes: 21 additions & 0 deletions docs/en/reference/fasthttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ app = FastHTTP(
middleware: list = [],
base_url: str = None,
get_request: dict = {},
query_request: dict = {},
post_request: dict = {},
put_request: dict = {},
patch_request: dict = {},
Expand All @@ -36,6 +37,7 @@ app = FastHTTP(
| `middleware` | `list` | `[]` | Middleware list |
| `base_url` | `str` | `None` | Default base URL for decorators and routers |
| `get_request` | `dict` | `{}` | Default GET settings |
| `query_request` | `dict` | `{}` | Default QUERY settings |
| `post_request` | `dict` | `{}` | Default POST settings |
| `put_request` | `dict` | `{}` | Default PUT settings |
| `patch_request` | `dict` | `{}` | Default PATCH settings |
Expand Down Expand Up @@ -123,6 +125,24 @@ Decorator for GET requests.
)
```

### query()

Decorator for QUERY requests. Safe and idempotent like GET, but accepts a `json`/`data` body (like POST).

```python
@app.query(
url: str,
json: dict = None,
data: bytes = None,
params: dict = None,
tags: list = [],
dependencies: list = [],
response_model: type = None,
request_model: type = None,
responses: dict = None,
)
```

### post()

Decorator for POST requests.
Expand Down Expand Up @@ -227,6 +247,7 @@ AsyncSession(
| Method | Signature |
|--------|-----------|
| `get` | `(url, *, params, headers, timeout) β†’ Response \| None` |
| `query` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `post` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `put` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `patch` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
Expand Down
18 changes: 17 additions & 1 deletion docs/en/tutorial/http-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ async def patch_user(resp: Response) -> dict:
return resp.json()
```

## QUERY - Complex Reads with a Body

`QUERY` is a newer HTTP method (proposed in an IETF draft, `draft-ietf-httpbis-safe-method-w-body`) for read operations that don't fit in a URL. It's safe and idempotent like `GET`, but carries a JSON body like `POST` β€” useful for complex search/filter requests.

```python
@app.query(
url="https://api.example.com/users/search",
json={"role": "admin", "active": True}
)
async def search_users(resp: Response) -> dict:
return resp.json()
```

!!! note
`QUERY` is not yet universally supported by servers and proxies β€” only use it against APIs that explicitly document `QUERY` support. It also isn't part of the standard OpenAPI Path Item Object method set, so `QUERY` routes won't be rendered in Swagger UI (see [OpenAPI](openapi/index.md)), even though they're included in the generated `/openapi.json`.

## DELETE - Remove Data

```python
Expand Down Expand Up @@ -83,7 +99,7 @@ async def allowed_methods(resp: Response) -> dict:
|-----------|-------------|
| `url` | Request URL (required) |
| `params` | Query parameters |
| `json` | JSON body (for POST, PUT, PATCH) |
| `json` | JSON body (for POST, PUT, PATCH, QUERY) |
| `data` | Raw bytes body |
| `files` | File uploads (multipart/form-data) |
| `tags` | Tags for grouping |
Expand Down
2 changes: 1 addition & 1 deletion docs/en/tutorial/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The tutorial is divided into several sections:

### Getting Started
- [First Steps](first-steps.md) - Installation and basic concepts
- [HTTP Methods](http-methods.md) - GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
- [HTTP Methods](http-methods.md) - GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY
- [Request Parameters](request-parameters.md) - Query, JSON, headers
- [Response Handling](response-handling.md) - Working with responses

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The key features are:
* **Simple**: define HTTP requests as decorated async functions, no boilerplate.
* **Typed**: full type annotations throughout; validate responses with <a href="https://docs.pydantic.dev/" target="_blank">Pydantic</a> models.
* **Logged**: colorful, structured request/response logs with timing, built-in.
* **Complete**: GET, POST, PUT, PATCH, DELETE, and GraphQL out of the box.
* **Complete**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY, and GraphQL out of the box.
* **Extensible**: middleware, dependency injection, routers, lifespan hooks.
* **Interactive**: built-in Swagger UI via `app.web_run()` to browse and execute requests in the browser.
* **HTTP/2**: optional HTTP/2 support, with automatic fallback to HTTP/1.1.
Expand Down
21 changes: 21 additions & 0 deletions docs/ru/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ app = FastHTTP(
debug: bool = False,
http2: bool = False,
get_request: dict = {},
query_request: dict = {},
post_request: dict = {},
put_request: dict = {},
patch_request: dict = {},
Expand All @@ -36,6 +37,7 @@ app = FastHTTP(
| `debug` | `bool` | `False` | Π Π΅ΠΆΠΈΠΌ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ |
| `http2` | `bool` | `False` | Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ HTTP/2 |
| `get_request` | `dict` | `{}` | Настройки для GET |
| `query_request` | `dict` | `{}` | Настройки для QUERY |
| `post_request` | `dict` | `{}` | Настройки для POST |
| `put_request` | `dict` | `{}` | Настройки для PUT |
| `patch_request` | `dict` | `{}` | Настройки для PATCH |
Expand Down Expand Up @@ -131,6 +133,25 @@ async def lifespan(app):
)
```

### @app.query()

БСзопасСн ΠΈ ΠΈΠ΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π΅Π½ ΠΊΠ°ΠΊ GET, Π½ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚Π΅Π»ΠΎ `json`/`data` (ΠΊΠ°ΠΊ POST). Π‘ΠΌ. [HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹](tutorial/http-methods.md).

```python
@app.query(
url: str,
json: dict = None,
data: bytes = None,
params: dict = None,
tags: list = [],
dependencies: list = [],
response_model: type = None,
request_model: type = None,
responses: dict = None,
query_request: dict = None,
)
```

### @app.post()

```python
Expand Down
2 changes: 1 addition & 1 deletion docs/ru/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ FastHTTP β€” это соврСмСнная **асинхронная HTTP-ΠΊΠ»ΠΈ
* **ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ**: опрСдСляйтС HTTP-запросы ΠΊΠ°ΠΊ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ async-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π±Π΅Π· лишнСго ΠΊΠΎΠ΄Π°.
* **Π’ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ**: ΠΏΠΎΠ»Π½Ρ‹Π΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ²; валидация ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· <a href="https://docs.pydantic.dev/" target="_blank">Pydantic</a>.
* **Π›ΠΎΠ³ΠΈΡ€ΡƒΠ΅Ρ‚**: красочныС структурированныС Π»ΠΎΠ³ΠΈ запросов/ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ выполнСния, встроСно.
* **ΠŸΠΎΠ»Π½Ρ‹ΠΉ**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS ΠΈ GraphQL ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ.
* **ΠŸΠΎΠ»Π½Ρ‹ΠΉ**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY ΠΈ GraphQL ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ.
* **Π Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ**: middleware, dependency injection, Ρ€ΠΎΡƒΡ‚Π΅Ρ€Ρ‹, lifespan-Ρ…ΡƒΠΊΠΈ.
* **Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ**: встроСнный Swagger UI Ρ‡Π΅Ρ€Π΅Π· `app.web_run()` для просмотра ΠΈ выполнСния запросов Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅.
* **HTTP/2**: ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° HTTP/2 с автоматичСским fallback Π½Π° HTTP/1.1.
Expand Down
21 changes: 21 additions & 0 deletions docs/ru/reference/fasthttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ app = FastHTTP(
middleware: list = [],
base_url: str = None,
get_request: dict = {},
query_request: dict = {},
post_request: dict = {},
put_request: dict = {},
patch_request: dict = {},
Expand All @@ -36,6 +37,7 @@ app = FastHTTP(
| `middleware` | `list` | `[]` | Бписок middleware |
| `base_url` | `str` | `None` | Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ URL для Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈ Ρ€ΠΎΡƒΡ‚Π΅Ρ€ΠΎΠ² |
| `get_request` | `dict` | `{}` | Настройки GET |
| `query_request` | `dict` | `{}` | Настройки QUERY |
| `post_request` | `dict` | `{}` | Настройки POST |
| `put_request` | `dict` | `{}` | Настройки PUT |
| `patch_request` | `dict` | `{}` | Настройки PATCH |
Expand Down Expand Up @@ -97,6 +99,24 @@ app.include_router(

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ для HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ².

### query()

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ для QUERY-запросов. БСзопасСн ΠΈ ΠΈΠ΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π΅Π½ ΠΊΠ°ΠΊ GET, Π½ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚Π΅Π»ΠΎ `json`/`data` (ΠΊΠ°ΠΊ POST).

```python
@app.query(
url: str,
json: dict = None,
data: bytes = None,
params: dict = None,
tags: list = [],
dependencies: list = [],
response_model: type = None,
request_model: type = None,
responses: dict = None,
)
```

### graphql()

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ для GraphQL.
Expand Down Expand Up @@ -173,6 +193,7 @@ AsyncSession(
| ΠœΠ΅Ρ‚ΠΎΠ΄ | Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π° |
|-------|-----------|
| `get` | `(url, *, params, headers, timeout) β†’ Response \| None` |
| `query` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `post` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `put` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
| `patch` | `(url, *, json, data, headers, timeout) β†’ Response \| None` |
Expand Down
18 changes: 17 additions & 1 deletion docs/ru/tutorial/http-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ async def patch_user(resp: Response) -> dict:
return resp.json()
```

## QUERY - слоТныС запросы Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ с Ρ‚Π΅Π»ΠΎΠΌ

`QUERY` β€” Π±ΠΎΠ»Π΅Π΅ Π½ΠΎΠ²Ρ‹ΠΉ HTTP-ΠΌΠ΅Ρ‚ΠΎΠ΄ (ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ Π² IETF-Ρ‡Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊΠ΅ `draft-ietf-httpbis-safe-method-w-body`) для ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ чтСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² URL. Он бСзопасСн ΠΈ ΠΈΠ΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π΅Π½ ΠΊΠ°ΠΊ `GET`, Π½ΠΎ нСсёт JSON-Ρ‚Π΅Π»ΠΎ ΠΊΠ°ΠΊ `POST` β€” ΡƒΠ΄ΠΎΠ±Π½ΠΎ для слоТных запросов поиска/Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ.

```python
@app.query(
url="https://api.example.com/users/search",
json={"role": "admin", "active": True}
)
async def search_users(resp: Response) -> dict:
return resp.json()
```

!!! note
`QUERY` ΠΏΠΎΠΊΠ° поддСрТиваСтся Π½Π΅ всСми сСрвСрами ΠΈ прокси β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π΅Π³ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ явно Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ `QUERY`. Π’Π°ΠΊΠΆΠ΅ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² стандартный Π½Π°Π±ΠΎΡ€ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² OpenAPI Path Item Object, поэтому `QUERY`-ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ Π½Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ Π² Swagger UI (см. [OpenAPI](openapi/index.md)), хотя ΠΈ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² сгСнСрированный `/openapi.json`.

## DELETE - ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…

```python
Expand Down Expand Up @@ -83,7 +99,7 @@ async def allowed_methods(resp: Response) -> dict:
|----------|----------|
| `url` | URL запроса (ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ) |
| `params` | Query ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ |
| `json` | JSON Ρ‚Π΅Π»ΠΎ (для POST, PUT, PATCH) |
| `json` | JSON Ρ‚Π΅Π»ΠΎ (для POST, PUT, PATCH, QUERY) |
| `data` | Π‘Ρ‹Ρ€Ρ‹Π΅ Π±Π°ΠΉΡ‚Ρ‹ |
| `files` | Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ² (multipart/form-data) |
| `tags` | Π’Π΅Π³ΠΈ для Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠΈ |
Expand Down
2 changes: 1 addition & 1 deletion docs/ru/tutorial/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

### Начало Ρ€Π°Π±ΠΎΡ‚Ρ‹
- [ΠŸΠ΅Ρ€Π²Ρ‹Π΅ шаги](first-steps.md) - Установка ΠΈ основныС понятия
- [HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹](http-methods.md) - GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
- [HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹](http-methods.md) - GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, QUERY
- [ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ запроса](request-parameters.md) - Query, JSON, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ
- [ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚Π°](response-handling.md) - Π Π°Π±ΠΎΡ‚Π° с ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ

Expand Down
49 changes: 49 additions & 0 deletions fasthttp/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@ def __init__(
),
]
) = None,
query_request: (
Annotated[
RequestsOptional | None,
Doc(
"""
Default configuration for QUERY requests.

Allows setting headers, timeout and other request-level
options that will be applied to all QUERY requests.
"""
),
]
) = None,
post_request: (
Annotated[
RequestsOptional | None,
Expand Down Expand Up @@ -532,6 +545,7 @@ async def lifespan(app: FastHTTP):

self.request_configs = {
"GET": get_request or {},
"QUERY": query_request or {},
"POST": post_request or {},
"PUT": put_request or {},
"PATCH": patch_request or {},
Expand Down Expand Up @@ -831,6 +845,41 @@ def get(
responses=responses,
)

def query(
self,
url: str,
*,
json: dict[str, Any] | None = None,
data: object | None = None,
files: FileUpload | None = None,
response_model: type | None = None,
request_model: type[BaseModel] | None = None,
tags: list[str] | None = None,
dependencies: list[Any] | None = None,
raise_for_status: bool = False,
auth: BasicAuth | DigestAuth | BearerAuth | OAuth2ClientCredentials | None = None,
responses: dict[int, dict[Literal["model"], type[BaseModel]]] | None = None,
) -> Callable[[Callable[..., object]], Callable[..., object]]:
"""Decorator for registering a QUERY route.

QUERY is safe and idempotent like GET, but carries a request body
(per the IETF QUERY method draft), so it accepts ``json``/``data``.
"""
return self._add_route(
method="QUERY",
url=url,
json=json,
data=data,
files=files,
response_model=response_model,
request_model=request_model,
tags=tags,
dependencies=dependencies,
raise_for_status=raise_for_status,
auth=auth,
responses=responses,
)

def post(
self,
url: str,
Expand Down
4 changes: 2 additions & 2 deletions fasthttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,9 @@ async def _follow_redirect(
"follow_redirects": False,
"auth": resolve_auth(route.auth),
}
if new_method in ("POST", "PUT", "PATCH") and route.json:
if new_method in ("POST", "PUT", "PATCH", "QUERY") and route.json:
req_kwargs["json"] = route.json
elif new_method in ("POST", "PUT", "PATCH") and route.data:
elif new_method in ("POST", "PUT", "PATCH", "QUERY") and route.data:
req_kwargs["content"] = route.data

new_resp = await client.request(**req_kwargs)
Expand Down
2 changes: 1 addition & 1 deletion fasthttp/helpers/route_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def validate_handler(func: Callable[..., object]) -> None:

def create_route_params(
*,
method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"],
method: Literal["GET", "POST", "PUT", "PATCH", "DELETE", "QUERY"],
url: str,
params: dict | None = None,
json: dict | None = None,
Expand Down
Loading
Loading