#FastAPI Hello World应用
📂 所属阶段:第一阶段 — 快速筑基(基础篇)
🔗 相关章节:FastAPI简介与优势 · 环境搭建
#目录
#创建第一个FastAPI应用
让我们从创建一个最简单的FastAPI应用开始。创建一个名为main.py的文件:
from fastapi import FastAPI
# 创建FastAPI应用实例
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
# 运行应用
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)#代码解释
- 导入FastAPI: 从fastapi模块导入FastAPI类
- 创建应用实例:
app = FastAPI()创建一个FastAPI应用实例 - 定义路由:
@app.get("/")是一个装饰器,告诉FastAPI当收到GET请求到"/"路径时调用下面的函数 - 返回数据: 函数返回一个Python字典,FastAPI会自动将其转换为JSON格式
#关键概念
- 装饰器:
@app.get("/")是一个Python装饰器,它为函数添加元数据 - 路径操作装饰器:
@app.get,@app.post,@app.put,@app.delete等 - 路径操作函数: 装饰器下面的函数,处理对应的请求
#运行应用
#方法1: 直接运行Python文件
python main.py#方法2: 使用uvicorn命令
# 安装uvicorn(如果尚未安装)
pip install uvicorn[standard]
# 运行应用
uvicorn main:app --reload#方法3: 在开发环境中运行
# 使用热重载(文件变化时自动重启)
uvicorn main:app --reload --host 0.0.0.0 --port 8000#访问应用
启动后,您可以访问以下URL:
- 应用根路径: http://127.0.0.1:8000
- 自动API文档: http://127.0.0.1:8000/docs
- ReDoc文档: http://127.0.0.1:8000/redoc
#命令行参数详解
uvicorn main:app \
--host 0.0.0.0 \ # 监听所有IP地址
--port 8000 \ # 监听端口
--reload \ # 开发模式,文件变化时自动重启
--workers 4 \ # 工作进程数
--log-level info \ # 日志级别
--timeout-keep-alive 5 # 保持连接超时时间#基础路由详解
FastAPI支持多种HTTP方法,每种方法都有对应的装饰器:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
"""GET请求 - 获取资源"""
return {"message": "Hello World - GET"}
@app.post("/")
def create_item():
"""POST请求 - 创建资源"""
return {"message": "Item created - POST"}
@app.put("/{item_id}")
def update_item(item_id: int):
"""PUT请求 - 更新资源(完整替换)"""
return {"message": f"Item {item_id} updated - PUT", "item_id": item_id}
@app.patch("/{item_id}")
def partially_update_item(item_id: int):
"""PATCH请求 - 部分更新资源"""
return {"message": f"Item {item_id} partially updated - PATCH", "item_id": item_id}
@app.delete("/{item_id}")
def delete_item(item_id: int):
"""DELETE请求 - 删除资源"""
return {"message": f"Item {item_id} deleted - DELETE", "item_id": item_id}#路由参数
from fastapi import FastAPI
app = FastAPI()
# 路径参数
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
# 多个路径参数
@app.get("/users/{user_id}/items/{item_id}")
def read_user_item(user_id: int, item_id: int, q: str = None):
return {"user_id": user_id, "item_id": item_id, "q": q}#路由标签和描述
from fastapi import FastAPI
app = FastAPI()
@app.get(
"/",
summary="API根路径",
description="返回API的基本信息和欢迎消息",
tags=["General"]
)
def read_root():
return {"message": "Welcome to FastAPI!"}
@app.get(
"/status",
summary="健康检查",
description="检查API服务状态",
tags=["Health Check"],
response_description="服务状态信息"
)
def health_check():
return {"status": "healthy", "timestamp": "2026-04-10T19:07:23Z"}#路径参数
路径参数是在URL路径中捕获的值,使用花括号 {} 定义:
#基础路径参数
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
"""路径参数自动转换为int类型"""
return {"item_id": item_id, "type": type(item_id).__name__}#多种类型路径参数
from fastapi import FastAPI
from uuid import UUID
from typing import Union
app = FastAPI()
# 整数类型
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id, "type": "integer"}
# 字符串类型
@app.get("/files/{filename}")
def get_file(filename: str):
return {"filename": filename, "type": "string"}
# UUID类型
@app.get("/orders/{order_uuid}")
def get_order(order_uuid: UUID):
return {"order_uuid": str(order_uuid), "type": "UUID"}
# 路径类型(捕获整个路径)
@app.get("/static/{file_path:path}")
def get_static_file(file_path: str):
return {"file_path": file_path, "type": "path"}#路径参数验证
from fastapi import FastAPI, Path
from typing import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(
item_id: Annotated[
int,
Path(
title="项目ID",
description="项目的唯一标识符",
ge=1, # greater than or equal to 1
le=10000, # less than or equal to 10000
example=123
)
]
):
"""带验证的路径参数"""
return {"item_id": item_id}#查询参数
查询参数是从URL查询字符串中提取的参数:
#基础查询参数
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 100):
"""带默认值的查询参数"""
return {"skip": skip, "limit": limit}
@app.get("/users/")
def read_users(q: Optional[str] = None):
"""可选查询参数"""
if q:
return {"q": q, "message": f"Searching for {q}"}
return {"message": "No search query"}#多个查询参数
from fastapi import FastAPI, Query
from typing import Optional, List
from datetime import datetime
app = FastAPI()
@app.get("/search/")
def search_items(
q: Optional[str] = Query(None, min_length=3, max_length=50),
category: Optional[str] = Query(None),
tags: List[str] = Query([]),
min_price: Optional[float] = Query(None, ge=0),
max_price: Optional[float] = Query(None, gt=0),
sort: str = Query("id", regex=r"^(id|name|price|date)$"),
page: int = Query(1, ge=1),
size: int = Query(10, ge=1, le=100)
):
"""复杂查询参数示例"""
filters = {
"q": q,
"category": category,
"tags": tags,
"min_price": min_price,
"max_price": max_price,
"sort": sort,
"page": page,
"size": size
}
return {"filters": filters, "total": 100}#查询参数验证
from fastapi import FastAPI, Query
from typing import Annotated, Optional
app = FastAPI()
@app.get("/products/")
def filter_products(
price_min: Annotated[
Optional[float],
Query(description="最低价格", ge=0)
] = None,
price_max: Annotated[
Optional[float],
Query(description="最高价格", gt=0)
] = None,
rating: Annotated[
Optional[float],
Query(description="评分", ge=0, le=5)
] = None
):
"""带验证的查询参数"""
conditions = {}
if price_min is not None:
conditions["min_price"] = price_min
if price_max is not None:
conditions["max_price"] = price_max
if rating is not None:
conditions["rating"] = rating
return {"conditions": conditions, "filtered": True}#请求体
请求体是客户端发送到API的数据,通常用于POST、PUT、PATCH请求:
#基础请求体
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
"""请求体模型"""
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.post("/items/")
def create_item(item: Item):
"""接收请求体数据"""
return item
@app.post("/items-with-computation/")
def create_item_with_computation(item: Item):
"""处理请求体数据并返回计算结果"""
item_dict = item.model_dump()
if item.tax:
total = item.price + item.tax
item_dict["total"] = total
return item_dict#复杂请求体模型
from fastapi import FastAPI
from pydantic import BaseModel, Field
from typing import Optional, List, Dict
from datetime import datetime
app = FastAPI()
class Address(BaseModel):
"""嵌套模型"""
street: str
city: str
country: str
postal_code: str
class User(BaseModel):
"""复杂请求体模型"""
id: Optional[int] = None
username: str = Field(..., min_length=3, max_length=50)
email: str = Field(..., regex=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
age: Optional[int] = Field(None, ge=0, le=150)
address: Optional[Address] = None
hobbies: List[str] = Field(default=[], max_items=10)
metadata: Dict[str, str] = Field(default_factory=dict)
created_at: datetime = Field(default_factory=datetime.utcnow)
is_active: bool = True
@app.post("/users/")
def create_user(user: User):
"""复杂请求体处理"""
return user#多种参数类型组合
from fastapi import FastAPI, Path, Query, Body
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
class User(BaseModel):
username: str
email: str
@app.put("/users/{user_id}/items/{item_id}")
def update_user_item(
user_id: int = Path(..., ge=1),
item_id: int = Path(..., ge=1),
item: Item = Body(...),
user: User = Body(...),
importance: int = Body(..., ge=1, le=5),
reason: Optional[str] = Body(None)
):
"""组合多种参数类型"""
return {
"user_id": user_id,
"item_id": item_id,
"item": item,
"user": user,
"importance": importance,
"reason": reason
}#响应模型
响应模型定义了API返回数据的结构和类型:
#基础响应模型
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class ItemResponse(BaseModel):
"""响应模型"""
id: int
name: str
description: Optional[str] = None
price: float
created_at: str
@app.post("/items/", response_model=ItemResponse)
def create_item_response(item: dict) -> ItemResponse:
"""使用响应模型"""
return ItemResponse(
id=123,
name=item.get("name", ""),
description=item.get("description"),
price=item.get("price", 0.0),
created_at="2026-04-10T19:07:23Z"
)#嵌套响应模型
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
app = FastAPI()
class Category(BaseModel):
id: int
name: str
description: Optional[str] = None
class ProductResponse(BaseModel):
id: int
name: str
price: float
category: Category
created_at: datetime
class ProductListResponse(BaseModel):
products: List[ProductResponse]
total: int
page: int
has_more: bool
@app.get("/products/", response_model=ProductListResponse)
def get_products() -> ProductListResponse:
"""返回产品列表"""
category = Category(id=1, name="Electronics", description="Electronic devices")
products = [
ProductResponse(
id=1,
name="Laptop",
price=999.99,
category=category,
created_at=datetime.utcnow()
),
ProductResponse(
id=2,
name="Mouse",
price=29.99,
category=category,
created_at=datetime.utcnow()
)
]
return ProductListResponse(
products=products,
total=2,
page=1,
has_more=False
)#泛型响应模型
from fastapi import FastAPI
from pydantic import BaseModel
from typing import TypeVar, Generic, List, Optional, Dict, Any
from datetime import datetime
app = FastAPI()
T = TypeVar('T')
class ApiResponse(Generic[T], BaseModel):
"""泛型响应模型"""
success: bool
data: Optional[T] = None
message: str
timestamp: datetime = datetime.utcnow()
error_code: Optional[str] = None
metadata: Dict[str, Any] = {}
class User(BaseModel):
id: int
name: str
email: str
@app.get("/user/{user_id}", response_model=ApiResponse[User])
def get_user(user_id: int) -> ApiResponse[User]:
"""使用泛型响应模型"""
user = User(id=user_id, name="John Doe", email="john@example.com")
return ApiResponse[User](
success=True,
data=user,
message="User retrieved successfully"
)
@app.get("/users", response_model=ApiResponse[List[User]])
def get_users() -> ApiResponse[List[User]]:
"""返回用户列表"""
users = [
User(id=1, name="John Doe", email="john@example.com"),
User(id=2, name="Jane Smith", email="jane@example.com")
]
return ApiResponse[List[User]](
success=True,
data=users,
message="Users retrieved successfully"
)#应用配置
FastAPI应用可以通过多种方式进行配置:
#基础配置
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
# 创建应用时配置
app = FastAPI(
title="我的API",
description="一个使用FastAPI构建的示例API",
version="1.0.0",
terms_of_service="http://example.com/terms/",
contact={
"name": "API Support",
"url": "http://www.example.com/support",
"email": "support@example.com",
},
license_info={
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
},
)
# 添加中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 在生产环境中应指定具体域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)#自定义配置
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.openapi.docs import get_swagger_ui_html
import os
app = FastAPI(
title="企业级API",
version="2.0.0",
description="功能完整的API服务",
docs_url="/api/docs", # 自定义文档路径
redoc_url="/api/redoc", # 自定义Redoc路径
openapi_url="/api/openapi.json" # 自定义OpenAPI JSON路径
)
# 挂载静态文件
app.mount("/static", StaticFiles(directory="static"), name="static")
# 自定义根路径
@app.get("/")
def read_root():
return {
"message": "欢迎使用企业级API服务",
"version": "2.0.0",
"docs": "/api/docs",
"redoc": "/api/redoc"
}#环境配置
import os
from fastapi import FastAPI
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "FastAPI App"
admin_email: str = "admin@example.com"
database_url: str = "sqlite:///./test.db"
secret_key: str = "your-secret-key"
debug: bool = False
class Config:
env_file = ".env"
settings = Settings()
app = FastAPI(
title=settings.app_name,
debug=settings.debug
)
@app.get("/info")
def get_app_info():
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"debug_mode": settings.debug
}#开发模式与生产模式
#开发模式配置
from fastapi import FastAPI
import uvicorn
app = FastAPI(debug=True) # 启用调试模式
@app.get("/debug-info")
def debug_info():
"""调试信息端点"""
return {
"debug_mode": True,
"reload_enabled": True,
"development": True
}
if __name__ == "__main__":
# 开发模式运行
uvicorn.run(
"main:app",
host="127.0.0.1",
port=8000,
reload=True, # 自动重载
debug=True, # 调试模式
log_level="info"
)#生产模式配置
from fastapi import FastAPI
import uvicorn
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
# 启动时的初始化代码
print("Application starting...")
# 初始化数据库连接等
yield
# 关闭时的清理代码
print("Application shutting down...")
app = FastAPI(
title="生产级API",
version="1.0.0",
lifespan=lifespan
)
@app.get("/")
def read_root():
return {"message": "Production API Running"}
# 生产环境部署命令示例
"""
# 使用Gunicorn + Uvicorn
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
# 或直接使用Uvicorn
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
"""#环境检测
import os
from fastapi import FastAPI
# 检测运行环境
ENVIRONMENT = os.getenv("ENVIRONMENT", "development")
IS_PRODUCTION = ENVIRONMENT.lower() == "production"
app = FastAPI(
debug=not IS_PRODUCTION,
title="API Service" if IS_PRODUCTION else "Development API"
)
@app.get("/environment")
def get_environment():
return {
"environment": ENVIRONMENT,
"is_production": IS_PRODUCTION,
"debug_mode": not IS_PRODUCTION
}#常见错误与调试
#常见错误类型
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class TestItem(BaseModel):
name: str
value: int
@app.get("/test-errors")
def test_errors(error_type: str = "none"):
"""测试不同类型的错误"""
if error_type == "http":
raise HTTPException(status_code=404, detail="Item not found")
elif error_type == "validation":
# 这会触发Pydantic验证错误
return TestItem(name="test", value="invalid")
elif error_type == "generic":
raise ValueError("Generic error occurred")
return {"message": "No error", "type": error_type}
# 自定义异常处理器
@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
status_code=exc.status_code,
content={
"error": "HTTP Error",
"detail": exc.detail,
"status_code": exc.status_code
}
)
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={
"error": "Value Error",
"message": str(exc)
}
)#调试技巧
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
@app.middleware("http")
async def log_requests(request: Request, call_next):
"""请求日志中间件"""
logger.info(f"Request: {request.method} {request.url}")
logger.info(f"Headers: {request.headers}")
response = await call_next(request)
logger.info(f"Response status: {response.status_code}")
return response
@app.get("/debug-endpoint")
async def debug_endpoint(request: Request):
"""调试端点"""
return {
"method": request.method,
"url": str(request.url),
"headers": dict(request.headers),
"client": request.client.host if request.client else None
}#性能监控
import time
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
"""添加处理时间头"""
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
@app.get("/monitor")
async def monitor_endpoint():
"""监控端点"""
return {"message": "Performance monitoring enabled"}#相关教程
#总结
通过本文的学习,您已经掌握了FastAPI Hello World应用的核心概念:
- 应用创建: 使用
FastAPI()创建应用实例 - 路由定义: 使用装饰器定义不同HTTP方法的路由
- 参数处理: 理解路径参数、查询参数和请求体的使用
- 响应模型: 定义API返回数据的结构
- 应用配置: 配置应用的基本信息和中间件
- 运行模式: 区分开发模式和生产模式的配置
- 错误处理: 处理不同类型的应用错误
现在您已经具备了创建基本FastAPI应用的能力,可以开始构建更复杂的应用程序了!

