FastApi个人笔记

FastApi笔记

学习FastApi建议直接看官方文档:官方文档

一、环境准备

1.1 安装Fast Api

pip3 install fastapi[all]

[all] 指安装fastapi下提供的所有插件

二、第一个Restful API

2.1 创建第一个代码框架

main.py中写下如下代码:

from fastapi import FastApi

app = FastApi() 						# 构造一个app对象

@app.get('/helloworld')							# 定义所需要开发的api
async def index():						# async为异步函数
    return {'message': 'Hello World'}
# 程序到这里就拥有了/helloworld这个api

async作用(引自CSDN):

常规函数开始执行后一直运行到return实现退出,如果需要能够中断的函数,就需要添加async关键字。

async用来声明一个函数为异步函数,异步函数的特点就是能在函数执行过程中被挂起,去执行其他异步函数,等挂起条件消失后再回来执行。

因为fastapi很快,它所有基于api的定义都是异步化的,所以读用async关键字

2.2 运行第一个代码

在终端中输入:

uvicorn main:app --reload

由于fastapi不具备基本的网关服务,所以它需要借助于外部的网关服务器来提供web访问的基础架构。

uvicorn:就是一个非常高性能的SGI网关服务器。

main:app:表示加载main.py中的app程序 --reload表示进行加载

运行成功后,终端可能会显示如下代码:

(venv) PS C:\Users\UserName\Desktop\First_FastApi> uvicorn main:app --reload
INFO:     Will watch for changes in these directories: ['C:\\Users\\UserName\\Desktop\\First_FastApi']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [34768] using WatchFiles
INFO:     Started server process [20412]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:57829 - "GET / HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:58012 - "GET / HTTP/1.1" 404 Not Found

“Not Found”?这就对了,因为上面的代码没有定义根

代码中补充即可:

from fastapi import FastAPI

app = FastAPI()

@app.get('/')
async def root():
    return {'message' : 'Hello Root'}

@app.get('/helloworld')
async def read_get():
    return {'message': 'hello world'}

这个时候去重新刷新网站即可,网站会显示:

{
    "message": "Hello Root"
}

这里可以发现启动程序时uvicorn main:app --reload中最后加入--reload的作用其实就是在刷新网页时自动加载新的保存好的代码配置

如果想要访问/helloworld所在的api

在浏览器搜索框中改为如下地址即可,

http://127.0.0.1:8000/helloworld

返回的结果使用了jason,这就是最基本的restful api,是基于http请求的

2.3 Swag UI界面 (1)

在浏览器搜索框中将地址改为,

http://127.0.0.1:8000/docs

出现了这样的界面,在这里可以轻松的看到当前服务器中定义了哪些api。

这一点对于要开发restful api的人来讲,是很好的选择。

2.4 直接启动应用

在代码中进行如下修改即可,

from fastapi import FastAPI
import uvicorn # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/')
async def root():
    return {'message' : 'Hello Root'}

@app.get('/helloworld')
async def read_get():
    return {'message': 'hello world'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

完成修改后,直接点击if __name__ == '__main__':左边的绿色三角形,并在内置终端中点击网址即可在web中打开程序。

2.5 Swag UI界面 (2)

在swag ui中点击Try it out>Execute,也就是尝试>执行。可以做到直接向服务器发送请求并看到送回的返回结果。

三、路径参数

3.1 路径参数存在于uri当中

http://localhost:8000/users/2
@app.get('/users/{user_id}')
async def get_user(user_id: int):
    return {'user_id': user_id}

上面两端代码分别对应 uri 和 python 中用来提取信息的代码,其中 users/ 后面的内容 2 就是路径参数,fastapi 会根据定义的格式,自动提取出参数。上述例子中,当前端输入该地址后,fastapi 会提取 2 作为 user_id 的参数。

3.2 参数类型限定

对于下面的代码:

from fastapi import FastAPI
import uvicorn # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/users/{user_id}')
async def get_user(user_id):
    return {'user': f'This is the user for {user_id}'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

运行后在浏览器中查看, 再次可以看到swag UI的强大之处:

上述代码中并没有指定实际的类型,有时我们需要限定输入的数据类型。如果输入的数据类型不符合输入要求的类型,需要进行报错而不是直接使用。比如上述例子中我要求 id 是整数而不能是字符串,就要加上: int来进行类型的申明:

from fastapi import FastAPI
import uvicorn # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/users/{user_id}')
async def get_user(user_id: int):
    return {'user': f'This is the user for {user_id}'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

运行成功后路径参数不是 int 类型会有如下报错:

这里的报错提示是可以进行定制的,这里暂且不谈。

3.3 API定义的顺序影响

from fastapi import FastAPI
import uvicorn                  # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/users/{user_id}')
async def get_user(user_id: int):
    return {'user': f'This is the user for {user_id}'}

@app.get('/users/current')
async def get_current_user():
    return {'user': f'This is current user.'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

上面代码运行后,在Web中访问

http://127.0.0.1:8000/users/12

会返回

{
    "user": "This is the user for 12"
}

但是如果访问

http://127.0.0.1:8000/users/current

就会返回

{
    "detail": [
        {
            "type": "missing",
            "loc": [
                "query",
                "user_id"
            ],
            "msg": "Field required",
            "input": null
        }
    ]
}

为什么会出现这种情况?

因为user/current是满足第一种api的定义模式的格式要求,所以第一个api定义会执行并返回类型报错。换言之,fastapi并不知道你后面还定义了一个可以使用的方法。

但如如果将顺序反过来:

from fastapi import FastAPI
import uvicorn                  # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/users/current')
async def get_current_user():
    return {'user': f'This is current user.'}

@app.get('/users/{user_id}')
async def get_user(user_id: int):
    return {'user': f'This is the user for {user_id}'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

功能就正常了,current可以被正常识别,int型也能识别出来。

说白了,这个例子告诉我们,当api的格式定义很相似的时候,我们要主要api定义的顺序,以防止某些定义不能正常使用。

也就是“小范围在前,大范围在后”。

3.4 通过枚举定义参数值的可选项

如果路径的参数是一个性别,我们该怎么提供一个选择项呢?- (男/女)。也就是如何去在 swag UI 中提供一个选择菜单的意思。

from fastapi import FastAPI
import uvicorn                  # 导入uvicorn的服务调用启动服务器的方法
from enum import Enum

app = FastAPI()

class Gender(str, Enum):        # Gender 同时继承了`字符串类型` 和 `枚举类型`
    male = "male"
    female = "female"

@app.get('/student/{gender}')
async def get_gender(gender: Gender):
    return {'student': f'This is a {gender.value} student'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

上述代码定义了一个 Gender 的性别类,它同时继承了字符串和枚举类型,Gender类都是一个可供枚举的字符串值,只能选择枚举可能性中的一种。

运行后在swag UI中显示如下:

这个方法对于调用者来讲没有太大差别,但对于测试者来说,有极大的方便之处。

四、查询参数

4.1 查询参数存在于 uri 当中

http://localhost:8000/users?page_index=1&page_size=10
from fastapi import FastAPI
import uvicorn                  # 导入uvicorn的服务调用启动服务器的方法

app = FastAPI()

@app.get('/users')
async def get_user(page_index: int, page_size: int):
    return {'page info': f'index : {page_index} size: {page_size}'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

在uri中以xxx?xxx的键值对形式来表示查询的路径参数,使用&将它们串在一起。

4.2 可选查询参数

如果uri中只给了page_index不给page_size就叫可选查询参数

from fastapi import FastAPI
import uvicorn                  # 导入uvicorn的服务调用启动服务器的方法
from typing import Optional

app = FastAPI()

@app.get('/users')
async def get_user(page_index: int, page_size: Optional[int] = 30):
    return {'page info': f'index : {page_index} size: {page_size}'}

if __name__ == '__main__':
    uvicorn.run("main:app", reload=True) # 和命令行中的代码一致

在int前加一个Optional即可,这里缺省值设为30。

可以看到,默认的值为 14,是缺省值。

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值