Zmienne środowiskowe Pythona i jak z nimi pracować

Chcesz lepiej zarządzać swoją konfiguracją? Dowiedz się, jak pracować ze zmiennymi środowiskowymi w Pythonie.

Kiedy uczyłem się języka Python, tworzyłem projekty, w których stosowałem to, czego się właśnie nauczyłem. Podzbiór czynności związanych z łączeniem się z bazą danych i wysyłaniem do niej zapytań za pomocą języka Python. Oznaczało to, że musiałem przechowywać konfigurację bazy danych i poufne informacje, takie jak nazwa użytkownika i hasło, w celu uwierzytelnienia.

Twarde kodowanie tak wrażliwych informacji w skrypcie Pythona nie było dobrym pomysłem. Nauczyłem się także, jak używać plików konfiguracyjnych i zmiennych środowiskowych — a także wbudowanych modułów Pythona do pracy z nimi.

Dlatego zawsze, gdy muszę użyć w moich aplikacjach poufnych informacji, takich jak hasła i klucze API, ustawiam je jako zmienne środowiskowe i pobieram je w razie potrzeby. W tym samouczku przeprowadzę Cię przez zmienne środowiskowe i sposoby pracy z nimi w Pythonie.

Czym są zmienne środowiskowe?

Zmienne środowiskowe to zmienne zewnętrzne w stosunku do aplikacji, które przechowują informacje konfiguracyjne, ustawienia systemowe i tym podobne. Zazwyczaj zarządza nimi system operacyjny lub środowisko aplikacji. Kluczowe cechy zmiennych środowiskowych obejmują:

  • Pary nazwa-wartość: Zmienne środowiskowe składają się z nazwy (znanej również jako klucz) i odpowiadającej jej wartości.
  • Zakres systemu: Możesz ustawić zmienne środowiskowe na poziomie systemu, dzięki czemu będą one dostępne dla wszystkich procesów uruchomionych w systemie. W razie potrzeby możesz je także modyfikować lub definiować na poziomie aplikacji, wpływając tylko na tę konkretną aplikację.
  • Dynamiczny i zmienny: możesz modyfikować zmienne środowiskowe w czasie wykonywania, zapewniając elastyczność.

Jak zmienne środowiskowe są pomocne

Zmienne środowiskowe oferują kilka korzyści w zakresie zarządzania konfiguracją i poufnymi informacjami w aplikacjach Pythona:

  • Oddzielenie problemów: przechowując konfigurację poza kodem, oddzielasz problemy związane z zarządzaniem konfiguracją od logiki aplikacji.
  • Bezpieczeństwo: możesz przechowywać wrażliwe dane, takie jak klucze API i poświadczenia bazy danych, w zmiennych środowiskowych – bez ujawniania ich w kodzie źródłowym – zmniejszając ryzyko ujawnienia.
  • Elastyczność: dzięki zmiennym środowiskowym aktualizacja ustawień konfiguracyjnych jest prosta, ponieważ możesz aktualizować/wprowadzać zmiany poza bazą kodu. Zmienne środowiskowe umożliwiają dostosowanie ustawień konfiguracyjnych bez modyfikowania kodu. Ta elastyczność jest szczególnie przydatna przy wdrażaniu aplikacji w różnych środowiskach lub podczas aktualizowania poświadczeń.

W kolejnych sekcjach tego samouczka omówimy, jak ustawiać zmienne środowiskowe, uzyskiwać do nich dostęp i zarządzać nimi w języku Python oraz jak usprawniają one zarządzanie konfiguracją w projektach.

Jak ustawić zmienne środowiskowe

Zmienne środowiskowe można ustawić za pomocą wiersza poleceń. Zakres takich zmiennych środowiskowych dotyczy tylko bieżącej sesji i nie są one zachowywane poza bieżącą sesją.

Jeśli korzystasz z komputera Mac lub Linux, możesz ustawić zmienną środowiskową w bieżącej sesji terminala w następujący sposób:

export MY_VARIABLE=my_value

Jeśli jesteś użytkownikiem systemu Windows, możesz tymczasowo ustawić zmienną środowiskową, jak pokazano:

set MY_VARIABLE=my_value

Uzyskaj dostęp do zmiennych środowiskowych w Pythonie

Python udostępnia moduł systemu operacyjnego dla funkcjonalności związanych z systemem operacyjnym. A os.environ to słownik zmiennych środowiskowych. Nazwy zmiennych środowiskowych i ich wartości są odpowiednio kluczami i wartościami słownika.

Można zatem uzyskać dostęp do wartości zmiennych środowiskowych — używając (ich nazw jako) kluczy — w taki sam sposób, w jaki uzyskuje się dostęp do elementów słownika.

Oto kilka przykładów:

import os
print(os.environ['HOME'])
# Output: /home/balapriya
print(os.environ['USER'])
# Output: balapriya

Jak na razie dobrze. Ale co się stanie, jeśli spróbujesz uzyskać dostęp do wartości zmiennej środowiskowej, która nigdy nie została ustawiona?

Spróbujmy uzyskać dostęp do API_KEY, którego jeszcze nie ustawiliśmy:

print(os.environ['API_KEY'])

Zgodnie z oczekiwaniami otrzymasz KeyError:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<frozen os>", line 679, in __getitem__
KeyError: 'API_KEY'

Obsługa kluczowych błędów

Możesz obsłużyć KeyError, jak pokazano:

import os

try:
	api_key = os.environ['API_KEY']
	print(f'API_KEY is set to: {api_key}')
except KeyError:
	print('API_KEY is not set. Please configure it.')

Takie podejście nie powoduje nagłego zatrzymania wykonywania programu po zgłoszeniu wyjątku KeyError. Wyświetla jednak opisowy komunikat o błędzie:

# Output
API_KEY is not set. Please configure it.

Kiedy więc reszta programu nie wykonuje się zgodnie z oczekiwaniami, wiemy, że przegapiliśmy ustawienie wymaganej zmiennej środowiskowej.

Dostęp do zmiennych środowiskowych za pomocą metody get().

Aby uzyskać wartość zmiennej środowiskowej, możesz użyć metody słownikowej get(). Zamiast KeyError metoda get() zwraca None, jeśli zmienna nie zostanie znaleziona.

Dostęp do zmiennej NOT_SET, której nie ustawiliśmy, zwraca Brak:

print(os.environ.get('NOT_SET'))
# Output: None

Wolę zgłaszać błąd klucza, gdy zmienna środowiskowa nie jest ustawiona. Następnie pozwól, aby przeszedł po cichu lub został włączony do Braku zwracanego przez metodę get().

Jednak metoda get() jest pomocna, gdy możemy przekazać wartość domyślną dla określonej zmiennej środowiskowej, jeśli nie jest ona ustawiona.

Oto przykład:

print(os.environ.get('HOME','/home/user'))
# Output: /home/balapriya

Jak zarządzać konfiguracją za pomocą zmiennych środowiskowych

Rozważmy teraz kilka praktycznych przykładów, w których używamy zmiennych środowiskowych w naszej aplikacji.

Przykład 1: Konfigurowanie parametrów połączenia z bazą danych

Załóżmy, że chcesz połączyć się z bazą danych PostgreSQL z poziomu Pythona. W tym celu możesz zainstalować i używać złącza psycopg2:

pip install psycopg2

W tym przykładzie używamy zmiennych środowiskowych do skonfigurowania parametrów połączenia z bazą danych. Jeśli zmienne środowiskowe nie są ustawione, udostępniamy wartości domyślne do użycia.

import os
import psycopg2  

# Retrieve database configuration from environment variables
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')

# Establish a database connection
try:
	connection = psycopg2.connect(
    	host=db_host,
    	port=db_port,
    	user=db_user,
    	password=db_password,
    	database="mydb"
	)
	print('Connected to the database!')
except Exception as e:
	print(f'Error connecting to the database: {e}')

Przykład 2: Zarządzanie kluczami API

Weźmy inny przykład, który wiąże się z użyciem kluczy API.

Oprócz interfejsu ChatGPT możesz także używać OpenAI API do obsługi OpenAI LLM w swoich aplikacjach.

Kiedy zarejestrujesz się na konto OpenAI, będziesz (zwykle widzisz) darmowe, ograniczone czasowo kredyty API. Chwyć klucz API, przechodząc do opcji Ustawienia > Wyświetl klucze API.

Do tworzenia aplikacji możesz używać zestawu SDK Open AI Python i platformy takiej jak LangChain. Aby to zrobić, musisz zainstalować biblioteki (w środowisku wirtualnym) za pomocą pip:

pip install openai
pip install langchain 

Oto jak ustawić OPENAI_API_KEY jako zmienną środowiskową:

import os
os.environ["OPENAI_API_KEY"]='your-api-key'

Możesz teraz uzyskać dostęp do Open AI LLM w swoim skrypcie w następujący sposób:

from langchain.llms import OpenAI
model=OpenAI(model_name="gpt-3.5-turbo")

Jak modyfikować zmienne środowiskowe w Pythonie

Możesz skorzystać ze słownika os.environ z modułu os, aby zmodyfikować zmienne środowiskowe w bieżącym procesie Pythona:

import os

# Modify an existing environment variable or create a new one
os.environ['MY_VARIABLE'] = 'new_value'

W Pythonie możesz użyć moduł podprocesowy do tworzenia podprocesów z istniejącego skryptu Pythona. Jest to przydatne, gdy chcesz uruchamiać programy systemowe w Pythonie.

W poniższym przykładzie modyfikujemy zmienną środowiskową PATH, korzystając ze słownika os.environ. Następnie uruchamiamy echo $PATH jako podproces:

import os
import subprocess

# Set a custom environment variable for the subprocess
os.environ['PATH'] = '/custom/path'

# Run a subprocess that accesses the PATH environment variable
result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE)
output = result.stdout.decode()
print(output)
print(f'Subprocess output: {output}')

Widzimy, że PATH przyjmuje wartość /custom/path:

# Output
/custom/path

Zakres zmodyfikowanych zmiennych środowiskowych

Należy pamiętać, że te aktualizacje zmiennych środowiskowych są tymczasowe i obowiązują tylko dla bieżącego procesu Pythona. Po zakończeniu działania skryptu zmiany są odrzucane:

  • Bieżący proces w języku Python: Kiedy modyfikujesz zmienną środowiskową za pomocą os.environ w skrypcie języka Python, zmiana jest lokalna w stosunku do bieżącego procesu w języku Python. Nie będzie to miało wpływu na inne uruchomione procesy ani przyszłe sesje Pythona.
  • Procesy potomne: Zmiany zmiennych środowiskowych dokonane w bieżącym procesie Pythona są dziedziczone przez procesy potomne utworzone przez Twój skrypt. Na przykład, jeśli utworzysz podproces ze skryptu Pythona (proces nadrzędny), proces potomny będzie miał dostęp do zmodyfikowanych zmiennych środowiskowych (jak widać w przykładzie).
  • Nie w całym systemie: Zmienne środowiskowe ustawione w skrypcie Pythona nie będą trwałe poza wykonaniem tego skryptu.

Jeśli konieczne jest wprowadzenie trwałych zmian w zmiennych środowiskowych na poziomie systemu, zazwyczaj trzeba to zrobić przy użyciu metod specyficznych dla systemu operacyjnego.

Jak załadować pliki .env za pomocą python-dotenv

The biblioteka Pythona-dotenv to popularny pakiet Pythona, który upraszcza proces ładowania zmiennych środowiskowych z pliku .env do projektu w Pythonie. Jest to szczególnie przydatne, gdy masz wiele środowisk (np. programistycznych, produkcyjnych) z różnymi konfiguracjami i chcesz zachować te ustawienia oddzielnie od kodu źródłowego.

Instalowanie Pythona-dotenv

Aby używać Pythona-dotenv, musisz go najpierw zainstalować. Możesz go zainstalować — w środowisku wirtualnym — za pomocą pip, menedżera pakietów Pythona:

pip install python-dotenv

Ładowanie zmiennych środowiskowych z pliku .env

Możesz teraz utworzyć plik .env w katalogu głównym projektu i wypełnić go parami klucz-wartość, podobnie jak zwykłe zmienne środowiskowe. Utwórzmy następujący plik .env z wartościami zastępczymi:

API_KEY=your_api_key_here
DB_PASSWORD=your_database_password_here

Możesz teraz załadować zmienne środowiskowe z pliku .env za pomocą Pythona-dotenv w następujący sposób:

import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# Access the environment variables
api_key = os.getenv("API_KEY")
database_password = os.getenv("DB_PASSWORD")

# Print out the env variables
print(f"API Key: {api_key}")
print(f"Database Password: {database_password}")

Zauważ, że użyliśmy os.getenv(NAZWA_zmiennej) do pobrania wartości zmiennych środowiskowych. Jest to również prawidłowy (i rzadziej używany) sposób uzyskiwania dostępu do zmiennych środowiskowych.

Oto dane wyjściowe:

API Key: your-api-key-here
Database Password: your-database-url-here

W tym przykładzie:

  • Używamy funkcji Load_dotenv() do ładowania zmiennych środowiskowych zdefiniowanych w pliku .env do bieżącego środowiska.
  • Następnie używamy os.getenv(), aby uzyskać dostęp do zmiennych środowiskowych: API_KEY i DB_PASSWORD.

Wniosek

I to jest okład! Mam nadzieję, że nauczyłeś się zarządzać konfiguracją i poufnymi informacjami za pomocą zmiennych środowiskowych w aplikacjach Pythona. Omówiliśmy podstawy ustawiania i uzyskiwania dostępu do zmiennych środowiskowych, a także ich praktyczne zastosowanie w konfigurowaniu aplikacji.

Chociaż zmienne środowiskowe są z pewnością pomocne w oddzielaniu konfiguracji od kodu źródłowego, w przypadkach użycia produkcyjnego należy przechowywać wrażliwe zmienne jako klucze tajne. Do zarządzania sekretami polecam eksplorację narzędzi takich jak Skarbiec HashiCorp Lub Menedżer tajemnic AWS.