路由参数
FastAPI 允许开发者通过简洁的Python语法声明路径参数,实现动态路由及参数处理。
基础概念
-
• 路径参数:路径中包含的动态部分,用花括号
{}包裹,如/items/{item_id}中的item_id。 -
• 示例: 路径
/items/123将传递参数item_id值为123。
声明路径参数
@app.get("/items/{item_id}") async def read_item(item_id): # item_id 为路径的参数 return {"item_id": item_id}
访问 http://127.0.0.1:8000/items/foo,响应为 {"item_id": "foo"}。
类型标注与数据转换
使用标准的 Python 类型标注为函数中的路径参数声明类型,并且自动转换标注的数据类型。
-
• 声明
@应用名称.请求方式("路径/{参数}") async def 函数名(参数名:类型): return 返回数据 -
• 示例
@app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}
• 访问 http://127.0.0.1:8000/items/3,响应为 {"item_id": 3},自动将字符串 “3” 转换为整型。
• 访问 http://127.0.0.1:8000/items/foo,则返回错误信息,因为 “foo” 不能转换为整数。
• 类型
-
- 基本类型:
-
•
int: 整数类型,如item_id: int,会自动将路径中的字符串转换为整数。 -
•
float: 浮点数类型,同理,会转换字符串到浮点数。 -
•
str: 字符串类型,这是默认类型,通常不需要显式声明,但可以用于明确意图。 -
•
bool: 布尔类型,虽然不常用作路径参数,但在某些场景下可能有其用途。
-
- 复合类型:
-
•
List[类型]或Sequence[类型]: 允许参数为一个列表或序列,如tags: List[str]表示多个标签。 -
•
Dict[str, 类型]或Mapping[str, 类型]: 接受字典作为参数,键通常是字符串。 -
•
Union[类型1, 类型2, ...]: 表示参数可以是多个类型中的任意一种。
-
- 自定义类型:
-
• Pydantic模型: 可以定义Pydantic模型作为路径参数类型,用于复杂的数据结构验证,如
user: UserInPath,其中UserInPath是一个Pydantic模型。 -
• Enum类型: 如上文所述,使用枚举(Enum)来限制路径参数的取值范围,提供额外的验证和清晰性。
-
- 特殊类型转换器:
- • 路径转换器(如
path)可以用于处理路径中包含斜杠的特殊参数,例如file_path: Path使用path转换器。
-
- 可选参数与默认值:
-
• 使用默认值(如
item_id: int = None)可以标记路径参数为可选,尽管这在路径参数中较少见,因为路径通常要求所有组件都是必需的。
-
• 类型示例
-
• 整数类型 (int)当路径中需要接收整数参数时,可以直接声明
int类型。from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}访问
http://127.0.0.1:8000/items/42,预期响应为{"item_id": 42}。 -
• 浮点数类型 (float)若路径参数为浮点数,则声明为
float类型。@app.get("/prices/{price}") async def show_price(price: float): return {"price": price}访问
http://127.0.0.1:8000/prices/49.99,预期响应为{"price": 49.99}。 -
• 字符串类型 (str)字符串类型的路径参数是最常见的。
@app.get("/users/{username}") async def read_user(username: str): return {"username": username}访问
http://127.0.0.1:8000/users/john_doe,预期响应为{"username": "john_doe"}。 -
• 布尔类型 (bool)虽然不常见,但路径参数也可以是布尔类型。
@app.get("/features/{feature_enabled}") async def feature_status(feature_enabled: bool): return {"feature_enabled": feature_enabled}访问
http://127.0.0.1:8000/features/true或http://127.0.0.1:8000/features/false,预期响应分别为{"feature_enabled": true}和{"feature_enabled": false}。 -
• 复合类型示例
-
• 列表类型 (List[int])列表类型通常不直接用作路径参数,但可以这样声明。
from typing import List @app.get("/items/{item_ids}") async def read_items(item_ids: List[int]): return {"item_ids": item_ids} -
• 字典类型 (Dict[str, str])字典类型同样少见,但可以展示类型标注的灵活性。
from typing import Dict @app.get("/config/{settings}") async def read_config(settings: Dict[str, str]): return {"settings": settings} -
• 自定义类型示例
-
• Pydantic模型
-
Pydantic模型用于更复杂的请求处理和验证。
from pydantic import BaseModel from typing import Optional class Item(BaseModel): name: str description: str @app.get("/items/{item_id}") async def read_item(item_id: int, q: Optional[str] = None): item = {"item_id": item_id} if q: item.update({"q": q}) return item -
• 枚举类型 (Enum)
-
枚举类型确保参数值只能是预定义选项之一。
from enum import Enum class ModelName(str, Enum): alexnet = "alexnet" resnet = "resnet" lenet = "lenet" @app.get("/models/{model_name}") async def get_model(model_name: ModelName): return {"model_name": model_name.value}访问
http://127.0.0.1:8000/models/resnet,预期响应为{"model_name": "resnet"}。 -
可以通过
ModelName.lenet.value来获取值"lenet"。
数据校验
FastAPI 内置了强大的数据校验机制,能够确保传入的路径参数、查询参数、请求体等符合预期的类型。以下是一个使用 FastAPI 进行数据校验的例子:
整数类型校验 (int)
当你在路径操作中声明一个整数类型的参数时,FastAPI 会自动校验传入的值是否为有效的整数。
@app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}
如果你尝试使用非整数值访问此路径,例如访问 http://127.0.0.1:8000/items/foo,FastAPI 会返回一个清晰的错误响应:

{ "detail": [ { "type": "int_parsing", "loc": [ "path", "item_id" ], "msg": "Input should be a valid integer, unable to parse string as an integer", "input": "foo", "url": "https://errors.pydantic.dev/2.5/v/int_parsing" } ] }
这个错误响应指出了问题所在:item_id 应该是一个整数,但是接收到了字符串 “foo”。
浮点数类型校验 (float)
FastAPI 对浮点数类型的校验也同样严格。如果你声明的参数类型为 float,那么即使传入的是数值,但如果是整数,也会被认为不符合类型要求。
例如,对于以下路径操作:
@app.get("/items/{item_id}") async def read_item(item_id: float): return {"item_id": item_id}
访问 http://127.0.0.1:8000/items/4.2 是有效的,因为 “4.2” 可以被解析为浮点数。但是,如果访问 http://127.0.0.1:8000/items/4,即使 “4” 是一个数值,它也不是一个浮点数,因此会触发一个类型错误。
错误信息
FastAPI 提供的错误信息非常有助于调试。错误详细信息包括:
-
•
loc:错误发生的具体位置,例如路径参数["path","item_id"] -
•
msg:错误的描述信息,例如"Input should be a valid integer"。 -
•
type:错误的类型,例如"int_parsing"。
这些信息可以帮助开发者快速定位问题并采取相应的措施进行修复。
路径的路径参数
-
• 实现路径参数包含多级路径的情况,如处理
/files/home/johndoe/myfile.txt请求。 -
• 利用路径转换器处理特殊字符,如路径分隔符
/。
技巧介绍
-
- **路径参数声明:**这里的
{file_path:path}表明file_path能够匹配任何级别的目录结构。
- **路径参数声明:**这里的
-
• 使用
:path转换器来指示路径参数可以包含任意路径结构。/files/{file_path:path}
-
- **路径操作函数定义:**参数
file_path会接收完整的路径字符串,如home/johndoe/myfile.txt。

- **路径操作函数定义:**参数
-
• 在路径操作函数中,通过类型注解定义路径参数。
@app.get("/files/{file_path:path}") async def read_file(file_path: str): return {"file_path": file_path}
-
- **处理斜杠开头路径:**FastAPI内部处理时会正确解析,不会影响参数值。
-
• 若文件路径以斜杠开头(如
/home/johndoe/myfile.txt),URL中会展现为双斜杠序列(//)。/files//home/johndoe/myfile.txt
启动
在FastAPI应用中,通常使用Uvicorn作为ASGI服务器来运行应用程序。
# 如果当前模块是主模块(直接运行而非导入) if __name__ == "__main__": # 导入uvicorn模块 import uvicorn # 使用uvicorn.run方法启动FastAPI应用 # 参数说明: # - app:要运行的FastAPI应用实例 # - host:监听的IP地址,默认为'127.0.0.1',这里显式指定为本地环回地址 # - port:监听的端口号,默认为8000,这里同样明确指定 # - reload:是否启用自动重载,默认为False,在开发模式下设置为True可以让修改后的代码立即生效,无需重启服务器 uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)
当然,除了基本的host, port, 和 reload 参数外,uvicorn.run()还支持一些其他常用的配置选项,这些选项帮助你更细致地控制Uvicorn服务器的行为。以下是几个重要参数的简要说明:
-
log_level: 控制日志级别,可选值包括"debug","info","warning","error","critical"。默认值通常是"info",在开发过程中,你可能希望设置为"debug"以获得更详细的日志输出。
-
workers: 指定要启动的工作进程数量,这对于提高并发处理能力特别有用。在多核CPU环境下,增加工作进程数可以显著提升应用性能。默认情况下,Uvicorn会根据环境自动选择合适的工作者数量,但在某些场景下,你可能需要手动指定。
-
access_log: 一个布尔值,决定是否记录HTTP访问日志。默认为True,如果你不希望记录这些日志(比如在生产环境中出于性能考虑),可以设置为False。
-
timeout_keep_alive: 定义空闲连接在关闭前保持活动的秒数。默认值是5秒,根据你的应用特性,你可能需要调整这个值。
-
proxy_headers: 是否信任X-Forwarded-*头部信息,这对于在反向代理(如Nginx)后运行应用非常重要。设置为True会允许Uvicorn根据这些头信息正确解析客户端的真实IP地址等信息。
-
root_path: 如果你的应用部署在子路径下,可以通过这个参数指定根路径,这样路由也能正确解析。
-
limit_concurrency: 限制同时处理的请求的最大数量,有助于防止服务过载。
-
limit_max_requests: 设置每个工作进程在被重启前能处理的最大请求数量,有助于防止内存泄漏等问题。
示例代码,包含更多参数的使用:
# 使用uvicorn启动FastAPI应用,详细配置如下: uvicorn.run( # FastAPI应用实例 app, # 监听的IP地址,这里设置为本地环回地址,局域网内访问写”0.0.0.0“ host="127.0.0.1", # 监听的端口号 port=8000, # 开启自动重载,开发时非常有用,代码改动将自动重启服务器 reload=True, # 设置日志级别为debug,便于开发时查看详细日志信息 log_level="debug", # 启动的工作进程数,这里设置为2,适合多核CPU环境提高并发处理能力 workers=2, # 关闭访问日志记录,减少日志输出噪音,根据需要可开启 access_log=False, # 保持活动连接超时时间,单位秒,此处设置为10秒后关闭无活动连接 timeout_keep_alive=10, # 启用代理头部信任,当应用位于反向代理后方时,用于正确解析客户端信息 proxy_headers=True, # 指定应用部署的根路径,如果应用不是部署在域名根部,需设置此值,如"/my-app" root_path="/my-app", # 限制最大并发请求数,防止服务过载,根据服务器性能合理设定,这里设为100 limit_concurrency=100, # 工作进程处理的最大请求数量到达此值后将重启,有助于防止内存泄漏,设为5000 limit_max_requests=5000 )
通过这些参数,你可以根据实际部署环境和应用需求,微调Uvicorn服务器的配置,达到最佳的性能和管理效果。
为了帮助大家更好的学习网络安全,我给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂这些资料!
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享



因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

1145

被折叠的 条评论
为什么被折叠?



