FastAPI 开发 RESTAPI 实践
首页
重定向到 Swagger UI
@app.get("/", include_in_schema=False)
async def index():
    return RedirectResponse('/docs', status_code=303)
使用 route 的 docstring 作为首页内容
@app.get("/", response_class=HTMLResponse, include_in_schema=False)
async def index():
    # 需要过滤的路由
    filted_routes = [
        "/openapi.json",
        "/docs",
        "/docs/oauth2-redirect",
        "/redoc",
        "/static",
        "/"
    ]
    
    routes = []
    for route in app.routes:
        if route.path not in filted_routes:
            routes.append(route)
    HTML_TEMPLATE = """
        <center>
            <div class="main">
                <h1 class="title">{title}</h1>
                <small><pre class="version">{version}</pre></small>
            </div>
            <a href="docs" target="_blank" class="link">Swagger UI</a> <a href="redoc" target="_blank" class="link">ReDoc</a>
        </center>
        <div style="max-width: 100%;" class="content">
            <style>
                .main .title 
                .main .version 
                .content h1 
                img 
                table  table th  table tr:nth-child(even) 
                pre 
                .link 
                .link:hover 
            </style>
            {html_content}
        </div>
    """
    html_content = ""
    for route in routes:
        html_content += markdown(
            f"# {route.methods} {route.path} {route.summary}\n{textwrap.dedent(route.endpoint.__doc__)}",
            extensions=['fenced_code', 'tables'] # extra
        )
    html_content = HTML_TEMPLATE.format(
        title=TITLE, version=VERSION, 
        html_content=html_content
    )
    return HTMLResponse(content=html_content, status_code=200)
Markdown to HTML
安装
pip install markdown
使用
from markdown import markdown
print(markdown("# Title"))
<h1>Title</h1>
转换表格
md = """
  | EasyOCR | PaddleOCR |
  | ------- | --------- |
  | 1.7.1   | 2.5.1     |
"""
html = markdown(md, extensions=['tables'])
print(html)
<table>
<thead>
<tr>
<th>EasyOCR</th>
<th>PaddleOCR</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.7.1</td>
<td>2.5.1</td>
</tr>
</tbody>
</table>
代码高亮显示
同时使用 fenced_code 和 codehilite 扩展
md = """
    ```py
    from markdown import markdown
    html = markdown("# Title")
    ```
"""
html = markdown(md, extensions=['fenced_code', 'codehilite'])
print(html)
中文:生成将应用于 .codehilite 类的 CSS 样式
pygmentize -S monokai -f html -a .codehilite > static/css/codehilite.css
在 HTML 中引用
<link rel="stylesheet" href="/static/css/codehilite.css"/>
- Using Markdown as a Python Library
 - Python-Markdown 3.5 documentation » Extensions
 - Convert Markdown to HTML with Python
 - Convert Markdown tables to html tables using Python
 
CSS:层叠样式表
Swagger UI
控制 API 的显示
app = FastAPI(...)
@app.get("/", include_in_schema=False)
async def root():
控制 BaseModel 的显示
app = FastAPI(swagger_ui_parameters={"defaultModelsExpandDepth": -1})
- -1: schema section hidden
 - 0: schema section is closed
 - 
    
1: schema section is open (default)
 - FastAPI - @Schema(hidden=True) not working when trying to hide the schema section on swagger docs
 
HTMLResponse 响应
*How to return a HTMLResponse with FastAPI
requirements.txt
公共包 requirements_common.txt
--extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple
python-dotenv
fastapi[all]
uvicorn[standard]
gunicorn
aiofiles
markdown
项目包 requirements.txt
-r requirements_common.txt
--extra-index-url https://download.pytorch.org/whl/cpu
torch==2.0.1
torchvision==0.15.2
--extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple
# EasyOCR
easyocr
# PaddleOCR
numpy<1.24      # paddleocr 依赖
paddlepaddle
PyMuPDF==1.21.1 # paddleocr 依赖
paddleocr
调试
运行 FastAPI 项目中的文件,出现 ModuleNotFoundError: No module named ‘app’
在终端下运行脚本,出现下面的错误。
python app/aimodels/ocr_aimodel.py
Traceback (most recent call last):
  File "/Users/junjian/GitHub/gouchicao/WALL-E-AI/app/aimodels/ocr_aimodel.py", line 3, in <module>
    from app.config import *
ModuleNotFoundError: No module named 'app'
手动 - 设置环境变量 PYTHONPATH
export PYTHONPATH=$PWD
自动 - 在 env/bin/activate 文件中设置环境变量 PYTHONPATH
在 env/bin/activate 文件中加入下面的代码,每次新建终端时,都会自动执行。
$ vim env/bin/activate
# HACK: ModuleNotFoundError: No module named 'app'
export PYTHONPATH=$PWD
- ModuleNotFoundError: No module named ‘app.routes’
 - ModuleNotFoundError: No module named ‘app’ using uvicorn, fastapi #2582
 - How to correctly set PYTHONPATH for Visual Studio Code