Virtuelle Python-Umgebungen – deklarativ und portabel
Hidden gem würde man im Englisch wohl sagen: RCC ist auch außerhalb des vorgesehenen Robot-Framework-Kontexts ein tolles Open-Source-Tool
Hier handelt es sich wirklich um verborgenes Schätzchen: RCC ist dafür gedacht, virtuelle Python-Umgebungen zu erstellen, zu verwalten und verteilen zu können - und wird vor allem eingesetzt, um Software-Tests auf Basis von Robot Framework auf der Robocorp-Online-Plattform betreiben zu können. Ja gut, das klingt jetzt vermutlich nur nach Bahnhof, Bahnhof, Bahnhof ...
Update 11/24: RCC ist leider kein Open Source mehr - mehr zu dem traurigen Vorgang hier.
Virtuelle Umgebungen
Wer in diesem Artikel landet, wir es vermutlich wissen - dann einfach Kapitel überspringen -, hier aber trotzdem ganz kurz, was virtuelle Umgebungen sind und sollen. Virtuelle Umgebungen werden meist für Testing und Entwicklung genutzt. Angenommen Ihr testet eine bestimmte Version einer Software mit Abhängigkeiten in ebenfalls bestimmten Versionen und mit irgendwelchen Tools in vorgegebenen Versionen. Da kann alles systemweit installiert werden.
Müsst Ihr aber mit mehreren Versionen mit unterschiedlichen Abhängigkeiten testen, geht das natürlich nicht mit den systemweit installierten Programmen. Also erstellt man eine virtuelle Umgebung, in der man Software installieren und auch einige Systemeinstellungen vornehmen kann. Solche Umgebungen lassen sich dann ganz einfach betreten und verlassen.
In der Python-Welt macht man das gewöhnlich mit dem venv-Modul (virtual environment): Im gewünschten Ordner wird einfach per venv-Befehl eine Umbegung definiert und dann auf Wunsch gestartet. Nach dem Start verändert sich dann der Prompt und alles was fortan eingerichtet wird, steht nur in dieser einen, betretenen Umgebung zur Verfügung.
Wenn man so etwas ständig benötigt und vor allem auch mit Kollegen teilen will, kommt RCC ins Spiel - mit dessen Worten: "RCC ist ein Kommandozeilen-Tool, das es ermöglicht, Python-basierte, selbst-beinhaltende Automationspakete zu erstellen, zu verwalten und zu verteilen [...]".
RCC statt venv
Bei RCC funktioniert das Ganze über eine einzelne Binary und deklarative Konfiguration, sprich beschreibende Dateien im YAML-Format. Beschreibung heißt dabei: Ihr definiert eigentlich nur Abhängigkeiten wie Python, Pip, Firefox oder was auch immer. Im Hintergrund läuft Micromamba und kümmert sich um alles, orchestriert von RCC.
Am Ende genügt ein Ordner mit folgenden Dateien, der auf Windows- wie Linux-Rechnern virtuelle Umgebungen baut und einrichtet sowie optional Automatisierungen/Tests anstößt:
- rcc: Die RCC-Binary - verarbeitet robot.yaml und conda.yaml.
- robot.yaml: Hauptzweck ist der Verweis auf conda.yaml und tasks.yaml/tasks.py - muss nicht bearbeitet werden.
- conda.yaml: Deklaration der Umgebung.
- Optional: tasks.yaml/tasks.py: Tests und Automatisierungen - verarbeitet durch Robot Framework.
Die YAML-Dateien könnt Ihr einfach kopieren/manuell anlegen. Sie werden aber auch automatisch generiert, wenn Ihr einen solchen Robot, wie das ganze Konstrukt zusammen genannt wird, per rcc create über einen Assistenten anlegt. Die Sammlung dieser drei YAML-Dateien ist also das oben erwähnte Automationspaket.
In der robot.yaml ist die Frage, ob Tests/Automatisierungen per Robot Framework (tasks.yaml) oder direkt mit Python (tasks.py) erledigt werden sollen. Entsprechend verweist sie dann eben auf die jeweilige tasks-Datei. Ebenso findet sich darin der Verweis auf die conda.yaml. Letztlich gibt es noch ein paar Zeilen Konfiguration, die in der Regel nicht verändert werden müssen. Die robot.yaml ist also im Wesentlichen eine Art Meta-Datei, die die Beschreibungen von Umgebung und (optionalen) Tasks zusammenhält. Das nur zum Verständnis, kümmern müsst Ihr Euch darum nicht.
Für die virtuellen Umgebungen müsst Ihr also nur die conda.yaml bearbeiten, hier ein simples Beispiel:
channels:
- conda-forge
dependencies:
- python=3.10.12 # https://pyreadiness.org/3.10
- pip=23.2.1 # https://pip.pypa.io/en/stable/news
- robocorp-truststore=0.8.0 # https://pypi.org/project/robocorp-truststore/
- firefox
- pip:
- robotframework
- duckduckgo_search
- cowsay
Über channels wird die Quelle für Abhängigkeiten angegeben, hier eben conda-forge.org. Dann werden erst conda-forge-Pakete und in einem zweiten Schritt Pip-Pakete angegeben.
Zur Demonstration habe ich hier auch mal normale Nutzerprogramme eingefügt, die nichts mit Entwicklung oder Testing zu tun haben: Firefox, Cowsay und eine DuckDuckGo-Suche für den Terminal. Python und Pip sind obligatorisch. Die Robot-Framework-Pakete (robocorp-truststore und robotframework) werden natürlich auch nur benötigt, wenn denn Robot Framework genutzt wird (Ihr werdet sie praktisch immer sehen, weil RCC eben dafür gemacht wurde).
Und soweit es die virtuellen Umgebungen angeht, war's das auch schon. Ihr könnt diese Umgebung nun bauen lassen und betreten:
user@rechner/c/robot/nobot2> rcc.exe task shell
C:\robot\nobot2>
Ihr seht, dass sich der Terminal verändert hat und könnt nun testen, ob das Kommando robot aus dem Robot Framework vorhanden ist:
C:\robot\nobot2> where robot
Zum Verlassen der Umgebung:
C:\robot\nobot2> exit
Beim nächsten Betreten wird dann nur neu gebaut, wenn es etwas Neues gibt. Praktisch, denn hier kommen schnell ein paar Hundert Megabyte Download zusammen.
Eigentlicher Sinn des Ganzen sind wie gesagt Tests/Automatisierungen, hier mal eine super simple "Automatisierung" in der tasks.robot:
*** Settings ***
Documentation Just testing
Library OperatingSystem
*** Tasks ***
Firefox starten
Run firefox -private
Zunächst wird die Bibliothek OperatingSystem importiert, die in Robot Framework selbst enthalten ist. Diese Bibliothek stellt das Keyword (das Kernkonzept von Robot Framework) Run zur Verfügung, das schlicht Prozesse ausführt - hier den installierten Firefox im privaten Modus.
Zum Ausführen der tasks.robot in der virtuellen Umgebung:
C:\robot\nobot2> robot tasks.robot
Zum Schluss noch ein nützliches Kommando:
user@rechner/c/robot/nobot2> rcc.exe configuration cleanup --all
Beim ersten Aufruf werden die Umgebungen gebaut, später werden sie soweit möglich aus dem Cache wiederverwendet. Und da können schon mal Artefakte übrig bleiben, die stören. Zum Beispiel Firefox: Bisweilen kommt die Meldung, Firefox könne nicht gestartet werden, weil es Versionsprobleme gibt -, die auf alte Daten im Cache zurückzuführen sind. Mit dem obigen Kommando wird der Cache gelöscht. Heißt: Beim nächsten Aufruf wird komplett neu gebaut.
Übrigens: Mit RCC lässt sich noch deutlich mehr anstellen, beispielsweise können Robots aus dem Netz geladen werden - schaut einfach mal in die ganz gute Hilfe im Terminal.
Fazit
RCC eignet sich wunderbar, um virtuelle Python-Umgebungen zu verwalten und zu teilen - für welche Zwecke auch immer. Auch ganz abseits von Robot Framework, Robocorp, Testing und Automatisierung.
Perfekt ist das System allerdings nicht, im Betrieb sind hier immer wieder mal obskure Fehlermeldungen aufgetaucht und ebenso obskur wieder verschwunden. Zwischenzeitlich hatte ich hier eine Version, die auf deutschen Windows-Versionen gar nicht funktionieren wollte, was aber auch schnell wieder gefixt wurde. Die eigentliche Tragödie ist aber, dass RCC außerhalb der Robocorp-Nutzerschaft nicht sonderlich bekannt zu sein scheint.
Was die Anwendungsmöglichkeiten angeht, regt RCC jedenfalls zum Nachdenken an.