mitmario.dev

Virtuelle Umgebungen und requirements.txt

Python Sandbox 5 Min Lesezeit 2 BeispieleLektion 3 von 5

Ein neues Projekt braucht Flask in Version 3. Ein älteres Werkzeug, das du von einer Kollegin hast, läuft aber nur mit Flask 2. Bisher landete alles, was python -m pip install holt, an einer einzigen Stelle, bei dem einen Python auf dem Rechner, und das ging auch gut. Nur gibt es dort für Flask genau einen Platz. Wer die eine Version installiert, nimmt dem anderen Projekt seine weg. Und nach einem Jahr weiß sowieso niemand mehr, welches der vierzig installierten Pakete eigentlich zu welchem Projekt gehört.

Wenn pip sich weigert

Unter Ubuntu ab 23.04, Debian ab Version 12 und mit Python aus Homebrew kommt man gar nicht erst so weit. Homebrew ist ein verbreitetes Programm, mit dem man auf dem Mac Software installiert. Auf diesen Systemen antwortet python3 -m pip install tabulate mit dieser Zeile:

error: externally-managed-environment

Darunter steht This environment is externally managed und ein längerer Text von Debian, Ubuntu oder Homebrew. Im Kern heißt das, dieses Python gehört dem System und nicht dir. Ubuntu und Debian brauchen es für eigene Programme. Seine Pakete installiert dort apt, das Programm, mit dem diese Systeme Software einspielen, und auf dem Mac ist das Homebrew. Ein pip install an dieser Stelle könnte etwas überschreiben, auf das das System angewiesen ist.

Ganz unten nennt pip einen Ausweg, --break-system-packages. Der Name sagt ehrlich, was dabei passiert. Der eigentliche Rat steht weiter oben im Text, und der lautet, eine virtuelle Umgebung anzulegen.

Eine Umgebung je Projekt

Welches Python das ist
import sys

print("Python:", sys.executable)
print("Umgebung:", sys.prefix)

python -m venv .venv legt im Ordner des Projekts einen Ordner .venv an. Das ist eine virtuelle Umgebung (virtual environment), mit einem eigenen Python, einem eigenen pip und einem leeren Platz für Pakete. Der Punkt vorn ist Absicht. Auf dem Mac und unter Linux ist der Ordner damit versteckt, und viele Editoren erkennen ihn an genau diesem Namen.

Anlegen geht hier auch ohne Netz, in ein, zwei Sekunden, mit dem ersten Befehl der Befehlsleiste. Was in der Umgebung liegt, zeigt danach ls .venv/bin. Weil hier Python 3.14 läuft, steht neben python und pip noch eine Datei namens 𝜋thon. Die gibt es nur bei dieser einen Version. Erklärt wird sie nirgends, und hier bleibt es auch dabei.

Startest du dasselbe Programm mit dem Python aus der Umgebung, also mit .venv/bin/python main.py, zeigt es einen anderen Ort, denn es läuft jetzt in .venv. Und .venv/bin/python -m pip list kennt nur pip. Was du dort installierst, gehört diesem Projekt und keinem anderen. Ein zweites Projekt bekommt seine eigene Umgebung, mit seinem eigenen Flask in seiner eigenen Version.

Aktivieren

Den langen Pfad tippt niemand jedes Mal. Stattdessen aktiviert man die Umgebung, einmal für jedes Fenster des Terminals:

  • unter Windows mit .venv\Scripts\activate
  • auf dem Mac und unter Linux mit source .venv/bin/activate

Danach steht (.venv) vorn in der Zeile. Ab da meinen python und pip die aus der Umgebung, bis du deactivate tippst oder das Fenster schließt.

Hier im Kurs läuft jeder Befehl im Terminal für sich. Was activate einstellt, ist beim nächsten Befehl schon wieder weg, Aktivieren hält hier also genau eine Zeile lang. Im letzten Befehl der Befehlsleiste wird deshalb in einem Rutsch aktiviert und gestartet, mit && dazwischen.

requirements.txt

Die Umgebung selbst hebt man nicht auf und gibt sie auch nicht weiter. Sie hängt an dem Ordner, in dem sie angelegt wurde, und an dem Rechner. Verschieben lässt sie sich auch nicht. Weitergegeben wird stattdessen die Liste, aus der sie entsteht, eine Datei requirements.txt mit einem Paket je Zeile. Wer das Projekt bekommt, legt eine eigene Umgebung an, aktiviert sie und tippt python -m pip install -r requirements.txt. Dann holt pip alles, was in der Datei steht.

Was pip freeze aufschreibt
import openpyxl
import tabulate

print("Beide Pakete sind da.")

python -m pip freeze schreibt auf, was installiert ist, eine Zeile je Paket mit der genauen Version. Hier sind es drei, obwohl das Programm nur zwei importiert. et_xmlfile hat openpyxl mitgebracht.

Mit python -m pip freeze > requirements.txt landet die Liste in der Datei. In einer eigenen Umgebung ist das ein guter Weg, weil darin nur liegt, was das Projekt braucht, und weil mit den genauen Versionen beim nächsten Mal genau dieselbe Umgebung entsteht. Ohne eigene Umgebung sieht das anders aus. Dann schreibt freeze alles auf, was je für irgendein Projekt installiert wurde.

Schreibst du die Datei von Hand, kommen nur die Pakete hinein, die das Projekt selbst importiert. Was die mitbringen, holt pip von allein. Dazu kommt ein Bereich für die Version. openpyxl>=3.1,<4 heißt ab 3.1 und unter 4.

Die erste Zahl ist die Hauptversion. Ein Paket, das sich an die übliche Regel hält, erhöht sie nur dann, wenn sich etwas so ändert, dass alter Code damit nicht mehr läuft. Neuere Fassungen mit Fehlerbehebungen kommen also herein, der nächste große Umbau nicht. Was aus der Standardbibliothek kommt, wie csv oder json, gehört nie hinein. Das bringt Python ja mit.

Zu Hause

Unter Ubuntu und Debian fehlt dem Python des Systems oft sogar pip. python3 -m pip sagt dann nur No module named pip. Nachinstallieren muss man es nicht, in einer Umgebung ist pip von selbst dabei. Wenn aber schon python3 -m venv .venv meldet, dass ensurepip is not available, fehlt dem System ein Paket. Den Befehl dafür nennt die Meldung selbst, etwa apt install python3.13-venv, mit der Version, die bei dir läuft.

Unter Windows lehnt die PowerShell das Aktivieren oft ab, weil sie keine Skripte ausführen darf. Dann hilft einmal Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser, so steht es in der Dokumentation von Python. In Visual Studio Code öffnest du mit Strg+Umschalt+P die Befehlspalette und wählst dort mit „Python: Select Interpreter“ das Python aus .venv. Dann startet auch das Dreieck oben rechts damit.

Was die Aufgabe will

Ein Projekt von Mia soll auf einen zweiten Rechner. Bisher lief es ohne eigene Umgebung, und jetzt braucht es eine requirements.txt. Gestartet wird nichts. Das Ergebnis ist die Datei, und die wird direkt gelesen.

Zum Mitnehmen

Eine virtuelle Umgebung ist ein eigener Ordner mit eigenem Python und eigenen Paketen, für jedes Projekt einer. Angelegt wird er mit python -m venv .venv, aktiviert mit source .venv/bin/activate oder unter Windows mit .venv\Scripts\activate. Welche Pakete das Projekt braucht, steht in der requirements.txt, und python -m pip install -r requirements.txt holt sie in die nächste Umgebung.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 2 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, auf dem Server geprüft

    Öffnet sich mit dem Basis Konto.