关于fastapi请求,请求post的问题



我使用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):

idpassword是查询参数,但您试图传递JSON数据而不是查询参数。

response = requests.post(my_url, json={"id": id, "password": password})

如果你想让这段代码工作,你应该传递idpassword作为查询参数

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)