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

点击上方“Python爬虫与数据挖掘”,进行关注html

回复“书籍”便可获赠Python从入门到进阶共10本电子书web

api

浏览器

服务器

并发

迫不得已花落去,似曾相识燕归来。app

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

FastAPI 站在巨人的肩膀上异步

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

FastAPI 从语法上和 Flask 很是的类似,有殊途同归之妙。

技术背景:Py3.6+,StarlettePydantic

其实不只仅是 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/

------------------- End -------------------

往期精彩文章推荐:

欢迎你们点赞,留言,转发,转载,感谢你们的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山老是情,点个【在看】行不行

/今日留言主题/

说一两个你知道的Python框架吧~