【问题标题】:FastAPI's RedirectResponse doesn't work as expected in Swagger UIFastAPI 的 RedirectResponse 在 Swagger UI 中没有按预期工作
【发布时间】:2022-12-17 19:52:15
【问题描述】:

我有一个带有下载端点的 FastAPI 应用程序。此下载端点的作用是使用 BlobServiceClient(用于 Azure Blob 存储)为请求中指定的文件生成令牌和 Blob URL。我想要做的是将用户重定向到该 URL。这是下载点的代码 sn-p(我注释掉了一些东西,因为我不允许显示代码)。

@router.get("..path", tags=["some tags"], summary=..., responses={404: {"model": ...}, 403: {"model": ...}, 307: {"model": ...}}, response_model_exclude_none=True)
async def download_file(
        # there's a depends on an API key
        blob_path: str = Query(
            ...
        )):
credential = ClientSecretCredential(...)  //secrets
blob_service_client = BlobServiceClient(f"https://{storage_account}.blob.core.windows.net", credential=credential)
user_delegation_key = blob_service_client.get_user_delegation_key(key_start_time=datetime.utcnow(),key_expiry_time=datetime.utcnow() + timedelta(minutes=30))
    
token = generate_blob_sas(account_name=...,                                 
                          container_name=...,                                 
                          blob_name=blob_path,
                          user_delegation_key=user_delegation_key,
                          permission=BlobSasPermissions(read=True),
                          expiry=datetime.utcnow() + timedelta(minutes=30))
    
blob_url = f'https://{storage_account}.blob.core.windows.net/{container_name}/{blob_path}?{token}' 
print(blob_url)  
response = RedirectResponse(blob_url) 
return response

我期望的是要执行的查询,返回响应后,下载将在后台或单独的选项卡中开始。相反,我得到的是一个不同的响应,正如您在 Swagger 中看到的那样:

我还查看了“网络”选项卡以查看该请求发生了什么:

看起来有一个 OPTIONS 请求,我假设我正在收到对该请求的响应。不确定这是否是 Swagger 处理请求的方式。知道这是怎么/为什么发生的以及如何解决它吗?谢谢!

【问题讨论】:

  • 我明白你在说什么,OPTIONS 请求返回一个 File 响应,这就是它在 Swagger 中的原因。我的问题是为什么首先完成 OPTIONS 请求(我假设是因为重定向)但是为什么我想要重定向的那个 URL 不能简单地访问(比如当你点击一个 URL 来下载一些东西并且它开始下载时)。你是说不应该遵循重定向?
  • 我感到困惑的是我试图实现的功能是访问 URL 以及 Swagger 发送到该 URL 的 OPTIONS 请求

标签: python redirect swagger fastapi swagger-ui


【解决方案1】:

首先,CORS 中的 HTTP OPTIONS 是浏览器在实际请求之前自动发出的 preflight request,而不是返回 File 响应的那个。它请求给定服务器允许的通信选项,并且服务器以Access-Control-Allow-Methods 标头响应,其中包括一组允许的方法(例如Access-Control-Allow-Methods: OPTIONS, GET, HEAD, POST, DELETE)。对于使用Access-Control-Max-Age 标头在同一 URL 中创建的请求,可以选择缓存预检响应,从而允许服务器限制预检请求的数量。此标头的值以秒为单位表示;因此,允许缓存 10 分钟,例如,看起来像 Access-Control-Max-Age: 600

至于RedirectResponseSwagger UI always follows redirect responses。例如,在 fetch 请求中,redirect 参数将设置为 follow,表示应遵循 redirect。这意味着 Swagger UI 遵循重定向并等待响应完全接收,然后再为您提供 Download file 链接(如您上面提供的屏幕截图所示)以下载文件。这也是为什么您无法在后台或新选项卡中看到下载开始的原因。如上面链接的 github 帖子中所述,无法将 redirect 更改为 manual,以便 Swagger 不遵循重定向,这可能允许您以不同的方式处理它。

您可以通过在浏览器的地址栏中输入 API 端点的 URL 直接测试它(因为它是 GET 端点,您可以这样做),而不是使用 Swagger UI 来测试该特定端点,或者创建您自己的自定义Template(或使用HTMLResponse)和 提交HTML <form>,如this answer所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    相关资源
    最近更新 更多