【python】使用FastAPI开发文件下载和上传服务的详细分析与应用实战

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Fastapi零基础入门与进阶实战教学
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • FastAPI搭建文件下载和上传服务
    • 引言
    • 准备工作
      • 安装必要的库
      • 准备Excel文件
    • 创建 FastAPI 应用
      • 初始化 FastAPI
      • 文件下载路由
      • 改进的文件下载
      • 运行 FastAPI 应用
    • 拓展功能:文件上传和数据库管理
      • 文件上传
      • 数据库管理
    • 安全性和性能考虑
      • 安全性
      • 性能
      • 安全性与权限验证
        • 权限验证基础
        • 清理和验证文件名
        • 限制文件类型
      • 性能优化
    • 总结

FastAPI搭建文件下载和上传服务

引言

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API。它基于 Python 3.6+ 的类型提示,能够自动生成交互式 API 文档。在本教程中,我们将详细介绍如何使用 FastAPI 搭建一个文件下载服务。通过实际案例,我们将学习如何准备文件、创建路由、处理请求以及优化服务。

准备工作

安装必要的库

在开始之前,确保你的环境中安装了 Python 3.6 或更高版本,并安装了以下必要的库:

pip install fastapi uvicorn aiofiles pandas openpyxl

这些库的作用如下:

  • fastapi:用于构建 Web API。
  • uvicorn:用于运行 FastAPI 应用程序的 ASGI 服务器。
  • aiofiles:用于异步文件操作。
  • pandasopenpyxl:用于处理 Excel 文件。

准备Excel文件

我们将通过 pandas 创建一个 Excel 文件,并将其保存在项目中,以便下载。

import pandas as pd
from datetime import datetimedef prepare_excel_file():# 准备数据data = [{"id": 1, "name": "xxx", "age": 18},{"id": 2, "name": "bbb", "age": 19}]# 创建 DataFramedf = pd.DataFrame(data)df.columns = ["序号", "姓名", "年龄"]# 生成文件名file_name = str(datetime.now().date()) + ".xlsx"# 保存 Excel 文件df.to_excel(file_name, index=False)return file_name

这个函数会生成一个包含两行数据的 Excel 文件,文件名基于当前日期。

创建 FastAPI 应用

初始化 FastAPI

from fastapi import FastAPIapp = FastAPI()

文件下载路由

我们需要创建一个路由来处理文件下载请求。使用 FileResponse 来返回文件,这个类允许我们直接发送文件给客户端。

from starlette.responses import FileResponse@app.get("/download/excel")
async def download_excel():file_path = prepare_excel_file()  # 调用函数准备文件return FileResponse(file_path, filename="user_data.xlsx")

注意,这里我们使用了 prepare_excel_file 函数来准备 Excel 文件。然而,在实际应用中,你可能希望将文件保存在一个固定的位置,并在请求时直接读取这个文件,而不是每次请求都重新生成文件。

改进的文件下载

我们改进一下,将 Excel 文件预先生成并存放在项目中,然后直接返回这个文件。

# 假设文件已生成并存放在项目根目录下的 data/user_data.xlsx@app.get("/download/excel")
async def download_excel_improved():file_path = "data/user_data.xlsx"  # 文件路径return FileResponse(file_path, filename="user_data.xlsx")

运行 FastAPI 应用

使用 uvicorn 运行 FastAPI 应用:

uvicorn main:app --host 0.0.0.0 --port 8000

这里 main 是你的 Python 文件名(不包含 .py 后缀),app 是 FastAPI 实例的名称。

文件下载代码展示

import pandas as pd
from datetime import datetimeimport uvicorndef prepare_excel_file():# 准备数据data = [{"id": 1, "name": "xxx", "age": 18},{"id": 2, "name": "bbb", "age": 19}]# 创建 DataFramedf = pd.DataFrame(data)df.columns = ["序号", "姓名", "年龄"]# 生成文件名file_name = str(datetime.now().date()) + ".xlsx"# 保存 Excel 文件df.to_excel(file_name, index=False)return file_namefrom fastapi import FastAPIapp = FastAPI()from starlette.responses import FileResponse@app.get("/download/excel")
async def download_excel():file_path = prepare_excel_file()  # 调用函数准备文件#返回个文件对象,filename指定下载的文件名return FileResponse(file_path, filename="user_data.xlsx")if __name__ == '__main__':#注意,run的第一个参数 必须是文件名:应用程序名uvicorn.run("文件下载:app", port=8080,  reload=True)

浏览器访问下载地址:http://127.0.0.1:8080/download/excel
已将文件下载到本地
在这里插入图片描述
本地打开查看
在这里插入图片描述

拓展功能:文件上传和数据库管理

文件上传

FastAPI 支持文件上传,我们可以使用 UploadFile 类来处理上传的文件。

from fastapi import File, UploadFile
from typing import List@app.post("/upload/files/")
async def upload_files(files: List[UploadFile] = File(...)):uploaded_files = []for file in files:contents = await file.read()# 这里可以保存文件到服务器,或者进行其他处理uploaded_files.append({"filename": file.filename, "size": len(contents)})return {"message": "文件上传成功", "files": uploaded_files}

数据库管理

对于文件下载服务,如果文件存储在数据库中,我们可以根据文件ID或名称从数据库中检索文件信息,然后返回文件。

首先,需要设置数据库模型。这里以 SQLAlchemy 为例,创建一个简单的文件表。

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmakerBase = declarative_base()class FileModel(Base):__tablename__ = 'files'id = Column(Integer, primary_key=True)filename = Column(String(255), nullable=False)filepath = Column(String(512), nullable=False)# 配置数据库连接(这里以 SQLite 为例)
engine = create_engine('sqlite:///example.db', echo=True)
Base.metadata.create_all(engine)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)# 假设数据库中已有文件记录
# 接下来,我们编写一个根据文件ID下载文件的路由from fastapi import HTTPException@app.get("/download/file/{file_id}")
async def download_file_by_id(file_id: int, db: Session = SessionLocal()):# 从数据库中获取文件信息file_record = db.query(FileModel).filter(FileModel.id == file_id).first()if not file_record:raise HTTPException(status_code=404, detail="文件未找到")# 返回文件return FileResponse(path=file_record.filepath, filename=file_record.filename)# 注意:这里的 SessionLocal 是从 SQLAlchemy 会话工厂创建的,用于数据库操作。
# 你需要在 FastAPI 应用的依赖注入系统中注册它,以便在路由处理函数中自动传递数据库会话。
# 这里为了简化,我们没有展示依赖注入的完整设置。# 依赖注入的简单示例(通常放在 main.py 或其他配置文件中)
# from fastapi import Depends
# from sqlalchemy.orm import Session# def get_db(db_session: Session = Depends(SessionLocal)):
#     yield db_session# 然后,在路由函数中使用 Depends 注入数据库会话
# 但请注意,上面的 download_file_by_id 函数已经直接使用了 SessionLocal,这在实际应用中是不推荐的。
# 更好的做法是使用依赖注入来管理数据库会话的生命周期。

安全性和性能考虑

安全性

  1. 验证和清理文件名:在返回文件时,确保文件名是安全的,防止路径遍历攻击(例如,通过 .. 访问上级目录)。
  2. 权限验证:确保只有授权用户才能下载文件。
  3. 文件类型限制:根据需求限制可上传和下载的文件类型。

性能

  1. 缓存:对于频繁访问的文件,可以使用缓存来减少服务器负载和提高响应速度。
  2. 异步处理:利用 FastAPI 和 aiofiles 的异步特性,处理文件读写和网络请求,提高并发处理能力。
  3. 数据库优化:确保数据库索引正确,查询效率高效。

安全性与权限验证

在构建文件下载服务时,安全性是一个不可忽视的方面。特别是当服务涉及敏感文件或需要限制访问时,实现适当的权限验证至关重要。

权限验证基础

你可以使用 FastAPI 的依赖注入系统来管理权限验证逻辑。以下是一个简单的示例,展示了如何在下载文件之前验证用户的权限。

首先,定义一个模拟的用户验证函数(在实际应用中,这可能涉及检查数据库中的用户信息、JWT 令牌等):

from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBeareroauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")def get_current_user(token: str = Depends(oauth2_scheme)):# 这里只是一个模拟示例,实际中你应该根据token查询用户信息if token == "fake-super-secret-token":return {"username": "user123", "is_admin": True}else:raise HTTPException(status_code=403, detail="Invalid token")# 然后,在下载文件的路由中使用这个依赖
@app.get("/download/file/{file_id}")
async def download_file_with_auth(file_id: int, current_user: dict = Depends(get_current_user), db: Session = SessionLocal()):# 验证用户是否有权限下载文件(这里只是一个简单的示例)if not current_user.get("is_admin"):raise HTTPException(status_code=403, detail="You are not authorized to download this file")# 接下来是原有的文件下载逻辑...file_record = db.query(FileModel).filter(FileModel.id == file_id).first()if not file_record:raise HTTPException(status_code=404, detail="File not found")return FileResponse(path=file_record.filepath, filename=file_record.filename)

在这个示例中,get_current_user 函数通过检查一个模拟的令牌来验证用户身份。如果令牌有效,它将返回一个包含用户信息的字典;否则,将抛出一个 HTTPException 异常。然后,在 download_file_with_auth 路由中,我们通过 Depends 依赖项将 get_current_user 函数的结果作为 current_user 参数传入,并据此执行权限验证。

清理和验证文件名

当处理文件下载时,还需要确保文件名是安全的,以防止路径遍历攻击。你可以通过以下方式清理文件名:

  1. 移除危险字符:使用正则表达式或其他字符串处理方法移除文件名中的 ../ 等可能导致路径遍历的字符。
  2. 使用库函数:有些库提供了专门用于清理文件名的函数,可以利用这些库来避免手动处理可能出现的错误。
限制文件类型

根据需求,你可能还希望限制用户下载或上传的文件类型。这可以通过检查文件扩展名或MIME类型来实现。例如,在文件上传的路由中,你可以检查上传文件的MIME类型,确保它符合你的要求。

性能优化

在构建高性能的文件下载服务时,你可以考虑以下几个方面来优化性能:

  1. 使用CDN:对于频繁访问的静态文件,使用内容分发网络(CDN)可以显著减少加载时间。
  2. 缓存:在服务器端和客户端实施缓存策略,以减少对同一文件的重复请求。
  3. 异步处理:利用 FastAPI 和 aiofiles 的异步特性来同时处理多个文件下载请求,提高并发处理能力。
  4. 优化数据库查询:确保数据库索引正确,并使用高效的查询语句来检索文件信息。
  5. 限制文件大小:如果可能,限制可下载文件的大小,以防止过大的文件对服务器造成不必要的负担。

通过结合使用这些技术和策略,你可以构建一个既安全又高效的FastAPI文件下载服务。

总结

通过本文的讲解,我们学习了如何使用 FastAPI 搭建一个简单的文件下载服务,包括文件准备、路由创建、文件上传和数据库管理。同时,我们也讨论了安全性和性能优化的相关考虑。FastAPI 凭借其高性能和易用性,是构建现代 Web 服务的理想选择。希望这个教程能帮助你更好地理解和使用 FastAPI 来构建你的文件下载服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/397685.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用Zoom API创建一个会议?

一、注册一个免费的Zoom账号(zoom.us) 二、在Zoom 应用市场(App Marketplace)创建一个server to server 的app,授予创建会议的权限。 三、创建一个Zoom API的服务端程序(node.js) 1、git clone https://github.com/zoom/server-to-server-o…

英语口语成人英语生活英语口语表达四六级英语培训柯桥小语种学习

全红婵向外国人展示金牌夺冠后,全红婵向外国友人展示金牌。视频中,一位外国男子对全红婵说:“How are you?”全红婵回应:“Good!Good!全红婵比出“拿捏”手势对方说全红婵是奥运冠军&#xff0c…

SpringCloud与SpringBoot之间的关系解析

Spring Cloud和Spring Boot是两个独立的项目,分别用于构建微服务架构和快速构建Java应用程序。它们之间有着密切的关系,可以相互配合使用。 Spring Boot简介 Spring Boot是一个用于快速构建Java应用程序的框架。它简化了Spring应用程序的开发过程&#x…

IDEA使用LiveTemplate快速生成方法注释

文章目录 1 场景2 要点2.1 新增LiveTemplate模版2.2 模版内容填写 3 练习手段 1 场景 方法的注释,一般包含作者、创建时间、功能描述、输入参数、返回值,如果每个方法的注释都手写,非常耗时,且容易随着后期变更代码导致差异&#…

Python酷库之旅-第三方库Pandas(075)

目录 一、用法精讲 306、pandas.Series.str.cat方法 306-1、语法 306-2、参数 306-3、功能 306-4、返回值 306-5、说明 306-6、用法 306-6-1、数据准备 306-6-2、代码示例 306-6-3、结果输出 307、pandas.Series.str.center方法 307-1、语法 307-2、参数 307-3、…

Python | Leetcode Python题解之第331题验证二叉树的前序序列化

题目: 题解: class Solution:def isValidSerialization(self, preorder: str) -> bool:pre 1for i in preorder.split(,):if i.isdigit():if pre 0:return Falsepre 1else:if pre 0:return Falsepre - 1return pre 0

GPS跟踪环路MATLAB之——数字锁频环

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 GPS跟踪环路MATLAB之——数字锁频环 前言为什么要锁频环科斯塔斯环鉴别器环路滤波器matlab程序获取完整程序 前言 从事卫星导航基带处理的童鞋都知道,跟踪环路属…

【DM】Linux下安装 DM数据库-命令行安装

【DM】Linux下安装 DM数据库-图形化安装 1、安装前准备工作1.1 检查 Linux系统信息1.2 创建DM安装用户1.3 检查操作系统限制1.4 检查系统内存与存储空间1.4.1 检查内存1.4.2 检查存储空间1.4.2 检查临时文件目录1.4.3 设置 JAVA 环境 2、使用dmdba用户安装DM82.1 挂载 DM 安装光…

vue中v-html 后端返回html + script js中click事件不生效

效果图&#xff1a; 需求&#xff1a;点击加号执行后端返回的script中的代码 后端返回的html&#xff1a; <!DOCTYPE html> <html langzh> <head> <title>xxx</title> <style>body{font-size: 14px}p{text-indent: 30px;}textarea{width…

华兮云创始人王正一——探索未来之路

在竞争激烈且机遇丛生的行业大环境中&#xff0c;我们有幸邀请到王正一走进直播间&#xff0c;开启一场关于破局与发展、理想与现实的深度交流。 当谈及在行业中应秉持何种心态时&#xff0c;王正一的见解独到且深刻。他强调&#xff0c;无论在融整产业中处于怎样的位置、扮演何…

【C++算法】双指针

移动零 题目链接&#xff1a;移动零https://leetcode.cn/problems/move-zeroes/description/ 算法原理 这类题是属于数组划分、数组分开题型 代码步骤&#xff1a; 使用cur遍历数组当cur所指的元素等于0时&#xff0c;cur向后面移动当cur所指的元素不等于0时&#xff0c;de…

JAVA—异常

认识异常&#xff0c;学会从报错信息中发现问题&#xff0c;解决问题。并学会构建自定义异常&#xff0c;提醒编程时注意 目录 1.认识异常 2.自定义异常 1.自定义运行时异常 2.自定义编译时异常 3.异常的处理 1.认识异常 异常就是代表程序出现的问题&#xff0c;用来查询B…

(自用)交互协议设计——protobuf序列化

protobuf是一种比json和xml等序列化工具更加轻量和高效的结构化数据存储格式&#xff0c;性能比json和xml真的强很多&#xff0c;毕竟google出品。 protobuf原理 protobuf如何使用 创建xxx.proto文件 开头写上 syntax"proto2"package tutorial; 表明使用的proto…

机器学习——支持向量机(SVM)(2)

目录 一、SVC理解进阶 1. C&#xff08;硬间隔与软间隔&#xff09; 2. class_weight 二、模型评估指标&#xff08;SVC&#xff09; 1. 混淆矩阵 &#xff08;Confusion Matrix&#xff09; &#xff08;1&#xff09;准确率 —— 模型整体效果 &#xff08;2&#xff…

Spring AI 更新:支持OpenAI的结构化输出,增强对JSON响应的支持

就在昨晚&#xff0c;Spring AI发了个比较重要的更新。 由于最近OpenAI推出了结构化输出的功能&#xff0c;可确保 AI 生成的响应严格遵守预定义的 JSON 模式。此功能显着提高了人工智能生成内容在现实应用中的可靠性和可用性。Spring AI 紧随其后&#xff0c;现在也可以对Open…

STM32CubleMX创建FreeRtos工程教程,图文教程

前言&#xff1a;STM32CubeMX 是一个开发工具&#xff0c;它已经将 FreeRTOS 这个实时操作系统&#xff08;RTOS&#xff09;集成到其工具中。换句话说&#xff0c;通过 STM32CubeMX&#xff0c;可以非常方便地为 STM32 微控制器生成配置代码&#xff0c;其中包括对 FreeRTOS 的…

jdbc操作数据库MySQL

mysql创建class表 往数据库中使用代码插入一条数据 step1.创建DataSource DataSource dataSource new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java109?characterEncodingutf8&usessLfalse");((MysqlDataSour…

2024十大网站设计公司推荐TOP10

一个精心设计的网站对于企业来说不仅是品牌形象的延伸&#xff0c;也是吸引客户、提升业务的关键工具。 而选择一家专业的网站设计公司&#xff0c;不仅可以帮助企业在激烈的市场竞争中脱颖而出&#xff0c;还能收获更多的客流量&#xff0c;以下是我们精选的十大网站设计公司…

LVS负载均衡+集群+三种工作模式+调度算法及实战案例

一、LVS 1.1简介 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是由章文嵩主导开发的开源负载均衡项目&#xff0c;目前&#xff0c;LVS已经被集成到Linux内核模块中。该项目实现了在基于IP的数据基础上&#xff0c;请求负载均衡调度方案&a…

git推送错误-->远程分支比本地的分支更新,无法直接推送

每次上传本地修改好的代码的时候,十次有八次都会出现这样的问题!!(暴躁!!!) 现在写个帖子记录一下,这个问题目前我还没有解决,欢迎懂的佬指点一下. 情景: 我在本地仓库做了一些代码的修改,准备上传到远程仓库上,下边是上传步骤: git add . # 将所有的修改都提交到缓冲区git …