Czy chcesz usprawnić zarządzanie ustawieniami swojego oprogramowania? Odkryj, jak efektywnie wykorzystywać zmienne środowiskowe w Pythonie.
Gdy zaczynałem swoją przygodę z Pythonem, często tworzyłem projekty, które opierały się na nowo zdobytych umiejętnościach. Jednym z powtarzających się zadań było łączenie się z bazami danych i wykonywanie zapytań. Wymagało to przechowywania szczegółów konfiguracji bazy danych oraz poufnych informacji, takich jak nazwy użytkowników i hasła.
Umieszczanie tak wrażliwych danych bezpośrednio w kodzie Pythona nie było dobrym rozwiązaniem. Zrozumiałem, jak korzystać z plików konfiguracyjnych i zmiennych środowiskowych, a także z wbudowanych w Pythona modułów, które ułatwiają z nimi pracę.
Teraz, gdy w swoich aplikacjach potrzebuję haseł lub kluczy API, zawsze definiuję je jako zmienne środowiskowe, a następnie pobieram je w razie potrzeby. W tym poradniku wyjaśnię, czym są zmienne środowiskowe i jak można ich używać w Pythonie.
Czym są zmienne środowiskowe?
Zmienne środowiskowe to parametry zewnętrzne w stosunku do aplikacji, które służą do przechowywania ustawień konfiguracyjnych, parametrów systemowych i tym podobnych. Zazwyczaj są one zarządzane przez system operacyjny lub środowisko uruchomieniowe aplikacji. Do ich najważniejszych cech należą:
- Pary nazwa-wartość: Każda zmienna środowiskowa ma swoją nazwę (klucz) oraz przypisaną do niej wartość.
- Zakres systemowy: Zmienne środowiskowe mogą być ustawiane na poziomie systemu, dzięki czemu są dostępne dla wszystkich procesów działających na danym komputerze. Możliwe jest również ustawienie ich na poziomie aplikacji, wpływając tylko na konkretną aplikację.
- Dynamiczne i modyfikowalne: Zmienne środowiskowe można modyfikować w czasie działania programu, co zapewnia dużą elastyczność.
Dlaczego zmienne środowiskowe są przydatne?
Zmienne środowiskowe oferują wiele korzyści w kontekście zarządzania konfiguracją i poufnymi danymi w aplikacjach pisanych w Pythonie:
- Separacja zadań: Przechowywanie konfiguracji poza kodem pozwala na oddzielenie zarządzania konfiguracją od samej logiki aplikacji.
- Bezpieczeństwo: Wrażliwe dane, takie jak klucze API czy dane uwierzytelniające do bazy danych, mogą być bezpiecznie przechowywane w zmiennych środowiskowych, zamiast umieszczać je w kodzie źródłowym, co minimalizuje ryzyko ich wycieku.
- Elastyczność: Zmienne środowiskowe ułatwiają modyfikację ustawień konfiguracyjnych, ponieważ zmiany można wprowadzać niezależnie od bazy kodu. Pozwala to dostosować konfigurację bez konieczności modyfikacji kodu. Jest to szczególnie przydatne podczas wdrażania aplikacji w różnych środowiskach lub przy aktualizacji danych uwierzytelniających.
W dalszej części tego tekstu dowiesz się, jak ustawiać, uzyskiwać dostęp i zarządzać zmiennymi środowiskowymi w Pythonie, a także jak ułatwiają one zarządzanie konfiguracją w projektach.
Jak ustawiać zmienne środowiskowe?
Zmienne środowiskowe można ustawiać za pomocą wiersza poleceń. Zmienne ustawione w ten sposób działają tylko w ramach bieżącej sesji i nie są zachowywane po jej zakończeniu.
W systemie macOS lub Linux zmienną środowiskową w bieżącej sesji terminala ustawisz w następujący sposób:
export MY_VARIABLE=moja_wartosc
Jeśli korzystasz z systemu Windows, możesz tymczasowo ustawić zmienną środowiskową, jak pokazano poniżej:
set MY_VARIABLE=moja_wartosc
Uzyskiwanie dostępu do zmiennych środowiskowych w Pythonie
Python udostępnia moduł os, który umożliwia interakcję z systemem operacyjnym. Słownik `os.environ` zawiera wszystkie zmienne środowiskowe. Nazwy zmiennych są kluczami słownika, a ich wartości – odpowiadającymi im wartościami.
Dostęp do wartości zmiennych środowiskowych uzyskujemy w taki sam sposób, jak do elementów słownika – używając nazwy zmiennej jako klucza.
Oto kilka przykładów:
import os print(os.environ['HOME']) # Wyjście: /home/balapriya
print(os.environ['USER']) # Wyjście: balapriya
Na razie wszystko w porządku. Ale co się stanie, gdy spróbujemy uzyskać dostęp do zmiennej środowiskowej, która nie została zdefiniowana?
Spróbujmy odczytać wartość zmiennej `API_KEY`, której nie ustawiliśmy:
print(os.environ['API_KEY'])
Jak można się spodziewać, otrzymamy błąd `KeyError`:
Traceback (most recent call last): File "", line 1, in File " ", line 679, in __getitem__ KeyError: 'API_KEY'
Obsługa błędów `KeyError`
Błąd `KeyError` można obsłużyć w następujący sposób:
import os try: api_key = os.environ['API_KEY'] print(f'API_KEY ma wartość: {api_key}') except KeyError: print('API_KEY nie jest ustawiona. Proszę ją skonfigurować.')
Takie podejście zapobiega nagłemu zatrzymaniu programu w przypadku wystąpienia błędu `KeyError`. Zamiast tego, wyświetlany jest opisowy komunikat:
# Wyjście API_KEY nie jest ustawiona. Proszę ją skonfigurować.
W takim przypadku, jeśli program nie działa zgodnie z oczekiwaniami, wiemy, że pominięto ustawienie wymaganej zmiennej środowiskowej.
Dostęp do zmiennych środowiskowych za pomocą metody `get()`
Alternatywnie, aby pobrać wartość zmiennej środowiskowej, można użyć metody `get()` słownika. W przeciwieństwie do `KeyError`, metoda `get()` zwraca `None`, jeśli zmienna nie zostanie znaleziona.
Próba uzyskania dostępu do zmiennej `NOT_SET`, której nie ustawiliśmy, zwróci `None`:
print(os.environ.get('NOT_SET')) # Wyjście: None
Preferuję zgłaszanie błędu, gdy zmienna środowiskowa nie jest ustawiona, zamiast „ukrywania” braku zmiennej. Jednak metoda `get()` przydaje się, gdy możemy przekazać wartość domyślną, która ma zostać użyta, jeśli dana zmienna nie jest ustawiona.
Oto przykład:
print(os.environ.get('HOME','/home/użytkownik')) # Wyjście: /home/balapriya
Jak zarządzać konfiguracją za pomocą zmiennych środowiskowych?
Rozważmy teraz kilka praktycznych przykładów zastosowania zmiennych środowiskowych w naszych aplikacjach.
Przykład 1: Konfigurowanie parametrów połączenia z bazą danych
Załóżmy, że chcemy połączyć się z bazą danych PostgreSQL z poziomu Pythona. W tym celu możemy zainstalować i użyć złącza `psycopg2`:
pip install psycopg2
W tym przykładzie wykorzystamy zmienne środowiskowe do konfiguracji parametrów połączenia z bazą danych. Jeśli zmienne nie są ustawione, zostaną użyte wartości domyślne:
import os import psycopg2 # Pobranie konfiguracji bazy danych ze zmiennych środowiskowych db_host = os.environ.get('DB_HOST', 'localhost') db_port = os.environ.get('DB_PORT', '5432') db_user = os.environ.get('DB_USER', 'uzytkownik') db_password = os.environ.get('DB_PASSWORD', 'haslo') # Ustanowienie połączenia z bazą danych try: connection = psycopg2.connect( host=db_host, port=db_port, user=db_user, password=db_password, database="moja_baza" ) print('Połączono z bazą danych!') except Exception as e: print(f'Błąd połączenia z bazą danych: {e}')
Przykład 2: Zarządzanie kluczami API
Rozważmy inny przykład, który dotyczy użycia kluczy API.
Oprócz interfejsu ChatGPT, można również korzystać z OpenAI API do obsługi modeli językowych (LLM) w aplikacjach.
Po rejestracji konta w OpenAI, zwykle otrzymujesz darmowe kredyty API z ograniczonym czasem ważności. Klucz API znajdziesz w ustawieniach, w opcji „Wyświetl klucze API”.
Możesz tworzyć aplikacje, używając pakietu SDK Open AI Python i platformy takiej jak LangChain. W tym celu musisz zainstalować biblioteki za pomocą pip:
pip install openai pip install langchain
Oto jak ustawić zmienną środowiskową `OPENAI_API_KEY`:
import os os.environ["OPENAI_API_KEY"]='twój-klucz-api'
Teraz możesz uzyskać dostęp do modelu OpenAI 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?
Do modyfikacji zmiennych środowiskowych w bieżącym procesie Pythona możesz użyć słownika `os.environ` z modułu `os`:
import os # Zmiana istniejącej zmiennej lub utworzenie nowej os.environ['MOJA_ZMIENNA'] = 'nowa_wartosc'
W Pythonie można użyć modułu subprocess do tworzenia podprocesów z poziomu skryptu Pythona. Jest to przydatne, gdy chcesz uruchamiać programy systemowe w Pythonie.
W poniższym przykładzie zmodyfikujemy zmienną środowiskową `PATH`, używając słownika `os.environ`. Następnie uruchomimy `echo $PATH` jako podproces:
import os import subprocess # Ustawienie niestandardowej zmiennej środowiskowej dla podprocesu os.environ['PATH'] = '/sciezka/uzytkownika' # Uruchomienie podprocesu, który odczytuje zmienną PATH result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE) output = result.stdout.decode() print(output) print(f'Wyjście podprocesu: {output}')
Widzimy, że zmienna `PATH` przyjęła wartość `/sciezka/uzytkownika`:
# Wyjście /sciezka/uzytkownika
Zakres zmodyfikowanych zmiennych środowiskowych
Pamiętaj, że te modyfikacje zmiennych środowiskowych są tymczasowe i działają tylko w ramach bieżącego procesu Pythona. Po zakończeniu działania skryptu, zmiany są odrzucane:
- Bieżący proces Pythona: Jeśli modyfikujesz zmienną środowiskową za pomocą `os.environ` w skrypcie Pythona, zmiana jest lokalna dla tego procesu. Nie będzie miała 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 zmienionych zmiennych środowiskowych (jak widać w przykładzie).
- Nie w całym systemie: Zmienne środowiskowe ustawione w skrypcie Pythona nie są trwałe poza wykonaniem tego skryptu.
Jeśli konieczne jest wprowadzenie trwałych zmian w zmiennych środowiskowych na poziomie systemu, zazwyczaj trzeba to zrobić za pomocą narzędzi specyficznych dla systemu operacyjnego.
Jak ładować pliki `.env` za pomocą `python-dotenv`?
Biblioteka `python-dotenv` to popularny pakiet Pythona, który upraszcza proces ładowania zmiennych środowiskowych z pliku `.env` do projektu. Jest to szczególnie przydatne, gdy masz wiele środowisk (np. programistyczne, produkcyjne) z różnymi ustawieniami i chcesz zachować je oddzielnie od kodu źródłowego.
Instalacja `python-dotenv`
Aby użyć `python-dotenv`, musisz go najpierw zainstalować. Możesz to zrobić za pomocą pip:
pip install python-dotenv
Ładowanie zmiennych środowiskowych z pliku `.env`
Teraz możesz utworzyć plik `.env` w głównym katalogu projektu i wypełnić go parami klucz-wartość, tak jak zwykłe zmienne środowiskowe. Utwórzmy następujący plik `.env` z przykładowymi wartościami:
API_KEY=klucz_api_tutaj DB_PASSWORD=haslo_bazy_danych_tutaj
Możesz teraz załadować zmienne środowiskowe z pliku `.env` za pomocą `python-dotenv` w następujący sposób:
import os from dotenv import load_dotenv # Załadowanie zmiennych środowiskowych z pliku .env load_dotenv() # Odczytanie zmiennych środowiskowych api_key = os.getenv("API_KEY") database_password = os.getenv("DB_PASSWORD") # Wyświetlenie zmiennych środowiskowych print(f"Klucz API: {api_key}") print(f"Hasło do bazy danych: {database_password}")
Zwróć uwagę, że do pobrania wartości zmiennych środowiskowych użyliśmy `os.getenv(NAZWA_zmiennej)`. Jest to również prawidłowy (choć rzadziej używany) sposób dostępu do zmiennych środowiskowych.
Oto przykładowe wyjście:
Klucz API: klucz_api_tutaj Hasło do bazy danych: haslo_bazy_danych_tutaj
W tym przykładzie:
- Użyliśmy funkcji `load_dotenv()`, aby załadować zmienne środowiskowe z pliku `.env` do bieżącego środowiska.
- Następnie, za pomocą `os.getenv()`, uzyskaliśmy dostęp do zmiennych środowiskowych: `API_KEY` i `DB_PASSWORD`.
Podsumowanie
To wszystko! Mam nadzieję, że zrozumiałeś, jak zarządzać konfiguracją i wrażliwymi danymi za pomocą zmiennych środowiskowych w aplikacjach Pythona. Omówiliśmy podstawy ustawiania i odczytywania zmiennych środowiskowych oraz ich praktyczne zastosowanie w konfiguracji aplikacji.
Chociaż zmienne środowiskowe są przydatne w oddzielaniu konfiguracji od kodu źródłowego, w środowiskach produkcyjnych do przechowywania poufnych danych zaleca się korzystanie z bardziej zaawansowanych narzędzi, takich jak HashiCorp Vault lub AWS Secrets Manager.
newsblog.pl