我使用fastapi来构建我的web-server。
我需要知道客户端的ip地址,所以我遵循这个指南https://fastapi.tiangolo.com/advanced/using-request-directly/
这是我的路由器功能
from fastapi import Request
...
@router.post("/login")
async def login(id: str, password: str, request: Request):
我的客户喜欢这个
import requests
...
response = requests.post(my_url, json={"id": id, "password": password})
但是客户端收到这个消息:
{"detail":[{"loc":["query","dn"],"msg":"field required","type":"value_error.missing"},{"loc":["query","password"],"msg":"field required","type":"value_error.missing"}]}
服务器给出这个消息:
"POST /jobs/login HTTP/1.1" 422 Unprocessable Entity
所以我认为Request字段是需要的或者传输的数据格式是错误的。
有什么解决办法吗?
如果您没有定义Pydantic输入模式,则必须显式地告诉FastAPI您希望从JSON主体检索每个参数。
from fastapi import Request, FastAPI, APIRouter, Body
app = FastAPI()
router = APIRouter()
@router.post("/login")
async def login(request: Request, id: str = Body(...), password: str = Body(...)):
print(id, password)
app.include_router(router)
为登录请求定义一个模式,创建一个继承自BaseModel
的Pydantic类:
from fastapi import Request, FastAPI, APIRouter, Body
from pydantic import BaseModel
class LoginSchema(BaseModel):
id: str
password: str
app = FastAPI()
router = APIRouter()
@router.post("/login-schema")
async def login(request: Request, login: LoginSchema):
print(login.id, login.password)
app.include_router(router)
我想我发现了问题是什么,为什么你得到422不可处理的实体错误.
async def login(id: str, password: str, request: Request):
id
和password
是查询参数,但您试图传递JSON
数据而不是查询参数。
response = requests.post(my_url, json={"id": id, "password": password})
如果你想让这段代码工作,你应该传递id
和password
作为查询参数
import requests
my_url = "http://127.0.0.1:8000/login"
id = "1"
password = "hello"
params = {'id': id, 'password': password}
response = requests.post(my_url, params=params)
是完整的代码。main.py
from fastapi import Request, FastAPI
app = FastAPI()
@app.post("/login")
async def login(id: str, password: str, request: Request):
ip = request.client.host
return {
"id":id,
"password": password,
"host": ip
}
test.py
import requests
my_url = "http://127.0.0.1:8000/login"
id = "1"
password = "hello"
params = {'id': id, 'password': password}
response = requests.post(my_url, params=params)