dot_env_files
Environment variables provide a great way to configure your Python application, eliminating the need to edit your source code when the configuration changes. Common configuration items that are often passed to application through environment variables are third-party API keys, network ports, database servers, and any custom options that your application may need to work properly.
In this article I’m going to share some of the techniques and tools available in Python to work with environment variables.
How to access environment variables from Python
Использование словаря os.environ
В Python os.environ
словарь содержит все переменные среды. Самый простой способ извлечь переменную из приложения-использовать стандартный синтаксис словаря. Например, таким образом можно получить доступ к переменной среды с именемUSER
:
>>> import os
>>> user = os.environ['USER']
>>> user
'miguel'
Используя этот метод, если вы попытаетесь импортировать переменную среды, которой не существует, Python вызовет KeyError
исключение:
>>> database_url = os.environ['DATABASE_URL']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/miguel/.pyenv/versions/3.8.6/lib/python3.8/os.py", line 675, in __getitem__
raise KeyError(key) from None
KeyError: 'DATABASE_URL'
Использование os.environ.get()
Получение KeyError
этого-хорошая идея для переменных среды, которые требуются вашей программе, но есть ситуации, когда вы можете захотеть, чтобы некоторые переменные были необязательными. Чтобы избежать ошибки, вы можете использовать метод словаряget()
, который возвращаетNone
, когда запрошенный ключ не существует в словаре:
>>> database_url = os.environ.get('DATABASE_URL')
Добавление значения по умолчанию, если переменная не определена
Если вы хотите указать значение по умолчанию для отсутствующей переменной , которой нетNone
, вы можете добавить его в качестве второго аргумента:
>>> database_url = os.environ.get('DATABASE_URL', 'sqlite:///')
>>> database_url
'sqlite:///'
Использование функции os.getenv()
Python также предоставляет os.getenv()
функцию для доступа к переменным среды. Эта функция работает очень похоже на os.environ.get()
метод. Вот как получить доступ к переменной с ее помощью:
>>> user = os.getenv('USER')
>>> user
'miguel'
Эта функция не выдает ошибку для отсутствующих переменных, она возвращает None
точно так же, как os.environ.get()
. И он также принимает второй аргумент с пользовательским значением по умолчанию:
>>> database_url = os.getenv('DATABASE_URL', 'sqlite://')
>>> database_url
'sqlite://'
Это os.getenv()
лучше, чем os.environ
? Это действительно зависит от вас. Лично я предпочитаю использовать os.environ
словарь, так как он дает мне возможность остановить программу с помощью aKeyError
, если отсутствует требуемая переменная.
Как задать переменные среды
В этом разделе я дам вам краткое описание того, как задать переменные среды в терминале или окне командной строки. Если вы хотите знать все возможные способы установки переменных среды, мой коллега Доминик Кундель написал очень подробный пост в блоге на эту тему под названием "Как установить переменные среды".
Unix и macOS
Существует два основных способа установки переменной среды из сеанса терминала bash или zsh. Один из них использует export
ключевое слово:
Переменная, заданная таким образом, будет передана в любые программы или сценарии, которые вы запустите из этого терминального сеанса. Имейте в виду, что переменные среды нигде не сохраняются вне контекста сеанса оболочки, поэтому они исчезнут, когда вы закроете сеанс терминала.
Альтернативный способ определения переменной среды-установить ее в той же строке, в которой выполняется целевое приложение:
DEBUG=true python my_cool_application.py
Эта вторая форма имеет то преимущество, что переменная устанавливается только в пространстве среды предполагаемого приложения.
Microsoft Windows
Если вы используете Windows, у вас есть несколько вариантов. Если вы заинтересованы в настройке переменных среды с помощью панели управления, см. статью, приведенную выше.
Если вы находитесь в окне командной строки, вы можете задать переменную среды с помощью set
команды:
Как и в случае с Unix, переменная не сохраняется и не запоминается после текущего сеанса.
Если вы используете более новую консоль PowerShell, синтаксис для настройки переменных среды совершенно другой:
Наконец, если вы используете уровень совместимости с Unix, такой как WSL или Cygwin, вам необходимо перейти в раздел Unix выше и использовать любой из перечисленных там методов для bash или zsh.
Использование файлов .env
Вас смущают все различные способы установки переменных среды? Лично я нахожу неудобным, что для каждой платформы или оболочки требуется отдельная процедура.
По моему мнению, лучший способ управлять переменными среды-это хранить их в файле .env (произносится как точка env). Файл .env-это текстовый файл, в котором определены переменные, по одной на строку. Формат файла .env абсолютно одинаков во всех операционных системах, поэтому файлы .env делают работу с переменными среды единообразной для всех платформ. И как будто этого недостаточно, наличие переменных среды, записанных в файл, который автоматически импортируется Python, означает, что вам не нужно вручную устанавливать их каждый раз, когда вы запускаете новую оболочку.
Вот краткий пример файла .env с двумя переменными:
DEBUG=true
DATABASE_URL=sqlite:///mydb.sqlite
Вы можете создать файл .env в корневом каталоге каждого из ваших проектов, и таким образом вы сможете аккуратно упорядочить все переменные, необходимые для каждого проекта!
Пакет python-dotenv позволяет приложению Python импортировать переменные, определенные в файле .env, в среду. Вы можете установить python-dotenv
в своей виртуальной среде с помощьюpip
:
pip install python-dotenv
Ниже вы можете увидеть, как импортировать файл .env в приложение Python:
>>> from dotenv import load_dotenv
>>> load_dotenv()
load_dotenv()
Функция будет искать файл с именем .env в текущем каталоге и добавит все определения переменных в нем в os.environ
словарь. Если файл .env не найден в текущем каталоге, то его ищут в родительском каталоге. Поиск продолжается вверх по иерархии каталогов, пока не будет найден файл .env или не будет достигнут каталог верхнего уровня.
Если вы хотите запретить python-dotenv искать файл .env в ваших каталогах, вы можете передать явный путь к вашему файлу в качестве аргумента дляload_dotenv()
:
>>> from dotenv import load_dotenv
>>> load_dotenv('/home/miguel/my_project/.env')
Есть некоторые дополнительные аргументы, которые можно использовать при вызове load_dotenv()
функции. Если вы хотите узнать о них, ознакомьтесь с документацией.
Как только файл _._env будет импортирован, вы сможете получить доступ к переменным среды, используя любой из методов, показанных выше.
Примечание о безопасности файлов .env
Во многих случаях вы будете добавлять переменные среды, содержащие конфиденциальную информацию, в ваши файлы .env, например пароли или ключи API. По этой причине, как правило, вы не хотите добавлять эти файлы в репозиторий системы управления версиями вашего проекта.
Стандартная практика заключается в добавлении исключения для файлов с этим именем, чтобы они не были по ошибке переданы в систему управления версиями. Для git вы можете добавить строку с именем файла в файл _._gitignore в корневом каталоге вашего репозитория.
Но если вы не можете зафиксировать файл ._env, как вы сообщаете пользователям проекта, какие переменные необходимо установить? Для этого вы можете добавить файл example .env в свой репозиторий с таким именем, как .env.example_, который содержит список переменных, необходимых для проекта, но без включения их значений. Это служит руководством для пользователей вашего проекта, не разглашая конфиденциальную информацию.
Вывод
Я надеюсь, что эта статья была полезна, чтобы помочь вам понять, как использовать переменные среды для настройки ваших проектов на Python.
Есть ли у вас какие-либо другие способы работы с переменными среды? Я бы хотел знать!
Мигель Гринберг__-разработчик Python для технического контента в Twilio. Свяжитесь с ним по адресу mgrinberg [at] twilio [точка] com__, если у вас есть классный проект на Python, которым вы хотели бы поделиться в этом блоге!
###### tags: []