Azure Web App部署FastAPI执行Get请求返回内部服务器错误排查
问题场景
本地PyCharm运行以下FastAPI代码正常,但部署到Azure Web App后调用/file接口返回「Internal Server Error」,代码用于调用Azure DevOps Repo的API获取文件内容。
示例代码
from fastapi import FastAPI import requests import base64 import uvicorn app = FastAPI() @app.get("/") async def root(): return {"Hello": "Pycharm"} @app.get('/file') async def sqlcode(p: str = '/ppppppppp', v: str = 'vvvv', r: str = 'rrrrrr', pn: str = 'nnnnnnn'): organizational_url = f'https://xxxxxxxx/{pn}/_apis/git/repositories/{r}/items?path={p}&versionDescriptor.version={v}&api-version=6.1-preview.1' username = 'username' password = 'password' basic_authentication = base64.b64encode((f'{username}:{password}').encode('utf-8')).decode('utf-8') headers = { 'Authorization': f'Basic {basic_authentication}', } response = requests.get(url=organizational_url, headers=headers) return {"sqlcode": response.text} # Code ends for Fastapi with swagger def print_hi(name): print(f'Hi, {name}') if __name__ == '__main__': print_hi('PyCharm')
requirements.txt内容
Flask==2.0.1 asyncpg==0.21.0 databases==0.4.1 fastapi==0.63.0 gunicorn==20.0.4 pydantic==1.7.3 SQLAlchemy==1.3.22 uvicorn==0.11.5 config==0.3.9 pandas==1.5.3 dask==2023.1.0 azure.storage.blob==12.14.1 pysftp==0.2.9 azure-identity==1.12.0 azure-keyvault-secrets==4.6.0
可能的问题原因及排查解决方法
1. 端口配置不匹配
Azure Web App会通过环境变量PORT指定应用运行的端口,而非本地默认的8000端口。代码中未读取该环境变量,导致服务无法正常启动。
解决方法:
修改代码启动部分,读取PORT环境变量:
import os # ... 其他代码 ... if __name__ == '__main__': print_hi('PyCharm') port = int(os.getenv("PORT", 8000)) uvicorn.run(app, host="0.0.0.0", port=port)
2. 硬编码凭据问题
代码中直接硬编码了username和password,可能存在以下问题:
- 凭据在Azure环境中无效(如个人访问令牌PAT过期、权限不足)
- Azure环境禁止硬编码敏感信息,导致凭据无法正常读取
排查解决:
- 确认用于认证的PAT(若password是PAT)是否拥有
Code (Read)权限,且未过期 - 将敏感信息迁移到Azure环境变量或Key Vault,代码中通过环境变量读取:
在Azure Portal的Web App -> 配置 -> 应用程序设置中添加对应的环境变量。username = os.getenv("DEVOPS_USERNAME") password = os.getenv("DEVOPS_PAT")
3. 异步路由中调用同步阻塞函数
/file路由是async def定义的异步路由,但内部使用了requests.get同步阻塞方法,会阻塞FastAPI的事件循环,在Azure环境下可能引发超时或内部错误。
解决方法:
- 方法一:将路由改为同步定义(去掉
async):@app.get('/file') def sqlcode(p: str = '/ppppppppp', v: str = 'vvvv', r: str = 'rrrrrr', pn: str = 'nnnnnnn'): # 原有逻辑不变 - 方法二:使用异步HTTP客户端(如
httpx)替代requests:
同时在import httpx @app.get('/file') async def sqlcode(p: str = '/ppppppppp', v: str = 'vvvv', r: str = 'rrrrrr', pn: str = 'nnnnnnn'): organizational_url = f'https://xxxxxxxx/{pn}/_apis/git/repositories/{r}/items?path={p}&versionDescriptor.version={v}&api-version=6.1-preview.1' username = os.getenv("DEVOPS_USERNAME") password = os.getenv("DEVOPS_PAT") basic_authentication = base64.b64encode((f'{username}:{password}').encode('utf-8')).decode('utf-8') headers = { 'Authorization': f'Basic {basic_authentication}', } async with httpx.AsyncClient() as client: response = await client.get(url=organizational_url, headers=headers) return {"sqlcode": response.text}requirements.txt中添加httpx>=0.25.0。
4. 依赖包版本兼容问题
代码中使用的fastapi==0.63.0和uvicorn==0.11.5版本较旧,可能与Azure Web App的Python运行环境存在兼容性问题。
解决方法:
更新requirements.txt中的核心依赖版本:
fastapi>=0.100.0 uvicorn>=0.23.2 pydantic>=2.0.0
5. 网络访问限制
Azure Web App的出站网络可能被限制,导致无法访问Azure DevOps的API端点。
排查方法:
- 进入Kudu站点(
https://<你的应用名>.scm.azurewebsites.net),打开控制台,执行curl <你的organizational_url>,检查是否能正常获取响应。 - 若访问失败,检查Web App的网络配置(如是否启用了VNet集成、防火墙规则等),确保允许访问Azure DevOps的公网端点。
6. 未查看具体错误日志
「Internal Server Error」只是通用错误,需要查看具体的错误堆栈才能定位问题。
查看日志方法:
- 在Azure Portal的Web App -> 监控 -> 日志流,实时查看应用日志
- 进入Kudu站点,查看
/home/LogFiles/python.log文件,获取详细错误信息
内容的提问来源于stack exchange,提问作者d2907
相关产品推荐
相关产品推荐

