При чтении переменных среды в Python из аргумента Docker --env-file к каждому '\n' добавляется символ '\'. Как не иметь этого лишнего '\'?

Я занимаюсь контейнеризацией своего приложения Python. Обычно я загружаю свой файл .env и использую dotenv для чтения переменной.

Пример:

from dotenv import load_dotenv
import os


def test_env():
    load_dotenv()
    print(f"private_key : {repr(os.environ.get('PRIVATE_KEY'))}")


if __name__ == '__main__':
    test_env()

и в моем файле .env мне нужно было бы заключить переменную в кавычки, чтобы это тоже работало. Пример:

PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n.....=\n-----END PRIVATE KEY-----\n"

Это правильно распечатывается в моем приложении Python.

Однако, когда я запускаю тот же код, но с использованием Docker --env-file, к каждому \ добавляется дополнительный \n.

Пример команды докера:

docker run --env-file ./.env -d -p $(RUN_PORT):$(RUN_PORT) --name $(DOCKER_CONTAINER_NAME) $(FULL_IMG_NAME)

Результат выглядит так: '-----BEGIN PRIVATE KEY-----\\n...=\\n-----END PRIVATE KEY-----\\n' Это независимо от того, содержит ли файл .env "" вокруг переменной или нет. Все, что "" делает с переменной, - это ее литерал, чего нет в случае с dotenv.

Что должно быть сделано?

Проблема не столько в добавлении обратной косой черты, сколько в том, что \n преобразуется в символ новой строки при использовании dotenv. Файл среды Docker этого не делает, поэтому переменная среды содержит два символа: обратную косую черту и букву «n». И когда ваша программа Python печатает это, она добавляет дополнительную обратную косую черту, чтобы избежать обратной косой черты. Чтобы это исправить, вы можете заменить \n символом новой строки при чтении переменной среды.

Hans Kilian 10.04.2024 17:11
dotenv больше не используется, так как файла .env нет. Docker вводит переменные env непосредственно в программу. Когда я печатаю с помощью os.environ.get(), я получаю дополнительный символ.
mike_gundy123 10.04.2024 17:40

Разница в том, что dotenv интерпретирует \n и заменяет его на символ новой строки. os.environ.get нет, поэтому он возвращает \n в виде двух символов. Затем, когда вы его печатаете, repr убирает обратную косую черту и добавляет дополнительную обратную косую черту.

Hans Kilian 10.04.2024 20:14

Хорошо, думаю, теперь я понял. Мне нужно обновить переменную .env и заменить /n символом новой строки? Под символом новой строки вы подразумеваете буквально новую строку в моей переменной в файле .env?

mike_gundy123 10.04.2024 21:55

Я попытался поместить символы новой строки в файл среды, но не смог заставить его работать. Я думаю, что лучшее решение — позволить Python обрабатывать escape-символы. Я опубликовал ответ, показывающий, как это сделать.

Hans Kilian 11.04.2024 09:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

dotenv обрабатывает текст и декодирует escape-последовательности. Таким образом, он заменяет \n символом новой строки.

os.environ.get нет, поэтому ваша строка содержит два символа: обратную косую черту и 'n'. Затем функция repr экранирует обратную косую черту при ее печати, поэтому вы получаете двойную обратную косую черту, которую видите.

Вы можете самостоятельно обрабатывать escape-последовательности в Python, используя такую ​​функцию decode:

import os

def test_env():
    private_key = bytes(os.environ.get('PRIVATE_KEY'), "utf-8").decode("unicode_escape")
    print(f"private_key : {repr(private_key)}")

if __name__ == '__main__':
    test_env()

Это должно прочитать закрытый ключ из переменной среды и изменить \n на новую строку, как вы привыкли dotenv делать.

Черт, так мне придется сделать это для каждой переменной среды, чтобы убедиться, что у меня нет экранирующих символов? Попробую, спасибо!

mike_gundy123 11.04.2024 15:28

Другие вопросы по теме