Apps

App-Projekte sind für Webserver, Skripte und Befehlszeilenschnittstellen (CLI) geeignet. Auch sie können wir mit uv init --package erstellen:

$ uv init --package myapp
$ tree myapp -a
myapp
├── .git
│   └── ...
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── myapp
        └── __init__.py

Bemerkung

Ich bin der festen Überzeugung, dass eine Python-Anwendung richtig gepackt sein sollte, um die vielen Vorteile zu genießen, wie z.B.:

  • die Ressourcenverwaltung mit importlib

  • mit project.scripts ausführbare Skripte anstelle angehängter scripts-Ordner

  • die Vorteile des src-Layouts mit einer allgemeinen, dokumentierten und gut verstandenen Struktur.

myapp/pyproject.toml

Die Datei pyproject.toml enthält einen scripts-Einstiegspunkt myapp:main:

myapp/pyproject.toml
[project.scripts]
myapp = "myapp:main"
myapp/src/myapp/__init__.py

Das Modul definiert eine CLI-Funktion main():

myapp/src/myapp/__init__.py
def main() -> None:
    print("Hello from myapp!")

Sie kann mit uv run aufgerufen werden:

$ uv run mypapp
Hello from myapp!

Alternativ könnt ihr auch eine virtuelle Umgebung bauen und dann main() aus Python heraus aufrufen:

$  uv add --dev .
Resolved 1 package in 1ms
Audited in 0.01ms
>>> import myapp
>>> myapp.main()
Hello from myapp!
uv.lock-Datei

Mit uv add --dev . wurde auch die uv.lock-Datei neben der pyproject.toml-Datei erstellt. uv.lock ist ein plattformübergreifendes Lockfile, das die Pakete erfasst, die über alle möglichen Python-Merkmale wie Betriebssystem, Architektur und Python-Version installiert werden sollen.

Im Gegensatz zur pyproject.toml, die die allgemeinen Anforderungen eures Projekts spezifiziert, enthält uv.lock die genauen aufgelösten Versionen, die in der Projektumgebung installiert sind. Diese Datei sollte in die Versionskontrolle Git eingecheckt werden, um konsistente und reproduzierbare Installationen auf verschiedenen Rechnern zu ermöglichen.

myapp/uv.lock
version = 1
requires-python = ">=3.13"

[[package]]
name = "myapp"
version = "0.1.0"
source = { editable = "." }

[package.metadata]

[package.metadata.requires-dev]
dev = [{ name = "myapp", editable = "." }]

uv.lock ist eine für Menschen lesbare TOML-Datei, wird aber von uv verwaltet und sollte nicht manuell bearbeitet werden.

Bemerkung

Wenn uv in andere Tools oder Workflows integriert werden soll, könnt ihr die Inhalte mit uv export --format requirements-txt > CONSTRAINTS.TXT in das Requirements File Format exportieren. Umgekehrt kann die erzeugte CONSTRAINTS.TXT-Datei dann mit uv pip install oder anderen Tools verwendet werden.

Siehe auch

Reproduzieren der Python-Umgebung

In produktiven Umgebungen sollten immer exakt die Versionen verwendet werden, die auch getestet wurden. Mit uv sync --locked könnt ihr in eurer Umgebung sicherstellen, dass die uv.lock-Datei mit den Projekt-Metadaten übereinstimmt. Ansonsten wird eine Fehlermeldung ausgegeben.

Mit uv sync --frozen kann dann in der produktiven Umgebung erreicht werden, dass die Versionen von uv.lock als Quelle der Wahrheit verwendet werden.Sollte die uv.lock-Datei jedoch in der produktiven Umgebung fehlen, wird uv sync --frozen mit einem Fehler beendet. Schließlich werden Änderungen an Abhängigkeiten in der pyproject.toml-Datei ignoriert, wenn diese noch nicht in der uv.lock-Datei festgeschrieben sind.

Wollt ihr uv run in einer produktiven Umgebung verwenden, so wird mit der --no-sync-Option die Aktualisierung der Umgebung vermieden.

Aktualisieren der Python-Umgebung

Standardmässig bevorzugt uv bei der Ausführung von uv sync und uv lock die gesperrten Versionen der Pakete. Paketversionen werden nur dann geändert, wenn die Abhängigkeitsbedingungen des Projekts die vorherige, gesperrte Version ausschließen.

Mit uv lock --upgrade könnt ihr alle Pakete aktualisieren und mit uv lock --upgrade-package PACKAGE==VERSION lassen sich einzelnes Pakete auf eine bestimmte Version aktualisieren.

Tipp

Ihr könnt auch mit dem pre-commit-Framework regelmäßig eure eure uv.lock-Datei aktualisieren:

.pre-commit-config.yaml
- repo: https://github.com/astral-sh/uv-pre-commit
  rev: 0.5.21
  hooks:
    - id: uv-lock

Plattform- und Python-Versionen einschränken

Wenn euer Projekt nur eine begrenzte Anzahl von Plattformen oder Python-Versionen unterstützt, könnt ihr dies in der pyprojects.toml-Datei PEP 508-konform tun, z.B. um euer Projekt nur auf macOS und Linux einzuschränken könnt ihr in eurer pyproject.toml-Datei folgenden Abschnitt hinzufügen:

[tool.uv]
environments = [
    "sys_platform == 'darwin'",
    "sys_platform == 'linux'",
]