立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 963|回复: 5

[讨论] Django、Flask、FastAPI,Python 后端哪个更好?

[复制链接]
发表于 2025-3-17 21:26 | 显示全部楼层 |阅读模式
回复

使用道具 举报

发表于 2025-3-17 21:27 | 显示全部楼层
Django是最好的!
相信我!
什么系统臃肿啊、运行速度慢啊、设计优秀啊,别扯了!
Django大而全,什么都给你设计好了,官方文档我就没见过比Django还清晰的,中文翻译非常棒。
就这么说吧,学Django可以完全不用看各种视频教程,只需要按照官网文档做一下demo即可。
然后,用到哪里就查到哪里,很快就能入门了。
最关键的是,Django文档检索系统做的也很不错,中英文都可以快速检索到内容。
Flask、FastAPI所谓的精简,最后不还是要通过各种插件实现吗?
最后,装插件装到疯魔,蓦然回首,简洁早已消失不见,所有的功能都得自己安装。
各种插件的兼容性,使用方法都要自己搞,烦死了。
还有人扯性能啥的,别扯了,都沦落到用Py了,还扯什么性能?
反正,只要用上Django,基本上剩下的就是丝滑,丝滑你懂吗?德芙知道吗?
就是那种很润的。。
回复 支持 反对

使用道具 举报

发表于 2025-3-17 21:27 | 显示全部楼层
周末搜索一些信息时发现2023年还有不少人推荐使用Flask作为Python的Web框架,而我已经认为「Flask已死,FastAPI是未来」,所以写下本文,欢迎讨论和反驳。
Flask vs FastAPI

Flask是一个在Python开发者心目中十分重要的项目,如果你是一个Web开发者,我相信你一定用过Flask,但是可能没有用过FastAPI。这个和国外相比可能会更明显一点,我觉得主要是因为国内已经没有多少人在写技术文章推荐,教大家分辨趋势或者主流,而一些老手即便知道它们的优缺点可能也懒得写对比文章,结果造成很多新人不了解怎么选,只能看一些老的文章、大V或者书籍的推荐作为选择的依据。
但是如果你有兴趣,你可以考证2点:

  • 最近1-2年,Python相关的知名新项目中只要有Web的,基本都使用FastAPI。
  • 今天(2023年12月18日)在Github上,FastAPI的star数(66k)已经超过了Flask(65.2)。
接着看一下Python官方的开发者调查中Web框架占比的变化:


可以看到19年FastAPI甚至不是一个选项,而22年已经占到25%的比率。这个开发者调查需要年中才会统计出上一年的,所以2023年的得明天第三季度才能知道,我预计FastAPI可以达到35%左右。
需要注意这个占比数据包含了现有系统,所以Django和Flask不容易跌得很快,但是趋势是很明显的。
我们知道Web框架这个领域是很高产的,基本每年都有新的框架诞生,大部分框架昙花一现,但有的框架却能够长青。FastAPI诞生于2018年底,在2019年年底左右开始崭露头角,那么为什么它可以在短短的5年里让关注度超过在2010年底诞生的Flask呢?接着我们顺着时间线捋捋Python Web框架和相关解决方案的发展来理解吧。
Web框架(插件、工具)发展史

FastAPI作者是一个非常关注Python生态发展的开发者,延伸阅读链接2是一篇作者写的,详细的介绍了FastAPI出各个库中的借鉴或者启发的细节,而发展史这部分我也参考了这篇文章。大家应该看看原文,里面包含了为什么会出现FastAPI以及作者的一些设计哲学。
Django

Django是Python社区里最早做到统治级别的Web框架,当时知名的Instagram就是用它构建的。它的特点是大而全,各种web开发需要用到的细节它基本都有相关的模块,尤其和关系数据库、管理功能等方面耦合度非常高。对于熟悉的老手,这是一个生产级别的框架,但即便有完整的文档,对于初学者非常不友好,学习曲线中后期很陡峭,它的复杂度和定制成本非常高。
其实我这篇文章,也可以叫做「Django和Flask之死」,但是在框架应用场景角度来说Flask和FastAPI对比更合适,而Django直接和FastAPI相比有一些差别。在一些商业场景(例如CMS)Django依然是首选,而Flask(甚至FastAPI)看起来更像个「玩具」,所以Django短时间不会被取代(Flask这些年不是也是没取代的了嘛)。
Django REST Framework(DRF)

Django主旨是为了在后端生成 HTML,而不是创建现代前端(如 React、Vue.js )或与其通信的其他系统使用的 API。所以FastAPI其实和Django REST Framework直接对标,它们主要场景都是构建 Web API,但是名字上也可以看出来,DRF还是依托于Django框架,所以缺点一样。
Flask

Flask是一个「微」框架(Micro framework),和Django截然相反,它仅保留小部分的核心,还为了解耦把功能拆分成几个库(如Jinja2,Werkzeug等),所以开发者有足够的自由,你可以很容易写出相关功能的第三方插件。它里面的蓝图、上下文、装饰器表示路由、信号等等设计在当时是非常先进的,再加上文档写的很完整,可以说对新手极为友好。
Flask REST Frameworks

由于Flask的简单性,它非常适合构建API,不过由于Flask什么也不带,我们需要专门的REST框架。所以相继出现了 flask-restful 、Flask-RESTPlus、flask-api等框架,另外在Rest服务中,会需要数据验证、解析和规范等需要,也出现了Marshmallow、Webargs和APISpec,一直到Flask-apispec。但是整个发展过程中没有出现一个足够好的能够对标DRF的Flask REST Framework。
而到这个阶段,Flask的缺点其实也暴露了。
Flask本来的优点是灵活性和极简主义,但这意味着很多很多组件需要自己造,这个要不然需要公司够大专门有开发者开发和维护,要不然得个人能力极强,否则插件很难达到生产级别,这就造成Flask的第三方插件质量层次不齐,且无法保证长期维护。就像我上面说的那些库,现在来看,其中已经很多不再维护了。
所以即便是今天,你想用Flask构建一个API服务,还是要东拼西凑各个组件,其中某些组件有些没及时更新的地方要自己动手解决,这对于老手来说还好,对于新人来说很痛苦,尤其是你想要应用现在最新的实践方案和理念,只能望而兴叹。
Asyncio生态

从Python3.5开始,asyncio已经是未来的趋势了。所以开始出现了一些原生支持asyncio的Web框架,如aiohttp、Starlette和sanic。
这个时候Flask并不想接受改变,社区迟迟的不加入aio的支持,另外Flask原作者也去写rust了,把项目交给了2个维护者(现在只剩一个人了)。
而用于构架API服务的项目例如apistar,molten。它们都给FastAPI的带来了设计灵感。
FastAPI

接着就是诞生FastAPI了。作者本来也是想找到一个好的解决方案,但是以上种种都是自己的问题或者说局限性,所以作者就造了这个轮子。
FastAPI为什么能成为统治者

这篇文章的核心部分啦,这些理由也是为什么FastAPI会替代Flask的原因。
异步设计

在Flask的那个时代,代码执行是单线程、同步的,这意味着要依次处理请求,前一个请求完成前,其他请求消耗在等待 I/O 操作上。而asyncio是最好的解决方案,它让I/O成为异步操作,无需等待任务完成即可获取任务结果并继续处理其他任务请求。
而FastAPI天生支持并发和异步代码,代码写对了就可以在效率上达到极致,所以它被认为是目前最快的Python框架,效率和NodeJS或Go接近。当速度和性能至关重要时,FastAPI 是最佳选择。
使用Pydantic做用户数据验证

API开发中数据格式的验证、解析和序列化是很常用的,在这些年的发展过程中出了很多种方案,而目前最好的方案就是Pydantic:
from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item这个代码初看是ORM/dataclass的写法,其实是基于Python原生的Type Hints的语法给字段做类型注解,例如上例的/items/请求中的Item的schema已经定义好了,各个字段的值类型非常明确。和过去用schema描述甚至硬代码的方式相比很干净很pythonic,对于IDE支持也更好。
在现阶段,Pydantic在用户数据验证等领域是统治级别的,而FastAPI内置了它,这可以大大简化了验证过程,它还可以减少错误,所以FastAPI官网介绍优点中就提到这个方案可以将开发人员错误减少高达 40%。对于Python这种动态语言来说,如果不是用mypy强制类型检查,应用Pydantic是非常有必要的。
另外由于集成了Pydantic,所以非常容易在项目中添加ORM(如SQLAlchemy),从请求中获得的对象可以直接传递到数据库,因为已经做过数据验证。反之亦然,可以将从数据库获取的对象直接返回。
相对的,Flask这方面的缺失的。
原生支持ASGI

先提一下WSGI,他的全称是「Python Web Server Gateway Interface」,具体可以看延伸阅读链接三的《PEP 3333》,它是专门为 Web 应用程序和服务器相互交互而编写的 Python 标准。如果你使用过PHP或 Ruby 的人会更容易理解它。Flask的依赖Werkzeug就是WSGI套件,所以Flask支持的是这个老的WSGI,不支持ASGI。
WSGI的问题是无法利用异步达到性能和效率提升,所以Django组织首先提出了ASGI。它的全称是「Asynchronous Server Gateway Interface」,它是一个迭代但基本的重新设计,它提供了异步服务器/应用程序接口,并支持 HTTP、HTTP/2 和 WebSocket。与 WSGI 不同,ASGI 允许每个应用程序有多个异步事件。另外,ASGI 支持同步和异步应用程序。你可以将旧的同步WSGI Web应用程序迁移到 ASGI,也可以使用ASGI构建新的异步 Web 应用程序。
出结论之前,先稍微补充5个名词解释:

  • ASGI工具集。实现了ASGI相关功能(例如URL路由、Request/Response对象、模板引擎等)的库,在本文中主要指Starlette,它对标的是Flask的依赖Werkzeug。
  • ASGI Web框架。实现了ASGI规范的Web框架(例如FastAPI),而Flask、Django是实现了WSGI的Web框架,它是面向开发者编写应用程序,接口非常易用,开发者按照需求填业务逻辑就行。早期的框架都是内部实现了ASGI工具集,而后来的框架通常是组合合适的工具集来用,例如Flask用Werkzeug(自己家的),FastAPI用Starlette(别家的)。
  • Web应用。使用了Web框架创建的应用程序就是一个Web应用,而通常Web框架自带一个测试服务器,可以启动起来用于开发调试,如果不考虑性能和稳定性,你已经可以在浏览器里访问开发地址访问这个应用了。
  • Web服务器(Web Server)。现实世界要比预想的复杂,Web应用部署到生产环境后需要考虑请求负载均衡、服务静态文件、访问控制、反向代理等等需求,同时对于性能也很有要求,Web框架内置的Web服务器时远远达不到这个要求的,所以就需要有专门的Web服务器,现在主流的就是Nginx。
  • ASGI服务器。ASGI服务器是Web服务器和Web应用之间的桥梁,ASGI服务器也会遵守ASGI的规范,但是它的主要任务是满足转发请求的性能要求,所以主要做的是ASGI里面的G这部分,也就是网关,它的代码对于开发者写Web应用并不友好,不会有开发者直接使用ASGI写业务和路由逻辑。目前最知名的ASGI服务器是Uvicorn,另外使用本来是WSGI服务器的Gunicorn的uvicorn.workers.UvicornWorker也可以。都是生产环境推荐的用法。
过去一般WSGI的生产环境方案是 Nginx+Gunicorn+Flask(Django),而现在ASGI的生产环境方案是 Nginx+Uvicorn+FastAPI。
再补充一点。FastAPI无论看项目名字还是介绍都能感觉出来它是用于构建API服务的,事实上FastAPI自己的核心代码也确实是这样的,可以说它不是一个传统的、完全自己实现的框架,它更像是一个集各家之长的框架,从一个空壳开始,把需要的、适合的组件组装起来。例如它没有模版引擎,如果你确实需要用它实现一个web应用要渲染模版,你可以再组合你想要的选择,当然还可以用Starlette内置的Jinja2(是的,也是Flask内置的)。
为什么说Flask已死

上面提的是FastAPI的优势,但是也不能说明Flask已死,我为什么会这么觉得呢? 主要还是看开发者和用户的人气。
这个「人气」是一个很主观的感受,我能想到的有如下指标:

  • 社区活跃度。例如项目的Issue和Pull Request数量,Flask都是个位数,和FastAPI相比根本不是一个水平。这其实侧面证明项目不再活跃,因为如果活跃的话,老的用户会有更多需求,它们不来说明已经离开,而新的用户意味着有各种问题,文档即便足够全,其实我们要知道还是会有很多用户来提问和贡献代码的,没有就说明用得少。
  • 讨论度。也就是博客文章,Stackoverflow等网站咨询和讨论的热度,其实可以感受到,已经没什么人写Flask相关的内容了。
  • 开发迭代的频率。翻一下commits,可以看到Flask只有一个维护者会偶尔修修bug,没有什么大的功能特性开发。
  • 灵魂人物的影响力。Flask的灵魂人物,也就是项目的发起人其实早就不再参与项目了,搜一下项目贡献记录可以看到Armin Ronacher上次参与开发已经是6年前了。
以上种种在我这里其实都说明Flask已死,大家应该考虑替代品。
哎,有一点伤感,感谢Flask带我入了Web开发的坑。
后记

是的,我认为现在是抛弃Flask的时候了,如果你是一个Python Web服务的初学者请直接使用FastAPI,如果你是一个有一定工作经验的人,我建议下一个项目请使用FastAPI甚至替代现在的项目,欢迎讨论~
延伸阅读

回复 支持 反对

使用道具 举报

发表于 2025-3-17 21:28 | 显示全部楼层
在之前的文章中,我们介绍了如何使用FastAPI + NGINX + Gunicorn:一步一步教你部署一个高性能的Python网页应用,并将其部署到服务器上。这个过程中,我们学习了如何使用 FastAPI 框架来构建 Web API,以及如何使用 NGINX 和 Gunicorn 来部署这个应用程序。但是,Web API 的应用场景不仅仅局限于网页应用程序,它也可以用于构建各种类型的应用程序,包括机器学习应用程序、移动应用程序等等。
在今天的文章中,我们将重点介绍 FastAPI 的开发和部署。我们将学习如何使用 FastAPI 框架来构建 Python Web API,并将其容器化为 Docker 镜像部署运行。本文将提供一步一步的指导,帮助您快速入门 FastAPI 框架,并掌握如何将其应用于 Python Web API 的开发和部署。如果您是 Python 开发新手,本文可能会为您提供一些参考,对于FastAPI 框架还有很多高级的内容将在后续逐渐展开介绍。
一、FastAPI 简介

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示使用 Python 3.7+ 构建 API。
FastAPI 可简化使用 Python 编程创建 Web API 的过程。它允许开发人员快速轻松地构建 API,确保最佳性能和轻松管理,而不会影响代码质量和效率。它提供了许多优势,包括卓越的速度(基于 Starlette,使用 ASGI)、优于其他几个 Python 后端框架以及与 Express.js 等流行框架竞争。
它具有以下主要特点:

  • 快速:非常高的性能,与 NodeJS 和 Go 相当(感谢 StarlettePydantic)。可用的最快的 Python 框架之一。
  • 快速编码:将开发功能的速度提高约 200% 到 300%。
  • 更少的错误:减少约 40% 的人为(开发人员)引起的错误。
  • 直观:强大的编辑器支持。到处都完成。调试时间更少。
  • 简单:旨在易于使用和学习。阅读文档的时间更少。
  • 简而言之:最大限度地减少代码重复。每个参数声明具有多个功能。更少的错误。
  • 健壮:获取可用于生产的代码。具有自动交互式文档。
  • 基于标准:基于(并完全兼容)API 开放标准:OpenAPI(以前称为 Swagger)和 JSON Schema。
1.1、为什么选择 FastAPI

之所以选择 FastAPI 来创建API。除了其性能不错,运行快速之外,它不需要进行大量的设置和配置,即可快速构建 API。 FastAPI 支持直接生成 OpenAPI 规范文档,无需花费精力安装额外的库来生成 Flask 或 Django 的 OpenAPI 文档。
我认为 FastAPI 是在 Python 中构建 API 的原因是:

  • 性能:FastAPI 通过充分利用关键库和工具(例如 Pydantic 和 ASGI 生态系统)来最大限度地提高性能。此外,由于其基于 Starlette 框架,所以无缝集成了异步/等待功能的强大功能。
  • 可扩展性:FastAPI 的模块化和简单性允许与负载均衡器无缝集成,促进可扩展性并确保高效的资源利用。
  • 自动文档:通过要求各种 FastAPI 组件的显式定义,Pydantic 的集成允许 FastAPI 能够自动生成其 API 文档。 FastAPI 提供 Swagger API 文档。
  • 易用性:FastAPI是一个Python框架,因此继承了使用Python的好处。不仅如此,FastAPI 使创建服务器和构建端点变得简单快捷。
  • 请求验证:FastAPI 提供请求验证以及用户可读的更详细的错误消息。这也归因于它使用 Pydantic 来进行请求数据类型规范。
1.2、FastAPI 与其他 Python 框架的比较

FastAPI与其他Python框架(如Flask、Django和Pyramid)相比有以下特点:

  • 性能:FastAPI以其卓越的性能而脱颖而出。它使用现代Python技术,如异步编程和类型注解,以实现高速的请求处理和响应。
  • 类型注解和自动文档生成:FastAPI支持使用类型注解来定义API的输入和输出,并可以根据这些注解自动生成清晰易懂的文档。这使得开发人员能够更好地理解API的结构和功能。
  • 异步支持:FastAPI基于Starlette框架,充分利用了异步编程的优势。它可以处理大量并发请求,并具有出色的性能表现。
  • 生产力和易用性:FastAPI提供简单直观的API设计,具有清晰的文档和广泛的示例。它还附带了一些预构建的工具,如自动文档生成,以提高开发人员的生产力。
  • 生态系统:尽管FastAPI相对较新,但它的生态系统正在迅速发展。它可以与其他Python库和工具无缝集成,为开发人员提供更多选择和灵活性。
综上所述,FastAPI在性能、类型注解、自动文档生成、异步支持和生产力方面与其他Python框架相比具有独特的优势。对于需要高性能和易用性的应用程序开发,FastAPI是一个值得考虑的选择。
1.2.1、Django 与 FastAPI

Django和FastAPI是两个不同的Python后端框架,各自有其特点和适用场景。
Django是一个功能丰富的框架,拥有强大的内置库和功能。它提供了ORM(对象关系映射)工具、身份验证机制和路由功能等,使得开发复杂的Web应用程序变得更加容易。Django还有一个庞大的生态系统,可以满足各种项目需求。
FastAPI则是一个轻量级的微框架,专注于高性能和灵活性。虽然FastAPI缺乏像Django那样的完整生态系统,但它以其快速的处理速度而脱颖而出。FastAPI使用现代Python技术,如异步编程和类型注解,来提高性能和效率。
因此,选择使用Django还是FastAPI取决于项目的需求和优先考虑的方面。如果需要开发复杂的Web应用程序,并且需要全面的功能和生态系统支持,那么Django可能是更好的选择。而如果对性能和灵活性有较高的要求,且项目规模相对较小,那么FastAPI可能更适合。
1.2.2、Flask 与 FastAPI

Flask是一个轻量级的框架,旨在快速构建Web应用程序。它提供了简洁而灵活的设计,为开发人员提供更多的控制权和灵活性。Flask允许开发人员根据他们的具体需求或要求来定制应用程序,使得开发过程更加自由和定制化。
FastAPI则专注于以卓越的速度开发高性能和可扩展的应用程序。它使用现代Python技术,如异步编程和类型注解,以实现快速的请求处理和响应。FastAPI适用于需要处理大量并发请求和对性能有较高要求的复杂应用程序。
因此,选择使用Flask还是FastAPI取决于项目的需求和优先考虑的方面。如果你需要一个轻量级的框架,注重灵活性和定制化,并且对性能要求相对较低,那么Flask可能是更好的选择。而如果你需要一个高性能、可扩展的框架,对性能要求较高,那么FastAPI可能更适合。
1.2.3、Pyramid Vs FastAPI

Pyramid是Python最受欢迎的后端框架之一,它采用了“仅使用您需要的”理念。这意味着Pyramid提供了一个简约的核心,可以通过各种附加组件和库进行扩展。开发人员可以根据自己的需求选择和定制所需的组件,从而形成一个轻量级且高度可定制的框架。这种模块化的设计使得Pyramid非常灵活,能够满足各种特定的用例需求。
FastAPI则更注重开发人员的生产力和易用性。它具有简单直观的API设计,清晰的文档和广泛的示例。FastAPI还提供了一些预构建的工具,例如自动生成API文档。这些功能使得开发人员能够快速上手并提高开发效率。
因此,选择使用Pyramid还是FastAPI取决于项目的需求和优先考虑的方面。如果你需要一个高度可定制的框架,希望能够选择和定制所需的组件,那么Pyramid可能是更好的选择。而如果你注重开发人员的生产力和易用性,并且需要快速上手和高效开发的框架,那么FastAPI可能更适合。
二、FastAPI 安装

在安装 FastAPI 之前,使用 virtualenv 在新创建的目录中创建一个新的虚拟环境。
如果您尚未安装 virtualenv
pip install virtualenv创建一个新的 env 虚拟环境。
virtualenv env如果使用的是 Mac/Linux,您可以使用以下命令激活虚拟环境,Windows 用户可以运行此命令:
source ./env/bin/activate最后,您已准备好安装 FastAPI,请运行以下命令:
pip install fastapi由于 FastAPI 没有内置服务,因此您需要安装 uvicorn 才能运行。 uvicorn 是一个 ASGI 服务器,它允许我们使用异步/等待功能,使用命令安装 uvicorn。
pip install "uvicorn[standard]"三、FastAPI 开发

3.1、使用 FastAPI 创建 API

一旦你安装了这些库。使用以下内容创建一个名为 main.py 的新 python 文件:
# main.py

from typing import Union
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}在这里,首先导入并实例化 FastAPI,然后注册根端点 / ,然后返回 JSON 。

  • 第 1 步导入 FastAPI :FastAPI 是一个 Python 类,为您的 API 提供所有功能。
  • 第 2 步是创建一个 FastAPI 实例,这里的 app 变量将是类 FastAPI 的实例。这将是创建 API 的主要交互点。此 app 与您在上面使用 uvicorn 运行实时服务器的命令中提到的相同。
在继续步骤 3 之前,这里先解释几个术语。
1)、路径是指从第一个正斜杠字符 ( / ) 开始的 URL 的最后部分。因此,在 https://example.com/items/foo 这样的 URL 中,路径将为 /items/foo 。路径通常也称为端点或路由,但本教程中将使用术语路径。当您构建 API 时,路径是分离资源的主要方式。
2)、另一个需要了解的重要术语是操作,它用于引用任何 HTTP 请求方法:POST、GET、PUT、DELETE、OPTIONS、HEAD、PATCH、TRACE
通过 HTTP,你可以使用其中一个(或多个)操作与每个路径进行通信。了解这两个术语的含义后,您就可以继续第三步了。

  • 第3步是定义路径操作装饰器,@app.get("/") 告诉 FastAPI 下面的函数负责处理使用 get 操作发送到路径 / 的请求。这是一个与路径操作相关的装饰器,或者说路径操作装饰器。如果您想了解有关装饰器的更多信息,请查看 Python 装饰器入门。
您还可以使用上面提到的其他操作:

  • @app.post()
  • @app.put()
  • @app.delete()
  • @app.options()
  • @app.head()
  • @app.patch()
  • @app.trace()
在每种情况下,你都可以在负责处理这些请求的函数上方使用适当的路径操作装饰器。

  • 第四步是定义路径操作函数,或者路径操作装饰器下面的函数。
每当 FastAPI 使用 GET 操作接收到对指定 URL ( / ) 的请求时,都会调用此函数。在本例中,它是一个 async 函数。你还可以将其定义为普通函数,而不是使用 async def :
如果您不知道普通函数和 async 函数之间的区别以及何时使用它们,请查看 FastAPI 文档中的并发和 async/await。

  • 第五步,返回内容:你可以将字典、列表或异常值返回为字符串、整数等。您还可以返回 pydantic 模型。还有许多其他对象和模型将自动转换为 JSON,包括对象关系映射器 (ORM) 等。
3.2、运行服务器

使用以下命令运行服务器:
uvicorn main:app --reload --host 0.0.0.0这里 app.main 表示您使用 app 目录中的 main.py 文件, :app 表示我们的 FastAPI 实例名称。
启动完成后,可以在浏览器中输入 http://127.0.0.1:8000 访问该应用程序,它将发送包含以下内容的 JSON 响应:
{"message":"Hello World"}该 JSON 消息与您从应用程序中的函数返回的字典相同。 FastAPI 负责将 Python dict 序列化为 JSON 对象并设置适当的 Content-Type 。
3.3、路径参数:通过ID获取项目

可以使用与 Python 格式字符串相同的语法来声明路径参数或变量:
@app.get("/items/{item_id}")
async def read_item(item_id):   
    return {"item_id": item_id}路径参数 item_id 的值将作为参数 item_id 传递给您的函数。
因此,如果您运行此示例并转到 http://127.0.0.1:8000/items/foo ,您将看到以下响应:
{"item_id":"foo"}响应包含 "foo" ,它是在 item_id 路径参数中传递的内容,然后在字典中返回。
3.4、带类型的路径参数

可以使用标准 Python 类型提示在函数中声明路径参数的类型:
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}将 item_id 声明为 int,声明路径参数的类型将为您提供函数内部的编辑器支持,包括错误检查、完成等。
因此,如果您运行此示例并转到 http://127.0.0.1:8000/items/5?q=somequery ,您将看到以下响应:
{"item_id":5,"q":"somequery"}响应包含 "foo" ,它是在 item_id 路径参数中传递的内容,然后在字典中返回。
3.5、数据转换

从上面的请求中,我们定义的函数接收并返回的值是 5 ,它是 Python int ,而不是字符串 ( "5" )。因此,通过该类型声明,FastAPI 可以为您提供自动请求解析。
3.6、数据验证

如果你将浏览器指向 http://127.0.0.1:8000/items/foo ,那么你会看到一个很好的 HTTP 错误:
{
        "detail": [{
                "type": "int_parsing",
                "loc": ["path", "item_id"],
                "msg": "Input should be a valid integer, unable to parse string as an integer",
                "input": "foo",
                "url": "https://errors.pydantic.dev/2.3/v/int_parsing"
        }]
}这是因为路径参数 item_id 的值为 "foo" ,而不是 int 。
如果提供 float 而不是 int ,例如在浏览器中打开 http://127.0.0.1:8000/items/1.2 ,也会出现相同的错误。因此,通过相同的 Python 类型提示,FastAPI 为您提供数据解析和数据验证。
另请注意,该错误清楚地指出了验证未通过的确切点。这在开发和调试与 API 交互的代码时非常有用。
3.7、交互式 API 文档

要访问应用自动交互的API文档(由Swagger UI提供),请访问 http://127.0.0.1:8000/docs。您可以从浏览器本身使用您的 API 并与之交互。


同样,通过相同的 Python 类型声明,FastAPI 为您提供集成 Swagger UI 的自动交互式文档。请注意,路径参数被声明为整数。
3.8、替代 API 文档

由于 FastAPI 构建于 OpenAPI 标准之上,因此它还使用 ReDoc 提供替代 API 文档,您可以通过 http://127.0.0.1:8000/redoc 访问该文档:


还有许多其他兼容工具,包括许多语言的代码生成工具。
3.9、使用 pydantic 进行数据处理

所有数据验证都是由 pydantic 在后台执行的,你可以对 str 、 float 、 bool 和许多其他复杂数据类型使用相同的类型声明。
3.10、顺序很重要:将固定路径放在第一位

创建路径操作时,你可能会发现有固定路径的情况,例如 /users/me 。假设它是为了获取有关当前用户的数据。你可能还拥有路径 /users/{user_id} 来通过某个用户 ID 获取有关特定用户的数据。
由于路径操作是按顺序计算的,因此你需要确保 /users/me 的路径在 /users/{user_id} 的路径之前声明:
# main.py

from fastapi import FastAPI
app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}
   
@app.get("/users/{user_id}")
async def read_user(user_id: str):   
    return {"user_id": user_id}否则, /users/{user_id} 的路径也会匹配 /users/me ,认为它正在接收值为 "me" 的参数 user_id 。
3.11、请求正文:接收 JSON 数据

当客户端需要将数据发送到API时,可以将数据作为请求正文发送。请求正文是客户端发送给API的数据。而响应正文则是API发送给客户端的数据。在大多数情况下,API都需要发送响应正文给客户端,但是客户端并不一定需要始终发送请求正文。
3.12、使用 pydantic 声明 JSON 数据模型

首先,您需要从 pydantic 导入 BaseModel ,然后使用它来创建定义您想要接收的架构或数据形状的子类。
接下来,将数据模型声明为继承自 BaseModel 的类,对所有属性使用标准 Python 类型:
# main.py

from typing import Optional
from fastapi import FastAPI

from pydantic import BaseModel

class Item(BaseModel):   
    name: str   
    description: Optional[str] = None   
    price: float   
    tax: Optional[float] = None
   
app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item当模型属性具有默认值时,则不需要它。否则是需要的。要使属性可选,您可以使用 None 。
例如,上面的模型声明一个 JSON 对象(或 Python dict ),如下所示:
{
    "name": "Jack",
    "description": "可选属性",
    "price": 19.8,
    "tax": 2.2
}在本例中,由于 description 和 tax 是可选的,因为它们具有默认值 None ,因此此 JSON 对象也将有效:
{
    "name": "Jack",
    "price": 19.8
}省略默认值的 JSON 对象也是有效的。接下来,将新的 pydantic 模型作为参数添加到路径操作中。可以按照声明路径参数的方式声明它:
# main.py

from typing import Optional
from fastapi import FastAPI

from pydantic import BaseModel

class Item(BaseModel):   
    name: str   
    description: Optional[str] = None   
    price: float   
    tax: Optional[float] = None
   
app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item参数 item 具有 Item 类型提示,这意味着 item 被声明为类 Item 的实例。
通过该 Python 类型声明,FastAPI 将:

  • 以 JSON 形式读取请求正文
  • 如果需要转换对应的类型
  • 验证数据,如果无效则返回明确的错误
  • 在参数 item 中提供接收到的数据 - 由于您将其声明为 Item 类型,因此您还将获得所有编辑器支持,并对所有属性进行完成和类型检查以及它们的类型
  • 为您的模型生成 JSON 架构定义,您还可以在对您的项目有意义的任何其他地方使用该定义
通过将标准类型提示与 pydantic 结合使用,FastAPI 可以帮助您轻松构建默认具有所有这些最佳实践的 API。
3.13、使用 pydantic 自动记录

pydantic 模型的 JSON 模式将成为为您的应用程序生成的 OpenAPI 的一部分,并将显示在交互式 API 文档中:
您可以看到 API 文档中 Item 的属性与您在 pydantic 模型中声明的属性完全相同。
四、Docker 部署 FastAPI 服务

4.1、安装 Docker Engine

1、更新系统软件包列表:
sudo apt update2、安装Docker依赖的软件包:
sudo apt install apt-transport-https ca-certificates curl software-properties-common3、添加Docker官方的GPG密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg4、添加Docker的软件源:
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null5、更新软件包列表:
sudo apt update6、安装Docker Engine:
sudo apt install docker-ce docker-ce-cli containerd.io7、验证Docker是否正确安装:
sudo docker run hello-world4.2、创建 Docker 文件

在项目的根目录下创建一个 Dockerfile 文件。
├── Dockerfile
├── app
   ├── main.py
   ├── api.pyDocker 层构成了 Docker 镜像和 Docker 容器的文件系统。每一层都对应于 Dockerfile 中的某些指令。我们根据项目依赖和目录定义的Dockerfile文件内容如下:
FROM tiangolo/uvicorn-gunicorn:python3.10

LABEL maintainer="FrenzyTechAI <crossme0809@gmail.com>"

RUN pip install --no-cache-dir --upgrade --timeout 10000 fastapi uvicorn

WORKDIR /app

COPY ./app /app

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]4.3、创建 Docker 镜像

Docker 映像包含应用程序代码、库、工具、依赖项以及应用程序运行所需的其他文件。
docker build -t fastapi-test-app:new --network=host .注意:如果在构建 Docker 容器的时候执行到 pip install 安装依赖的时候出错,出现如下无法连接网络的问题,是因为在Docker容器内部无法连接宿主机网络,需要在docker命令后增加 --network=host 参数使用主机网络运行构建Docker容器。
Collecting pytest
  Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7feb52c30630>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution',)': /simple/pytest/此输出显示创建 docker 映像时使用的过程。


列出我们创建的所有镜像
要列出之前创建的所有 docker 映像,可以使用以下命令。
docker image ls输出结果:
(base) root@hecs-275553:/opt/fastapi# docker image ls                                                                                            
REPOSITORY                   TAG             IMAGE ID       CREATED          SIZE                                                               
fastapi-test-app             new             1ea9708114e7   55 seconds ago   1.05GB
danswer/danswer-web-server   latest          24e5b346cad5   2 weeks ago      231MB
qdrant/qdrant                v1.3.0          2de9d6b3de91   2 months ago     139MB
hello-world                  latest          9c7a54a9a43c   3 months ago     13.3kB
typesense/typesense          0.24.1          de9eadc78acf   4 months ago     799MB
postgres                     15.2-alpine     ddc12ac7fa27   5 months ago     243MB
nginx                        1.23.4-alpine   8e75cbc5b25c   5 months ago     41MB我们最新的镜像是 fastapi-test-app 。这是您刚刚创建的 id 为 1ea9708114e7 的镜像。
4.4、创建docker容器

Docker 容器是 Docker 镜像的实时运行实例,用户可以与它们交互,管理员可以使用 docker 命令调整其设置和条件。
docker run --network=host -p 8000:8000 fastapi-test-app:new 输出结果:
(base) root@hecs-275553:/opt/fastapi# docker run --network=host -p 8000:8000 fastapi-test-app:new
WARNING: Published ports are discarded when using host network mode
INFO:     Will watch for changes in these directories: ['/app']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [1] using WatchFiles
INFO:     Started server process [9]
INFO:     Waiting for application startup.
INFO:     Application startup complete.Docker容器启动完成后,可以在浏览器中输入 http://127.0.0.1:8000 访问该应用程序。
五、使用 PyCharm 开发 FastAPI 服务

FastAPI 是一个用于使用 Python 构建 API 的 Web 框架。需要 Python 3.7 及以上版本。 PyCharm Professional 为开发 FastAPI 应用程序提供以下支持:

  • 具体项目类型
  • 编码协助
  • 运行/调试配置
PyCharm Professional 下载地址:https://www.jetbrains.com/pycharm/download/
5.1、创建FastAPI项目

1、从主菜单中,选择文件|新建项目,或单击欢迎屏幕中的新建项目按钮。新项目对话框打开。


2、在[New Project]对话框中,执行以下操作:

  • 指定项目类型 FastAPI
  • 位置:保留建议的项目位置或指定替代目录
  • 接下来,通过单击相应的单选按钮来选择是要创建新环境还是使用现有解释器。
  • 在[Location]字段中指定新 Virtualenv 环境的位置,或单击   并浏览文件系统中的所需位置。新 Virtualenv 环境的目录应该为空。默认在项目文件的根目录。
  • 从列表中选择 Python 版本。
  • 通常,PyCharm 会检测 Virtualenv 安装。否则,请指定 Virtualenv 可执行文件的位置.
  • 如果您想在 PyCharm 中创建 Python 解释器时重用此环境,请选中 [Make available to all projects] 复选框。
3、单击[Create]后,PyCharm 将创建一个 Python 环境并安装 fastapi 和 uvicorn 包。它还添加了 main.py 和 test_main.http 文件以及一些默认代码结构。


5.2、使用编码辅助来开发应用程序

开发 FastAPI 应用程序时,您可以受益于 IDE 中提供的编码帮助。
1、使用检查来分析代码问题。您可以使用检查小部件来简要预览问题的摘要。单击小部件可获取有关[Problem]工具窗口中每个检测到的问题的更多信息。


2、可以使用上下文感知代码完成来加速编码过程。只需开始输入代码构造,就会出现完成弹出窗口。您还可以按 ⌃Ctrl Space 显示可用项目。


5.3、启动和修改运行/调试配置

1、创建新项目后,PyCharm 会为您提供运行/调试配置,以便您可以执行 FastAPI 应用程序。在可用运行/调试配置列表中选择创建的配置。单击“Run”以启动您的应用程序。


目标应用程序在运行工具窗口中执行。您可以单击链接在浏览器中预览应用程序。


2、您可以修改使用项目创建的默认运行/调试配置。从可用配置列表中选择编辑配置...:


在左侧窗格中选择目标配置并修改其参数,例如,您可以添加更多 uvicorn 选项(在此示例中: --reload delay 10 )。


3、你还可以执行 .http 文件来测试 GET 请求。您可以单独运行每个请求,也可以单击 .http 文件工具栏上的绿色按钮来一次测试所有请求。


选择一个选项以在没有环境的情况下执行请求,或者在公共或私有文件中创建环境。PyCharm 在“Services”工具窗口中执行 GET 测试。您可以选择特定请求来预览其执行状态的摘要。


5.4、管理Endpoints

在 PyCharm 中,可以很方便的预览、修改、创建和测试 FastAPI 应用程序的端点。
选择 View | Tool Windows | Endpoints 打开 Endpoints 工具窗口,Endpoints 工具窗口包含应用程序中定义的端点列表。专用窗格显示所选端点的详细信息,包括文档、生成的 HTTP 请求和生成的 OpenAPI 规范。


双击端点列表中的任意项目可导航到 .py 文件中的相应方法。你还可以右键单击列表中的任何项目以获取上下文菜单,其中包含导航到源代码、查找用法、在 HTTP 客户端中生成请求或导出 OpenAPI 规范草案的选项。
您可以在编辑器的单独选项卡中预览 HTTP 客户端。单击[Open in Editor],PyCharm 将使用 HTTP 请求打开一个临时草稿文件。您可以点击装订线中的绿色按钮来测试它。


六、总结

FastAPI 是一个现代、高性能的 Web 框架,用于基于 Python 3.7+ 构建 API。本文介绍了如何使用 FastAPI 构建 Python Web API,并将其容器化为 Docker 镜像部署运行。FastAPI 的优势包括卓越的速度、优于其他几个 Python 后端框架以及与 Express.js 等流行框架竞争。选择 FastAPI 的原因包括高性能、快速运行以及无需进行大量设置和配置即可快速构建 API。此外,FastAPI 支持直接生成 OpenAPI 规范文档,无需花费精力安装额外的库来生成 Flask 或 Django 的 OpenAPI 文档。
为了部署 FastAPI 服务,可以使用 Docker 进行容器化。Docker 可以简化应用程序的部署和管理过程,提高应用程序在不同环境中的可移植性。在开发过程中,推荐使用 PyCharm 这样的集成开发环境(IDE)来编写和调试 FastAPI 服务。
总之,FastAPI 是一个高性能、易用的 Web 框架,非常适合构建各种类型的应用程序,如机器学习应用程序、移动应用程序等。通过结合 Docker 部署,可以轻松地将 FastAPI 应用程序部署到服务器上,并实现容器化管理。希望本文能为 Python 开发新手提供一些参考,并期待在后续文章中进一步介绍 FastAPI 框架的高级功能。
七、References


如果你对这篇文章感兴趣,而且你想要了解更多关于AI领域的实战技巧,可以关注「技术狂潮AI」公众号。在这里,你可以看到最新最热的AIGC领域的干货文章和案例实战教程。
回复 支持 反对

使用道具 举报

发表于 2025-3-17 21:28 | 显示全部楼层
Django 的工具集更全一些,这也导致很多时候它的性能并不理想。认识我的同行知道我是个很不关注性能的人,但是Django的性能感性的说,已经到了我这种人也觉得不够理想的程度。这是开发的便捷带来的代价,另外就是很多Django用起来非常方便的东西,比如Admin Form,其实是有其应用背景的,在最初Django就是为了支持新闻类网站项目开发出来的,很多组件放在这种应用场景下就非常合理了。但是如果脱离了这个背景,Django没有必然的优势。比如你要搭建复杂业务的后台时,如果 Admin Form不够用,你需要扩展一个已经开始使用 Admin Form的项目,就会非常的麻烦。
Django 向产业界证明了,Python可以在互联网开发中提供类似 ROR 的生产效率,此后有一系列类似的 Python Web Framework产生,很多流行甚至不那么流行的,我都用过,老实说大部分框架在性能和复杂应用的搭建上,跟 Django比没有本质性的优越,相反在 Django 最擅长的领域,它仍然是最好的。
Flask 可以看作松散组件方向的演化结果,它的设计思路是从一开始就让所有的组件尽可能正交分解,Flask 本身尽可能保持中立,这个方向的远古产品是……嗯太多年不用了,我都想不起那个东西叫什么了,Pyramid ?这个方向的设计思路类似 Spring,Flask 是这个体系中比较现代的产品,风格足够 Pythonic,也足够轻量,CSDN 的 AI 组也用这个框架,好处是它本身对业务代码的侵入比较弱,当然对性能也不必期待过高。
FastAPI可以看作协程体系的现代产品,跟 Tornado 相比充分利用了高版本 Python 的异步语法,对 Python 3.6 之后的异步技术有更好的集成,也对很多现代互联网的运维和架构技术有更好的支持,比如对 swigger/openapi 的支持,对grafana之类的日志和tracing工具的支持,这对于现代互联网行业的软件工程,有非常高的价值。但是说到性能,其实不要被它们的测试数据蒙蔽,理论上说 Tornado 和 FastAPI 是qps在 10k以上的产品,属于比较高性能的应用框架。但是实践上要发挥协程框架的性能,要求开发者能够驾驭协程技术,也要求业务本身足够适配,也就是说,其实很难写出这么快的应用。我以前工作过的团队,有大量使用 tornado的,也有大量使用 FastAPI的,那些应用的性能都很不好。一个好的应用框架,它的性能不应该过度的依赖开发者的水平,比如我用过 Java 的协程框架 quarkus,就很容易写出性能比较好的应用,虽然受限于 Java 笨拙的语法,处理多个monad 的合并和链式操作的时候相当的啰嗦,但是总体来说业务的表达仍然是很浅白的,这一点 Python 的协程框架一般是做不到,要么是一个性能热点卡死整个进程,要么是要精心安排逻辑流程使其尽量的异步并发。
如果以找工作的角度,我的建议是不要把自己异化为某一个framework的工具人,先熟悉Flask和FastAPI,现在的Python团队用这两个多一些,但是其它的框架也应该做到可以拿来就用,特别是Django这种工具箱内容丰富的老牌技术,学会了自己接活都是个不错的选择。最好Java/Go/Javascript的竞争技术和相关也都学一学。当然这会辛苦一些,但是无论对将来的长期发展还是找个工作这样的短期目标,都是有好处的。现实世界的应用很少有单纯的CURD,要更好的实现复杂业务,需要开发者有比较灵活的思路,适当扩展知识面的宽度,对此是有帮助的。
回复 支持 反对

使用道具 举报

发表于 2025-3-17 21:29 | 显示全部楼层
说的好不如做的好,下面我就提供两个分别使用 Django 和 Flask 编写的项目,大家自己体会吧
基于 Django 3 的网盘系统

该项目为基于Python的 Django 框架搭建的在线网盘系统
我们先来看一下整体项目结构


项目运行

1、安装依赖
pip install -r requirements.txt
我们再来看下,依赖的组件都有哪些
asgiref==3.4.1
Django==3.2.8
django-cors-headers==3.10.0
django-debug-toolbar==3.2.4
django-debug-toolbar-request-history==0.1.4
django-extensions==3.1.5
django-simpleui==2021.11.5
djangorestframework==3.12.4
httpagentparser==1.9.1
mysqlclient==2.0.3
Pillow==8.4.0
pytz==2021.3
sqlparse==0.4.2
typing-extensions==3.10.0.2可以看到依赖的库不多,主要都是 Django 相关的库
2、检查配置文件,修改数据库配置
# mycloud/settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'cloud',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'your password',
    }
}
这里编写我们的数据库信息
3、迁移数据库
python manage.py migrate
通过上述命令,可以进行数据库的迁移工作
4、执行基础sql文件
下面我们进入 MySQL 数据库中,执行数据库脚本
mysql> use cloud;
mysql> source C:/Users/..../.sql;
5、创建超级用户
python manage.py createsuperuser
该命令也是 Django 的命令
6、启动本地服务器
python manage.py runserver
最后就是启动本地服务了,当然也可以部署到云服务器上,关于云服务器的相关部署,我们在后面的文章中着重介绍
项目展示





基于Python的Flask框架搭建的在线电影网站

项目介绍:网站前端采用HTML5编写,使用Bootstrap前端开发框架,后端使用Python3语言编写,以及Flask的Web框架,将MySQL作为数据库,开发工具使用PyCharm
网站功能:网站前台模块具有浏览视频、搜索视频、筛选视频、登录注册、收藏评论等功能。后台模块具有对视频、用户、管理员等各类管理功能
项目文件:整个movie_project目录
运行方法:运行movie_project目录下的manage.py
nginx配置文件:位于movie_project目录下的nginx.conf,用于部署到服务器进行反向代理的相关配置
运行环境

Version: Python3
安装依赖库

pip3 install -r requirements.txt
项目截图

首页展示图



视频展示页



视频播放页



后台管理页



整体架构设计图



项目目录结构图



前台功能模块图



后台功能模块图



本地运行图



整体项目而言,对于入门的朋友,还是蛮友好的,做的好的,部署一个线上小网站也是不错的哦~
其他项目截图



好嘞,这就是今天分享的全部内容,访问下面链接获取全部源码哦
❝ 链接: https://pan.baidu.com/s/1h2v8TEyCtvkP628Ja6rCZA 提取码: pnb6
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表