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
setuptools
vorbereitet ist, dann istpip install .
das Mittel der Wahlansonsten findet sich vielleicht eine Datei
requirements.txt
im Ordner (Best-Practice) und man kann diese perpip install -r requirements.txt
auf 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.txt
zu 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:
pip
ist auch in Python geschrieben und kann somit auch als solches perpython -m pip install foo
aufgerufen 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
readers
erkennt man in dersetup.py
, daĂ die Anwendung bei der Installation alsrealpython
zum Aufruf per Console zur VerfĂźgung gestellt wird:entry_points={"console_scripts": ["realpython=reader.__main__:main"]},
Statt eines
python -m reader
kann man also auch einfachrealpython
ausfĂź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-Code
ACHTUNG: ob die Tests in einen eigenen Ordner
test
gehĂś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.txt
Datei bereitstellen, um solche Development Dependencies zu definieren ... das wßrde aber das Dependency-Management auf unterschiediche Ansätze verteilen :-( BTW:requirements.txt
macht Sinn, wenn man reine Developer-Tools hat, die nicht als Package, sondern nur als Source-Code bereitgestellt werden. Man kann einerequirements.txt
aus den aktuell installierten Packages perpip freeze > requirements.txt
generieren 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Ă
pip
auf 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?