Skip to content

Commit 2c466cf

Browse files
committed
第八章 中间件、CORS、后台任务、测试用例
1 parent 005317f commit 2c466cf

File tree

4 files changed

+115
-11
lines changed

4 files changed

+115
-11
lines changed

run.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
# -*- coding:utf-8 -*-
33
# __author__ = '__Jack__'
44

5+
import time
6+
57
import uvicorn
6-
from fastapi import FastAPI
7-
from fastapi.exceptions import RequestValidationError
8-
from fastapi.responses import PlainTextResponse
9-
from starlette.exceptions import HTTPException as StarletteHTTPException
8+
from fastapi import FastAPI, Request
9+
from fastapi.middleware.cors import CORSMiddleware
1010

1111
from coronavirus import application
12-
from tutorial import app03, app04, app05, app06
12+
from tutorial import app03, app04, app05, app06, app08
13+
14+
# from fastapi.exceptions import RequestValidationError
15+
# from fastapi.responses import PlainTextResponse
16+
# from starlette.exceptions import HTTPException as StarletteHTTPException
1317

1418
app = FastAPI(
1519
title='FastAPI Tutorial and Coronavirus Tracker API Docs',
@@ -40,11 +44,34 @@
4044
# return PlainTextResponse(str(exc), status_code=400)
4145

4246

43-
app.include_router(app03, prefix="/chapter03", tags=['第三章 请求参数和验证'])
44-
app.include_router(app04, prefix="/chapter04", tags=['第四章 响应处理和FastAPI配置'])
45-
app.include_router(app05, prefix="/chapter05", tags=['第五章 FastAPI的依赖注入系统'])
46-
app.include_router(app06, prefix="/chapter06", tags=['第六章 安全、认证和授权'])
47-
app.include_router(application, prefix="/coronavirus", tags=['新冠病毒疫情跟踪器API'])
47+
@app.middleware('http')
48+
async def add_process_time_header(request: Request, call_next): # call_next将接收request请求最为参数
49+
start_time = time.time()
50+
response = await call_next(request)
51+
process_time = time.time() - start_time
52+
response.headers['X-Process-Time'] = str(process_time) # 添加自定义的以“X-”开头的请求头
53+
return response
54+
55+
56+
app.add_middleware(
57+
CORSMiddleware,
58+
allow_origins=[
59+
"http://127.0.0.1.tiangolo.com",
60+
"https://127.0.0.1.tiangolo.com",
61+
"http://127.0.0.1",
62+
"http://127.0.0.1:8080",
63+
],
64+
allow_credentials=True,
65+
allow_methods=["*"],
66+
allow_headers=["*"],
67+
)
68+
69+
app.include_router(app03, prefix='/chapter03', tags=['第三章 请求参数和验证'])
70+
app.include_router(app04, prefix='/chapter04', tags=['第四章 响应处理和FastAPI配置'])
71+
app.include_router(app05, prefix='/chapter05', tags=['第五章 FastAPI的依赖注入系统'])
72+
app.include_router(app06, prefix='/chapter06', tags=['第六章 安全、认证和授权'])
73+
app.include_router(app08, prefix='/chapter08', tags=['第八章 中间件、CORS、后台任务、测试用例'])
74+
app.include_router(application, prefix='/coronavirus', tags=['新冠病毒疫情跟踪器API'])
4875

4976
if __name__ == '__main__':
50-
uvicorn.run("run:app", host="0.0.0.0", port=8000, reload=True, debug=True, workers=1)
77+
uvicorn.run('run:app', host='0.0.0.0', port=8000, reload=True, debug=True, workers=1)

tutorial/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
from .chapter04 import app04
77
from .chapter05 import app05
88
from .chapter06 import app06
9+
from .chapter08 import app08

tutorial/chapter08.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/python3
2+
# -*- coding:utf-8 -*-
3+
# __author__ = '__Jack__'
4+
5+
from typing import Optional
6+
7+
from fastapi import APIRouter, BackgroundTasks, Depends
8+
9+
app08 = APIRouter()
10+
11+
"""【见run.py】Middleware 中间件"""
12+
13+
# 注:带yield的依赖的退出部分的代码 和 后台任务 会在中间件之后运行
14+
15+
"""【见run.py】CORS (Cross-Origin Resource Sharing) 跨源资源共享"""
16+
17+
# 域的概念:协议+域名+端口
18+
19+
"""Background Tasks 后台任务"""
20+
21+
22+
def bg_task(framework: str):
23+
with open("README.md", mode="a") as f:
24+
f.write(f"## {framework} 框架精讲")
25+
26+
27+
@app08.post("/background_tasks")
28+
async def run_bg_task(framework: str, background_tasks: BackgroundTasks):
29+
"""
30+
:param framework: 被调用的后台任务函数的参数
31+
:param background_tasks: FastAPI.BackgroundTasks
32+
:return:
33+
"""
34+
background_tasks.add_task(bg_task, framework)
35+
return {"message": "任务已在后台运行"}
36+
37+
38+
def continue_write_readme(background_tasks: BackgroundTasks, q: Optional[str] = None):
39+
if q:
40+
background_tasks.add_task(bg_task, "\n> 整体的介绍 FastAPI,快速上手开发,结合 API 交互文档逐个讲解核心模块的使用\n")
41+
return q
42+
43+
44+
@app08.post("/dependency/background_tasks")
45+
async def dependency_run_bg_task(q: str = Depends(continue_write_readme)):
46+
if q:
47+
return {"message": "README.md更新成功"}

tutorial/test_chapter08.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/python3
2+
# -*- coding:utf-8 -*-
3+
# __author__ = '__Jack__'
4+
5+
from fastapi.testclient import TestClient
6+
7+
from run import app
8+
9+
"""Testing 测试用例"""
10+
11+
client = TestClient(app) # 先pip install pytest
12+
13+
14+
def test_run_bg_task(): # 函数名用“test_”开头是 pytest 的规范。注意不是async def
15+
response = client.post(url="/chapter08/background_tasks?framework=FastAPI")
16+
assert response.status_code == 200
17+
assert response.json() == {"message": "任务已在后台运行"}
18+
19+
20+
def test_dependency_run_bg_task():
21+
response = client.post(url="/chapter08/dependency/background_tasks")
22+
assert response.status_code == 200
23+
assert response.json() is None
24+
25+
26+
def test_dependency_run_bg_task_q():
27+
response = client.post(url="/chapter08/dependency/background_tasks?q=1")
28+
assert response.status_code == 200
29+
assert response.json() == {"message": "README.md更新成功"}

0 commit comments

Comments
 (0)