当前位置:   article > 正文

『Python学习笔记』Python中的异步Web框架之fastAPI介绍&RestAPI_fastapi post

fastapi post
Python中的异步Web框架之fastAPI介绍&RestAPI

一. fastAPI简要介绍

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示使用 Python 3.6+ 构建 API。主要特点是:

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

1.1. 安装

  • Pip安装如下:
pip install fastapi
# 您还需要一个 ASGI 服务器,用于生产,例如Uvicorn或Hypercorn。
pip install "uvicorn[standard]"
  • 1
  • 2
  • 3

1.2. 创建

  • 创建一个文件main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 运行服务器:
uvicorn main:app --reload
# 显示如下:
INFO:     Will watch for changes in these directories: ['/Users/devinzhang/allennlp/project_template']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [18257] using watchgod
INFO:     Started server process [18259]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

  • 如果不是在本地,而是使用远程服务器,那么你的启动命令变成:
uvicorn main:app --host '远程机器ip' --port 端口 --reload
# 比如:
uvicorn main:app --host '192.168.30.17' --port 8000 --reload
  • 1
  • 2
  • 3
  • 参数说明:
main: 指定主程序文件main.py文件, 如果main.py文件改成test.py 则命令也需要改为uvicorn test:app
app:在main.py中使用app = FastAPI()创建的对象
--host:远程主机ip,如果是本地则可以不要这个参数
--host:端口号
--reload:在修改源代码后程序会自动重新加载不用退出重新启动
  • 1
  • 2
  • 3
  • 4
  • 5

1.3. get方法

  • 这个是最常见的请求形式
  • (1) url参数:修改main.py
from fastapi import FastAPI

app = FastAPI()

# url参数定义在这个修饰器里面
@app.get("/{url}")
def read_root():
    return {"Hello": "World"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • (2) param参数:修改main.py
from fastapi import FastAPI

app = FastAPI()

# url参数可以和param重合
@app.get("/{url}")
def read_root(url: str, parms_1: str, parms_2: str = None):
    return {'url地址是: ': url, "parms_1参数是 ": parms_1, "parms_2参数是 ": parms_2}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

  • 参数说明:
  • 1. 如果有parm参数则在地址后面加 ?,多个parm参数使用 & 连接
  • 2. return单引号和双引号没有区别
  • 3. 从上面可以看出url参数可以和parm参数合一,这是第一个url参数就不需要?url=,而是直接跟在端口8000/后面

1.4. post方法

  • post方法参数不是直接接在url后面,安全性会好一些,使用post时需要继承BaseModel这个类
  • (1)body参数
from fastapi import FastAPI
from pydantic import BaseModel  # fastapi的一个依赖,需要从pydantic中引入

app = FastAPI()

class Args(BaseModel):  # 继承BaseModel
    data_str: str  # 定义一个字符串型参数
    data_int: int  # 定义一个整形参数
    data_list: list  # 定义一个列表

@app.post("/test_image")
async def postEchoApi(args: Args):  # 设置刚才定义的参数
    dict_args = args.dict()  # 也可以转化为字典
    return {"str data": args.data_str,
            'int data': args.data_int,
            'list data': args.data_list,
            'args 数据类型': str(type(args))}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 使用postman软件测试结果如下:

在这里插入图片描述

1.5. 在服务器部署fastAPI

  • 第一种使用方式:就是上面介绍的方法
uvicorn main:app --host '0.0.0.0' --port 8000 --reload --workers 1
  • 1
  • 第二种使用方式(推荐)
  • Gunicorn是一个成熟的、功能齐全的服务器和流程管理器。Uvicorn包含一个Gunicorn worker类,允许您运行ASGI应用程序,具有Uvicorn的所有性能优势,同时还为您提供了Gunicorn的全功能流程管理。这允许您动态地增加或减少工作进程的数量,正常地重新启动工作进程,或者在不停机的情况下执行服务器升级。对于生产部署,建议将gunicorn与uvicorn worker类一起使用。
gunicorn main:app -b 0.0.0.0:8000 -w 1 -k uvicorn.workers.UvicornWorker
  • 1

二. RestAPI简要介绍

# !/usr/bin/env python
# -*- encoding: utf-8 -*-
"""====================================
@Project: Autoformer
@Author : kaifang zhang
@Date   : 2021/10/3 20:24
@Contact: kaifang.zkf@dtwave-inc.com
====================================="""
import io
import json

from torchvision import models
import torchvision.transforms as transforms
from PIL import Image
from flask import Flask, jsonify, request

app = Flask(__name__)
imagenet_class_index = json.load(open('imagenet_class_index.json'))
model = models.densenet121(pretrained=True)
model.eval()


def transform_image(image_bytes):
    # torchvision.transforms是pytorch中的图像预处理包。一般用Compose把多个步骤整合到一起
    my_transforms = transforms.Compose([transforms.Resize(255),  # 把给定的图片resize到given size
                                        transforms.CenterCrop(224),  # 在图片的中间区域进行裁剪
                                        transforms.ToTensor(),
                                        transforms.Normalize([0.485, 0.456, 0.406],  # 用均值和标准差归一化张量图像
                                                             [0.229, 0.224, 0.225])])
    image = Image.open(io.BytesIO(image_bytes))
    return my_transforms(image).unsqueeze(0)


def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    predicted_idx = str(y_hat.item())
    return imagenet_class_index[predicted_idx]


@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        filepath = request.get_data().decode('utf-8')
        with open(filepath, 'rb') as f:
            img_bytes = f.read()
        class_id, class_name = get_prediction(image_bytes=img_bytes)
        return jsonify({'class_id': class_id, 'class_name': class_name})


if __name__ == '__main__':
    app.run(port=5000, debug=True)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • Python发送请求:
# !/usr/bin/env python
# -*- encoding: utf-8 -*-
"""====================================
@Project: Autoformer
@Author : kaifang zhang
@Date   : 2021/10/3 00:51
@Contact: kaifang.zkf@dtwave-inc.com
====================================="""
import requests

resp = requests.post("http://localhost:5000/predict", data="my_demo.jpg")
print(resp.json())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • Postman发送请求:

在这里插入图片描述

二. 参考文章

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/1005465
推荐阅读
相关标签
  

闽ICP备14008679号