Werken met omgevingsvariabelen in Python

veilighed, handigheid en fun

Als beginnend Pythonista ben je vast al tegengekomen dat je soms gevoelige informatie zoals wachtwoorden, API-sleutels of database-URL's in je applicatie wilt gebruiken. Natuurlijk zou je deze info nooit rechtstreeks (hard coded) in je code plakken, toch? TOCH?!๐Ÿคจ Geen zorgen, je bent echt niet de enige die die fout heeft gemaakt. Gelukkig zijn er oplossing voor om op een veiliger manier met dit soort geheimen te werken: omgevingsvariabelen en digitale kluizen! In dit blog leer je wat dat zijn, waarom ze superhandig zijn en hoe je ze veilig gebruikt met een paar toffe Python-trucjes!

Wat kun je wel of juist niet met omgevingsvariabelen voorkomen?

Zoals helaas wel vaker in het leven, is het werken met omgevingsvariabelen geen oplossing voor alles. Zo bieden omgevingsvariabelen geen bescherming tegen diefstal van gegevens wanneer de (digitale) boef toegang heeft tot de server, PC, of terminal-sessie waar met de geheimen gewerkt wordt. Het voorkomt wel dat geheimen (per abuis) in je versiebeheersysteem belanden en/of in een publieke repo op GitHub komen te staan.

Wat zijn omgevingsvariabelen?

Omgevingsvariabelen zijn stukjes data die je systeem aan je programma kan doorgeven. Denk bijvoorbeeld aan een geheim dat alleen jij en je systeem kennen. In plaats van dat geheim in je code te zetten (dus waar iedereen het kan zien), vraag je er gewoon naar op een veiliger manier.

Stel je voor: Je hebt een sleutelkastje, en elke keer als je een sleutel nodig hebt, steek je je hand erin zonder dat iemand anders weet welke sleutel erin zit. Omgevingsvariabelen werken precies zo!

Het maken van een omgevingsvariabelen is heel eenvoudig als je een Linux-distributie gebruikt. In de terminal kun je het volgende doen:


                  # maak en exporteer een omgevingsvariabele (environment variable)
                  $ export API_KEY="23lsjflsdf890u23jj1289uf"
                  
                  # print de omgevingsvariabele
                  $ echo "$API_KEY"
                  23lsjflsdf890u23jj1289uf
                

bash



Met Python kun je deze omgevingsvariabele vervolgens eenvoudig benaderen met de ingebouwde os-module. Dit werkt als volgt:


                #!/bin/python3
                import os

                # Haal een omgevingsvariabele op
                api_key = os.environ.get('API_KEY')

                if api_key:
                    print("We hebben een sleutel! ๐ŸŽ‰")
                    print(api_key)
                else:
                    print("Oeps! Geen sleutel gevonden. ๐Ÿ˜ฌ")
                

python



Waarom zou je omgevingsvariabele gebruiken?

Veiligheid: je gevoelige gegevens staan niet in je code of in versiebeheer.
Flexibiliteit: je kunt verschillende variabelen gebruiken voor ontwikkel-, test- en productie-omgevingen. Ook kun je de waarde van de variabele eenvoudig aanpassen, zonder je code te hoeven wijzigen.
Samenwerking: niemand in je team krijgt jouw super geheime API-sleutel te kennen (tenzij je die natuurlijk per ongeluk toch nog ergens anders in je code hebt achtergelaten...).

.env

Je kunt natuurlijk je hele dag besteden aan het exporteren van allemaal omgevingsvariabelen in je terminal. Dat is misschien eventjes leuk, maar niet zo handig op den duur. Daarom is het handig om voor alle variabelen die je in je Python applicatie nodig hebt een speciaal bestandje te maken waarin je al je variabelen netjes onder elkaar opslaat. Dit bestandje krijgt de naam .env en is ideaal voor lokaal testen. Je voegt het bestand NOOIT toe aan je versiebeheer-systeem (aka je git repo). Hiervoor kun je binnen je git-repo de file .gitignore aanmaken of bewerken en voorzien van .env om alleen het .env-bestand over te slaan of .* om alle bestanden die met een punt beginnen over te slaan. Ben je eigenwijs en voeg je het .env bestand toch toe dan staan je geheimen waarschijnlijk binnen korte tijd alsnog leesbaar op een plek waar je dat (hoogstwaarschijnlijk) niet wilt! Laten we eens kijken hoe je met Python een .env-bestand gebruikt. Hiervoor importeren we een module genaamd python-dotenv. Eerst maken we met de terminal het .env bestand aan.



                  # maak het .env bestand aan en zet de API_KEY variabele erin
                  $ echo 'API_KEY="23lsjflsdf890u23jj1289uf"' > .env
                  
                  # bekijk het .env bestand
                  $ cat .env
                  API_KEY="23lsjflsdf890u23jj1289uf"
                

bash




                #!/bin/python3
                from dotenv import load_dotenv
                import os

                # Laad variabelen uit het .env-bestand
                # dit bestand dient standaard in dezelfde directory te staan 
                # als jouw Python-app
                load_dotenv()

                # Haal een variabele op
                api_key = os.getenv("API_KEY")

                print(f"Jouw API-sleutel is: {api_key}")
                

python



Pro-tips #1: kies een andere locatie voor .env en het unset commando

Het kan natuurlijk zijn dat je jouw .env bestand op een andere plek wilt zetten dan waar de dotenv module standaard kijkt. Dit kun je als volgt doen:


                #!/bin/python3
                from dotenv import load_dotenv
                import os

                load_dotenv(dotenv_path="/absoluut/pad/naar/.env")
                # of
                load_dotenv(dotenv_path="relatief/pad/naar/.env")

                print(os.getenv("API_KEY"))
                

python



Soms heb je de waarde van een omgevingsvariabele aangepast, maar lijkt je Python app deze nog niet te kunnen vinden. Dit komt omdat je bij het definieren van de variabele in de (Bash) shell wel het vaderproces (parent proces) van de variabele hebt voorzien, maar nog niet de eventuele kindprocessen (zoals Python). Door gebruik van het export commando worden de omgevingsvariabelen ook aan de kindprocessen doorgegeven en zul je ze wel met jouw Python app kunnen vinden.

Pro-tips #2: gebruik een kluis voor productie en een lokaal een venv

Wanneer je omgevingsvariabelen in productie wilt gebruiken, is het het beste om ze te versleutelen en in een daarvoor bestemde digitale kluis op te slaan: tools zoals AWS Secrets Manager, Azure Key Vault, Google Secret Manager of HashiCorp Vault zijn hiervoor bedoeld. Voor deze digitale kluis hebben veel leveranciers een speciale Python-module geschreven die je kunt gebruiken om met de kluis te communiceren genaamd hvac. Meer weten? Check deze pagina.

Ga je lokaal aan de slag en ben je voornemens een echt meesterwerk van je nieuwe Python-project te maken? Werk dan in een virtuele omgeving (venv). Dit voorkomt dat je je hele systeem vervuilt met allerlei modules die je verder niet gebruikt. Zeker wanneer je aan verschillende projecten werkt, met verschillende versies van modules dan kan dat tot slapeloze nachten en overmatig gebruik van caffeine leiden. Een virtuele omgeving kun je eenvoudig maken met deze stappen:


              python3 -m venv mijn_venv
              source mijn_venv/bin/activate
              

bash



Je weet dat je in een Python venv zit als de prompt van je terminal verandert is in iets met (mijn_venv) ervoor. Installeer nu je afhankelijkheden zoals python-dotenv zonder de rest van je systeem te belasten. Ga je bezig aan een ander Python-project? Voer dan in die directory opnieuw het source commando uit.

Tot Slot

Omgevingsvariabelen zijn je geheime wapens voor het beheren van gevoelige gegevens tijdens het ontwikkelen en testen van je (Python) app. Gebruik ze verstandig, werk veilig en vergeet vooral niet om plezier te hebben terwijl je leert en programmeert: fouten maken mag! Dus hup, maak een venv, pip install python-dotenv en ga lekker aan de slag! ๐Ÿ˜„. In een volgend blog gaan we in meer detail kijken naar de werking van omgevingsvariabelen binnen de Linux-shell.

$ blog-details

Dit vind je wellicht ook interessant...