Сообщить об ошибке.

Передача переменной NGINX в request.environ Flask

Если приложение Flask работает в связке WEB сервер NGINX + WSGI сервер (например gunicorn) то среда приложения request.environ уже содержит часто используемые (стандартные) переменные NGINX, такие как $remote_addr, $args и т.д.

Однако бывают ситуации, когда встает необходимость передать НЕСТАНДАРТНУЮ переменную WEB сервера NGINX в приложение Flask, что бы основываясь на ее значении принимать какие-то решения. Передачу пользовательской переменной NGINX в окружение request.environ фреймворка Flask разберем на примере подключения динамического модуля GeoIP2.

При сборке и подключении динамического модуля ngx_http_geoip2_module в основном файле конфигурации WEB сервера NGINX nginx.conf создается пользовательская переменная, например $country_iso_code (имя может быть любое):

# файл конфигурации `nginx.conf`
...

load_module modules/ngx_http_geoip2_module.so;

http {
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
       # $country_iso_code - НЕСТАНДАРТНАЯ переменная NGINX
       $country_iso_code country iso_code;
    }

    ...
    # другие параметры конфигурации сервера
}

В данном случае, пользовательская переменная $country_iso_code будет принимать значение кода страны в формате ISO в зависимости от IP-адреса посетителя сайта. На основе значения этой переменной, например, можно будет осуществить какую то локализацию приложения Flask.

Что бы передать значение переменной $country_iso_code в окружение приложения Flask необходимо ее проксировать в WSGI сервер. За проксирование переменных в NGINX отвечает файл proxy.conf. Добавим переменную GeoIP2 в эту конфигурацию.

# файл конфигурации `proxy.conf`
proxy_redirect                          off;
proxy_set_header Host                   $http_host;
proxy_set_header X-Real-IP              $remote_addr;
# переменная `$country_iso_code` передается  
# в HTTP заголовок с именем `X-ISO-Code`
proxy_set_header X-ISO-Code             $country_iso_code;
...
# Другие параметры конфигурации

Теперь эту переменную в приложении Flask можно считать двумя способами:

  1. Как HTTP-заголовок request.headers;
  2. Через окружение request.environ;

Например:

country_iso_code = request.headers.get('X-ISO-Code', 'RU')

# или

country_iso_code = request.environ.get('HTTP_X_ISO_CODE', 'RU')

Обратите внимание на извлечение пользовательской переменной NGINX через окружение request.environ. Можно заметить что при чтении заголовка, WSGI сервер изменил ее имя, дополнив префиксом HTTP_. Это стандартное поведение WSGI сервера.

Использовать можно следующим образом:

# в приложении Flask
country_iso_code = request.environ.get('HTTP_X_ISO_CODE', 'RU')
if country_iso_code in ['RU', 'BY']:
    # локализация для России и республики Беларусь
elif country_iso_code in ['US', 'GB']:
    # локализация на английском языке
else:
    # и т.д.