百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

(入门篇)简析一个比Flask和Tornado更高性能的API 框架FastAPI

ccwgpt 2024-10-14 08:42 25 浏览 0 评论

用官方的话来说,FastAPI 是一种现代,快速(高性能)的 Web 框架,基于标准Python 类型提示使用 Python 3.6+ 构建 API



FastAPI 站在巨人的肩膀上?

很大程度上来说,这个巨人就是指 Flask 框架。


FastAPI 从语法上和 Flask 非常的相似,有异曲同工之妙。

技术背景:Py3.6+,Starlette,Pydantic

其实不仅仅是 FastAPI ,就连 Sanic 也是基于 Flask 快速开发的 Web API 框架。


废话少说,代码总是能给人带来愉悦感 (抱头),直接开怼。


安装


pip install fastapi 
pip install uvicorn


创建一个 main.py 文件


from fastapi import FastAPI

app = FastAPI() # 创建 api 对象

@app.get("/") # 根路由
def root():
    return {"武汉": "加油!!!"}

@app.get("/say/{data}")
def say(data: str,q: int):
    return {"data": data, "item": q}


上面搭建了一个最简单的 FastAPI 应用,看起来和 Flask 完全一样,莫名的喜感。


使用以下命令来启动服务器:


uvicorn main:app --reload


FastAPI 推荐使用 uvicorn 来运行服务,Uvicorn 是基于uvloop 和 httptools 构建的闪电般快速的 ASGI 服务器。


uvicorn main:app 指的是:

main:文件main.py

app: 创建的启用对象

--reload: 热启动,方便代码的开发


启动界面如下:


INFO 信息告诉我们已经监听了本地的 8000 端口,访问 http://127.0.0.1:8000 得到结果


传入参数



再来看看 FastAPI 的异步代码


from fastapi import FastAPI

app = FastAPI() # 创建 api 对象

@app.get("/") # 根路由
async def root():
    return {"武汉": "加油!!!"}

@app.get("/say/{data}")
async def say(data: str,q: int = None):
    return {"data": data, "q": q}


开启服务后访问结果是一样的。


在上面的路由方法中,我们传入了一个 q 参数并且初始为 None,如果不给默认值,并且不传参,代码将直接报错。

来看看 FastAPI 是如何处理错误的:

可以看到,即使是报错,也是优美的输入一个带有错误字段的 JSON,这就非常的友好了,这也是体现了 FastAPI 减少更多的人为错误的特性,返回也更加的简洁直观。


在命令行输出:


再来看看 FastAPI 的交互文档

根据官方文档,打开 http://127.0.0.1:8000/docs


看到:


支持动态传入数据:

结果:


从交互体验上也是无比的友好,让代码在生产中更加健壮。


现在我们算是快速的体验了一波 FastAPI 骚操作,从代码上和 Flask 及其的类似,体验性更好。


那么再来看看最新的 Python web框架的性能响应排行版


从并发性上来说是完全碾压了 Flask (实际上也领先了同为异步框架的tornado 不少),看来 FastAPI 也真不是盖的,名副其实的高性能 API 框架呀!


查询参数


先来看看官方小 demo

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]


该查询是 ? URL中位于关键字之后的一组键值对,以&字符分隔。


在 url 中进行查询

http://127.0.0.1:8000/items/?skip=0&limit=10


skip:查询的起始参数

limit:查询的结束参数


成功返回查询列表。


查询参数类型转换

FastAPI 非常聪明,足以辨别 路径参数 和 查询参数。


来看看具体的例子:

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item


看看其访问路径,执行以下的任何一种 url 访问方式


http://127.0.0.1:8000/items/武汉加油?short=1


http://127.0.0.1:8000/items/武汉加油?short=True


http://127.0.0.1:8000/items/武汉加油?short=true


http://127.0.0.1:8000/items/武汉加油?short=on


http://127.0.0.1:8000/items/武汉加油?short=yes


可以发现任何大小写的字母等都会被转换成 bool 值的参数 True,这就是所谓模糊验证参数,对于开发者来说这是个好消息。


要知道的是,如果 short 参数没有默认值,则必须传参,否则 FastAPI 将会返回类似以下的错误信息。


{
    "detail": [
        {
            "loc": [
                "query",
                "needy"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}


创建数据模型

前面说到 FastAPI 依赖 Pydantic 模块,所以首先,你需要导入 Pydantic 的 BaseModel 类。


from fastapi import FastAPI
from pydantic import BaseModel

# 请求主体类
class Item(BaseModel):
    name: str = "武汉加油 !!"
    description: str = None
    price: float = 233
    tax: float = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item


发送 post 请求来提交一个 Item(请求主体) 并返回,来看看提交过程。



成功提交并返回 200 状态码

请求主体+路径+查询参数,在请求主体的基础上加入 url 动态路径参数 和 查询参数

from fastapi import FastAPI
from pydantic import BaseModel


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


app = FastAPI()


@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: str = None):
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result


put 方法用于更新,传入参数后成功返回一个字典。


关于模板引擎


FastAPI 不像 Flask 那样自带 模板引擎(Jinja2),也就是说没有默认的模板引擎,从另一个角度上说,FastAPI 在模板引擎的选择上变得更加灵活,极度舒适。


以 Jinja2 模板为例


安装依赖

pip install jinja2
pip install aiofiles # 用于 fastapi 的异步静态文件


具体的用法

# -*- coding:utf-8 -*-
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import uvicorn

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static") # 挂载静态文件,指定目录


templates = Jinja2Templates(directory="templates") # 模板目录


@app.get("/data/{data}")
async def read_data(request: Request, data: str):
    return templates.TemplateResponse("index.html", {"request": request, "data": data})

if __name__ == '__main__':
    uvicorn.run(app, host="127.0.0.1", port=8000)


html 文件渲染

<html>
<head>
    <title>武汉加油</title>
</head>
<body>
    <h1>高呼: {{ data }}</h1>
</body>
</html>


在浏览器键入 http://127.0.0.1:8000/data/武汉加油


值得注意的是,在返回的 TemplateRespone 响应时,必须带上 request 的上下文对象,传入参数放在同一字典。


这样一来,又可以像 Flask 一样的使用熟悉的 Jinja2 了,哈哈。


做个小总结的话就是 FastAPI 在用法上也是及其简单,速度更快,性能更好,容错率更高,整体上更牛逼。但是我在设想如此之快的框架,毕竟发布的时间不长,缺少像 Flask 框架的第三方库和各种插件,所以要想真正意义上替代还是需要一定的时间,要冷静,冷静。


好啊,至此 FastAPI 的一些基本用法就差不多结束啦,FastAPI 的官方文档有详细的介绍和实例,入门篇到此结束。


官方文档:https://fastapi.tiangolo.com/

相关推荐

RACI矩阵:项目管理中的角色与责任分配利器

作者:赵小燕RACI矩阵RACI矩阵是项目管理中的一种重要工具,旨在明确团队在各个任务中的角色和职责。通过将每个角色划分为负责人、最终责任人、咨询人和知情人四种类型,RACI矩阵确保每个人都清楚自己...

在弱矩阵组织中,如何做好项目管理工作?「慕哲制图」

慕哲出品必属精品系列在弱矩阵组织中,如何做好项目管理工作?【慕哲制图】-------------------------------慕哲制图系列0:一图掌握项目、项目集、项目组合、P2、商业分析和NP...

Scrum模式:每日站会(Daily Scrum)

定义每日站会(DailyScrum)是一个Scrum团队在进行Sprint期间的日常会议。这个会议的主要目的是为了应对Sprint计划中的不断变化,确保团队能够有效应对挑战并达成Sprint目标。为...

大家都在谈论的敏捷开发&amp;Scrum,到底是什么?

敏捷开发作为一种开发模式,近年来深受研发团队欢迎,与瀑布式开发相比,敏捷开发更轻量,灵活性更高,在当下多变环境下,越来越多团队选择敏捷开发。什么是敏捷?敏捷是一种在不确定和变化的环境中,通过创造和响应...

敏捷与Scrum是什么?(scrum敏捷开发是什么)

敏捷是一种思维模式和哲学,它描述了敏捷宣言中的一系列原则。另一方面,Scrum是一个框架,规定了实现这种思维方式的角色,事件,工件和规则/指南。换句话说,敏捷是思维方式,Scrum是规定实施敏捷哲学的...

敏捷项目管理与敏捷:Scrum流程图一览

敏捷开发中的Scrum流程通常可以用一个简单的流程图来表示,以便更清晰地展示Scrum框架的各个阶段和活动。以下是一个常见的Scrum流程图示例:这个流程图涵盖了Scrum框架的主要阶段和活动,其中包...

一张图掌握项目生命周期模型及Scrum框架

Mockito 的最佳实践(mock方法)

记得以前面试的时候,面试官问我,平常开发过程中自己会不会测试?我回答当然会呀,自己写的代码怎么不测呢。现在想想我好像误会他的意思了,他应该是想问我关于单元测试,集成测试以及背后相关的知识,然而当时说到...

EffectiveJava-5-枚举和注解(java枚举的作用与好处)

用enum代替int常量1.int枚举:引入枚举前,一般是声明一组具名的int常量,每个常量代表一个类型成员,这种方法叫做int枚举模式。int枚举模式是类型不安全的,例如下面两组常量:性别和动物种...

Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!

Maven简介Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”。Maven是一个跨平台的项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。仔...

Java单元测试框架PowerMock学习(java单元测试是什么意思)

前言高德的技术大佬在谈论方法论时说到:“复杂的问题要简单化,简单的问题要深入化。”这句话让我感触颇深,这何尝不是一套编写代码的方法——把一个复杂逻辑拆分为许多简单逻辑,然后把每一个简单逻辑进行深入实现...

Spring框架基础知识-第六节内容(Spring高级话题)

Spring高级话题SpringAware基本概念Spring的依赖注入的最大亮点是你所有的Bean对Spring容器的存在是没有意识的。但是在实际的项目中,你的Bean必须要意识到Spring容器...

Java单元测试浅析(JUnit+Mockito)

作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作...

揭秘Java代码背后的质检双侠:JUnit与Mockito!

你有没有发现,现在我们用的手机App、逛的网站,甚至各种智能设备,功能越来越复杂,但用起来却越来越顺畅,很少遇到那种崩溃、卡顿的闹心事儿?这背后可不是程序员一拍脑袋写完代码就完事儿了!他们需要一套严谨...

单元测试框架哪家强?Junit来帮忙!

大家好,在前面的文章中,给大家介绍了以注解和XML的方式分别实现IOC和依赖注入。并且我们定义了一个测试类,通过测试类来获取到了容器中的Bean,具体的测试类定义如下:@Testpublicvoid...

取消回复欢迎 发表评论: