FastAPI--路由(2)
一、概述
路由方法有 GET, POST, PUT, PATCH, DELETE 和 OPTIONS。
import uvicorn from fastapi import FastAPI app = FastAPI() @app.post("/") @app.put("/") @app.delete("/") @app.get("/") @app.options("/") @app.head("/") @app.patch("/") @app.trace("/") async def root(): return {"message": "Hello 454533333343433World"} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
二、路由Route上参数获取和校验
一般我们的路由分会静态和动态,静态路由就是参数是固定写死,也就是访问地址是写死的,而动态地址,就是需要动态的生成,类似简书的博文的地址94710ed35b92就是动态,其实和Bottle和Flask一样。
https://www.jianshu.com/p/94710ed35b92
代码如下:
import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id): return {"item_id": item_id} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
上述的示例代码中的item_id 就是一个动态的参数,你可以随意传一个进来。
http://127.0.0.1:8000/items/ask
然后就是和bottle(微型Web框架)一样也可以对传入的参数进行数据验证的定义: 如:
import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
item_id: int 这种情况item_id必须是可以转为int类似的数据,否则,肯定会报错!
http://127.0.0.1:8000/items/ask
它会给出提示,必须是int类型。返回的HTTP状态码为422
关于路由覆盖问题: 如下两个路由地址:
import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/users/me") async def read_user_me(): return {"user_id": "the current user"} @app.get("/users/{user_id}") async def read_user(user_id: str): return {"被优先匹配到:": user_id} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
上面两个路由同时存在的话,会按照匹配规则进行匹配。什么意思呢?
@app.get("/users/me") 表示精确匹配
@app.get("/users/{user_id}") 表示模糊匹配
下面我来验证一下。
http://127.0.0.1:8000/users/me
可以看到,它匹配了是第一条。注意:只有正常情况下,才会返回HTTP 200
http://127.0.0.1:8000/users/123
发现它是匹配的第2个路径。
查询路径参数和参数校验
关于查询参数,其实就是在使用POSTMAN 提交的时候的参数信息: 如:
http://127.0.0.1:8000/items/?skip=0&limit=10
skip=0&limit 就是所谓的查询参数。
import uvicorn 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] if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
第一种访问的情况:
http://127.0.0.1:8000/items/
我们发现,它返回的是list所有数据。这是为什么呢?来,我来细细品一下代码。
在这个url中,并没有传入参数skip和limit,那么它会使用默认值,分别是0,100
那么fake_items_db[skip: skip + limit] 等同于fake_items_db[0:10]
看到这里,学过python基础知识的,应该明白,这是列表切片。
第二种访问情况:
http://127.0.0.1:8000/items/?skip=1
返回了最后2条数据,第一条没有显示。因为此时fake_items_db[skip: skip + limit] 等同于fake_items_db[1:10]
第三种访问情况:
http://127.0.0.1:8000/items/?skip=abc
提示错误信息,值不是整形,HTTP状态码为:422
多路径和查询参数
所谓的多路径和查询参数就是URL上包含了有动态的参数,还有需要通过&分隔符提交的参数,这情况,通常再GET提交的中也很常见,那么如何处理呐?
import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/users/{user_id}/items/{item_id}") async def read_user_item( user_id: int, item_id: str, q: str = None, short: bool = False ): item = {"item_id": item_id, "owner_id": user_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 if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
请求:
http://127.0.0.1:8000/users/123456/items/items_xinxiid/?q=assa&short=True
注意:item.update 是python字典的一个语法。存在即更新,不存在,即添加。
其他逻辑我就不解释了,仔细看也能明白。
请求:
http://127.0.0.1:8000/users/123456/items/items_xinxiid/?q=assa&short=False
由于short=False,因此description值做了更新操作。
路径参数和查询参数的必选和可选
参数的可选和必选主要是通过是否给默认值来决定的,如:
import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_user_item(item_id: str, needy: str): item = {"item_id": item_id, "needy": needy} return item if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
上述的代码中 needy 没有给与默认的值,当个没提交这个值的时候,会提示错误:
http://127.0.0.1:8000/items/123456
还可以定义可选参数和必选的参数的提交类型: 其中还可以使用Optional来定义需要提交的数据类型: 如:
import uvicorn from fastapi import FastAPI from typing import Optional app = FastAPI() @app.get("/items/{item_id}") async def read_user_item(item_id: str, limit: Optional[int] = None): item = {"item_id": item_id, "limit": limit} return item if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
我们把查询参数limit规定为了int类型,但是它是可选的的参数,设置为了None:
http://127.0.0.1:8000/items/ask
如果传入的参数类型不对,就会报错
http://127.0.0.1:8000/items/ask?limit=422w
路径参数的枚举
import uvicorn from fastapi import FastAPI from enum import Enum app = FastAPI() class ModelName(str, Enum): alexnet = "alexnet" resnet = "resnet" lenet = "lenet" @app.get("/model/{model_name}") async def get_model(model_name: ModelName): if model_name == ModelName.alexnet: return {"model_name": model_name, "message": "Deep Learning FTW!"} if model_name.value == "lenet": return {"model_name": model_name, "message": "LeCNN all the images"} return {"model_name": model_name, "message": "Have some residuals"} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
访问地址:
http://127.0.0.1:8000/model/alexnet
可以发现,它匹配了第一条规则。
查询参数Query参数的其他校验
在以前通常是使用wtform来定义提交的字段信息的类似或可选或长度类型。在Fastapi里面,我们是通过: from fastapi import FastAPI, Query 中的Query来定义,如:
import uvicorn from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") async def read_items(q: str = Query(None, min_length=3,max_length=50,regex="^fixedquery")): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) return results if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
注意:参考文章中有一个小错误,regex必须在Query里面才能生效。
参数解释:
q: str = Query(None, min_length=3,max_length=50,regex="^fixedquery") 意思是:q参数是可选的参数,但是如果填写的话,最大长度必须是小于50内,且最小的长度必须大于3: 且需要符合regex的匹配
当然None可以修改为其他默认值,可以写如:
q: q: str = Query('xiaozhong', min_length=3,max_length=50,regex="^fixedquery"))
注意:如果正则为^fixedquery$,表示精确匹配,q必须是fixedquery才行。前后左右多一点都不行。
为了下面的测试,我去掉了$
不传q的情况下:
http://127.0.0.1:8000/items/
传q的情况下且长度大于50:
http://127.0.0.1:8000/items/?q=fixedquery333333333333333333333333333333333333333333
传q的情况下且长度小于3:
http://127.0.0.1:8000/items/?q=fixedquery333
查询参数Query的参数正则校验
http://127.0.0.1:8000/items/?q=433
查询参数Query参数多值列表
一般在我们的接口中很少说同一个参数提交多个值如:
http://127.0.0.1:8000/items/?q=foo&q=bar
但也不排查这种情况的存在,所以也可以定义我们的参数类似必须是列表的形式:
import uvicorn from fastapi import FastAPI, Query from typing import List app = FastAPI() @app.get("/items/") async def read_items(q: List[str] = Query(["foo", "bar"])): # <!--也可以使用list直接代替List[str]:--> query_items = {"q": q} return query_items if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
默认值:
http://127.0.0.1:8000/items/
非默认值:
http://127.0.0.1:8000/items/?q=123&q=456
路径参数的其他校验方式
对于查询参数可以通过Query,同样对于路径参数也可以使用Fastapi自带的Path来进行校验。
import uvicorn from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( q: str, item_id: int = Path(..., title="The ID of the item to get") ): results = {"item_id": item_id} if q: results.update({"q": q}) return results if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
http://127.0.0.1:8000/items/11?q=22
对于路径参数校验中,还可以对item_id进行大于或等于的校验如:
import uvicorn from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( *, item_id: int = Path(..., title="The ID of the item to get", ge=1), q: str): results = {"item_id": item_id} if q: results.update({"q": q}) return results if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
在上面代码意思是,item_id必须是整数,而且必须大于等于1。其中ge=1表示大于等于1
传入0就会报错
http://127.0.0.1:8000/items/0?q=aa
本文参考链接:
http://www.zyiz.net/tech/detail-119883.html
FastAPI--路由(2)相关推荐
- 【Python开发】FastAPI 07:Depends 依赖注入
在 FastAPI 中,Depends 是一个依赖注入系统,用于注入应用程序中所需的依赖项,通过 Depends,我们可以轻松地将依赖项注入到 FastAPI 路由函数中.简单来说,Depends 依 ...
- Python后端工程师之2022年5月技术栈大盘点
Python后端工程师之2022年5月盘点 盘点就web后端进行讨论: 后端开发技术栈: 开发:基于Python虚拟环境进行标准开发. web框架:flask.tornado.fastapi 路由:设 ...
- FastAPI学习-3(路由参数详解)
1.路径参数 声明路径参数时,可以使用Python格式字符串使用的相同语法声明路径"参数"或"变量" 无参数类型 from fastapi import Fas ...
- FastAPI从入门到实战(15)——设置通用路由
本文主要记录fastapi实现一个接口多个请求方式的实现:例如同样的接口,既可以通过查询参数或路径参数的方式请求得到数据,也可以通过发送请求体的方式得到响应. 常见的请求方式 Get 向特定资源发出请 ...
- FastAPI 的路由介绍及使用
上一篇文章中,我介绍了 FastAPI 框架的安装和 HelloWorld 项目搭建方式.本文将介绍如何使用 Router 路由处理 FastAPI 中的请求. 什么是路由 路由 Router 就像是 ...
- fastapi jinja2_(入门篇)Python框架之FastAPI——一个比Flask和Tornado更高性能的API 框架
用官方的话来说,FastAPI 是一种现代,快速(高性能)的 Web 框架,基于标准Python 类型提示使用 Python 3.6+ 构建 API FastAPI 站在巨人的肩膀上? 很大程度上来说 ...
- 三分钟了解 Python3 的异步 Web 框架 FastAPI
快速编码,功能完善.从启动到部署,实例详解异步 py3 框架选择 FastAPI 的原因. FastAPI 介绍 FastAPI 与其它 Python-Web 框架的区别 在 FastAPI 之前,P ...
- 全面拥抱 FastApi — 多应用程序项目结构规划
FastAPI最近比较火,自从看到这款框架后就一直在关注着.据官方文档上的介绍它是一个并发性可以和 NodeJS 以及 Go 相媲美的 web 框架,具有强大的性能 本人最近也是一直在使用和学习 Fa ...
- 干货:使用Fastapi开发自己的Mock server(附源码)
最近几天抽空看了下Fastapi的文档,顺便使用它开发了个HTTP(s)协议的Mock server.以后有需要用到挡板的地方,就可以直接使用啦. 项目一级目录: logs用来存放日志文件,日切 ma ...
- flask异步操作_从Flask到FastAPI的平滑迁移
作者 | Ng Wai Foong 译者 | 马可薇 策划 | 田晓旭 迁移 Flask 服务器以获得更好的性能和可维护性. 本文最初发布于 BetterProgramming,经原作者授权由 Inf ...
最新文章
- 译者招募 | 《Java编程思想》作者Bruce Eckel新作On Java 8
- spark匹配html字段,Apache Spark中的高效字符串匹配
- Spring-Data-JPA 动态查询黑科技
- 发布CodeBuild.Net代码自动生成器 V2008 2.01(Vs2008)和架构实例源码Demo
- kettle 内存设置_【转】kettle 的内存设置及输出日志的时间类型
- 免费的微软OneCare防病毒软件
- [Pku 2774] 字符串(六) {后缀数组的构造}
- javascript_如何不再害怕JavaScript
- DataTable筛选某列最大值
- 介绍一下Python中webbrowser的用法?
- [Robot Framework] 怎么写动态等待?
- oracle 10g 各版本下载地址
- Python中函数介绍及其使用
- 【场景化解决方案】ERP系统与钉钉实现数据互通
- js判断ie11和qq,opera浏览器(亲测)
- 查看oracle数据库防火墙设置,用三个方法设置Oracle数据库穿越防火墙
- SpringSecurity之授权
- python语言+selenium自动化,编写脚本调用Chrome、Firefox浏览器打开百度网站
- ヴィアッカ / 风锤
- Java 17全新特性,快到模糊