我是 webdev 新手,我有这样的用例:用户向 API 发送一个大文件(例如视频文件),然后该文件需要可供其他 API 访问(这些 API 可能位于不同的 API 上)服务器)以进行进一步处理。
我使用 FastAPI 作为后端,定义一个类型为
UploadFile
的文件参数来接收和存储文件。但是,让其他 API 可以访问此文件的最佳方法是什么?有没有办法从保存的文件中获取可公开访问的 URL
,其他 API 可以用来下载该文件?
首先,要返回从 FastAPI 后端保存在磁盘上的
file
,您可以使用 FileResponse
(如果文件已完全加载到内存中,请参阅此处)。例如:
from fastapi import FastAPI
from fastapi.responses import FileResponse
some_file_path = "large-video-file.mp4"
app = FastAPI()
@app.get("/")
def main():
return FileResponse(some_file_path)
如果
file
太大而无法装入内存,因为您可能没有足够的内存来处理文件数据,例如,如果您有 16GB RAM,则无法加载 100GB 文件 - 您可以使用 StreamingResponse
。这样,您不必先将其全部读取到内存中,而是将其分块加载到内存中,从而一次处理一个块的数据。下面给出示例。如果您发现使用 yield from f
时 StreamingResponse
相当慢,您可以创建一个自定义生成器,如此答案中所述。
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
some_file_path = "large-video-file.mp4"
app = FastAPI()
@app.get("/")
def main():
def iterfile():
with open(some_file_path, mode="rb") as f:
yield from f
return StreamingResponse(iterfile(), media_type="video/mp4")
至于将您的 API 公开给公众(即外部 API、用户、开发人员等),您可以使用 ngrok(或 expose,如此答案中所建议)。
Ngrok 是一个跨平台应用程序,使开发人员能够以最小的努力将本地“开发服务器”公开到互联网。要将 ngrok
代理嵌入到您的 FastAPI 应用程序中,您可以使用
pyngrok
— 如here 建议(请参阅 here 了解 FastAPI 集成示例)。如果您想通过 Google Colab(使用
ngrok
)而不是本地计算机来运行和公开您的 FastAPI 应用程序,请查看 这个答案(也可以在网络)。 如果您正在寻找更持久的解决方案,您可能需要看看云平台,更具体地说,是平台即服务 (PaaS)。我强烈建议您仔细阅读FastAPI 的部署文档
HTTPS
),以及
authentication
(验证用户身份)和 authorisation
(验证他们的访问权限;换句话说,验证用户有权访问哪些特定路由、文件和数据)—查看 1. OAuth2 和 JWT 令牌、2. OAuth2 范围、3. 基于角色访问控制 (RBAC),4.获取当前用户和如何使用 FastAPI 实现基于角色的访问控制。 此外,如果您将 API 公开供公众使用,您可能希望限制 API 的使用,因为计算成本高昂、资源有限、DDoS 攻击
、暴力攻击、网页抓取,或只是由于固定数量的请求的每月费用。您可以在应用程序级别使用slowapi(相关帖子此处)来实现这一点,或者在平台级别通过托管服务设置速率限制(如果允许)。此外,您需要确保用户上传的文件具有允许的文件扩展名,例如 .mp4
,并且不是具有
.exe
等扩展名的文件,这些文件可能对您的系统有害。最后,您还需要确保上传的文件不超过预定义的 MAX_FILE_SIZE
限制(基于您的需求和系统资源),以便防止经过身份验证的用户或攻击者上传极大的文件,从而导致导致消耗服务器资源,导致应用程序最终崩溃。但是,您不应该依赖 Content-Length
中存在的 request
标头来执行此操作,因为客户端可能很容易更改甚至删除它。您应该使用类似于 这个答案(查看“更新”部分)的方法,该方法使用 request.stream()
在传入数据到达时分块处理它们,而不是首先将整个文件加载到内存中。通过使用简单的计数器,例如 total_len += len(chunk)
,您可以检查文件大小是否超过 MAX_FILE_SIZE
,如果是,则使用 HTTPException
状态代码引发 HTTP_413_REQUEST_ENTITY_TOO_LARGE
(请参阅 此答案 同样,了解更多详细信息和代码示例)。
阅读有关 Cloudflare 上 FastAPI 的 安全文档 和 API 安全 的更多信息。