编辑FastAPI的OpenAPI Schema时出现KeyError问题求助
解决FastAPI自定义OpenAPI时的KeyError问题
我在修改FastAPI的Redoc代码示例时,使用了以下代码:
def custom_openapi(): # cache the generated schema if app.openapi_schema: return app.openapi_schema # custom settings openapi_schema = get_openapi( title="Test API", version="0.0.1", description=description, routes=app.routes, ) # setting new logo to docs openapi_schema["info"]["x-logo"] = { "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" } api_uri_list = ["/url1", "/url2", "/url3", "/url4"] for uri in api_uri_list: openapi_schema["paths"][str(uri)]["get"]["x-codeSamples"] = [ { 'lang': 'NodeJS', 'source': 'const http = require("http") ' 'http.get("' + uri + '", res => { ' 'console.log(res.data)', 'label': 'NodeJS' }, { 'lang': 'Python', 'source': 'import requests ' 'response = requests.get("' + uri + '") ' 'print(response.text())', 'label': 'Python' }, ] app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi()
但执行时出现如下错误:
Process SpawnProcess-3: Traceback (most recent call last): File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 314, in _bootstrap self.run() File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run self._target(*self._args, **self._kwargs) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\site-packages\uvicorn\_subprocess.py", line 76, in subprocess_started target(sockets=sockets) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\site-packages\uvicorn\server.py", line 59, in run return asyncio.run(self.serve(sockets=sockets)) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run return loop.run_until_complete(main) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete return future.result() File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\site-packages\uvicorn\server.py", line 66, in serve config.load() File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\site-packages\uvicorn\config.py", line 471, in load self.loaded_app = import_from_string(self.app) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\site-packages\uvicorn\importer.py", line 21, in import_from_string module = importlib.import_module(module_str) File "C:\Users\Aadhi\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "C:\Users\Aadhi\Desktop\TestAPI\run.py", line 1, in <module> from app.main import app File "C:\Users\Aadhi\Desktop\TestAPI\app\main.py", line 110, in <module> app.openapi = custom_openapi(app, description) File "C:\Users\Aadhi\Desktop\TestAPI\app\main.py", line 24, in custom_openapi openapi_schema["paths"][str(uri)]["get"]["x-codeSamples"] = [ KeyError: '/url1'
之前代码运行正常,优化后回改仍出现该错误,不清楚问题所在。
问题原因及修复方案
核心问题
KeyError: '/url1'说明生成的OpenAPI schema中paths字段里不存在/url1这个路径,或者该路径没有定义GET方法。- 致命错误:
app.openapi = custom_openapi()是错误的赋值方式,这会在模块加载时直接执行函数,此时FastAPI的路由可能还未完成注册,导致生成的schema不包含目标路由。
修复步骤
- 修正函数赋值方式:将
app.openapi = custom_openapi()改为app.openapi = custom_openapi,把函数本身赋值给app.openapi,确保在第一次访问docs时才生成schema,此时路由已完全注册。 - 检查路由定义:确认FastAPI应用中确实存在
/url1、/url2等路径的GET路由,路径拼写完全匹配(注意带参数的路由如/url/{id}与/url1是不同路径)。 - 添加存在性检查:在修改schema前先验证路径和方法是否存在,避免直接访问不存在的键:
def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title="Test API", version="0.0.1", description=description, routes=app.routes, ) openapi_schema["info"]["x-logo"] = { "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" } api_uri_list = ["/url1", "/url2", "/url3", "/url4"] for uri in api_uri_list: # 检查路径是否存在 path_item = openapi_schema["paths"].get(uri) if not path_item: print(f"路径 {uri} 不在OpenAPI schema中,跳过") continue # 检查GET方法是否存在 get_op = path_item.get("get") if not get_op: print(f"路径 {uri} 没有GET方法,跳过") continue # 使用f-string简化字符串拼接,修复代码示例错误 get_op["x-codeSamples"] = [ { 'lang': 'NodeJS', 'source': f"""const http = require("http")
- 修正函数赋值方式:将
http.get("{uri}", res => {{
console.log(res.data)
}})""",
'label': 'NodeJS'
},
{
'lang': 'Python',
'source': f"""import requests
response = requests.get("{uri}")
print(response.text)""",
'label': 'Python'
},
]
app.openapi_schema = openapi_schema
return app.openapi_schema
# 正确赋值:不要加括号 app.openapi = custom_openapi ```
- 修复代码示例错误:原Python代码示例中
response.text()是错误的,requests响应的文本是属性response.text,不是方法。
内容的提问来源于stack exchange,提问作者Aadhi Verma
相关产品推荐
相关产品推荐

