Sobes.tech
Junior
97
questionbank

Как получить тело запроса в Python?

Ответ от нейросети

sobes.tech AI

В Python получить тело запроса можно различными способами, в зависимости от используемого веб-фреймворка.

Flask:

from flask import Flask, request

app = Flask(__name__)

@app.route('/my_endpoint', methods=['POST'])
def handle_post():
    # Получить тело запроса в виде байтов
    raw_body = request.data

    # Получить тело запроса в виде словаря (для JSON)
    try:
        json_body = request.get_json() # или request.json
    except:
        json_body = None # Обработка ошибки, если не JSON

    # Получить данные формы
    form_data = request.form # ImmutableMultiDict

    return "OK", 200

if __name__ == '__main__':
    app.run()
  • request.data: Получает необработанное тело запроса в байтах. Полезно, когда тип контента неизвестен или не является обычными форматами.
  • request.get_json(): Пытается разобрать тело запроса как JSON и вернуть его в виде словаря Python. Может принимать аргументы, например, для строгой проверки типа контента.
  • request.json: Аналогичен request.get_json(), но вернет None, если тело не является корректным JSON.
  • request.form: Получает данные из тела запроса, если тип contеnt-type равен application/x-www-form-urlencoded или multipart/form-data.

Django:

from django.http import HttpResponse
import json

def my_view(request):
    if request.method == 'POST':
        # Получить тело запроса в виде байтов
        raw_body = request.body

        # Получить тело запроса в виде словаря (для JSON)
        try:
            json_body = json.loads(raw_body)
        except:
            json_body = None # Обработка ошибки, если не JSON

        # Данные формы обрабатываются по-другому (в request.POST)
        form_data = request.POST # QueryDict

        return HttpResponse("OK")

    return HttpResponse("Method not allowed", status=405)
  • request.body: Получает необработанное тело запроса в байтах.
  • Для JSON необходимо вручную десериализовать байты, используя json.loads().
  • request.POST: Получает данные из тела запроса, если тип content-type равен application/x-www-form-urlencoded или multipart/form-data.

FastAPI:

from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/my_endpoint")
async def handle_post(request: Request):
    # Получить тело запроса в виде байтов (async)
    raw_body = await request.body()

    # Получить тело запроса в виде словаря (для JSON) (async)
    try:
        json_body = await request.json()
    except:
        json_body = None # Обработка ошибки, если не JSON

    # Получить данные формы (async)
    form_data = await request.form() # FormData

    return {"status": "OK"}
  • await request.body(): Асинхронно получает необработанное тело запроса.
  • await request.json(): Асинхронно пытается разобрать тело запроса как JSON.
  • await request.form(): Асинхронно получает данные формы.

Общий подход (независимо от фреймворка, например, в WSGI приложениях):

# Пример для WSGI приложения
def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])

    try:
        content_length = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        content_length = 0

    # Чтение тела запроса из входного потока
    raw_body = environ['wsgi.input'].read(content_length)

    # Для JSON можно десериализовать raw_body
    # json_body = json.loads(raw_body)

    return [raw_body]

В WSGI приложениях тело запроса доступно через файл-подобный объект environ['wsgi.input']. Необходимо получить размер тела из заголовка CONTENT_LENGTH.