Behöver du förbättra din konfigurationshantering? Upptäck hur du arbetar med omgivningsvariabler i Python.
Under min inlärningsperiod i Python konstruerade jag projekt för att konkretisera mina nyförvärvade kunskaper. Bland dessa projekt fanns de som krävde anslutning till en databas och datainhämtning genom Python. Detta nödvändiggjorde lagring av databaskonfiguration samt känslig information som användarnamn och autentiseringslösenord.
Att direkt inkorporera sådan konfidentiell information i ett Python-skript var en olämplig metod. Jag lärde mig istället att utnyttja konfigurationsfiler och omgivningsvariabler, tillsammans med Pythons integrerade moduler för att interagera med dessa.
Därmed använder jag mig av omgivningsvariabler för att lagra känsliga data som lösenord och API-nycklar i mina applikationer, och hämtar dem när det behövs. I denna guide kommer jag att utforska omgivningsvariabler och deras användning i Python.
Vad är omgivningsvariabler?
Omgivningsvariabler är variabler som befinner sig utanför en applikation och som används för att lagra konfigurationsinformation, systeminställningar och liknande data. De hanteras vanligen av operativsystemet eller applikationsmiljön. Kärnegenskaper för omgivningsvariabler är:
- Namn-värdepar: En omgivningsvariabel består av ett namn (nyckel) och ett motsvarande värde.
- Systemomfattning: Variabler kan definieras på systemnivå och därmed göras tillgängliga för alla processer inom systemet. Vid behov kan de även definieras eller ändras på applikationsnivå, där de endast påverkar den aktuella applikationen.
- Dynamiska och flexibla: Omvandlingsvariabler kan modifieras under drift, vilket möjliggör anpassning och flexibilitet.
Hur omgivningsvariabler är användbara
Omgivningsvariabler erbjuder flera fördelar för hantering av konfiguration och känslig information i Python-applikationer:
- Separation av ansvar: Genom att lagra konfigurationen utanför koden hålls hantering av konfiguration åtskild från applikationens kärnlogik.
- Säkerhet: Känslig information, som API-nycklar och databasuppgifter, kan lagras i omgivningsvariabler och därmed undviks exponering i källkoden, vilket minskar säkerhetsrisker.
- Flexibilitet: Det är enkelt att uppdatera konfigurationsinställningar med omgivningsvariabler, genom att ändra inställningarna utanför kodbasen. Denna flexibilitet är särskilt fördelaktig vid distribution av applikationer till olika miljöer eller vid uppdatering av referenser.
I de följande avsnitten av denna guide kommer vi att undersöka hur du definierar, använder och hanterar omgivningsvariabler i Python, och hur de förbättrar konfigurationshanteringen i dina projekt.
Hur man definierar omgivningsvariabler
Omgivningsvariabler kan definieras via kommandoraden. Omfattningen av sådana variabler är begränsad till den aktuella sessionen och kvarstår inte efter sessionens avslut.
För Mac- eller Linux-användare kan en omgivningsvariabel definieras i en terminalsession enligt följande:
export MY_VARIABLE=my_value
För Windows-användare kan en omgivningsvariabel tillfälligt definieras genom att använda kommandot:
set MY_VARIABLE=my_value
Åtkomst till omgivningsvariabler i Python
Python erbjuder os-modulen för operativsystemrelaterade funktioner. `os.environ` är en ordbok av omgivningsvariabler. Variablernas namn och värden fungerar som nycklar och värden i ordboken.
Därmed kan du komma åt värdena för omgivningsvariabler genom att använda deras namn som nycklar, precis som du gör för att få tillgång till element i en ordbok.
Här är några exempel:
import os print(os.environ['HOME']) # Output: /home/balapriya
print(os.environ['USER']) # Output: balapriya
Hittills allt väl. Men vad händer om du försöker komma åt en omgivningsvariabel som inte är definierad?
Låt oss försöka nå API_KEY, som ännu inte har definierats:
print(os.environ['API_KEY'])
Som förväntat genereras ett `KeyError`:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<frozen os>", line 679, in __getitem__ KeyError: 'API_KEY'
Hantering av nyckelfel
Du kan hantera `KeyError` på följande sätt:
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.')
Denna metod stoppar inte programmet abrupt när ett `KeyError`-undantag uppstår, utan visar istället ett tydligt felmeddelande:
# Output API_KEY is not set. Please configure it.
På det sättet blir vi medvetna om att en nödvändig omgivningsvariabel saknas om resterande program inte körs som väntat.
Åtkomst till omgivningsvariabler med `get()`-metoden.
Du kan även använda ordbokens `get()`-metod för att erhålla värdet på en omgivningsvariabel. Istället för ett `KeyError` returnerar `get()`-metoden `None` om variabeln inte hittas.
Åtkomst till variabeln `NOT_SET` som vi inte har definierat returnerar `None`:
print(os.environ.get('NOT_SET')) # Output: None
Jag föredrar att ett `KeyError` utlöses när en omgivningsvariabel saknas. Att tyst acceptera `None` som `get()`-metoden returnerar är inte min preferens.
Däremot är `get()`-metoden användbar när ett standardvärde ska användas för en specifik variabel om den inte är definierad.
Här är ett exempel:
print(os.environ.get('HOME','/home/user')) # Output: /home/balapriya
Hur man hanterar konfiguration med omgivningsvariabler
Låt oss undersöka några praktiska scenarion där omgivningsvariabler används i applikationer.
Exempel 1: Konfigurering av databasanslutningsparametrar
Anta att du vill ansluta till en PostgreSQL-databas från Python. För att åstadkomma detta kan du installera och använda `psycopg2`-kontakten:
pip install psycopg2
I detta exempel använder vi omgivningsvariabler för att konfigurera databasanslutningsparametrarna. Om omgivningsvariablerna saknas tillhandahåller vi standardvärden för användning.
import os import psycopg2 # Hämtar databaskonfiguration från omgivningsvariabler 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') # Upprättar en databasanslutning try: connection = psycopg2.connect( host=db_host, port=db_port, user=db_user, password=db_password, database="mydb" ) print('Ansluten till databasen!') except Exception as e: print(f'Fel vid anslutning till databasen: {e}')
Exempel 2: Hantering av API-nycklar
Låt oss granska ett annat exempel som rör användningen av API-nycklar.
Förutom ChatGPT-gränssnittet, kan du även använda OpenAI API för att stödja OpenAI LLMs i dina applikationer.
Efter att ha registrerat ett OpenAI-konto erhålls (vanligtvis) gratis tidsbegränsade API-krediter. Din API-nyckel hämtas genom att navigera till Inställningar > Visa API-nycklar.
Du kan utnyttja Open AI Python SDK och ramverk som LangChain för att skapa applikationer. För detta måste biblioteken installeras (i en virtuell miljö) med hjälp av pip:
pip install openai pip install langchain
Så här kan `OPENAI_API_KEY` definieras som en omgivningsvariabel:
import os os.environ["OPENAI_API_KEY"]='your-api-key'
Du kan nu använda Open AI LLMs i ditt skript på följande sätt:
from langchain.llms import OpenAI model=OpenAI(model_name="gpt-3.5-turbo")
Hur man modifierar omgivningsvariabler i Python
Du kan använda `os.environ`-ordboken från `os`-modulen för att modifiera omgivningsvariabler inom den aktuella Python-processen:
import os # Modifierar en befintlig omgivningsvariabel eller skapar en ny os.environ['MY_VARIABLE'] = 'new_value'
I Python kan du använda `subprocess`-modulen för att skapa underprocesser från ett existerande Python-skript. Detta är användbart om du vill köra systemprogram i Python.
I följande exempel modifierar vi omgivningsvariabeln `PATH` med hjälp av `os.environ`-ordboken. Sedan kör vi `echo $PATH` som en underprocess:
import os import subprocess # Sätter en anpassad omgivningsvariabel för underprocessen os.environ['PATH'] = '/custom/path' # Kör en underprocess som använder PATH omgivningsvariabeln result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE) output = result.stdout.decode() print(output) print(f'Subprocess output: {output}')
Vi noterar att `PATH` antar värdet `/custom/path`:
# Output /custom/path
Omfattningen av de modifierade omgivningsvariablerna
Det är viktigt att observera att dessa ändringar av omgivningsvariablerna är temporära och endast giltiga för den aktuella Python-processen. När skriptet har avslutats försvinner ändringarna:
- Aktuell Python-process: När en omgivningsvariabel modifieras med `os.environ` i ett Python-skript, är förändringen lokal för den aktuella Python-processen. Det påverkar inte andra processer eller framtida Python-sessioner.
- Underordnade processer: Ändringar av omgivningsvariabler som utförs inom den aktuella Python-processen ärvs av underordnade processer som skapas av skriptet. Om du t.ex. skapar en underprocess från ditt Python-skript (föräldraprocess), kommer underprocessen att ha tillgång till de modifierade omgivningsvariablerna (som ses i exemplet).
- Ej systemomfattande: Omgivningsvariabler som definieras i ett Python-skript kvarstår inte utanför skriptets utförande.
För att göra permanenta systemomfattande ändringar av omgivningsvariabler, krävs det användning av operativsystemspecifika metoder.
Hur man laddar .env-filer med `python-dotenv`
`python-dotenv`-biblioteket är ett populärt Python-paket som förenklar inläsningen av omgivningsvariabler från en `.env`-fil i ett Python-projekt. Detta är särskilt användbart vid hantering av flera miljöer (t.ex. utveckling, produktion) med olika konfigurationer, där man vill hålla dessa inställningar åtskilda från källkoden.
Installera `python-dotenv`
För att använda `python-dotenv` måste du först installera det. Detta görs i en virtuell miljö med hjälp av `pip`, Pythons pakethanterare:
pip install python-dotenv
Ladda omgivningsvariabler från en `.env`-fil
Du kan skapa en `.env`-fil i projektets rotkatalog och fylla den med nyckel-värdepar, precis som vanliga omgivningsvariabler. Låt oss skapa följande `.env`-fil med platshållarvärden:
API_KEY=din_api_nyckel_har DB_PASSWORD=ditt_databas_losenord_har
Nu kan du ladda omgivningsvariablerna från `.env`-filen med hjälp av `python-dotenv` på följande sätt:
import os from dotenv import load_dotenv # Laddar omgivningsvariabler från .env fil load_dotenv() # Använder omgivningsvariablerna api_key = os.getenv("API_KEY") database_password = os.getenv("DB_PASSWORD") # Skriver ut omgivningsvariablerna print(f"API Key: {api_key}") print(f"Database Password: {database_password}")
Observera att vi har använt `os.getenv(VARIABLE_NAME)` för att få värdena för omgivningsvariablerna. Detta är också ett giltigt (om än mindre vanligt) sätt att komma åt omgivningsvariabler.
Här är resultatet:
API Key: din_api_nyckel_har Database Password: ditt_databas_losenord_har
I detta exempel:
- Använder vi `load_dotenv()` för att ladda omgivningsvariablerna som definieras i `.env`-filen till den aktuella miljön.
- Använder vi `os.getenv()` för att få tillgång till omgivningsvariablerna: `API_KEY` och `DB_PASSWORD`.
Slutsats
Och det var allt! Jag hoppas att du har lärt dig hur man hanterar konfiguration och känslig information med hjälp av omgivningsvariabler i Python-applikationer. Vi har berört grunderna för att definiera och använda omgivningsvariabler samt deras praktiska användning vid konfigurering av applikationer.
Även om omgivningsvariabler är praktiska för att separera konfiguration från källkoden, bör du lagra känsliga variabler som hemligheter i produktionsmiljöer. För hantering av hemligheter rekommenderar jag att undersöka verktyg som HashiCorp Vault eller AWS Secrets Manager.