Быстрая загрузка файла API

#python-requests #fastapi #uvicorn #http-status-code-422

#python-запросы #fastapi #uvicorn #http-status-code-422

Вопрос:

Я пытаюсь загрузить данные JSON файл (двоичный) в конечную точку FastAPI ‘POST’ с помощью запросов.

Это код сервера:

 @app.post("/files/")
async def create_file(
    file: bytes = File(...), fileb: UploadFile = File(...), timestamp: str = Form(...)
):
    return {
        "file_size": len(file),
        "timestamp": timestamp,
        "fileb_content_type": fileb.content_type,
    }
 

Это клиентский код:

 session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=0)
session.mount('http://', adapter)

jpg_image = open(IMG_PATH, 'rb').read()

timestamp_str = datetime.datetime.now().isoformat()
files = {
    'timestamp': (None, timestamp_str),
    'file': ('image.jpg', jpg_image),
}
request = requests.Request('POST',
                           FILE_UPLOAD_ENDPOINT,
                           files=files)
prepared_request = request.prepare()
response = session.send(prepared_request)
 

Сервер выходит из строя с

«POST / files / HTTP / 1.1» 422 Необработанный объект

Комментарии:

1. Пожалуйста, добавьте тело ответа 422 в свой вопрос для ясности.

2. Для чего это стоит, ответ со статусом 422 приходит fastapi.exception_handlers.request_validation_exception_handler(req, exc) , если вы находитесь на стадии разработки, вы можете установить точку останова, а затем получить более подробную информацию об ошибке из exc (объект исключения), исключение должно описывать, что отсутствует поле fileb , что означает, что в вашем клиентском коде вы также должны указатьто же имя поля fileb в теле запроса

Ответ №1:

Конечные точки FastAPI обычно отвечают 422, когда в теле запроса отсутствует обязательное поле или имеются неожиданные поля и т. Д.

Кажется, что вам не хватает fileb в теле вашего запроса.

  • Если это поле является необязательным, вы должны объявить его следующим образом в определении конечной точки:
     fileb: Optional[UploadFile] = File(None)
     

    Вам также нужно будет выполнить некоторые проверки внутри вашего кода конечной точки…

  • Если это обязательное поле, вам нужно добавить его в тело вашего запроса.

Комментарии:

1. Спасибо @JohnMoutafis за ответ. Я исправил конечную точку в соответствии с запросом, и это сработало. Правильный код: @app.post("/files/", status_code=201) async def create_file( file: bytes = File(...), timestamp: str = Form(...), ):