Что такое WSGI и какую роль он играет в Python веб-приложениях

Ответ

WSGI (Web Server Gateway Interface) — это стандартный интерфейс, который определяет, как веб-сервер взаимодействует с Python-приложением. Его основная задача — отделить веб-сервер от веб-фреймворка, позволяя им работать вместе независимо от их реализации.

Зачем нужен WSGI?

Без WSGI разработчикам фреймворков (Django, Flask) пришлось бы писать код для интеграции с каждым веб-сервером (Nginx, Apache) в отдельности. WSGI предоставляет единый, стандартизированный контракт, который должны соблюдать обе стороны.

Схема работы

Запрос пользователя проходит по следующей цепочке:

Клиент <-> Веб-сервер (Nginx) <-> WSGI-сервер (Gunicorn) <-> Python-приложение (Flask/Django)

  • Веб-сервер (Nginx, Apache) принимает HTTP-запросы и часто отвечает за раздачу статики.
  • WSGI-сервер (Gunicorn, uWSGI) — это приложение, которое реализует стандарт WSGI. Оно получает запрос от веб-сервера и преобразует его в формат, понятный Python-приложению.
  • Python-приложение обрабатывает запрос и возвращает ответ через WSGI-сервер.

Спецификация WSGI

Стандарт определяет, что Python-приложение должно быть вызываемым объектом (callable), который принимает два аргумента:

  1. environ: Словарь, содержащий переменные окружения и детали HTTP-запроса (путь, заголовки, метод и т.д.).
  2. start_response: Функция, которую приложение должно вызвать для отправки HTTP-статуса и заголовков ответа.

Приложение должно вернуть итерируемый объект с телом ответа.

Пример простого WSGI-приложения

def application(environ, start_response):
    """
    Простейшее приложение, соответствующее спецификации WSGI.
    """
    # Получаем путь из запроса
    path = environ.get('PATH_INFO', '/')

    # Формируем тело ответа в байтах
    response_body = f'Hello, WSGI! You requested the path: {path}'.encode('utf-8')

    # Устанавливаем HTTP-статус и заголовки
    status = '200 OK'
    headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(response_body)))
    ]

    # Вызываем start_response
    start_response(status, headers)

    # Возвращаем тело ответа
    return [response_body]

# Этот файл можно запустить с помощью Gunicorn:
# gunicorn my_app:application

Популярные WSGI-серверы: Gunicorn, uWSGI, Waitress.