Kolumne, UTC

Python & Node.js mit Benutzerrechten unter Linux

Aufbau einer kombinierten virtuellen Umgebung für F&E

In diesem Artikel demonstriere ich, wie man eine kombinierte virtuelle Python- und Node.js-Umgebung von Grund auf unter Linux ausschließlich mit Benutzerrechten installiert. Administrative Privilegien (root-Rechte) werden, wenn überhaupt, nur zur Installation von System-Abhängigkeiten benötigt. Die beschriebene Installation dient als meine gegenwärtige Ausgangsbasis für Softwareentwicklung und Datenanalyse. Sie basiert auf Python 3.4 (CPython), virtualenv, nodeevn, Node.js 6.2, PyQt4, numpy, matplotlib, pymongo sowie h5py und läuft gleichermaßen auf den Varianten für 32-Bit-Architekturen (x86) sowie 64-Bit-Architekturen (x86_64) von openSUSE 13.1 Linux (jetzt, Stand Frühjahr 2016, weitergepflegt im Rahmen der Langzeit-Unterstützung durch das "Evergreen"-Projekt). Der folgende Text sollte auf andere Versionen von openSUSE sowie andere Linux-Distributionen anwendbar sein, wobei jedoch Paket-Namen und Versionen abweichen können.

In: Datenanalyse, Softwareentwicklung, Python, Python 3, Node.js, virtualenv, nodeenv, PyQt, PyQt4, JavaScript, Linux
 

Worin besteht der Sinn?

Es gibt viele Gründe, warum dieser Ansatz Sinn macht. Am Ende hängt jedoch alles von den jeweiligen Anforderungen ab. In meinem Fall bevorzuge ich es, so weit es Python betrifft, eine jüngere Version als die mit openSUSE 13.1 mitgelieferten Versionen - 2.7 und 3.3 - zu nutzen. Obwohl es selbstverständlich jüngere Versionen als Pakete in diversen Gemeinschaftsrepositorien gibt, verursacht ihre Installation jedoch in Regel einiges Chaos unter den Systemverknüpfungen in /usr/bin, was es anschließend manuell zu beheben gilt. Unabhängig davon möchte ich es vermeiden, Python-Pakete systemweit installieren zu müssen und ich möchte in der Lage sein, den Python-Interpreter bei Bedarf mit verschiedenen Optionen unkompliziert neu übersetzen und installieren zu können. Des weiteren war ich in der Vergangenheit mit Situationen konfrontiert, in denen ich relativ schnell Rechen-Knoten aufsetzen und verwalten musste. In diesen Fällen erwies es sich als sinnvoll, die Knoten mit einem so rudimentär wie möglich gehaltenem Betriebssystem auszustatten und die jeweils aktuellste Version meiner sich stetig weiterentwickelnden virtuellen Umgebung vor jedem größeren Durchlauf von Berechnungen automatisch auf die einzelnen Knoten zu verteilen. Ein anderes verbreitetes Szenario, in dem diese Methode ebenfalls Sinn macht, besteht darin, an seinem Arbeitsplatz oder in einer Universität mit einem Benutzerkonto ohne administrative Rechte arbeiten zu müssen.

Python und Node.js zu kombinieren ist fast eine Geschichte für sich. Während ich meine Programme zumeist in Python (und C) schreibe, passiert es gelegentlich, dass ich die eine oder andere sehr nützliche Bibliotheken finde, welche in JavaScript geschrieben wurde und auf Node.js. läuft (oder irgendjemand verbreitet äußerst hilfreichen JavaScript-Code auf seiner Website, den ich nutzen möchte). Mit der zunehmenden Beliebtheit von Node.js nimmt auch die Anzahl an brauchbaren Werkzeugen zur Datenanalyse in diesem Ökosystem drastisch zu. Aus diesem Grund möchte ich in der Lage sein, Node.js-Pakete mit npm schnell installieren zu können ohne damit mein System vollzumüllen. Darüber hinaus macht es aus genau den gleichen vorher für den Python-Interpreter beschriebenen Gründen Sinn, die relativ alte Version von Node.js, die mit openSUSE mitgeliefert wird, zu umgehen. Eine virtuelle Umgebung für Python mit einer isolierten Umgebung für Node.js zu kombinieren ist daher für mich die logische Konsequenz und glücklicherweise gibt es ein (in Python geschriebenes) Werkzeug dafür: nodeenv.

In diesem Artikel werde ich zeigen, wie man ausschließlich mit Benutzerrechten Python 3.4 (das "originale" CPython von python.org) - genau wie eine Reihe weiterer Softwarepakete - aus dem Quelltext übersetzt und installiert.

Voraussetzungen

Es muss sicher gestellt werden, dass das Betriebssystem alle Abhängigkeiten (Werkzeuge, Bibliotheken, "Header") befriedigt. Unter openSUSE sollte es ausreichen, die Schemata ("patterns") "patterns_openSUSE-devel_basis" und "patterns_openSUSE-devel_C_C++" zu installieren. Darüber hinaus sollte sicher gestellt werden, dass eine Version von readline (5 oder 6) sowie das dafür entsprechende Entwicklungspaket (readline-devel) installiert ist - sonst beschwert sich der Python-Interpreter später beim Start. Eine detaillierte Beschreibung des Prozeduren zum Bau von Python finden sich im Entwicklerhandbuch für Python. Für Node.js könnte es darüber hinausgehend notwendig sein, openssl sowie das dazugehörige Entwicklungspaket (libopenssl-devel) zu installieren.

1 sudo zypper in patterns_openSUSE-devel_basis \
2 	patterns_openSUSE-devel_C_C++ openssl libopenssl-devel \
3 	readline readline-devel
Voraussetzungen 1: Installation von Systemabhängigkeiten mit administrativen Privilegien aus einer Kommandozeile

Etwas über das eigentliche Ziel hinausführend werde ich erklären, wie man PyQt4 installiert (welches beispielsweise von matplotlib vorausgesetzt wird). Dabei ist hervorzuheben, dass weder Python noch Node.js Pyqt benötigen, so dass diese Abschnitte bei Bedarf einfach ignoriert werden können. Falls PyQt jedoch gewünscht ist, sollte sicher gestellt sein, dass die entsprechenden Entwicklungspakete für Qt installiert sind.

1 sudo zypper in libqt4-devel
Voraussetzungen 2: Installation von Qt-Headern mit administrativen Privilegien aus einer Kommandozeile
Grundlagen: Python übersetzen, eine virtuelle Umgebung erstellen

In den meisten Fällen bevorzuge ich für meine Arbeit einen zentrales Projektverzeichnis, welches sich auf meinem Desktop befindet. Dorthin wird zuerst gewechselt.

1 cd ~/Desktop/PROJEKTE
Schritt 1: In den Projektordner wechseln

Bevor ich anfange, etwas zu installieren, erstelle ich eine Reihe an Unterordnern. Der erste, "_python34", wird in Zukunft als Wurzelverzeichnis für Python dienen. Der zweite, "_env34a", wird meine virtuelle Umgebung enthalten. Wichtig hierbei ist, dass die Ordnernamen einen Hinweis aus die jeweils verwendete Version (3.4) von Python enthalten und das angehängte "a" anzeigt, dass es sich um die erste virtuelle Umgebung basierend auf dieser Version von Python handelt. Die systematische Benennung dieser Verzeichnisse vereinfacht langfristig vor Verwaltung weiterer Interpreter und virtueller Umgebungen.

1 mkdir _python34
2 mkdir _env34a
Schritt 2: Neue Ordner für Wurzelverzeichnis von Python und eine virtuelle Umgebung erstellen

Jetzt ist es an der Zeit, die aktuellste Version von CPython 3.4 von python.org herunterzuladen:

1 wget https://www.python.org/ftp/python/3.4.4/Python-3.4.4.tar.xz
Schritt 3: Herunterladen des Quelltextes von Python

Das xz-komprimierte tar-Archiv muss als nächstes entpackt werden, was in einem neuen Verzeichnis, "Python-3.4.4", in meinem Projektordner resultiert. Ich bevorzuge es, "src." als Präfix vor die Namen von Verzeichnissen zu setzen, welche Quelltext enthalten. Danach wechsle ich in das Quelltextverzeichnis.

1 tar xpvf Python-3.4.4.tar.xz
2 mv Python-3.4.4 src.Python-3.4.4
3 cd src.Python-3.4.4
Schritt 4: Den Quelltext von Python entpacken, Verzeichnisnamen ändern, hinein wechseln

Jetzt konfiguriere, übersetzte und installiere ich den Python-Interpreter. Dabei ist es wichtig, bei der Konfiguration mit Hilfe des "prefix"-Schalters auf das vorher erstellte Wurzelverzeichnis von Python zu zeigen.

1 ./configure --prefix=$HOME/Desktop/PROJEKTE/_python34
2 make
3 make install
4 cd ..
schritt 5: Konfigurieren, übersetzen, installieren, ins Projektverzeichnis wechseln

Falls der bis hier her beschriebene Prozess erfolgreich durchlaufen wurde, sollte es an dieser Stelle möglich sein, eine virtuelle Umgebung zu erstellen und diese mit Hilfe des Werkzeugs "source" zu aktivieren.

1 cd _python34
2 ./bin/python3.4 -m venv ../_env34a/
3 cd..
4 source _env34a/bin/activate
Schritt 6: Eine virtuelle Umgebung erstellen, diese aktivieren

An dieser Stelle ist es sinnvoll, aus der virtuellem Umgebung heraus auf die Header von Python zu verweisen. Eine Programme werden sie hier erwarten.

1 cd _env34a/include/
2 ln -s ../../_python34/include/python3.4m/ python3.4m
3 cd ../../
Schritt 7: Einen symbolischen Link auf die Python-Header anlegen
PyQt4 in die virtuelle Umgebung installieren

Eine der häufigsten Abhängigkeiten für Anwendungen mit graphischer Benutzeroberfläche besteht zu Qt, weil es schlicht eine der besten quelloffenen plattformunabhängigen Bibliotheken auf diesem Gebiet ist. Die meisten auf Qt aufbauenden Anwendungen benutzen immer noch Qt4 (obwohl sich Qt5 zunehmender Popularität erfreut), so dass es im allgemeinen eine gute Idee ist, PyQt4 zu installieren. An dieser Stelle wird es etwas problematisch, da sich PyQt4 offiziell nicht in eine virtuelle Umgebung hinein installieren lässt. Man muss einige Tricks anwenden, um es dennoch erfolgreich zum Laufen zu bringen. Um jedoch überhaupt so PyQt installieren zu können, muss vorher SIP installiert werden. SIP ist eine Python-Bibliothek, die dazu dient, auf große C/C++-Bibliotheken zugreifen zu können. Sie wurde von gleichen Hersteller entwickelt, der auch PyQt betreut. Die erste Schwierigkeit besteht darin, ein zusammenpassendes Paar von SIP und PyQt zu finden da sonst die Installation von PyQt scheitern kann. Da es leider unmöglich ist, ein solches Paar anhand der Versionsnummern zu identifizieren, besteht die einige Möglichkeit darin, sich etwas tiefer auf Sourceforge.net umzuschauen und herauszufinden, wann die gewünschte Version von PyQt dort hochgeladen wurde. Darauf basierend ist es möglich, eine Version von SIP zu wählen, die im gleichen Zeitraum hochgeladen wurde.

openSUSE 13.1 wird mit Qt 4.8.5 ausgeliefert, was durch die Ausführung von qmake herausgefunden werden kann.

1 ~> qmake --version
2 QMake version 2.01a
3 Using Qt version 4.8.5 in /usr/lib
Schritt 8: Die Version von Qt bestimmen

Für diese Version von Qt besteht das passende (und funktionierende) Paar von SIP und PyQt in sip-4.16.9 und PyQt-x11-gpl-4.11.4, welche beide am 1. August 2015 veröffentlicht wurden. Sie finden auf Sourceforge.net hier und hier Nachdem ich die entsprechenden Dateien herunter geladen habe, schiebe ich sie in mein Projektverzeichnis und entpacke sie mit den folgenden Kommandos.

1 tar -xvzf sip-4.16.9.tar.gz
2 tar -xvzf PyQt-x11-gpl-4.11.4.tar.gz
3 mv sip-4.16.9 src.sip-4.16.9
4 mv PyQt-x11-gpl-4.11.4 src.PyQt-x11-gpl-4.11.4
Schritt 9: Den Quelltext von SIP und PyQt entpacken und die Verzeichnisse umbenennen

Als nächstes muss SIP konfiguriert, übersetzt und installiert werden. Dazu ist es wichtig, mit einem absoluten Pfad auf die Python-Header zu zeigen - alles andere scheint nicht zu funktionieren. Zur Konfiguration des Quelltextes nutze ich bereits den Python-Interpreter meiner virtuellen Umgebung.

1 cd src.sip-4.16.9
2 python configure.py \
3 	--incdir=$HOME/Desktop/PROJEKTE/_env34a/include/python3.4m/
4 make
5 make install
6 cd ..
Schritt 10: Konfigurieren, übersetzen, installieren

Jetzt ist es möglich, PyQt zu übersetzen. Zuerst gehe ich in das entsprechende Verzeichnis und konfiguriere den Quelltext.

1 cd src.PyQt-x11-gpl-4.11.4
2 python configure.py
Schritt 11: Konfiguration des PyQt-Quelltextes

Die dadurch automatisch erstellte Datei "Makefile" benötigt einige manuelle Änderungen. Ich öffne sie mit einem Texteditor und ändere die Zeilen 52 sowie 53 wir folgt:

1 @test -d $(DESTDIR)/home/ernst/Desktop/PROJEKTE/_env34a/share/qt4/qsci/api/python || mkdir -p $(DESTDIR)/home/ernst/Desktop/PROJEKTE/_env34a/share/qt4/qsci/api/python
2 cp -f PyQt4.api $(DESTDIR)/home/ernst/Desktop/PROJEKTE/_env34a/share/qt4/qsci/api/python/PyQt4.api
Schritt 12: Anpassung des Makefile

Die Zeilennummern können je nach System etwas abweichen, sollten sich jedoch relativ einfach identifizieren lassen, in dem man nach Installationsanweisungen für "qsci" sucht.

Jetzt ist es tatsächlich möglich, PyQt4 zu übersetzen und in die virtuelle Umgebung zu installieren. Dieser Schritt kann durchaus einige Zeit in Anspruch nehmen.

1 make
2 make install
Schritt 13: PyQt übersetzen und installieren
Relevante Python-Pakete installieren

Nachdem die Installation von PqQt abgeschlossen ist, ist es an der Zeit, weitere relevante bzw. wichtige Python-Pakete zu installieren. Vorher sollte man jedoch nicht vergessen, pip auf den neusten Stand zu bringen.

1 pip install --upgrade pip
2 pip install -v numpy
3 pip install -v pymongo
4 pip install -v h5py
Schritt 14 (a): Pip aktualisieren, für Datenanalyse notwendige Python-Pakte installieren

Falls PyQt gegen alle Widerstände erfolgreich installiert wurde, kann man jetzt auch matplotlib installieren.

1 pip install -v matplotlib
Schritt 14 (b): Matplotlib installieren
Node.js in die virtuelle Umgebung installieren

Mit dem Abschluss des letzten Schrittes ist meine Ausgangsbasis für Softwareentwicklung und Datenanalyse fast fertig. Es fehlt nur noch Node.js. Wie bereits vorher erwähnt ist es mein Ziel, Node.js direkt in die virtuelle Umgebung zu installieren. Dafür benötige ich ein weiteres Python-Paket: nodeenv. Es kümmert sich darum, Node.js herunterzuladen, zu kompilieren und direkt in die virtuelle Umgebung zu installieren und automatisiert den beschriebenen Prozess nahezu vollkommen.

1 pip install -v nodeenv
Schritt 15: Nodeenv mit pip installieren

Nodeenv ist ein vielseitiges Werkzeug, daher lohnt es sich, einen Blick in die Bedienungsanleitung oder auf eine Reihe an Blog-Einträgen zu werfen, wie beispielsweise diesen, welche die Fähigkeiten von nodeenv illustrieren. Für meine Zwecke ist es ausreichend, nodeenv einmal mit dem "p"-Schalter auszuführen. Dies gibt mir Node.js und npm.

1 nodeenv -p
Schritt 16: Node.js und npm mit nodeenv installieren

An diesem Punkt kann npm durch die Installation eines Paketes wie d3 für Node.js getestet werden. Dabei darf nicht vergessen werden, den "g"-Schalter zu aktivieren.

1 npm install d3 -g
Schritt 17: Installation von d3 mit npm

Sebastian M. Ernst