Я работала над созданием модуля BI, в основе которого использование Apache Superset для расчета и демонстрации различных метрик. Планировалось использовать дашборды в общем интерфейсе приложения целиком, просто встроив их в интерфейс, а настройки для создания метрик и прочего спрятать в общую админку. Соответственно, появилась необходимость локализовать интерфейс Superset’а.
Готового решения найти не удалось, поэтому пришлось разбираться самостоятельно.
Сразу оговорюсь, речь пойдет о версии 6.1.0 с расширением dev, в которое включены библиотеки для работы с другими БД, помимо SQLite. В репозитории с исходным кодом есть ветка с информацией о релизах.
Для разворачивания я использую Docker.
Проблема частичной локализации
Если вы пытались перевести суперсет на другой язык, то наверняка сталкивались с проблемой частичной локализации интерфейса.
Итак, на пути к переводу интерфейса первое действие - изменить конфигурационный файл. Он позволяет нам указать перечень доступных для использования языков и выбрать язык по умолчанию.
Таким образом, в файле pythonpath/superset_config.py мы указываем значения для двух переменных:
LANGUAGES = { 'ru': {'flag': 'ru', 'name': 'Russian'}, 'en': {'flag': 'us', 'name': 'English'}, } BABEL_DEFAULT_LOCALE = 'ru'
В результате в интерфейсе рядом с настройками появляется кнопка переключения языка с тем количеством языков, которое вы указали. Однако тут будет переведена всего лишь часть настроек. Выглядит это так:

Причины и исправления
Дело в том, что в image по умолчанию не включены скомпилированные локализационные файлы для разных языков, хотя сами файлы с переводом представлены. Таким образом, первой задачей по исправлению будет компиляция файла.
Кроме того, в Superset используются две независимые системы локализации:
Backend (Python, Babel, .mo файлы)
Frontend (JavaScript, JSON словари)
Выполним локализацию в два этапа:
Подготовим скомпилированные файлы перевода для python
Запустим скрипт, который составит словарь для JS
Далее будет необходимость добавлять файлы в image и выполнять команды над ними. Один из удобных вариантов решения в данном случае - создание собственного image на основе официального с добавлением необходимых файлов, библиотек и выполнением действий.
Компиляция файла перевода
Начнем с компиляции файлов локализации. Они располагаются в папке superset/translations
Проверьте состав папки:
файл
messages.potявляется шаблоном для файлов локализации, он должен быть в корне папки. Его трогать нет необходимости.в папках с
<язык>/LC_MESSAGESхранятся файлы с расширением.po, в каждом файле.poесть перевод строк интерфейса для соответствующего языка. Он представляет собой заполненный словарь.

Если чего-то из этого у вас недостает, советую заглянуть в официальный репозиторий superset: https://github.com/apache/superset
Итак, мы подобрались к первой причине нашей проблемы. В папке не хватает скомпилированного файла .mo, это наш словарь, но уже для машины. Мы получаем его из файла messages.po с помощью библиотеки Babel. Я выполняла эту компиляцию локально, не в docker-контейнере.
python -m babel.messages.frontend compile -d <Абсолютный путь к папке>/translations
Теперь, когда мы располагаем .mo файлом, большая часть интерфейса для нас переведена.

На данном этапе Dockerfile будет выглядеть так, вам необходимо заново собрать image, чтобы проверить это:
FROM apache/superset:6.1.0rc1-dev USER root RUN apt-get update && apt-get install -y \ curl \ gnupg \ ca-certificates \ && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/* COPY ./<Относительный путь к файлу>/superset_config.py /app/pythonpath/superset_config.py COPY <Относительный путь к файлу>/ru /app/superset/translations/ru USER superset
Создание словаря для перевода фронта
Часть интерфейса, которая переводится python, теперь располагает скомпилированным файлом локализации.
Другая же часть переводится JS. Для этого ей нужно составить собственный словарь так же на основе .po файла. Вам нужно запустить скрипт, который этот словарь составит superset/superset-frontend/scripts/po2json.sh. Для этого вам может понадобиться добавить скрипт в image, прежде чем его выполнить.
В Dockerfile добавляем следующие команды:
COPY ./<Относительный путь к папке scripts/po2json.sh> /app/superset-frontend RUN cd /app/superset-frontend && \ npm install --legacy-peer-deps && \ npm run build-translation
Теперь переведен весь интерфейс:

Развертывание
В результате Dockerfile будет выглядеть следующим образом:
FROM apache/superset:6.1.0rc1-dev USER root RUN apt-get update && apt-get install -y \ curl \ gnupg \ ca-certificates \ && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/* COPY ./<Относительный путь к файлу>/superset_config.py /app/pythonpath/superset_config.py COPY <Относительный путь к файлу>/ru /app/superset/translations/ru COPY ./<Относительный путь к папке scripts/po2json.sh> /app/superset-frontend RUN cd /app/superset-frontend && \ npm install --legacy-peer-deps && \ npm run build-translation USER superset
Обратите внимание, сначала мы используем пользователя root, это дает нам право на установку утилит, а в конце снова переходим на пользователя superset.
Пояснение по установленным утилитам:
curlиспользуется для загрузки внешних скриптов и файлов по HTTP. В данном случае — для скачивания установочного скрипта Node.js.gnupgнеобходим для работы с GPG-ключами. Используется при добавлении внешних репозиториев (например, NodeSource), чтобы проверять их подлинность.ca-certificates- набор корневых сертификатов, обеспечивающий корректную работу HTTPS. Без них curl не сможет безопасно скачивать файлы.nodejsнеобходим для сборки фронтенда Apache Superset, включая компиляцию переводов (npm run build-translation).
После установки утилит мы копируем файл конфиг, затем папку со скомпилированным переводом, затем файл со скриптом, создающим словарь для JS.
После того, как мы все скопировали, запускаем скрипт, создающий словарь. Image готов!
Теперь переключим внимание на docker-compose.yml. По умолчанию Superset использует БД SQLite и внутренние инструменты кеширования. Подключим его вместо этого к PostgreSQL и Redis.
Для начала нам надо обозначить эти два сервиса в нашем docker-compose.yml.
redis: image: redis:7 container_name: redis restart: until-stopped networks: - app-network
Мы задаем сеть, внутри которой будут доступны контейнеры, и, поскольку нам не нужен доступ извне, не добавляем порты.
db: image: postgres:15 restart: always env_file: .env volumes: - pgdata:/var/lib/postgresql/data networks: - app-network
При создании контейнера БД удобно добавить файл .env с основными настройами: название бд, пользователь, пароль
POSTGRES_USER=postgres POSTGRES_PASSWORD=secret POSTGRES_DB=superset
Для подключения superset к новым сервисам нам нужно всего лишь расширить superset_config.py, добавив туда следующие переменные:
REDIS_URL = "redis://redis:6379/0" RATELIMIT_STORAGE_URI = REDIS_URL SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://postgres:secret@db:5432/superset"
Сам superset мы пробрасываем наружу, не забывая при этом, что контенер должен быть в той же сети, что и остальные два, чтобы он мог к ним обращаться. В файле ./superset/.env нам нужно сохранить всего лишь одну переменную SUPERSET_SECRET_KEY - это просто случайно сгенерированная строка. Ее можно создать любым удобным способом, например, через openssl.
superset: build: context: . dockerfile: superset/Dockerfile depends_on: - db - redis env_file: - ./superset/.env ports: - "8088:8088" restart: always networks: - app-network volumes: pgdata: networks: app-network: driver: bridge
После того, как вы подготовили image в Dockerfile и контейнеры в docker-compose, надо выполнить две команды сборки и запуска:
docker-compose build docker-compose up -d