惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Forbes - Security
Forbes - Security
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
GbyAI
GbyAI
B
Blog RSS Feed
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
小众软件
小众软件
The Last Watchdog
The Last Watchdog
W
WeLiveSecurity
Webroot Blog
Webroot Blog
S
Security @ Cisco Blogs
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
月光博客
月光博客
博客园 - 聂微东
F
Fortinet All Blogs
H
Hacker News: Front Page
A
About on SuperTechFans
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Check Point Blog
V
V2EX
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
N
News | PayPal Newsroom
Cisco Talos Blog
Cisco Talos Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Cloudflare Blog
P
Privacy & Cybersecurity Law Blog
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
大猫的无限游戏
大猫的无限游戏
美团技术团队
Security Latest
Security Latest
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
I
InfoQ
Recent Announcements
Recent Announcements
The GitHub Blog
The GitHub Blog
Google Online Security Blog
Google Online Security Blog
T
The Exploit Database - CXSecurity.com

博客园 - 一名程序媛呀

Anki插件开发必知必会:钩子函数与右键菜单定制 httpx 传参总报错?这次把 GET、POST、文件上传到响应处理的坑给你一次填平 从卡顿到丝滑:FastAPI 调用外部 API 的正确姿势(httpx 实战) 还在 XHR、Fetch 和 Axios 之间纠结?我踩过的坑,希望你一个都不用碰到 你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南 Uvicorn、Gunicorn 傻傻分不清?FastAPI 生产部署避坑指南 Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招! 刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API 别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了 掏出手机就能搭个 WebDAV 同步服务器?这操作有点香 别只盯着GitBook了!这个文档神器让你的笔记秒变网站 写爬虫时用了代理还被封?Python 代理的那些隐藏坑,我替你踩明白了 FastAPI 身份验证总踩坑?这份 FastAPI Users “避坑指南”请收好 旧手机别扔!用 Termux 搭个私人云盘,比网盘香多了 你的FastAPI又在服务器上“跑不起来”了?来,今天咱把打包这件事彻底聊透 写页面时别再把 Element Plus 整个搬进来啦!Vue3按需加载的坑我帮你踩平了 前端包管理咋选?我从npm叛逃到pnpm的血泪史(附避坑指南) 聊聊 fetch 使用中我踩过的那些坑和正确打开方式 FastApiAdmin 后端接口开发好了,前端管理界面怎么调用与显示? 给 FastApiAdmin 加个“会议纪要”模块,我把后端二次开发的坑踩了个遍 我用了FastApiAdmin后,连夜把踩过的坑都整理出来了 告别 Typora 后的新欢:我把所有笔记迁移到了 Obsidian 这个“第二大脑” 你的Agent API还在裸奔?从认证到沙箱,我用FastAPI搭了几道防线 让 FastAPI Agent 思考不阻塞:手把手教你实现异步任务与后台处理方案 让FastAPI Agent真正记住你:聊聊会话记忆与持久化存储的落地实践 FastAPI Agent 函数调用实战:我让 AI 学会了“自己动手查天气“ 初探:用 FastAPI 搭建你的第一个 AI Agent 接口 FastAPI 少有人提的实用技巧:把 Depends 依赖提到路由层,代码少写60% FastAPI 生产环境静态文件完全指南:从 /favicon.ico 404 到 HSTS 混合内容,一次全根治 用了loguru我才明白,Python日志还能这么写 FastAPI 后台任务:BackgroundTasks 的使用场景与注意事项 FastAPI配置管理避坑指南:从硬编码到 .env 与 pydantic_settings 类,连路由用法都给你捋清楚 FastAPI 文件上传避坑全指南:分块存盘、类型校验与安全兜底 FastAPI + Pydantic 模型终极实战手册:从能跑就行到固若金汤,这些技巧你一定用得上 FastAPI + SQLAlchemy 2.0 通用CRUD操作手册 —— 从同步到异步,一次讲透 FastAPI订单防超卖实战:从数据库锁到Saga分布式事务,这一篇给你理清了 FastAPI 生产环境避坑指南:用 Alembic 管理数据库迁移,别再手动改表结构了! FastAPI服务半夜又挂了?先别急着重启,查查你的数据库连接池“池子”是不是漏了 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 Vue 3 组合式 API 香是香,但从Vue2迁移时你可别像我当初一样踩进这 3 个深坑里 我用fastapi-scaff搭了个项目,两天工期缩到两小时,老板以为我开挂了 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! 告别手写 API 胶水代码:FastAPI 与 Vue 的“契约自动机” OpenAPI 实战 FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南” FastAPI + Celery 实战:异步任务里调用 Redis 和数据库的全解析,及生产级组织方案 FastAPI里玩转Redis和数据库的正确姿势,别让异步任务把你坑哭了! FastAPI + Celery 实战:异步任务的坑与解法,我帮你踩了一遍 FastAPI子应用挂载:别再让root_path坑你一夜 FastAPI项目半夜报警吵醒你?聊聊告警这事儿怎么搞! 别再数据线了!用FastAPI 5分钟搭个局域网文件+剪贴板神器 FastAPI单元测试实战:别等上线被喷才后悔,TestClient用对了真香! FastAPI状态共享秘籍:别再让中间件、依赖和路由“各自为政”了! FastAPI实战:WebSocket vs Socket.IO,这回真给我整明白了! 从0到1,FastAPI + PostgreSQL + Tortoise ORM 实战避坑指南 FastAPI + PostgreSQL 实战:给应用装上“缓存”和“日志”翅膀 FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
FastAPI自动生成的API文档太丑?我花了一晚上把它改成了客户愿意付费的样子
一名程序媛呀 · 2026-04-10 · via 博客园 - 一名程序媛呀

你是不是也遇到过这种情况——后端接口写得飞起,FastAPI自动蹦出个 /docs 地址,你兴冲冲地把链接发给老板或者客户看,结果对面来了一句:“就这?这红配绿的页面,看着像内部测试工具啊,能拿给甲方演示吗?”

嗐,别说了,都是泪。试想你用FastAPI做项目交付,就因为没改那个默认的Swagger文档,被产品经理追着问:“咱们公司是不是没钱请前端了?” 🎯 其实真不是技术不行,是咱们很多时候压根没意识到——这文档本身就是产品的一部分

今天这篇,咱们不扯高深的理论,我就想拉着你的手,把我踩过的坑和那点压箱底的定制小技巧掏出来给你看看。看完这篇,你再去点开那个 /docs ,绝对能让它看起来像是值五万块钱的项目。

🎯 别急着写代码,先想想咱们要给谁看

我写这篇文章,最想告诉你的一件事是:定制OpenAPI文档不是瞎折腾UI,而是用最低成本建立技术信任。 一个好的文档门户,能让调用方感觉你这个人、这个团队“很靠谱”。

咱们按这条叙事线走:
😫 问题:默认文档太简陋,像草稿纸。 🤔 踩坑:改个标题就完事了?太天真。 🛠️ 解决:从修修补补到“换头术”。 💡 升华:把文档变成产品说明书。

📝 第一部分:最基础的“遮羞布”——修修改改 FastAPI 对象

好,咱们先来第一步。你可能会问:“我就想改个标题,把那个‘FastAPI’字样换成我项目的Logo名称,难吗?” 一点都不难,甚至有点简单得想笑。

在你初始化 app = FastAPI() 的时候,把参数塞进去就行了。这里千万别学我当初偷懒,为了图省事全是默认参数,结果被测试同事问:“哎,你那个接口文档的邮箱怎么是 your@email.com 啊?”

from fastapi import FastAPI

# 这一小段配置,直接决定了你文档的门面
app = FastAPI(
    title="一名程序媛常用小工具 API 服务",
    description="这是一个专为小程序端提供的高并发接口服务。**注意:所有接口均需鉴权。**",
    version="2.0.1",
    contact={
        "name": "一名程序媛",
        "url": "https://github.com/zhqunyan",
        "email": "zhqunyan@yourdomain.com",
    },
    license_info={
        "name": "Apache 2.0",
        "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
    },
    # 这个小细节别忘了,不然在线测试时域名不对
    servers=[
        {"url": "https://api-dev.yourdomain.com", "description": "开发环境"},
        {"url": "https://api.yourdomain.com", "description": "生产环境"},
    ],
)

你看,加了这几行,再打开文档,是不是瞬间感觉正规军了?那个 description支持 Markdown 语法,你可以贴图、写表格,把这里当作一个简要的对接说明。

image

✨ 第二部分:进阶整容——给文档加点“人情味”

接下来重点来了。光是改个标题,只能算及格。要想让前端或客户看着舒服,你得在路由上加“注释”。FastAPI 的设计哲学就是代码即文档,你的 Docstring 和参数描述,都会变成文档里的文案。

再说个容易翻车的点:tags 。很多兄弟写接口从来不分组,几十个接口堆在 default 里,看着就头皮发麻。你得像整理衣柜一样,把衣服分分类。

from fastapi import APIRouter, Query
from typing import Annotated

router = APIRouter(prefix="/users", tags=["👤 用户管理模块"])

@router.get("/", summary="获取用户列表", description="支持分页查询,默认每页20条数据")
async def get_users(
    page: Annotated[int, Query(description="当前页码,从1开始", ge=1)] = 1,
    size: Annotated[int, Query(description="每页数量,最大100", le=100)] = 20,
):
    """
    这里是详细的接口说明:
    - 如果用户未登录,返回公开信息
    - 如果已登录,返回好友关系状态
    """
    return {"page": page, "size": size}

看到没?用 Annotated 配合 Query 的 description,生成的文档 Schema 界面会非常清晰。别人点开一看,不用问你,自己就知道怎么传参。这就是减少沟通成本的细节。

image

🚀 第三部分:终极换头术——抛弃红绿配,拥抱专业门户

是不是以为这样就完了?改到这里,文档是挺好用了,但视觉上还是那个熟悉的 Swagger 风格。如果你要给外部合作伙伴看,或者想装个X,我强烈推荐你试试 ScalarRedoc

这个工具的选择,好比选螺丝刀,不是最贵的就好,而是看场景。Swagger UI 适合开发自测;Redoc 适合生成静态的、给老板看的 PDF 级文档;而 Scalar 是我现在的首选,UI 现代化,交互丝滑,看起来像个正经的 API 客户端。

安装非常简单,就一个库:

pip install scalar-fastapi

然后去你的主文件里挂载一下:

from scalar_fastapi import get_scalar_api_reference, Theme

# 保留你原来的 Swagger /docs 给开发看
# 新增一个 /portal 给外人看,多有面子
@app.get("/portal", include_in_schema=False)
async def scalar_portal():
    return get_scalar_api_reference(
        openapi_url=app.openapi_url,
        title="一名程序媛常用小工具 API 服务",
        # 甚至可以配个深色模式默认开启
        theme=Theme.DEEP_SPACE,
    )

你试试看,那个页面打开的一瞬间,紫黑色的高级感扑面而来,左侧是清爽的目录树,右侧还能直接生成各种语言的请求代码。官方文档虽然没细说怎么深度定制,但根据以往的经验,这个 theme 参数调整成 DEEP_SPACE 是最稳的,显得有科技感。

image

⚠️ 最后啰嗦一句:安全红线别碰

在你沉浸在定制文档的喜悦中时,我必须泼一盆冷水。千万、千万、千万不要把带有调试功能或者暴露敏感字段的文档直接 openapi_url 甩到公网上裸奔!

在生产环境,务必通过 Nginx 加一层基础认证,或者至少用 FastAPI 的中间件把 /docs/portal 保护起来。别问我为什么知道,问就是…… 😭

好了,今天的分享就到这。这篇文章中的代码都是在本地运行通过的,全是实打实的经验笔记。

你想想,以后开会的时候,别人还在那干巴巴地念接口地址,你直接把定制的 /portal 链接往群里一扔,那种感觉是不是特别踏实?

如果觉得有用,千万别客气,点个赞、关注一下,或者直接收藏夹吃灰都行。 毕竟这种压箱底的骚操作,说不定哪天老板让你优化文档体验的时候,你就得回来翻这篇救命稻草了。咱们下篇见,拜拜~ 👋