Web 服务与常用框架
从标准库 http.server 到 WSGI/ASGI 心智模型,FastAPI 与 Flask 路由范式,以及 uvicorn、gunicorn、httpx 等服务端常见栈。
1 标准库:http.server(原型与静态目录)
适合本地预览静态构建产物、写最小 demo,不适合承载生产流量(无进程模型、安全与性能特性有限)。
from http.server import HTTPServer, SimpleHTTPRequestHandler
server = HTTPServer(("127.0.0.1", 8000), SimpleHTTPRequestHandler)
print("Serving at http://127.0.0.1:8000/")
server.serve_forever()自定义路径可用 BaseHTTPRequestHandler 子类解析 path、写 self.send_response / self.end_headers / self.wfile.write(...),心智接近手写 Node IncomingMessage/ServerResponse,但更啰嗦。
资料:http.server
2 WSGI 与 ASGI
- WSGI:同步调用约定——框架给你一个
(environ, start_response)式的可调用对象,服务器逐请求调用。对标:早期同步 CGI 风格_pipeline,常见组合是 Flask + gunicorn(sync worker)。 - ASGI:异步优先的调用约定,支持 WebSocket、长时间连接与
async def。对标:更易对齐「现代 HTTP + 流式 + WS」需求,FastAPI / Starlette + uvicorn 是常见默认。
只要记住:应用协议(WSGI/ASGI)要和服务器匹配,混用会踩坑(例如把纯 WSGI 应用硬塞进只懂 ASGI 的服务器,需要适配层)。
WSGI:Web Server Gateway Interface(Web 服务器网关接口)
ASGI:Asynchronous Server Gateway Interface(异步服务器网关接口)
3 FastAPI(类型驱动路由 + OpenAPI)
依赖 Starlette(ASGI)与 Pydantic 做校验;自动生成 OpenAPI 文档,对熟悉 TypeScript 类型注解的读者较友好。
pip install fastapi uvicornfrom fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}本地运行(开发热重载示例):
uvicorn main:app --reload --host 127.0.0.1 --port 8000main:app表示模块main中的变量app。- 生产环境通常关掉
--reload,由进程管理器拉起多个 worker,前置反向代理(Nginx 等)。
Starlette 是一个轻量、高性能的 ASGI Web 框架:实现路由、
Request/Response、中间件、WebSocket、后台任务等与 HTTP 生命周期相关的基础设施。FastAPI 在它之上叠加 类型注解路由 + Pydantic 校验 + OpenAPI 文档,关系可以理解为:Starlette 管 ASGI 与 Web 管道,FastAPI 管「按类型声明的 API 门面」;你也可以只用 Starlette 搭更小依赖的服务。资料:Starlette
Pydantic 是基于 Python 类型注解 的数据校验与解析库:用
BaseModel(或dataclass风格配置)描述字段类型与约束(范围、长度、可选等),在运行时把「字典 / JSON / 表单」转成模型实例,不合法则抛出清晰的校验错误。FastAPI 用它来解析 请求体 / 路径与查询参数的一部分场景,并自动生成 OpenAPI 里的 schema;心智上可类比「带运行时检查的 structured typing」,接近前端生态里的 schema 校验思路。资料:Pydantic
4 Flask(轻量 WSGI 框架)
同步栈、生态老而稳;扩展与教程极多,中小服务与后台页面很常见。
pip install flaskfrom flask import Flask, request
app = Flask(__name__)
@app.get("/hello")
def hello():
name = request.args.get("name", "world")
return {"hello": name}开发内置服务器(仅开发):
flask --app main run --debug生产常见:gunicorn + Flask app,前面再接反向代理与 TLS。
资料:Flask
5 进程模型:uvicorn / gunicorn
| 场景 | 常见命令心智 |
|---|---|
| ASGI(FastAPI 等) | uvicorn main:app --host 0.0.0.0 --port 8000 |
| 多 worker | gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app(示例) |
| WSGI(Flask 等) | gunicorn -w 4 main:app(app 为 Flask 实例名) |
Worker 数与 CPU、阻塞/非阻塞代码有关:大量阻塞 IO 时仅靠少 worker + 同步框架容易排队;CPU 密集应挪到任务队列或独立进程,而不是疯狂加线程。
6 服务端发起 HTTP:httpx
标准库 urllib 够用简单 GET;要打 Cookie、HTTP/2、超时与连接池、异步客户端时,httpx 更顺手(可对标前端 fetch + 更好用的会话)。
pip install httpximport httpx
with httpx.Client(timeout=5.0) as client:
r = client.get("https://example.com")
print(r.status_code, len(r.content))异步示例(在 ASGI 路由里配合 async def):
import httpx
async def fetch_title(url: str) -> int:
async with httpx.AsyncClient(timeout=5.0) as client:
r = await client.get(url)
return r.status_code资料:httpx
7 WebSocket(ASGI 栈)
需要双向长连接时选 ASGI(FastAPI / Starlette 原生支持),WSGI 栈要做 WS 往往绕一层网关或换栈。具体 API 直接查框架文档中的 WebSocket 章节即可。
8 小结:怎么选?
- 新项目 + REST/JSON + 可能要 WS:优先考虑 FastAPI + uvicorn,类型与文档成本低。
- 已有 Flask 生态或模板渲染为主:继续 Flask + gunicorn,按需引入异步任务队列(Celery、RQ 等)。
- 只静态预览:
python -m http.server或http.server脚本即可。 - 调用下游 API:从
httpx开始;极简单脚本仍可urllib。
资料:WSGI(PEP 3333) · ASGI 规范