Перейти к основному содержимому

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: []