赞
踩
Python中的异步Web框架之fastAPI介绍&RestAPI |
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示使用 Python 3.6+ 构建 API。主要特点是:
- 快速:非常高的性能,与NodeJS和Go相当(感谢 Starlette 和 Pydantic)。可用的最快的 Python 框架之一。
- 快速编码:将开发功能的速度提高约 200% 到 300%。*
- 更少的错误:减少约 40% 的人为(开发人员)导致的错误。*
- 直观:出色的编辑器支持。到处完成。更少的调试时间。
- 简单:旨在易于使用和学习。减少阅读文档的时间。
- Short : 尽量减少代码重复。每个参数声明的多个功能。更少的错误。
- 健壮:获取生产就绪的代码。具有自动交互式文档。
- 基于标准:基于(并完全兼容)API 的开放标准:OpenAPI(以前称为 Swagger)和JSON Schema。
- Pip安装如下:
pip install fastapi
# 您还需要一个 ASGI 服务器,用于生产,例如Uvicorn或Hypercorn。
pip install "uvicorn[standard]"
- 创建一个文件
main.py
:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
- 运行服务器:
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.
- 接下来你在浏览器中打开 http://127.0.0.1:8000 就会显示一个最基础的
get
页面
- 如果不是在本地,而是使用远程服务器,那么你的启动命令变成:
uvicorn main:app --host '远程机器ip' --port 端口 --reload
# 比如:
uvicorn main:app --host '192.168.30.17' --port 8000 --reload
- 参数说明:
main: 指定主程序文件main.py文件, 如果main.py文件改成test.py 则命令也需要改为uvicorn test:app
app:在main.py中使用app = FastAPI()创建的对象
--host:远程主机ip,如果是本地则可以不要这个参数
--host:端口号
--reload:在修改源代码后程序会自动重新加载不用退出重新启动
- 这个是最常见的请求形式
- (1)
url
参数:修改main.py
from fastapi import FastAPI
app = FastAPI()
# url参数定义在这个修饰器里面
@app.get("/{url}")
def read_root():
return {"Hello": "World"}
- 在
@app.get
中定义了url
参数,那么我们下次get
请求时就不能直接输入http://127.0.0.1:8000而是http://127.0.0.1:8000/xxxx(其中xxxx表示任意字符串)
- (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}
- 这是输入http://127.0.0.1:8000/anywords?parms_1=abc&parms_2=def就可以了,这里我使用的是远程服务器,因此我指定了ip和端口
- 参数说明:
- 1. 如果有parm参数则在地址后面加 ?,多个parm参数使用 & 连接
- 2.
return
中单引号和双引号没有区别- 3. 从上面可以看出
url
参数可以和parm
参数合一,这是第一个url
参数就不需要?url=
,而是直接跟在端口8000/
后面
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))}
- 使用
postman
软件测试结果如下:
- 第一种使用方式:就是上面介绍的方法
uvicorn main:app --host '0.0.0.0' --port 8000 --reload --workers 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
- 一文彻底弄懂REST API: https://zhuanlan.zhihu.com/p/536437382
- 使用Flask通过 REST API 在Python中部署Pytorch:https://pytorch.org/tutorials/intermediate/flask_rest_api_tutorial.html
# !/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)
- 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())
- Postman发送请求:
- FastAPI简单操作:https://www.jianshu.com/p/3d391d022239
- FastAPI:Python 世界里最受欢迎的异步框架:https://www.cnblogs.com/traditional/p/14733610.html
- fastAPI官网:https://fastapi.tiangolo.com/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。