Бажаєте оптимізувати керування налаштуваннями вашого програмного забезпечення? Розглянемо можливості роботи зі змінними оточення у Python.
Коли я вивчав Python, я створював різноманітні проєкти, щоб закріпити отримані знання. Значна частина цих проєктів передбачала підключення до баз даних та виконання запитів. Це означало, що мені потрібно було надійно зберігати параметри конфігурації бази даних, а також конфіденційну інформацію, таку як логіни та паролі.
Включення такої чутливої інформації безпосередньо в код Python було б невдалим рішенням. Тому я почав використовувати файли конфігурації та змінні оточення разом із вбудованими бібліотеками Python для роботи з ними.
Тепер, коли мені потрібна конфіденційна інформація, наприклад, паролі або ключі API, я зберігаю їх як змінні оточення та використовую їх у своїх програмах. У цій статті я розкажу про змінні оточення та як їх використовувати у Python.
Що таке змінні оточення?
Змінні оточення – це змінні, що знаходяться за межами вашої програми, в яких зберігається інформація про налаштування, параметри системи та інше. Зазвичай, вони контролюються операційною системою або середовищем, в якому виконується програма. Основні характеристики змінних оточення:
- Структура «ім’я-значення»: Змінні оточення складаються з імені (або ключа) та відповідного значення.
- Область видимості: Змінні оточення можна встановити на рівні операційної системи, що зробить їх доступними для всіх процесів. Також, їх можна змінити або визначити на рівні окремої програми, впливаючи лише на неї.
- Динамічність та мінливість: Змінні оточення можна змінювати під час виконання програми, що забезпечує гнучкість.
Переваги використання змінних оточення
Змінні оточення надають ряд переваг для управління конфігурацією та конфіденційною інформацією у ваших Python-програмах:
- Розділення відповідальності: Зберігаючи налаштування поза кодом, ви відокремлюєте конфігурацію від логіки програми.
- Безпека: Конфіденційні дані, такі як ключі API та облікові записи баз даних, можна зберігати у змінних оточення, не показуючи їх у вихідному коді. Це зменшує ризик їх розкриття.
- Гнучкість: Змінні оточення дозволяють легко оновлювати параметри конфігурації, оскільки зміни можна робити за межами коду. Це особливо корисно для розгортання програм у різних середовищах або при зміні облікових даних.
У наступних розділах статті ми розглянемо, як встановлювати, отримувати доступ та керувати змінними оточення у Python, а також як вони покращують керування налаштуваннями ваших проєктів.
Як встановити змінні оточення
Змінні оточення можна встановити через командний рядок. Однак, такі змінні будуть дійсні лише для поточного сеансу та не зберігаються після його завершення.
Для користувачів macOS або Linux, змінну оточення в поточному терміналі можна встановити наступним чином:
export MY_VARIABLE=my_value
Для користувачів Windows, тимчасово встановити змінну оточення можна так:
set MY_VARIABLE=my_value
Доступ до змінних оточення у Python
Python надає модуль os для роботи з функціями операційної системи. Словник `os.environ` містить змінні оточення. Ключами цього словника є імена змінних оточення, а їх значення – відповідні значення змінних.
Отже, доступ до значень змінних оточення можна отримати, використовуючи їх імена як ключі, як і при доступі до елементів словника.
Розглянемо кілька прикладів:
import os print(os.environ['HOME']) # Output: /home/balapriya
print(os.environ['USER']) # Output: balapriya
Все працює добре. Але що трапиться, якщо ви спробуєте отримати доступ до значення змінної оточення, яка не була встановлена?
Спробуємо отримати доступ до `API_KEY`, яку ми ще не встановили:
print(os.environ['API_KEY'])
Як і очікувалось, ви отримаєте помилку `KeyError`:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<frozen os>", line 679, in __getitem__ KeyError: 'API_KEY'
Обробка помилок KeyError
Ви можете обробити помилку `KeyError` таким чином:
import os try: api_key = os.environ['API_KEY'] print(f'API_KEY встановлено: {api_key}') except KeyError: print('API_KEY не встановлено. Будь ласка, налаштуйте її.')
Цей підхід запобігає раптовому завершенню програми у випадку виникнення винятку `KeyError`. Замість цього, він виводить інформативне повідомлення про помилку:
# Output API_KEY не встановлено. Будь ласка, налаштуйте її.
Отже, якщо програма не працює належним чином, ми розуміємо, що пропустили налаштування необхідної змінної оточення.
Доступ до змінних оточення за допомогою методу get()
Ви також можете використовувати метод `get()` словника, щоб отримати значення змінної оточення. Замість `KeyError`, метод `get()` поверне `None`, якщо змінна не знайдена.
При спробі отримати доступ до змінної `NOT_SET`, яка не встановлена, метод `get()` поверне `None`:
print(os.environ.get('NOT_SET')) # Output: None
Я вважаю за краще отримувати `KeyError`, якщо змінна оточення не встановлена. Це дозволяє нам явно обробляти цей випадок, замість того щоб мовчки працювати з `None`.
Однак, метод `get()` корисний, коли потрібно задати значення за замовчуванням для певної змінної оточення, якщо вона не встановлена.
Ось приклад:
print(os.environ.get('HOME','/home/user')) # Output: /home/balapriya
Як керувати налаштуваннями за допомогою змінних оточення
Розглянемо декілька практичних прикладів використання змінних оточення у наших програмах.
Приклад 1: Налаштування параметрів підключення до бази даних
Припустимо, ви хочете підключитися до бази даних PostgreSQL з Python. Для цього, ви можете встановити та використовувати конектор `psycopg2`:
pip install psycopg2
У цьому прикладі ми використовуємо змінні оточення для налаштування параметрів підключення до бази даних. Якщо змінні оточення не встановлені, ми використовуємо значення за замовчуванням.
import os import psycopg2 # Отримання конфігурації бази даних зі змінних оточення db_host = os.environ.get('DB_HOST', 'localhost') db_port = os.environ.get('DB_PORT', '5432') db_user = os.environ.get('DB_USER', 'myuser') db_password = os.environ.get('DB_PASSWORD', 'mypassword') # Встановлення з'єднання з базою даних try: connection = psycopg2.connect( host=db_host, port=db_port, user=db_user, password=db_password, database="mydb" ) print('Підключено до бази даних!') except Exception as e: print(f'Помилка підключення до бази даних: {e}')
Приклад 2: Керування ключами API
Розглянемо приклад використання ключів API.
Крім інтерфейсу ChatGPT, ви також можете використовувати OpenAI API для інтеграції моделей LLM у свої програми.
Після реєстрації облікового запису OpenAI ви, як правило, отримуєте певну кількість безкоштовних кредитів API, обмежених часом. Отримайте свій ключ API, перейшовши до Налаштувань > Переглянути ключі API.
Ви можете використовувати Python SDK Open AI та фреймворки, такі як LangChain, для створення програм. Для цього потрібно встановити бібліотеки (у віртуальному середовищі) за допомогою `pip`:
pip install openai pip install langchain
Ось як можна встановити `OPENAI_API_KEY` як змінну оточення:
import os os.environ["OPENAI_API_KEY"]='your-api-key'
Тепер ви можете використовувати Open AI LLM у вашому скрипті наступним чином:
from langchain.llms import OpenAI model=OpenAI(model_name="gpt-3.5-turbo")
Як змінити змінні оточення у Python
Ви можете використовувати словник `os.environ` з модуля `os`, щоб змінювати змінні оточення в поточному процесі Python:
import os # Зміна існуючої змінної оточення або створення нової os.environ['MY_VARIABLE'] = 'new_value'
У Python ви можете використовувати модуль `subprocess` для запуску підпроцесів з існуючого Python-скрипта. Це корисно, коли вам потрібно запускати системні команди в Python.
У наступному прикладі ми змінюємо змінну оточення `PATH`, маніпулюючи словником `os.environ`. Потім ми запускаємо `echo $PATH` як підпроцес:
import os import subprocess # Встановлення кастомної змінної оточення для підпроцесу os.environ['PATH'] = '/custom/path' # Запуск підпроцесу, який звертається до змінної оточення PATH result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE) output = result.stdout.decode() print(output) print(f'Вивід підпроцесу: {output}')
Ми бачимо, що PATH тепер має значення `/custom/path`:
# Output /custom/path
Область видимості змінених змінних оточення
Важливо зазначити, що зміни змінних оточення є тимчасовими і діють лише для поточного процесу Python. Після завершення скрипту зміни скасовуються:
- Поточний процес Python: Коли ви змінюєте змінну оточення за допомогою `os.environ` у вашому Python-скрипті, зміна є локальною для поточного процесу Python. Це не вплине на інші процеси або майбутні сеанси Python.
- Дочірні процеси: Зміни змінних оточення, внесені в поточному процесі Python, успадковуються дочірніми процесами, створеними вашим скриптом. Наприклад, якщо ви запускаєте підпроцес з вашого Python-скрипта (батьківського процесу), то дочірній процес матиме доступ до змінених змінних оточення (як показано в прикладі).
- Не є загальносистемними: Змінні оточення, встановлені в Python-скрипті, не будуть збережені за межами виконання цього скрипта.
Якщо вам потрібно зробити постійні зміни змінних оточення на рівні операційної системи, зазвичай необхідно використовувати методи, специфічні для вашої операційної системи.
Як завантажувати файли .env за допомогою python-dotenv
Бібліотека `python-dotenv` – популярний Python-пакет, що спрощує завантаження змінних оточення з файлу `.env` у ваш Python-проєкт. Це особливо корисно, коли у вас є декілька середовищ (наприклад, розробка, продакшн) з різними налаштуваннями, і ви хочете зберігати ці налаштування окремо від вихідного коду.
Встановлення python-dotenv
Для використання `python-dotenv`, спочатку потрібно його встановити. Це можна зробити за допомогою `pip`, менеджера пакетів Python, у віртуальному середовищі:
pip install python-dotenv
Завантаження змінних оточення з файлу .env
Тепер можна створити файл `.env` у кореневому каталозі вашого проєкту і заповнити його парами ключ-значення, як і звичайні змінні оточення. Створимо такий файл `.env` із тимчасовими значеннями:
API_KEY=your_api_key_here DB_PASSWORD=your_database_password_here
Тепер можна завантажити змінні оточення з файлу `.env`, використовуючи `python-dotenv`, наступним чином:
import os from dotenv import load_dotenv # Завантаження змінних оточення з файлу .env load_dotenv() # Доступ до змінних оточення api_key = os.getenv("API_KEY") database_password = os.getenv("DB_PASSWORD") # Вивід змінних оточення print(f"API Key: {api_key}") print(f"Database Password: {database_password}")
Зверніть увагу, що ми використовували `os.getenv(VARIABLE_NAME)` для отримання значень змінних оточення. Це також валідний (хоча і рідше використовуваний) спосіб доступу до змінних оточення.
Ось результат:
API Key: your-api-key-here Database Password: your-database-url-here
У цьому прикладі:
- Ми використовуємо `load_dotenv()` для завантаження змінних оточення, визначених у файлі `.env`, у поточне середовище.
- Потім ми використовуємо `os.getenv()` для доступу до змінних оточення: `API_KEY` та `DB_PASSWORD`.
Висновок
На цьому все! Сподіваюся, ви навчилися керувати налаштуваннями та конфіденційною інформацією за допомогою змінних оточення у Python-програмах. Ми розглянули основи налаштування та доступу до змінних оточення, а також їх практичне використання для конфігурації програм.
Хоча змінні оточення, безумовно, корисні для відокремлення конфігурації від вихідного коду, для використання у продакшені, конфіденційні змінні потрібно зберігати як секрети. Для керування секретами я рекомендую дослідити такі інструменти, як HashiCorp Vault або AWS Secrets Manager.