学习内容:FastAPI的所有核心模块
学习效果:查询页面和FastAPI的Swagger UI
FastAPI的主要特点:
- 性能优越
- 开发效率高 200%-300%的提升
- 减少约40%的BUG
- 直观
- 简单易学
- 代码重复率低,精简编码
- 自带API交互文档 开发成果易于交付
Starlette、Pydantic与FastAPl的关系:
- Python的类型提示type hints
- 数据库是一个基于Python类型提示来定义数据验证,序列化和文档(使用JSON模式)库
- Starlette是一种轻量级的ASGI框架/工具包,是构建高性能Asyncio(Asyncio)服务的理想选择
ASGI和WSGI是什么
-
ASGI 和 WSGI 概述
- WSGI (Web Server Gateway Interface) 是一种 Python Web 服务器和 Web 应用之间的通信协议标准,用于同步请求的处理。主要适用于传统的 Web 应用,比如 Django 和 Flask,它们大多只支持同步代码,因此 WSGI 成为了 Python Web 应用的广泛标准。
- ASGI (Asynchronous Server Gateway Interface) 是为了应对现代 Web 应用对异步特性(如 WebSocket 支持、长轮询等)的需求而创建的接口协议。ASGI 允许异步处理,支持 HTTP 和 WebSocket 协议,并适用于需要高并发或实时通信的应用,例如 FastAPI 和 Django Channels。
-
ASGI 和 Uvicorn、Hypercorn、Daphne 之间的关系
- Uvicorn、Hypercorn 和 Daphne 是支持 ASGI 的 Web 服务器。它们主要用于托管 ASGI 应用,使其能够处理异步请求和 WebSocket 等实时通信。
- Uvicorn 是一个高性能的 ASGI 服务器,基于 uvloop 和 httptools,适合运行高并发的异步应用。
- Hypercorn 是支持 ASGI 和 HTTP/2 的服务器,提供了更多配置选项,灵活性较高。
- Daphne 是由 Django Channels 项目开发的 ASGI 服务器,专注于支持 Django 的 WebSocket 和长连接需求。
- Uvicorn、Hypercorn 和 Daphne 是支持 ASGI 的 Web 服务器。它们主要用于托管 ASGI 应用,使其能够处理异步请求和 WebSocket 等实时通信。
-
WSGI 和 uWSGI、Gunicorn 之间的关系
- uWSGI 和 Gunicorn 是支持 WSGI 的 Web 服务器,专为同步 Web 应用设计,用于托管基于 WSGI 的应用。
- uWSGI 是一个高效、可扩展的应用服务器,不仅支持 WSGI,还支持多种协议,适用于部署大型的 Web 应用。
- Gunicorn 是一个简单且广泛使用的 WSGI 服务器,配置方便,适合中小型 Python Web 应用的生产环境部署。
- uWSGI 和 Gunicorn 是支持 WSGI 的 Web 服务器,专为同步 Web 应用设计,用于托管基于 WSGI 的应用。
简而言之,ASGI 和 WSGI 是用于 Web 应用的接口标准,而 Uvicorn、Hypercorn、Daphne、uWSGI 和 Gunicorn 是遵循这些标准的服务器,它们的选择取决于应用对同步或异步功能的需求。
创建项目
安装依赖:
python3.7以上:fastapi-tutorial/requirements.txt at master · liaogx/fastapi-tutorial 下载requirements
若是出现版本问题,检查python版本。其中celery,django,channels可能会出现版本兼容性的问题
Pydantic 基础教程_高性能 FastAPI 框架入门精讲-慕课网
#!/usr/bin/python3
# -*- coding:utf-8 -*-
# __author__ = "__Jack__"
from datetime import datetime, date
from pathlib import Path
from typing import List
from typing import Optional
from pydantic import BaseModel, ValidationError
from pydantic import constr
from sqlalchemy import Column, Integer, String
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.declarative import declarative_base
"""
Data validation and settings management using python type annotations.
使用Python的类型注解来进行数据校验和settings管理
pydantic enforces type hints at runtime, and provides user friendly errors when data is invalid.
Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
Define how data should be in pure, canonical python; validate it with pydantic.
定义数据应该如何在纯规范的Python代码中保存,并用Pydantic验证它
"""
print("\033[31m1. --- Pydantic的基本用法。Pycharm可以安装Pydantic插件 ---\033[0m")
class User(BaseModel):
id: int # 必须字段
name: str = "John Snow" # 有默认值,选填字段
signup_ts: Optional[datetime] = None
friends: List[int] = [] # 列表中元素是int类型或者可以直接转换成int类型
external_data = {
"id": "123",
"signup_ts": "2020-12-22 12:22",
"friends": [1, 2, "3"], # "3"是可以int("3")的
}
user = User(**external_data)
print(user.id, user.friends) # 实例化后调用属性
print(repr(user.signup_ts))
print(user.dict())
print("\033[31m2. --- 校验失败处理 ---\033[0m")
try:
User(id=1, signup_ts=datetime.today(), friends=[1, 2, "not number"])
except ValidationError as e:
print(e.json())
print("\033[31m3. --- 模型类的的属性和方法 ---\033[0m")
print(user.dict())
print(user.json())
print(user.copy()) # 这里是浅拷贝
print(User.parse_obj(external_data))
print(User.parse_raw('{"id": "123", "signup_ts": "2020-12-22 12:22", "friends": [1, 2, "3"]}'))
path = Path('pydantic_tutorial.json')
path.write_text('{"id": "123", "signup_ts": "2020-12-22 12:22", "friends": [1, 2, "3"]}')
print(User.parse_file(path))
print(user.schema())
print(user.schema_json())
user_data = {"id": "error", "signup_ts": "2020-12-22 12 22", "friends": [1, 2, 3]} # id是字符串 是错误的
print(User.construct(**user_data)) # 不检验数据直接创建模型类,不建议在construct方法中传入未经验证的数据
print(User.__fields__.keys()) # 定义模型类的时候,所有字段都注明类型,字段顺序就不会乱
print("\033[31m4. --- 递归模型 ---\033[0m")
class Sound(BaseModel):
sound: str
class Dog(BaseModel):
birthday: date
weight: float = Optional[None]
sound: List[Sound] # 不同的狗有不同的叫声。递归模型(Recursive Models)就是指一个嵌套一个
dogs = Dog(birthday=date.today(), weight=6.66, sound=[{"sound": "wang wang ~"}, {"sound": "ying ying ~"}])
print(dogs.dict())
print("\033[31m5. --- ORM模型:从类实例创建符合ORM对象的模型 ---\033[0m")
Base = declarative_base()
class CompanyOrm(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True, nullable=False)
public_key = Column(String(20), index=True, nullable=False, unique=True)
name = Column(String(63), unique=True)
domains = Column(ARRAY(String(255)))
class CompanyModel(BaseModel):
id: int
public_key: constr(max_length=20)
name: constr(max_length=63)
domains: List[constr(max_length=255)]
class Config:
orm_mode = True
co_orm = CompanyOrm(
id=123,
public_key='foobar',
name='Testing',
domains=['example.com', 'foobar.com'],
)
print(CompanyModel.from_orm(co_orm))
print("\033[31m6. --- Pydantic支撑的字段类型 ---\033[0m") # 官方文档:https://pydantic-docs.helpmanual.io/usage/types/