Что такое WSGI и каково его назначение в Python?

Ответ

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

Ключевые задачи, которые решает WSGI:

  • Портативность: Приложение, написанное с соблюдением стандарта WSGI, может работать с любым WSGI-совместимым сервером (Gunicorn, uWSGI, mod_wsgi) без изменений в коде.
  • Разделение ответственности: Веб-сервер (например, Nginx) отвечает за обработку сетевых соединений, а WSGI-сервер — за управление процессами Python и передачу им запросов.
  • Простота: Стандарт определяет простой callable объект (функцию или класс) в качестве точки входа в приложение.

Схема работы: Клиент <-> Веб-сервер (Nginx) <-> WSGI-сервер (Gunicorn) <-> Python-приложение (Django, Flask)

Пример минимального WSGI-приложения:

# Это приложение может быть запущено любым WSGI-сервером
def application(environ, start_response):
    # environ: словарь с переменными запроса
    # start_response: функция для отправки HTTP-статуса и заголовков
    status = '200 OK'
    headers = [('Content-Type', 'text/plain')]
    start_response(status, headers)
    return [b'Hello, WSGI!']

Современным асинхронным преемником WSGI является ASGI (Asynchronous Server Gateway Interface), предназначенный для работы с asyncio.

Ответ 18+ 🔞

Вот, слушай, про эту вашу WSGI. Сидишь ты такой, пишешь на Python, и думаешь: "Ну какого хуя мой код не запускается на сервере?" А всё потому, что сервер — он тупой как пробка, блядь. Он не знает, как с твоим приложением разговаривать. Вот тут-то и вылезает, как чёрт из табакерки, этот самый WSGI (Web Server Gateway Interface).

Если по-простому, то это такой договор, пиздец какой важный, между твоим кодом и сервером. Договор о том, как они будут друг другу пачки с запросами и ответами передавать. Без него — анархия, бардак и ничего не работает.

А зачем он вообще нужен, эта WSGI? Да чтобы голова не болела, вот зачем!

  • Портативность, ёпта! Написал ты приложение по этим правилам — и тебе уже похуй, на каком сервере его запускать. Хоть на Gunicorn, хоть на uWSGI, хоть на чёрте лысом. Оно везде побежит, как миленькое. Не надо под каждый сервер код переписывать, вот это да.
  • Разделение труда, блядь. Пусть каждый занимается своим делом. Nginx, например, пусть с браузерами общается, соединения принимает, статику раздаёт — он это быстро делает. А WSGI-сервер (тот же Gunicorn) — это уже такой спец по Python. Он процессы эти твои порождает, следит, чтобы они не сдохли, и кормиет их запросами. Красота!
  • Простота до безобразия. Всё, что от тебя хотят — сделать одну хуёвую функцию (или класс), которая будет принимать два параметра. И всё! Больше нихуя.

Как это всё, блядь, работает, схематично:

Твой браузер (олень) <-> Веб-сервер (Nginx, сторожевой пёс) <-> WSGI-сервер (Gunicorn, переводчик) <-> Твоё приложение (Python-код, который ты написал)

Переводчик (WSGI) берёт лай сторожевого пса (HTTP-запрос), переводит его на человеческий Python-язык, отдаёт тебе. Ты что-то там посчитал, написал ответ. Переводчик берёт твой ответ, переводит обратно на собачий и отдаёт псу, чтобы тот отнёс его оленю. Идеально.

Вот, смотри, самый простой пример приложения, которое понимает этот договор:

# Эта функция — и есть твоё веб-приложение по стандарту WSGI.
# Любой совместимый сервер умеет с ней работать.
def application(environ, start_response):
    # environ — это такой здоровенный словарь, куда сервер свалил всю хуйню про запрос:
    # какой URL, какие заголовки, метод (GET/POST) и прочее. Прямо пиздец сколько всего.
    # start_response — это функция, которую ТЫ должен вызвать, чтобы сказать серверу:
    # "Э, слушай, статус ответа вот такой, заголовки вот такие, готовься принимать тело!"

    status = '200 OK'  # Всё хорошо, мудила!
    headers = [('Content-Type', 'text/plain')]  # Отвечаем простым текстом.
    start_response(status, headers)  # Кричим серверу: "Внимание, отвечаю!"

    # А возвращаем мы тело ответа. ОБЯЗАТЕЛЬНО как список байтовых строк, блядь!
    return [b'Hello, WSGI! Наконец-то ты заработал, сука!']

Вот и вся магия. Правда, сейчас все умные на ASGI переходят, потому что он асинхронный и для современных штук вроде WebSocket'ов подходит лучше. Но WSGI — это классика, ёпта, основа основ. Без неё никуда.