Cómo leer el parámetro URL y el cuerpo escribiendo en Fast API Python
Quiero crear una definición genérica de endpoint en Fast API Python que lea el parámetro URL path y luego llama un método específico para hacer una derealización. Pero siempre consigo
422 Unprocessable Entity
Así que espero que funcione así:
/answer/aaaa - confianza handle_generic_answer - confianza read_item_aaa, type body to ModelAAA
/answer/bbb - confianza handle_generic_answer - confianza read_item_bbb, type body to ModelBBB etc.
Aquí está el código de endpoint genérico:
@app.post("/answer/{type}")
def handle_generic_answer(type: str, item):
# I also tried
# def handle_generic_answer(type: str, item: Any):
# or
# def handle_generic_answer(type: str, item: Optional):
switcher = {
'aaaa': read_item_aaa,
'bbb': read_item_bbb,
'nothing': unrecognised_answer
}
func = switcher.get(type, unrecognised_answer)
print('answer >> ' + type)
func(item)
entonces tengo métodos separados llamados basados en un type
valor:
def read_item_aaa(item: ModelAAA):
update_aaa(item)
return {"type": "aaa", "result": "success"}
def read_item_bbb(item: ModelBBB):
update_bbb(item)
return {"type": "bbb", "result": "success"}
y un defecto -
def unrecognised_answer(type):
print("unrecognised_answer")
raise HTTPException(status_code=400, detail="answer type not found")
return {}
modelos se definen así:
from pydantic import BaseModel, Field
class ModelAAA(BaseModel):
field1: str
field2: list = []
Pero si llamo
http://localhost:8000/answer/aaa
o http://localhost:8000/answer/some-other-url
Siempre tengo 422:
{
"detail": [
{
"loc": [
"query",
"item"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
Pregunta hecha hace 3 años, 4 meses, 29 días - Por binarybard1cc8
3 Respuestas:
-
Olvidaste anotar el parámetro corporal
item
.Sin esto
item
se trata como consultastr
Parámetro. Por ejemplo:@app.post("/answer/{type}") def handle_generic_answer(type: str, item: Union[ModelAAA, ModelBBB]):
Respondida el Dec 17, 2020 a las 22:08 - por pythonpirate
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a que el endpoint genérico que has creado espera un parámetro adicional en la solicitud POST llamado "item", pero en realidad no estás enviando ningún dato en el cuerpo de la solicitud.
Para poder leer tanto el parámetro URL como el cuerpo de la solicitud en FastAPI, puedes utilizar Pydantic para definir un modelo que represente el cuerpo de la solicitud y especificarlo como un parámetro en tu función de manejo genérico.
Aquí te muestro cómo puedes modificar tu código para lograr esto:
python from typing import Any from fastapi import FastAPI, HTTPException from pydantic import BaseModel app = FastAPI()
Define el modelo para el cuerpo de la solicitud
class GenericItem(BaseModel): field1: str field2: list = []Endpoint genérico que recibe el tipo y el cuerpo en la solicitud
@app.post("/answer/{type}") def handle_generic_answer(type: str, item: GenericItem): switcher = { 'aaaa': read_item_aaa, 'bbb': read_item_bbb, 'nothing': unrecognised_answer } func = switcher.get(type, unrecognised_answer) print('answer >> ' + type) func(item)Métodos para manejar diferentes tipos de elementos
def read_item_aaa(item: GenericItem): update_aaa(item) return {"type": "aaa", "result": "success"} def read_item_bbb(item: GenericItem): update_bbb(item) return {"type": "bbb", "result": "success"} def unrecognised_answer(type): print("unrecognised_answer") raise HTTPException(status_code=400, detail="answer type not found") return {}Modelos se definen así:
class ModelAAA(BaseModel): field1: str field2: list = [] class ModelBBB(BaseModel): field1: str field2: list = []Puedes añadir más modelos según sea necesario
Métodos de actualización específicos
def update_aaa(item: ModelAAA):Implementa la lógica para actualizar ModelAAA
pass def update_bbb(item: ModelBBB):Implementa la lógica para actualizar ModelBBB
passCon esta modificación, ahora tu endpoint genérico espera recibir un objeto JSON en el cuerpo de la solicitud que coincida con el modelo
GenericItem
. Asegúrate de enviar los datos requeridos en el cuerpo de tu solicitud POST cuando pruebes tus endpoints.Respondida el Dec 18, 2020 a las 22:09 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error
422 Unprocessable Entity
indica que la solicitud tiene un formato válido, pero no se puede procesar debido a un error en el cuerpo de la solicitud. En este caso, el problema es que FastAPI espera que el cuerpo de la solicitud coincida con el tipo deModelAAA
, pero estás enviando un cuerpo vacío.Para resolver este problema, puedes hacer que el parámetro
item
sea opcional y proporcionar un valor predeterminado. Aquí tienes un código actualizado:python @app.post("/answer/{type}") def handle_generic_answer(type: str, item: ModelAAA = None): ...
Al hacer que
item
sea opcional, FastAPI ya no esperará un cuerpo de solicitud. Si se proporciona un cuerpo de solicitud, FastAPI lo analizará y lo convertirá en una instancia deModelAAA
. Si no se proporciona un cuerpo de solicitud,item
seráNone
.Espero que esto resuelva tu problema. Déjame saber si tienes más preguntas.
Respondida el Dec 18, 2020 a las 22:20 - por Gemini
Votos positivos: 0 | Votos negativos: 0