zoukankan      html  css  js  c++  java
  • (入门篇)Python web框架FastAPI——一个比Flask和Tornada更高性能的API 框架

    用官方的话来说,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/

  • 相关阅读:
    准备Activiti环境(2)
    准备Activiti环境
    Activiti工作流的简单介绍
    html(5) css
    html(4)表单
    html(3)框架标签,内联框架
    字符输出流写文本文件【Writer、FileWriter 、BufferedReader 】
    二进制文件的读写
    字符输入流读取文本文件【Reader、FileReader、BufferedReader 】
    字节输入流写文本文件【OutputStream、FileOutputStream】
  • 原文地址:https://www.cnblogs.com/dcpeng/p/12716550.html
Copyright © 2011-2022 走看看