fastapi
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFastAPI
FastAPI
Official FastAPI skill to write code with best practices, keeping up to date with new versions and features.
官方FastAPI技能指南,遵循最佳实践编写代码,同步最新版本与功能。
Use the fastapi
CLI
fastapi使用fastapi
命令行工具
fastapiRun the development server on localhost with reload:
bash
fastapi devRun the production server:
bash
fastapi run在本地启动带热重载的开发服务器:
bash
fastapi dev启动生产环境服务器:
bash
fastapi runAdd an entrypoint in pyproject.toml
pyproject.toml在pyproject.toml
中添加入口点
pyproject.tomlFastAPI CLI will read the entrypoint in to know where the FastAPI app is declared.
pyproject.tomltoml
[tool.fastapi]
entrypoint = "my_app.main:app"FastAPI命令行工具会读取中的入口点信息,以确定FastAPI应用的声明位置。
pyproject.tomltoml
[tool.fastapi]
entrypoint = "my_app.main:app"Use fastapi
with a path
fastapi结合路径使用fastapi
fastapiWhen adding the entrypoint to is not possible, or the user explicitly asks not to, or it's running an independent small app, you can pass the app file path to the command:
pyproject.tomlfastapibash
fastapi dev my_app/main.pyPrefer to set the entrypoint in when possible.
pyproject.toml当无法在中添加入口点,或者用户明确要求不添加,或是运行独立的小型应用时,可以将应用文件路径传递给命令:
pyproject.tomlfastapibash
fastapi dev my_app/main.py尽可能优先在中设置入口点。
pyproject.tomlUse Annotated
Annotated使用Annotated
AnnotatedAlways prefer the style for parameter and dependency declarations.
AnnotatedIt keeps the function signatures working in other contexts, respects the types, allows reusability.
声明参数和依赖项时,始终优先使用风格。
Annotated这种方式能让函数签名在其他环境中正常工作,尊重类型定义,并支持复用。
In Parameter Declarations
参数声明中使用
Use for parameter declarations, including , , , etc.:
AnnotatedPathQueryHeaderpython
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(
item_id: Annotated[int, Path(ge=1, description="The item ID")],
q: Annotated[str | None, Query(max_length=50)] = None,
):
return {"message": "Hello World"}instead of:
python
undefined在参数声明中使用,包括、、等:
AnnotatedPathQueryHeaderpython
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(
item_id: Annotated[int, Path(ge=1, description="The item ID")],
q: Annotated[str | None, Query(max_length=50)] = None,
):
return {"message": "Hello World"}而非:
python
undefinedDO NOT DO THIS
请勿这样做
@app.get("/items/{item_id}")
async def read_item(
item_id: int = Path(ge=1, description="The item ID"),
q: str | None = Query(default=None, max_length=50),
):
return {"message": "Hello World"}
undefined@app.get("/items/{item_id}")
async def read_item(
item_id: int = Path(ge=1, description="The item ID"),
q: str | None = Query(default=None, max_length=50),
):
return {"message": "Hello World"}
undefinedFor Dependencies
依赖项中使用
Use for dependencies with .
AnnotatedDepends()Unless asked not to, create a new type alias for the dependency to allow re-using it.
python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_current_user():
return {"username": "johndoe"}
CurrentUserDep = Annotated[dict, Depends(get_current_user)]
@app.get("/items/")
async def read_item(current_user: CurrentUserDep):
return {"message": "Hello World"}instead of:
python
undefined为带的依赖项使用。
Depends()Annotated除非用户要求不使用,否则应为依赖项创建新的类型别名以支持复用。
python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_current_user():
return {"username": "johndoe"}
CurrentUserDep = Annotated[dict, Depends(get_current_user)]
@app.get("/items/")
async def read_item(current_user: CurrentUserDep):
return {"message": "Hello World"}而非:
python
undefinedDO NOT DO THIS
请勿这样做
@app.get("/items/")
async def read_item(current_user: dict = Depends(get_current_user)):
return {"message": "Hello World"}
undefined@app.get("/items/")
async def read_item(current_user: dict = Depends(get_current_user)):
return {"message": "Hello World"}
undefinedDo not use Ellipsis for path operations or Pydantic models
路径操作或Pydantic模型请勿使用省略号
Do not use as a default value for required parameters, it's not needed and not recommended.
...Do this, without Ellipsis ():
...python
from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str
description: str | None = None
price: float = Field(gt=0)
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query()]): ...instead of this:
python
undefined请勿将作为必填参数的默认值,这没有必要且不推荐。
...正确做法,不使用省略号():
...python
from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str
description: str | None = None
price: float = Field(gt=0)
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query()]): ...而非:
python
undefinedDO NOT DO THIS
请勿这样做
class Item(BaseModel):
name: str = ...
description: str | None = None
price: float = Field(..., gt=0)
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query(...)]): ...
undefinedclass Item(BaseModel):
name: str = ...
description: str | None = None
price: float = Field(..., gt=0)
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query(...)]): ...
undefinedReturn Type or Response Model
返回类型或响应模型
When possible, include a return type. It will be used to validate, filter, document, and serialize the response.
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me")
async def get_item() -> Item:
return Item(name="Plumbus", description="All-purpose home device")Important: Return types or response models are what filter data ensuring no sensitive information is exposed. And they are used to serialize data with Pydantic (in Rust), this is the main idea that can increase response performance.
The return type doesn't have to be a Pydantic model, it could be a different type, like a list of integers, or a dict, etc.
尽可能添加返回类型。它将用于验证、过滤、文档化和序列化响应。
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me")
async def get_item() -> Item:
return Item(name="Plumbus", description="All-purpose home device")重要提示:返回类型或响应模型可过滤数据,确保敏感信息不被泄露。并且它们会通过Pydantic(Rust实现)序列化数据,这是提升响应性能的核心机制。
返回类型不一定是Pydantic模型,也可以是其他类型,比如整数列表或字典等。
When to use response_model
instead
response_model何时改用response_model
response_modelIf the return type is not the same as the type that you want to use to validate, filter, or serialize, use the parameter on the decorator instead.
response_modelpython
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
return {"name": "Foo", "description": "A very nice Item"}This can be particularly useful when filtering data to expose only the public fields and avoid exposing sensitive information.
python
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class InternalItem(BaseModel):
name: str
description: str | None = None
secret_key: str
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
item = InternalItem(
name="Foo", description="A very nice Item", secret_key="supersecret"
)
return item如果返回类型与你用于验证、过滤或序列化的类型不一致,请在装饰器中使用参数。
response_modelpython
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
return {"name": "Foo", "description": "A very nice Item"}这在过滤数据以仅暴露公共字段、避免敏感信息泄露时尤其有用。
python
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class InternalItem(BaseModel):
name: str
description: str | None = None
secret_key: str
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
item = InternalItem(
name="Foo", description="A very nice Item", secret_key="supersecret"
)
return itemPerformance
性能
Do not use or , they are deprecated.
ORJSONResponseUJSONResponseInstead, declare a return type or response model. Pydantic will handle the data serialization on the Rust side.
请勿使用或,它们已被弃用。
ORJSONResponseUJSONResponse取而代之的是声明返回类型或响应模型。Pydantic会在Rust端处理数据序列化。
Including Routers
包含路由
When declaring routers, prefer to add router level parameters like prefix, tags, etc. to the router itself, instead of in .
include_router()Do this:
python
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter(prefix="/items", tags=["items"])
@router.get("/")
async def list_items():
return []声明路由时,优先将前缀、标签等路由级参数添加到路由本身,而非中。
include_router()正确做法:
python
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter(prefix="/items", tags=["items"])
@router.get("/")
async def list_items():
return []In main.py
在main.py中
app.include_router(router)
instead of this:
```pythonapp.include_router(router)
而非:
```pythonDO NOT DO THIS
请勿这样做
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter()
@router.get("/")
async def list_items():
return []
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter()
@router.get("/")
async def list_items():
return []
In main.py
在main.py中
app.include_router(router, prefix="/items", tags=["items"])
There could be exceptions, but try to follow this convention.
Apply shared dependencies at the router level via `dependencies=[Depends(...)]`.app.include_router(router, prefix="/items", tags=["items"])
可能存在例外情况,但请尽量遵循此约定。
通过`dependencies=[Depends(...)]`在路由级别应用共享依赖项。Dependency Injection
依赖注入
Use dependencies when:
- They can't be declared in Pydantic validation and require additional logic
- The logic depends on external resources or could block in any other way
- Other dependencies need their results (it's a sub-dependency)
- The logic can be shared by multiple endpoints to do things like error early, authentication, etc.
- They need to handle cleanup (e.g., DB sessions, file handles), using dependencies with
yield - Their logic needs input data from the request, like headers, query parameters, etc.
在以下场景使用依赖项:
- 无法通过Pydantic验证声明,且需要额外逻辑
- 逻辑依赖外部资源或可能导致阻塞
- 其他依赖项需要其结果(作为子依赖项)
- 逻辑可被多个端点共享,用于提前错误处理、身份验证等
- 需要处理清理操作(如数据库会话、文件句柄),使用带的依赖项
yield - 逻辑需要从请求中获取输入数据,如请求头、查询参数等
Dependencies with yield
and scope
yieldscope带yield
和scope
的依赖项
yieldscopeWhen using dependencies with , they can have a that defines when the exit code is run.
yieldscopeUse the default scope to run the exit code after the response is sent back.
"request"python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
DBDep = Annotated[DBSession, Depends(get_db)]
@app.get("/items/")
async def read_items(db: DBDep):
return db.query(Item).all()Use the scope when they should run the exit code after the response data is generated but before the response is sent back to the client.
"function"python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_username():
try:
yield "Rick"
finally:
print("Cleanup up before response is sent")
UserNameDep = Annotated[str, Depends(get_username, scope="function")]
@app.get("/users/me")
def get_user_me(username: UserNameDep):
return username使用带的依赖项时,可通过定义退出代码的执行时机。
yieldscope使用默认作用域,在响应返回后执行退出代码。
"request"python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
DBDep = Annotated[DBSession, Depends(get_db)]
@app.get("/items/")
async def read_items(db: DBDep):
return db.query(Item).all()使用作用域时,在响应数据生成后、返回给客户端前执行退出代码。
"function"python
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_username():
try:
yield "Rick"
finally:
print("Cleanup up before response is sent")
UserNameDep = Annotated[str, Depends(get_username, scope="function")]
@app.get("/users/me")
def get_user_me(username: UserNameDep):
return usernameClass Dependencies
类依赖项
Avoid creating class dependencies when possible.
If a class is needed, instead create a regular function dependency that returns a class instance.
Do this:
python
from dataclasses import dataclass
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
@dataclass
class DatabasePaginator:
offset: int = 0
limit: int = 100
q: str | None = None
def get_page(self) -> dict:
# Simulate a page of data
return {
"offset": self.offset,
"limit": self.limit,
"q": self.q,
"items": [],
}
def get_db_paginator(
offset: int = 0, limit: int = 100, q: str | None = None
) -> DatabasePaginator:
return DatabasePaginator(offset=offset, limit=limit, q=q)
PaginatorDep = Annotated[DatabasePaginator, Depends(get_db_paginator)]
@app.get("/items/")
async def read_items(paginator: PaginatorDep):
return paginator.get_page()instead of this:
python
undefined尽可能避免创建类依赖项。
如果需要类,应创建一个常规函数依赖项,返回类实例。
正确做法:
python
from dataclasses import dataclass
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
@dataclass
class DatabasePaginator:
offset: int = 0
limit: int = 100
q: str | None = None
def get_page(self) -> dict:
# Simulate a page of data
return {
"offset": self.offset,
"limit": self.limit,
"q": self.q,
"items": [],
}
def get_db_paginator(
offset: int = 0, limit: int = 100, q: str | None = None
) -> DatabasePaginator:
return DatabasePaginator(offset=offset, limit=limit, q=q)
PaginatorDep = Annotated[DatabasePaginator, Depends(get_db_paginator)]
@app.get("/items/")
async def read_items(paginator: PaginatorDep):
return paginator.get_page()而非:
python
undefinedDO NOT DO THIS
请勿这样做
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class DatabasePaginator:
def init(self, offset: int = 0, limit: int = 100, q: str | None = None):
self.offset = offset
self.limit = limit
self.q = q
def get_page(self) -> dict:
# Simulate a page of data
return {
"offset": self.offset,
"limit": self.limit,
"q": self.q,
"items": [],
}@app.get("/items/")
async def read_items(paginator: Annotated[DatabasePaginator, Depends()]):
return paginator.get_page()
undefinedfrom typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class DatabasePaginator:
def init(self, offset: int = 0, limit: int = 100, q: str | None = None):
self.offset = offset
self.limit = limit
self.q = q
def get_page(self) -> dict:
# Simulate a page of data
return {
"offset": self.offset,
"limit": self.limit,
"q": self.q,
"items": [],
}@app.get("/items/")
async def read_items(paginator: Annotated[DatabasePaginator, Depends()]):
return paginator.get_page()
undefinedAsync vs Sync path operations
异步与同步路径操作
Use path operations only when fully certain that the logic called inside is compatible with async and await (it's called with ) or that doesn't block.
asyncawaitpython
from fastapi import FastAPI
app = FastAPI()仅当确定内部调用的逻辑兼容异步/await(通过调用)或不会导致阻塞时,才使用路径操作。
awaitasyncpython
from fastapi import FastAPI
app = FastAPI()Use async def when calling async code
调用异步代码时使用async def
@app.get("/async-items/")
async def read_async_items():
data = await some_async_library.fetch_items()
return data
@app.get("/async-items/")
async def read_async_items():
data = await some_async_library.fetch_items()
return data
Use plain def when calling blocking/sync code or when in doubt
调用阻塞/同步代码或存疑时使用普通def
@app.get("/items/")
def read_items():
data = some_blocking_library.fetch_items()
return data
In case of doubt, or by default, use regular `def` functions, those will be run in a threadpool so they don't block the event loop.
The same rules apply to dependencies.
Make sure blocking code is not run inside of `async` functions. The logic will work, but will damage the performance heavily.@app.get("/items/")
def read_items():
data = some_blocking_library.fetch_items()
return data
存疑时或默认情况下,使用普通`def`函数,它们会在线程池中运行,不会阻塞事件循环。
相同规则适用于依赖项。
确保阻塞代码不会在`async`函数中运行。逻辑虽能正常工作,但会严重影响性能。Asyncer
Asyncer
When needing to run blocking code inside of async functions, or async code inside of blocking functions, suggest using Asyncer.
Install:
bash
uv add asyncerRun blocking sync code inside of async with :
asyncify()python
from asyncer import asyncify
from fastapi import FastAPI
app = FastAPI()
def do_blocking_work(name: str) -> str:
# Some blocking I/O operation
return f"Hello {name}"
@app.get("/items/")
async def read_items():
result = await asyncify(do_blocking_work)(name="World")
return {"message": result}And run async code inside of blocking sync code with :
syncify()python
from asyncer import syncify
from fastapi import FastAPI
app = FastAPI()
async def do_async_work(name: str) -> str:
return f"Hello {name}"
@app.get("/items/")
def read_items():
result = syncify(do_async_work)(name="World")
return {"message": result}当需要在异步函数中运行阻塞代码,或在阻塞函数中运行异步代码时,建议使用Asyncer。
安装:
bash
uv add asyncer使用在异步函数中运行阻塞同步代码:
asyncify()python
from asyncer import asyncify
from fastapi import FastAPI
app = FastAPI()
def do_blocking_work(name: str) -> str:
# Some blocking I/O operation
return f"Hello {name}"
@app.get("/items/")
async def read_items():
result = await asyncify(do_blocking_work)(name="World")
return {"message": result}使用在阻塞同步函数中运行异步代码:
syncify()python
from asyncer import syncify
from fastapi import FastAPI
app = FastAPI()
async def do_async_work(name: str) -> str:
return f"Hello {name}"
@app.get("/items/")
def read_items():
result = syncify(do_async_work)(name="World")
return {"message": result}Stream JSON Lines
流式JSON Lines
To stream JSON Lines, declare the return type and use to return the data.
yieldpython
@app.get("/items/stream")
async def stream_items() -> AsyncIterable[Item]:
for item in items:
yield item要流式传输JSON Lines,声明返回类型并使用返回数据。
yieldpython
@app.get("/items/stream")
async def stream_items() -> AsyncIterable[Item]:
for item in items:
yield itemStream bytes
流式字节
To stream bytes, declare a of or a sub-class, and use to return the data.
response_class=StreamingResponseyieldpython
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from app.utils import read_image
app = FastAPI()
class PNGStreamingResponse(StreamingResponse):
media_type = "image/png"
@app.get("/image", response_class=PNGStreamingResponse)
def stream_image_no_async_no_annotation():
with read_image() as image_file:
yield from image_fileprefer this over returning a directly:
StreamingResponsepython
undefined要流式传输字节,声明为或其子类,并使用返回数据。
response_class=StreamingResponseyieldpython
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from app.utils import read_image
app = FastAPI()
class PNGStreamingResponse(StreamingResponse):
media_type = "image/png"
@app.get("/image", response_class=PNGStreamingResponse)
def stream_image_no_async_no_annotation():
with read_image() as image_file:
yield from image_file优先使用此方式,而非直接返回:
StreamingResponsepython
undefinedDO NOT DO THIS
请勿这样做
import anyio
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from app.utils import read_image
app = FastAPI()
class PNGStreamingResponse(StreamingResponse):
media_type = "image/png"
@app.get("/")
async def main():
return PNGStreamingResponse(read_image())
undefinedimport anyio
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from app.utils import read_image
app = FastAPI()
class PNGStreamingResponse(StreamingResponse):
media_type = "image/png"
@app.get("/")
async def main():
return PNGStreamingResponse(read_image())
undefinedUse uv, ruff, ty
使用uv、ruff、ty
If uv is available, use it to manage dependencies.
If Ruff is available, use it to lint and format the code. Consider enabling the FastAPI rules.
If ty is available, use it to check types.
如果uv可用,使用它管理依赖项。
如果Ruff可用,使用它进行代码检查和格式化。考虑启用FastAPI规则。
如果ty可用,使用它进行类型检查。
SQLModel for SQL databases
SQL数据库使用SQLModel
When working with SQL databases, prefer using SQLModel as it is integrated with Pydantic and will allow declaring data validation with the same models.
处理SQL数据库时,优先使用SQLModel,它与Pydantic集成,可通过同一模型声明数据验证规则。
Do not use Pydantic RootModels
请勿使用Pydantic RootModels
Do not use Pydantic , instead use regular type annotations with and Pydantic validation utilities.
RootModelAnnotatedFor example, for a list with validations you could do:
python
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import Field
app = FastAPI()
@app.post("/items/")
async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]):
return itemsinstead of:
python
undefined请勿使用Pydantic ,应改用带的常规类型注解和Pydantic验证工具。
RootModelAnnotated例如,要验证列表可这样做:
python
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import Field
app = FastAPI()
@app.post("/items/")
async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]):
return items而非:
python
undefinedDO NOT DO THIS
请勿这样做
from typing import Annotated
from fastapi import FastAPI
from pydantic import Field, RootModel
app = FastAPI()
class ItemList(RootModel[Annotated[list[int], Field(min_length=1)]]):
pass
@app.post("/items/")
async def create_items(items: ItemList):
return items
FastAPI supports these type annotations and will create a Pydantic `TypeAdapter` for them, so that types can work as normally and there's no need for the custom logic and types in RootModels.from typing import Annotated
from fastapi import FastAPI
from pydantic import Field, RootModel
app = FastAPI()
class ItemList(RootModel[Annotated[list[int], Field(min_length=1)]]):
pass
@app.post("/items/")
async def create_items(items: ItemList):
return items
FastAPI支持这些类型注解,并会为其创建Pydantic `TypeAdapter`,因此类型可正常工作,无需RootModels中的自定义逻辑和类型。Use one HTTP operation per function
每个函数对应一个HTTP操作
Don't mix HTTP operations in a single function, having one function per HTTP operation helps separate concerns and organize the code.
Do this:
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
@app.get("/items/")
async def list_items():
return []
@app.post("/items/")
async def create_item(item: Item):
return iteminstead of this:
python
undefined请勿在单个函数中混合多个HTTP操作,每个函数对应一个HTTP操作有助于分离关注点并组织代码。
正确做法:
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
@app.get("/items/")
async def list_items():
return []
@app.post("/items/")
async def create_item(item: Item):
return item而非:
python
undefinedDO NOT DO THIS
请勿这样做
from fastapi import FastAPI, Request
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
@app.api_route("/items/", methods=["GET", "POST"])
async def handle_items(request: Request):
if request.method == "GET":
return []
undefinedfrom fastapi import FastAPI, Request
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
@app.api_route("/items/", methods=["GET", "POST"])
async def handle_items(request: Request):
if request.method == "GET":
return []
undefined