Python Libraries
Die Mächtigkeit einer Sprache steht und fällt mit den Libraries - erst dadurch wird ein Tool richtig effizient. Python lernt man schnell, doch es dauert bis man sich gut in den Libraries und Frameworks auskennt. Es lohnt sich, denn Python hat einiges zu bieten.
Konzept
Module/Packages (Distributions), die Python nicht mitliefert müssen per pip install MODULE_NAME installiert werden (bzw. pip install MODULE_NAME --upgrade für ein upgrade auf die letzte Version). Pakete von einem Python-Repository definieren i. a. alle notwendigen Dependencies, so daß diese automatisch mitinstalliert werden.
Hat man hingegen eine Source-Code-Repository geclont (z. B. von GitHub), dann gibt es verschiedene Wege
handelt es sich um ein Source-Code-Respository, das schon für
setuptoolsvorbereitet ist, dann istpip install .das Mittel der Wahlansonsten findet sich vielleicht eine Datei
requirements.txtim Ordner (Best-Practice) und man kann diese perpip install -r requirements.txtauf einen Schlag installieren.
ACHTUNG: hier sollte man die Systeminstallation (z. B.
/usr/bin/python) nicht mit allerhand Libraries vollballern. Auf einem System nutzt man i. a. viele Versionen einer Bibliothek und deshalb sollte man die Ausführungsumgebung immer projektspezifisch halten. Das hilft auch beim Fail-Fast-Prinzip ... vergißt man eine notwendige Bibliothek inrequirements.txtzu erwähnen. Am besten funktioniert das mit virtuellen Umgebungen. Docker-Container bieten auch eine Möglichkeit, doch sind virtuelle Umgebungen noch besser in die Entwicklungsarbeit (z. B. Shell) integriert.
Paketmanager Pip
Für die Installation neuer Pakete (zusätzlich zu den Paketen in der Python-Installation) verwendet man pip install foo. Die Python-Pakete werden dann von PyPI runtergeladen und lokal (in der Python Distribution bzw. im virtuellen Environment) installiert, so daß sie für die Nutzung im eigenen Code oder als eigenständige Anwendung zur Verfügung stehen.
BTW:
pipist auch in Python geschrieben und kann somit auch als solches perpython -m pip install fooaufgerufen werden. Tatsächlich ist daspip-Kommando nur ein Python-Script, das so aussieht:
#!/home/pfh/venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())Will man ein installiertes Paket, das eine Anwendung repräsentiert, starten, so tut man das per python -m reader (in diesem Beispiel muß man das Paket realpython-reader vorher natürlich per pip install realpython-reader installiert haben).
Im Source-Code dieses
readerserkennt man in dersetup.py, daß die Anwendung bei der Installation alsrealpythonzum Aufruf per Console zur Verfügung gestellt wird:entry_points={"console_scripts": ["realpython=reader.__main__:main"]},Statt eines
python -m readerkann man also auch einfachrealpythonausführen.
Eine Alternative zu Pip ist Easy Install - Vergleich, das vor pip existierte.
Pip präferiert das "Wheel"-Paketformat, kann aber auch mit Source-Distributions umgehen, die sich teilweise parallel auf PyPI befinden.
Eigene Package-Repositories
Per Default werden Python-Packages auf PyPI gesucht. Hat man ein eigenes Python-Repository, so muß man ds konfigurieren. Wo man ds tut findet man am besten per pip config -v list raus. Unter Linux kann man die Konfiguration i. a. in ~/.pip/pip.conf user-spezifisch oder in /etc/pip.conf System-global durchführen. Unter Windows ist das vermutlich anders.
Paketformate
Ein Paket enthält die ausführbaren Python-Module und zudem noch Meta-Informationen
Wheel ... supported von Pip
Egg ... supported von Easy-Install
setuptools
mit
setuptools(Built-In-Package) lassen sich Python-Packages als Python-Eggs oder als Wheel verteilen ("Eggs are to Pythons as Jars are to Java") ... ich denke es gibt hier auch Alternativen. Python-Eggs werden von den beiden bekanntesten Python-Paketmanagers (Pip, Easy Install)
Der Source-Code eines Python-Pakets muß folgende Struktur haben und entsprechende Dateien bereitstellen:
your-package/
    __init__.py
    __main__.py     # support for python -m
    foo.py
test/
setup.py            # <==== MANDATORY ... Python-Code
README.md
LICENSE.txt         # choosealicense.com
MANIFEST.in         # Build-File (welche Dateien sollen ins Package?)
                    # setup.py behandelt nur den Source-CodeACHTUNG: ob die Tests in einen eigenen Ordner
testgehören ist mir noch nicht klar ... habe noch keine Best-Practices gefunden.
Zum lokalen Testen (im Development Mode) kann man dann ein pip install --editable . verwenden ... pip wertet dann das setup.py-Datei aus und installiert das Paket in die aktuelle Python-Distribution (z. B. Virtuelles Environment). Die Option --editable kann weggelassen werden, sie ermöglicht Änderungen ohne erneutes pip install . sichtbar zu machen (zumindest viele Änderungen ... natürlich keine Änderungen an setup.py), da direkt auf dem Source-Code gearbeitet wird anstatt auf site-packages der Python-Distribution => Realtime-Updates (SEHR zu EMPFEHLEN).
Binary Distributions bauen - Wheel Format
Ein Package im Wheel-Format ist eine Binärdistribution, die bereist für die Zielplatform compiliert wurde (im Gegensatz zur Source-Code-Distribution) ... eine lokale Compilierung (erfordert häufig irgendwelche Header-Datei, die man als Endanwender nicht unbedingt installiert hat) ist nicht mehr erforderlich.
Installiert man ein Package per pip, so werden Wheel-Distributionen gegenüber Source-Distributionen präferiert.
Binary Distributions bauen - Wheel Format
Per python setup.py bdist_wheel ("B Dist" = "Binary Distribution") wird eine Binary Distribution im Wheel-Format (*.whl) gebaut. Anschließend die Ordner build (plattformabhängig) und dist (enthält die Wheel-Datei). Hängt man hintendran noch ein upload (z. B. python setup.py bdist_wheel upload -r "my-pypi"), dann wird das Wheel-Paket in das Python-Repository my-pypi hochgeladen (das in ~/.pypirc mit Credential konfiguriert werden muß).
Eine Wheel-Datei kann auch beispielsweise per twine auf ein Artifact-Repository (PyPI, Nexus) hochgeladen werden.
Da setup.py tatsächlich Configuration-as-Python-Code ist kann man darin solche Dinge machen:
from setuptools import setup, find_packages
with open("README.md", "r") as readme_file_handle:
  long_description = readme_file_handle.read()
setup(
  long_description=long_description,
  long_description_content_type="text/markdown",
  packages=find_packages(exclude=("test*", "testing*"))
)Die "Konfiguration" ist also tatsächlich Code !!!
In dieser setup.py definiert man die Runtime-Dependencies (install_requires=['jinja2','Click']) und auch die Development Dependencies (z. B. um Tests auszuführen extras_require={ "dev": ["pytest>=3.7"]}). Verwendet man diese Form der extras_require, kann man die dev-Dependencies per pip install .[dev] mitinstallieren.
alternativ könnte man auch eine
requirements.txtDatei bereitstellen, um solche Development Dependencies zu definieren ... das würde aber das Dependency-Management auf unterschiediche Ansätze verteilen :-( BTW:requirements.txtmacht Sinn, wenn man reine Developer-Tools hat, die nicht als Package, sondern nur als Source-Code bereitgestellt werden. Man kann einerequirements.txtaus den aktuell installierten Packages perpip freeze > requirements.txtgenerieren lassen.
Es existiert auch die Möglichkeit, die Konfiguration in einem setup.cfg in einem ini-Format durchzuführen. Allerdings gibt man hiermit natürlich die Vorteile des Codings (z. B. find_packages(exclude=("test*", "testing*"))) auf.
Binary Distributions - Egg Format
Per python setup.py bdist_egg ("B Dist" = "Binary Distribution") wird eine Binary Distribution im Egg-Format gebaut.
Source Distributions
Per python setup.py sdist ("S Dist") wird eine Source-Distribution (in Form eines tar.gz) runtergeladen und lokal gebaut (beispielsweise als Wheel).
Der Vorteil einer Source-Distribution besteht darin, daß man den Code lokal hat und und prüfen kann.
twine - upload Packages
pip install twine
twine upload dist/*distutils
Alternative zu setuptools
PyPI
Eigenes Python Repository
Bei der Entwicklung von Non-Open-Source Software will man seine Software natürlich nicht für die ganze Welt bereitstellen, sondern evtl. nur innerhalb eines Unternehmens. Hierzu benötigt man ein Artifact-Repositiory (z. B. Nexus), das die Pakete beherbergt (als Ersatz für PyPI).
Hierzu bedarf es
Artifact-Repository (z. B. Nexus)
kann auch als Cache fungieren, so daß
pipauf dem Client nicht mehr PyPI direkt verwendet, sondern nur über das eigene Artifact-Repository ... kann die Downloadmenge reduzieren - außerdem stehen dann alle bereits runtergeladenen Pakete gecached zur Verfügung (Ausfallsicherheit)
Konfiguration der lokalen Python-Konfiguration (
pip.conf), um dieses Artifact-Repository zu berücksichtigen
Selenium
CLIs - Command Line Interfacse
Web-Services - requests
Was wäre die Welt ohne Webservices ...
Template-Engine - jinja2
... zur Generierung von Content (HTML-Seiten, JSON, XML, ...) - ein Tool, das wirklich jeder (insbes. im DevOps-Bereich) braucht.
Django
FastAPI
Jenkins - api4jenkins
Last updated
Was this helpful?