Загрузка python envvars без использования `source` - PullRequest
1 голос
/ 19 октября 2019

Я ищу решение для загрузки файла envvars.sh в приложении django. Я бы предпочел сделать это в модуле настроек и сохранить файл вне его. Вот что у меня сейчас есть:

SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

def source_envvars(fname='envvars.sh'):
    """Equivalent of `$ source {fname}` with lines in the form of `export key=value`"""
    envvars = os.path.join(SITE_ROOT, fname)
    if not os.path.exists(envvars): return
    with open(fname, 'r') as f:
        for line in f:
            if line.startswith('export '):
                line = line.strip()
                key = line.split('=')[0].split()[1]
                value = line.split('=')[1].strip('"\'')
                os.environ[key] = value


if not os.environ.get('DB_HOST'): source_envvars()
# rest of settings.py file...

Есть ли недостатки у этого подхода? Я знаю, что это не поддерживает сложные экспорты типа bash, но все, что у меня есть, это базовые экспорты в форме:

export DB_HOST=rds.amazon.com/12345

Правильно ли описан вышеупомянутый подход для создания всех переменных, или он отсутствует? что-то или небезопасно, так или иначе?

1 Ответ

1 голос
/ 19 октября 2019

Ваша реализация может обрабатывать только фиксированные форматы. Сценарий оболочки потенциально может иметь условные операторы и циклы и т. Д., Ни один из которых не может быть обработан должным образом без фактического использования его через оболочку.

Поэтому более надежный метод - использовать subprocess.check_output для запуска оболочкис . для источника envvars.sh и командой env для вывода переменных среды, выходные данные которых затем можно использовать для создания выражения генератора для обновления os.environ с помощью:

os.environ.update(
    line.rstrip().split('=', 1)
    for line in subprocess.check_output(['sh', '-c', '. envvars.sh; env']).splitlines()
)
...