FastAPI: 极速开发Python Web应用的未来之星

Posted 码农老关【关东升】

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastAPI: 极速开发Python Web应用的未来之星相关的知识,希望对你有一定的参考价值。

我在工作中经常使用Flask来开发Web应用。但是随着项目规模的增长,我发现自己需要写越来越多的重复代码,同时Flask并没有提供一个良好的数据验证和文档生成工具。

有一天,我听说了一个名为FastAPI的框架,它被誉为是Python Web框架的“未来之星”,而且还支持异步请求处理,可以极大提高Web应用的性能。于是我决定尝试一下。

在使用FastAPI之后,我深深感受到了它的优势。使用Python的类型提示,可以让代码更加直观易懂,数据验证也变得非常简单。同时,FastAPI提供了自动生成API文档的功能,这对于团队协作和后续的维护非常有帮助。

在实际开发中,FastAPI也证明了它的高性能和易用性,我用它开发了多个Web应用,都得到了很好的反馈和效果。现在,每当有同事问我要推荐一个Python Web框架时,我总是毫不犹豫地推荐FastAPI。

FastAPI是一个现代的、高性能的Python Web框架,它基于Python的类型提示,使用Python3.6及以上版本构建API。它的优点包括:

高性能:FastAPI支持异步请求处理,可以处理高并发场景,而且运行速度非常快,可以和NodeJS和Go相提并论。
快速开发:FastAPI提供了很多现成的功能和工具,可以大大简化代码开发,让开发速度提高约200%至300%。
更少的Bug:FastAPI使用Python的类型提示和数据验证,可以减少40%开发人员容易引发的错误。
直观:FastAPI完美支持编辑器,可以在开发过程中提供自动补全和语法提示等功能,让代码开发更加直观易懂。
简单易用:FastAPI的API设计非常简单明了,使用起来非常方便,并且有很多详细的文档和教程,可以帮助开发者快速上手。
标准化:FastAPI基于并完全兼容API的开发标准:OpenAPI(以前称为Swagger)和JSON Schema,可以更好地进行团队协作和API文档生成。
FastAPI特点:

· 高性能 -FastAPI非常快。它被认为是目前最快的框架之一。它与NodeJS和Go以及Starlette和Pedantic相当。

· 快速编码 -它允许显着提高开发速度。

· 强大的-它有一个写得很好的文档,我们可以通过阅读其文档使用自己的 API 创建生产就绪的 API。

· 直觉的-它的设计是每个人都可以轻松理解,易于使用并提供出色的编辑器支持。

· 更少的错误 -它减少了大约 40% 的诱发错误。

· 插件 -它提供了使用依赖注入创建插件的工具。

· 类型提示 -我们可以使用类型提示进行数据验证和转换。

· 基于标准 -它基于API,OpenAI和JSON模式的开放标准。

· 简单-它很简单,因此我们可以花更少的时间阅读文档。

在 FastAPI 中,开发者可以使用基于 REST 架构风格的 API 来定义和实现 Web API。

FastAPI 结构

环境搭建

1、安装 FastAP

pip install fastapi

要求

Python 3.7+

2、安装 Uvicorn

Uvicorn 是一个基于 Python 并使用 ASGI(Asynchronous Server Gateway Interface)协议的高性能Web服务器。ASGI是一个 Python 的异步Web服务器网关协议,它提供了比旧的WSGI协议更高级的异步能力,可以支持异步的HTTP请求和响应。Uvicorn 的主要优点是它可以处理高并发的HTTP连接请求,使用异步I/O的方式实现高效的网络连接处理,同时保持高度的可靠性和稳定性。Uvicorn 可以作为一个独立的Web服务器使用,也可以与其他 ASGI 框架(如FastAPI、Starlette等)一起使用,构建高效、可扩展的Web应用程序。

pip install uvicorn[standard]

在 pip install 命令中,方括号用来表示可选项。在这种情况下,[standard] 表示可选的附加包,可以通过在命令中添加它来安装该包。在这个例子中,[standard] 是用来安装 FastAPI 应用程序所需的附加软件包,包括 Uvicorn 服务器和其它的一些工具和库。这些包通常被称为 FastAPI 的标准依赖项。因此,通过在命令中包含 [standard],可以确保安装 FastAPI 所需的所有依赖项。如果不包括 [standard],则只会安装 FastAPI 包本身,而不会安装其他必要的包。

3、开发工具Pycharm、Sublime、Visual Studio Code等

本课程推荐Visual Studio Code

3.1、安装Visual Studio Code

3.2、安装Python插件

3.3、运行和调试Python程序

  1.   4.第一个Fast API程序
    

1.1、Hello示例代码:

main.py from fastapi import FastAPI

app = FastAPI()

装饰器@app.get(“/”)async def home(): # 路由处理函数

return "message": "Hello World" 

1.2、启动应用

在控制台运行如下指令:

uvicorn main:app --reload

· uvicorn:它是一个服务器库。

· main:要启动的脚本文件名。

· app:它是指在main.py文件中创建的FastAPI的对象。

· --reload:代码更改后使服务器重新启动(热部署)。

在浏览器中打开网址http://127.0.0.1:8000/测试

在IDE工具中启动和运行,添加如下代码

if name == “main”:
uvicorn.run(app, host=“0.0.0.0”, port=8000)带有热部署参数代码。

uvicorn.run(“main:app”, host=“0.0.0.0”, port=8000, reload=True)

· app:FastAPI的对象。

· host:服务器主机名,默认是127.0.0.1 (localhost),如果设置0.0.0.0可以在本机之外访问。

· port:主机端口,默认是8000。

· reload:是否支持热部署。

· 1.3 交互式 API 文档与Swagger :

Swagger GUI(Graphical User Interface)是一个 Web 界面,用于显示和操作使用 Swagger 规范编写的 RESTful API(Representational State Transfer Application Programming Interface)。Swagger 是一种 API 规范和工具集,它提供了一种描述 API 的标准格式,以及自动生成 API 文档和客户端代码的工具。

Swagger GUI 可以通过 Web 界面直观地显示和测试 API,提供了方便的 API 调试和交互方式。在 Swagger GUI 中,可以浏览 API 的不同端点和操作,并且可以向这些端点发送请求并查看响应。Swagger GUI 还提供了交互式的文档,以及针对每个端点和操作的请求示例和响应示例。通过 Swagger GUI,开发人员可以更容易地理解和使用 API,同时也可以更快地进行 API 开发和测试。

3、自动生成 API 文档的功能

可以在浏览器中查看 API 文档。这个页面是使用 Swagger UI 生成的,可以交互地浏览 API 的接口、输入参数、响应结果等信息。除了 Swagger UI,FastAPI 还支持 ReDoc 和自定义的文档生成方式。

1、 http://127.0.0.1:8000/docs

2、 http://127.0.0.1:8000/redoc

OK,更多文章敬请其期待。

CSDN学院相关课程:
《Python Web之FastAPI框架实战训练营:老程序员手把d带您学习FastAPI》

三分钟了解 Python3 的异步 Web 框架 FastAPI

技术图片

快速编码,功能完善。从启动到部署,实例详解异步 py3 框架选择 FastAPI 的原因。

FastAPI 介绍

FastAPI 与其它 Python-Web 框架的区别

在 FastAPI 之前,Python 的 Web 框架使用的是 django、flask、tornado 三种 Web 框架。

  • django 自带 admin,可快速构建,但是比较笨重。如果是 mvc 形式的开发,很多已经封装好了,的确蛮合适。但如果是 restful 风格设计,则 django 就显得有一些笨重了。

  • flask 快速构建,自由度高。因为它十分轻盈,插件即插即用,很适合用来做 restful 风格的设计

  • tornado Python Web 框架和异步网络库,它执行非阻塞 I/O , 没有对 REST API 的内置支持,但是用户可以手动实现。

  • FastAPI 快速构建,异步 IO,自带 Swagger 作为 API 文档,不用后续去内嵌 Swagger-Ui

我个人认为 FastAPI 是一个专门为 restful 风格设计,全面服务于 API 形式的 Web 后端框架。

FastAPI 官方定位

在 FastAPI 官方文档中,可以看到官方对 FastAPI 的定位:

  • 快速:非常高的性能,向 NodeJS 和 go 看齐(感谢 Starlette 和 Pydantic)

  • 快速编码:将功能开发速度提高约 200% 至 300%。

  • 错误更少:减少约 40% 的人为错误(开发人员)。* (FastAPI 内置很多 Python 高版本的语法,比如类型注释,typing 库等等,因此被要求的 Python 版本为 3.6+)

  • 简易:旨在易于使用和学习。减少阅读文档的时间。

  • 功能完善: 自带 Swagger 作为 API 文档

Framework Benchmarks

https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=fortune

技术图片

技术图片

上图可以看出,在高并发下 4 个框架的排名情况。单纯从性能出发,Web 框架是排在第一的。在选用框架的时候,性能是一方面,我们还要看业务上的需求和使用场景,最适合的才是最好的。

下面简单介绍一下 FastAPI 的一些用法和特性.

启动FastAPI

1 # pip install fastapi
2 # pip install uvicorn
3 from fastapi import FastAPI
4 app = FastAPI()
5 @app.get("/")
6 def read_root():
7 return {"Hello": "World"}
8 @app.get("/items/{item_id}")
0 def read_item(item_id: int, q: str = None):
10 return {"item_id": item_id, "q": q}
11 # uvicorn main:app # 启动
12 # uvicorn main:app --reload # 支持热更新
13 # uvicorn main:app --host 0.0.0.0 --port 8889 --reload # 自定义IP+端口
14

FastAPI 支持异步请求

1 from fastapi import FastAPI
2 app = FastAPI()
3 @app.get("/")
4 async def read_root():
5 return {"Hello": "World"}
6
7 @app.get("/items/{item_id}")
8 async def read_item(item_id: int, q: str = None):
9 return {"item_id": item_id, "q": q}
10

技术图片

技术图片

对 API 接口的支持性优异

设置根目录

1 # main.py
2 from fastapi import FastAPI
3 import users
4 app = FastAPI()
5 app.include_router(
6 users.router,
7 prefix="/fastapi/play/v1/users", # 路由前缀
8 tags=[‘users‘] # 路由接口类别
9 )
10 # routers/users.py
11 from fastapi import FastAPI,APIRouter
12 from datetime import datetime,timedelta
13 router = APIRouter()
14 @router.get("/get/users/")
15 async def get_users():
16 return {
17 "desc":"Return to user list"
18 }
19

技术图片

对路径参数进行限制

1 # 根据名字获取列表
2 @router.get("/get/user/{username}")
3 async def get_user_by_username(username :str):
4 """
5 - username: 用户名
6 """
7 return {
8 "desc":"this username is "+ username
9 }
10

技术图片

对查询参数做限制

1 @router.get("/friends/")
2
3 # 设置为None的时候,默认不可以不填
4 async def get_friends_by_id(id :int=None):
5 for item in test_json[‘friends‘]:
6 if item[‘id‘] == id:
7 return item
8 else:
9 return {
10 "desc": "no this id"
11 }
12 # 多参数请求查询
13 from typing import List
14 @router.get("/items/")
15 async def read_items(q: List[str] = Query(["foo", "bar"])):
16 query_items = {"q": q}
17 return query_items
18

设置请求体

1 # 设置请求实体
2 from pydantic import BaseModel,Field
3 class requestModel(BaseModel):
4 name :str
5 age : int = Field(..., gt=0, description="The age must be greater than zero")
6 desc: str
7
8
9 @router.post("/post/UserInfo/")
10 async def post_UserInfo(item: requestModel):
11 return item
12

技术图片

请求体嵌套

1 from pydantic import BaseModel,Field
2 class levelInfoModel(BaseModel):
3 id:int = None
4 info: str = None
5
6 class ClassInfo(BaseModel):
7 id: int = None
8 name: str = Field(..., max_length=20, min_length=10,
9 description="The necessary fields")
10 desc: str = Field(None, max_length=30, min_length=10)
11 levelInfo: List[levelInfoModel]
12
13 class Config:
14 schema_extra = {
15 "example": {
16 "id": 1,
17 "name": "Foo",
18 "desc": "A very nice Item",
19 "levelInfo": [{
20 "id": 1,
21 "info": "一级"
22 }]
23 }
24 }
25
26 @router.post("/info/")
27 async def get_classInfo(item:ClassInfo):
28 return item
29

技术图片

自定义响应码

1 @router.post("/items/", status_code=201)
2 async def create_item(name: str):
3 return {"name": name}
4
5 from fastapi import FastAPI, status
6
7
8 @app.post("/items/", status_code=status.HTTP_201_CREATED)
9 async def create_item(name: str):
10 return {"name": name}
11

依赖注入

1 from fastapi import Depends, FastAPI
2
3 async def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
4 return {"q": q, "skip": skip, "limit": limit}
5
6 @router.get("/items/")
7 async def read_items(commons: dict = Depends(common_parameters)):
8 return commons
9
10 @router.get("/users/")
11 async def read_users(commons: dict = Depends(common_parameters)):
12 return commons
13

FastAPI 框架支持多层嵌套依赖注入

登录demo

1 # 安装环境
2 mkdir fastapi-demo && cd fastapi-demo
3 virtualenv env
4 source env/bin/activate
5
6 # 下载项目
7 git clone https://github.com/hzjsea/BaseFastapi
8 cd BaseFastapi/
9 pip install -r requirements.txt
10 # 开启项目
11 uvicorn main:app --reload
12 # uvicorn main:app --host 0.0.0.0 --port 80 --reload
13

总结

FastAPI 的设计还是很符合 restful 的,在用到很多新技术的同时,也没有抛弃之前一些比较好用的内容,包括类型注释、依赖注入,Websocket,swaggerui 等等,以及其它的一些注释,比如 GraphQL。

数据库以及 orm 的选择

  • sqlalchemy 但是不支持异步,不过貌似可以扩展成异步。

  • tortoise-orm 类 django-orm 的异步 orm,不过正在起步过程中,有些功能还没有完成。

sqlalchemy实例

1 from typing import List
2 import databases
3 import sqlalchemy
4 from fastapi import FastAPI
5 from pydantic import BaseModel
6 # SQLAlchemy specific code, as with any other app
7 DATABASE_URL = "sqlite:///./test.db"
8 # DATABASE_URL = "postgresql://user:password@postgresserver/db"
9 database = databases.Database(DATABASE_URL)
10 metadata = sqlalchemy.MetaData()
11 notes = sqlalchemy.Table(
12 "notes",
13 metadata,
14 sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True),
15 sqlalchemy.Column("text", sqlalchemy.String),
16 sqlalchemy.Column("completed", sqlalchemy.Boolean),
17 )
18 engine = sqlalchemy.create_engine(
19 DATABASE_URL, connect_args={"check_same_thread": False}
20 )
21 metadata.create_all(engine)
22
23
24 class NoteIn(BaseModel):
25 text: str
26 completed: bool
27
28
29 class Note(BaseModel):
30 id: int
31 text: str
32 completed: bool
33
34
35 app = FastAPI()
36
37
38 @app.on_event("startup")
39 async def startup():
40 await database.connect()
41
42
43 @app.on_event("shutdown")
44 async def shutdown():
45 await database.disconnect()
46
47
48 @app.get("/notes/", response_model=List[Note])
49 async def read_notes():
50 query = notes.select()
51 return await database.fetch_all(query)
52
53
54 @app.post("/notes/", response_model=Note)
55 async def create_note(note: NoteIn):
56 query = notes.insert().values(text=note.text, completed=note.completed)
57 last_record_id = await database.execute(query)
58 return {**note.dict(), "id": last_record_id}
59

tortoise-orm实例

1 # main.py
2 from tortoise.contrib.fastapi import HTTPNotFoundError, register_tortois
3 # 创建的数据表
4 models = [
5 "app.Users.models",
6 "app.Face.models",
7 "app.Roster.models",
8 "app.Statistical.models",
9 "app.pay.models"
10 ]
11
12 register_tortoise(
13 app,
14 db_url="mysql://username:password@ip:port/yydb",
15 modules={"models": models},
16 generate_schemas=True,
17 add_exception_handlers=True,
18 )
19
20 # models.py
21 from tortoise import fields,models
22 from tortoise.contrib.pydantic import pydantic_queryset_creator
23 from pydantic import BaseModel
24 class RosterGroupTable(models.Model):
25 id = fields.IntField(pk=True)
26 phone = fields.CharField(max_length=20,blank=True,null=True)
27 name = fields.CharField(max_length=20)
28
29 class Meta:
30 db = "RosterGroupTable"
31
32 class RosterTabel(models.Model):
33 id = fields.IntField(pk=True)
34 phone = fields.CharField(max_length=20,blank=True,null=True)
35 name = fields.CharField(max_length=20)
36 group_id = fields.ForeignKeyField(model_name=‘models.RosterGroupTable‘,on_delete=fields.CASCADE,related_name="events",blank=True,null=True)
37
38 class Meta:
39 db = "RosterTabel"
40
41 RosterGroupTable_desc = pydantic_queryset_creator(RosterGroupTable)
42 RosterTabel_desc = pydantic_queryset_creator(RosterTabel)
43
44
45
46 # roster.py
47 @router.post("/roster_statistics/add")
48 async def roster_add_statics(*,item:RosterItem,token :str):
49 res = await RosterTabel.filter(id=item[‘memberId‘]).first()
50 if res:
51 await StatisticalRosterTable.create(
52 phone = current_user.Phone,
53 date = item[‘date‘],
54 time = item[‘time‘],
55 data = item[‘data‘],
56 name_id_id = item[‘memberId‘],
57 temp_type = item[‘tm_type‘],
58 today_num = item[‘todayNum‘],
59 group_id_id = res.group_id_id,
60 name = res.name
61 )
62 else:
63 return rp_faildMessage(msg="名单不存在",code=-1)
64 return rp_successMessage(msg="名单创建成功",code=0)
65

部署

dockerfile

1 #================================================================================
2 # 基于Python3.7的创建fastapi的dockerfile文件
3 # fastapi + Python3.7 + guvicorn
4 #================================================================================
5
6 FROM Python:3.7
7 LABEL version="v1"
8 description="fastapi"
9 maintainer="hzjsea"
10 using="fastapi & Python3.7 office image & gunicorn"
11 WORKDIR /root/code
12 COPY . .
13 RUN pip install -r requirements.txt
14 EXPOSE 8889
15 CMD ["gunicorn","-c","guvicorn.conf","main:app"]
16

supervisor项目托管

1 [program:webserver]
2 directory=/root/hzj/fastapi_play
3 command=/root/hzj/pro_env_all/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8888
4 autostart = true
5

部署完整示例

FastAPI官方提供了一个前后端分离项目完整示例
https://github.com/tiangolo/full-stack-fastapi-postgresql

文档及项目地址:

Documentation: https://fastapi.tiangolo.com

技术图片

推荐阅读

从 301 跳转,聊聊边缘规则的那些小妙用

从新冠疫情出发,漫谈 Gossip 协议


























































































































































































































































































以上是关于FastAPI: 极速开发Python Web应用的未来之星的主要内容,如果未能解决你的问题,请参考以下文章

API接口开发其实特简单,Python FastApi Web 框架教程来了

API接口开发其实特简单,Python FastApi Web 框架教程来了

三分钟了解 Python3 的异步 Web 框架 FastAPI

GitHub:FastAPI是一种现代,快速(高性能)的Web框架

FastAPI - 一款新型的 Python Web 框架(对比 Flask)

fastapi异步web框架入门