路径参数
文章目录
学习自 https://www.bilibili.com/video/BV1sE411x7bi
在教程基础上,增加了 requests 请求。
一、URL 请求
No.7
# -*- coding: UTF-8 -*-
from fastapi import FastAPI
app = FastAPI()
@app.get("/me/xx")
async def read_item_me():
return {"me": 'me'}
'''
访问 http://127.0.0.1:8000/me/xx
返回 {"me":"me"}
'''
@app.get("/me/{item_id}")
async def read_item(item_id: str):
return {"item_id": item_id}
'''
http://127.0.0.1:8000/me/123
{"item_id":"123"}
'''
@app.get("/")
async def main():
return {"message": "Hello,FastAPI"}
'''
访问 http://127.0.0.1:8000/
返回 {"message":"Hello,FastAPI"}
'''
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8001)
使用枚举 Enum
from enum import Enum
class Name(str, Enum):
Allan = '张三'
Jon = '李四'
Bob = '王五'
app = FastAPI()
@app.get("/{who}")
async def get_day(who: Name):
if who == Name.Allan:
return {"who": who, "message": "张三是德国人"}
if who.value == '李四':
return {"who": who, "message": "李四是英国人"}
return {"who": who, "message": "王五是法国人"}
'''
访问 http://127.0.0.1:8001/%E5%BC%A0%E4%B8%89 (张三)
{"who":"张三","message":"张三是德国人"}
访问 http://127.0.0.1:8001/%E6%9D%8E%E5%9B%9B ( http://127.0.0.1:8001/李四 )
返回 {"who":"李四","message":"李四是英国人"}
访问 http://127.0.0.1:8001/Allan
返回 {"detail":[{"loc":["path","who"],"msg":"value is not a valid enumeration member; permitted: '张三', '李四', '王五'","type":"type_error.enum","ctx":{"enum_values":["张三","李四","王五"]}}]}
'''
@app.get("/")
async def main():
return {"message": "Hello,FastAPI2"}
'''
访问 http://127.0.0.1:8000/
返回 {"message":"Hello,FastAPI2"}
'''
二、查询参数 Query Parameters
No.8
传递不同数据类型
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]
'''
访问 http://127.0.0.1:8000/items/
页面显示 [{"item_name":"Foo"},{"item_name":"Bar"},{"item_name":"Baz"}]
访问 http://127.0.0.1:8000/items/?skip=1&limit=2
页面显示:[{"item_name":"Bar"},{"item_name":"Baz"}]
'''
@app.get("/i/")
async def i(A: str = 'HI..', B: str = 'Hello..', C: str = 'He..'):
return {'cc': A+B+C},{'dd': B+C}
'''
http://127.0.0.1:8000/i/
[{"cc":"HI..Hello..He.."},{"dd":"Hello..He.."}]
http://127.0.0.1:8000/i/?A=Sun
[{"cc":"SunHello..He.."},{"dd":"Hello..He.."}]
http://127.0.0.1:8000/i/?A=Sun..&C=Rain...
[{"cc":"Sun..Hello..Rain..."},{"dd":"Hello..Rain..."}]
'''
@app.get("/ii/")
async def ii(A: int = 0, B: int = 10, C: int = 20):
return {'cc': A+B+C},{'dd': B+C}
@app.get("/iii/")
async def iii(A: int = 0, B: int = 10, C: int = 20):
return 'A+B+C',A+B+C
'''
http://127.0.0.1:8000/iii/
"A+B+C",30]
'''
# bool与类型转换
@app.get("/xxx/{item_id}")
async def xxx(item_id: str, QQ: str = None, SS: bool = False):
item = {"item_id": item_id}
if QQ:
item.update({"QQ": QQ})
if not SS: # 如果SS是假
item.update(
{"item_id": "This is SSSSSSS"}
)
return item
'''
# 传入的是路径,而非参数,所以不使用 ?
http://127.0.0.1:8000/xxx/123
{"item_id":"This is SSSSSSS"}
http://127.0.0.1:8000/xxx/123?QQ=SUN&SS=True
{"item_id":"123","QQ":"SUN"}
'''
多路径 和 查询参数 和 必填字段
#多路径 和 查询参数 和 必填字段
@app.get("/user/{user_id}/item/{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
'''
http://127.0.0.1:8000/user/1/item/2
{"item_id":"2","owner_id":1,"description":"This is an amazing item that has a long description"}
? 接参数,应该放最后面,而不是放在 user_id 之后 中间的位置
比如 http://127.0.0.1:8000/user/1?q=1/item/2 不对
http://127.0.0.1:8000/user/1/item/2?q=2 正确
返回 {"item_id":"2","owner_id":1,"q":"2","description":"This is an amazing item that has a long description"}
'''
三、查询参数和字符验证 Query Validations
No.10
1、长度限制
from fastapi import FastAPI, Query
from typing import List
# 限制长度
@app.get("/items/")
async def read_items(q: str = Query(..., min_length=3, max_length=50)):
#填None就是默认值 填 ...则是必填项
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
'''
... 代表什么都没有,None 代表这里有东西,只是是 None
q: str = Query(..., min_length=3, max_length=50) 这样写,q 不是必填项
q: str = Query(None, min_length=3, max_length=50) 这样写,q 是必填项
'''
测试请求
import requests
def test1():
item_id = 5
q = 'qaqa'
url = f'http://127.0.0.1:8000/items/?q={q}'
# url = f'http://127.0.0.1:8000/items/'
ret = requests.get(url=url, timeout=10)
print('ret 0 : ', ret) # ret 0 : <Response [200]>
print('ret 1 : ', ret.text)
# {"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"qaqa"}
#
'''
q 是必填项
如果请求 http://127.0.0.1:8000/items/,返回 {"detail":[{"loc":["query","q"],"msg":"field required","type":"value_error.missing"}]}
如果 q = 'qa', 小于三位,则返回:
{"detail":[{"loc":["query","q"],"msg":"ensure this value has at least 3 characters","type":"value_error.any_str.min_length","ctx":{"limit_value":3}}]}
'''
2、正则
#正则表达式
@app.get("/items2/")
async def read_items2(
q: str = Query(None, min_length=3, max_length=50, regex="^nice")
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
'''
q = 'nice to meet you'
url = f'http://127.0.0.1:8000/items2/?q={q}'
# {"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"nice to meet you"}
q 需要匹配正则 ^nice
'''
3、列表
#列表
@app.get("/items3/")
async def read_items3(q: List[str] = Query(["foo", "bar"])):
query_items = {"q": q}
return query_items
'''
列表的默认值为 ["foo", "bar"]
request : http://127.0.0.1:8002/items3/?q=foo&q=bar
ret 1 : {"q":["foo","bar"]}
request : http://127.0.0.1:8002/items3/?q=foo
ret 1 : {"q":["foo"]}
request : http://127.0.0.1:8000/items3/?q=['foo', 'bar']
Read timed out.
'''
请求
def test3():
item_id = 5
q = ['1', 'a']
q = [ "foo", "bar" ]
url = f'http://127.0.0.1:8000/items3/?q={q}'
# url = f'http://127.0.0.1:8000/items/'
print('request : ', url)
ret = requests.get(url=url, timeout=10)
print('ret 0 : ', ret) # ret 0 : <Response [200]>
print('ret 1 : ', ret.text)
# {"q":["['1', 'a']"]}
# {"q":["['foo', 'bar']"]}
# 如果不输入q,返回 {"q":["foo","bar"]}
4、别名参数
#别名参数
@app.get("/items4/")
async def read_items4(q: str = Query(None, alias="item-query")):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
'''
使用别名 alias 查询
request : http://127.0.0.1:8002/items4/?item-query=fish
ret 1 : {"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"fish"}
# 使用 q 来查询,没有效果;
request : http://127.0.0.1:8002/items4/?q=fish
ret 1 : {"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}
'''
5、弃用参数
#弃用参数
@app.get("/items5/")
async def read_items5(
q: str = Query(
None,
alias="item-query",
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
max_length=50,
regex="^fixedquery$",
deprecated=True,
)
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
'''
'''
四、路径参数与数值验证
No.11
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(..., title="The ID of the item to get", ge=50, le=100),#ge 大于等于 gt是大于 le是小于等于
q: str = Query(None, alias="item-query"),
size: float = Query(1, gt=0, lt=10.5)
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
'''
request : http://127.0.0.1:8004/items/12
ret 0 : <Response [422]>
ret 1 : {"detail":[{"loc":["path","item_id"],"msg":"ensure this value is greater than or equal to 50","type":"value_error.number.not_ge","ctx":{"limit_value":50}}]}
request : http://127.0.0.1:8004/items/65
ret 1 : {"item_id":65}
'''
五、Cookie Parameters
No.16
# -*- coding: UTF-8 -*-
from fastapi import Cookie, FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(*, ads_id: str = Cookie(None)):
return {"ads_id": ads_id}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
def test1():
url = 'http://127.0.0.1:8000/items/'
headers = {'Cookie':'ads_id=100'}
headers = {'Cookie':'ads_id=100;ads_id=199'} # 多个赋值之间用分号;而非逗号隔开;相同键取最后一个赋值。
print('request : ', url)
ret = requests.get(url=url, headers=headers, timeout=10)
print('ret 0 : ', ret)
print('ret 1 : ', ret.text) # {"ads_id":"199"}
六、Head Patameters
No.17
from fastapi import FastAPI, Header
from typing import List
app = FastAPI()
@app.get("/items/")
async def read_items(*, user_agent: str = Header(None), users_agent: str = Header(None)):
return {"User-Agent": user_agent},{"AAAAA": user_agent},{'ABCD': users_agent}
@app.get("/items2/")
async def read_items2(x_token: List[str] = Header(None)):
return {"X-Token values": x_token}
def test2():
url = 'http://127.0.0.1:8000/items/'
headers = {'user_agent':'a1',
'User-Agent':'a2',
'users_agent':'a3'}
print('request : ', url)
ret = requests.get(url=url, headers=headers, timeout=10)
print('ret 0 : ', ret)
print('ret 1 : ', ret.text) # [{"User-Agent":"a2"},{"AAAAA":"a2"},{"ABCD":null}]
def test2():
url = 'http://127.0.0.1:8000/items2/'
headers = {'x-token':['b1', 'b2', 'b3'] } # 报错 Value for header {x-token: ['b1', 'b2', 'b3']} must be of type str or bytes, not <class 'list'>
headers = {'x-token':'b1,b2,b3' }
print('request : ', url)
ret = requests.get(url=url, headers=headers, timeout=10)
print('ret 0 : ', ret)
print('ret 1 : ', ret.text) # {"X-Token values":["b1,b2,b3"]}
伊织 2021-11-28