目录

首页

重定向到 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_codecodehilite 扩展

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"/>

CSS:层叠样式表

Swagger UI

控制 API 的显示

app = FastAPI(...)

@app.get("/", include_in_schema=False)
async def root():

控制 BaseModel 的显示

app = FastAPI(swagger_ui_parameters={"defaultModelsExpandDepth": -1})

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

Generate Client

参考资料