Labas! Šiandien sužinosime kaip nuo nulio susikurti ir publikuoti Python paketą į PyPI su uv programa. uv yra labai greita, todėl programavimas su ja dar smagesnis!
Įsidiegiame uv
Jeigu dar neturi uv, įsidiek jį terminale:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Įsitikink, kad veikia:
uv --version
Sukuriame naują biblioteką
uv turi patogią komandą projektui inicijuoti. Naudosime --lib vėliavėlę, kuri sukuria biblioteką (angl. library) — paketą, skirtą naudoti kituose projektuose.
uv init --lib mano-paketas
cd mano-paketas
Ši komanda sukurs tokią projekto struktūrą:
mano-paketas/
├── .python-version
├── README.md
├── pyproject.toml
└── src/
└── mano_paketas/
├── __init__.py
└── py.typed
Kuriant paketą, uv naudoja src struktūrą (angl. src layout). Tai reiškia, kad paketo kodas gyvena src/ direktorijoje, o ne projekto šaknyje.
Kodėl tai svarbu? Be src/ struktūros, Python importuotų tavo modulį tiesiogiai iš projekto šaknies — testuotum šaltinio failus, o ne tai, ką gaus naudotojas. Su src/ struktūra, uv run pirmiau instaliuoja paketą į laikiną aplinką, tada importuoja — taip testuoji tikrą instaliuotą paketą, kaip ir jį gautų kiti žmonės. Tai padeda pastebėti paketo konfigūracijos klaidas (pamiršti failai, neteisingi path’ai).
Peržvelgiame pyproject.toml
Sugeneruotas pyproject.toml failas atrodys maždaug taip:
[project]
name = "mano-paketas"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []
[build-system]
requires = ["uv_build>=0.10.2,<0.11.0"]
build-backend = "uv_build"
Čia mums svarbiausia:
[project]— paketo metaduomenys: pavadinimas, versija, aprašymas, priklausomybės.[build-system]— kompiliavimo sistema. uv naudoja savouv_buildpagal nutylėjimą, bet galima naudoti irhatchling,flit-core,setuptoolsar kitas.
Papildome metaduomenis pagal savo poreikius: aprašymą, autorių, licenciją:
[project]
name = "mano-paketas"
version = "0.1.0"
description = "Mano nuostabus Python paketas"
readme = "README.md"
requires-python = ">=3.11"
license = "MIT"
authors = [
{ name = "Mano Vardas", email = "mano@email.com" },
]
dependencies = []
Rašome kodą
Atsidarome src/my_package/__init__.py ir aprašome savo paketo logiką. Pavyzdžiui:
def hello(vardas: str = "Pasauli") -> str:
return f"Labas, {vardas}!"
Galime iškart patikrinti veikimą:
uv run python -c "import mano_paketas; print(mano_paketas.hello('PyPI'))"
Turėtum pamatyti:
Labas, PyPI!
Pridedame priklausomybes (jei reikia)
Jeigu tavo paketas naudoja kitas bibliotekas, pridėk jas su uv add:
uv add requests
Tai automatiškai atnaujins pyproject.toml bei uv.lock failą.
Kompiliuojame paketą
Kai kodas paruoštas, sukompiliuojame jį į distribucijos formatus (angl. source distribution ir wheel):
uv build
Rezultatas atsiras dist/ direktorijoje:
dist/
├── mano_paketas-0.1.0-py3-none-any.whl
└── mano_paketas-0.1.0.tar.gz
.tar.gz— tai šaltinio (angl. source) distribucija su visu kodu..whl— tai sukompiliuota dvejetainė (angl. wheel) distribucija, kuri įsidiegia greičiau.
PyPI paskyra ir API raktas
Prieš publikuojant reikia:
- Susikurti paskyrą pypi.org.
- Susigeneruoti API raktą (angl. API token): eik į Account Settings → API tokens ir sukurk naują raktą.
PyPI nepalaiko slaptažodžio autentifikacijos, todėl būtinas API raktas.
Rekomenduoju pirmiausia išbandyti su TestPyPI — tai PyPI kopija testavimui, kur galima bandyti publikavimą be pasekmių. Susikurk paskyrą ir API raktą ten atskirai.
Publikuojame į TestPyPI
Pirmausia, apsirašome TestPyPI indeksą savo pyproject.toml:
[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true
Tuomet publikuojame:
uv publish --index testpypi --token tavo-testpypi-api-raktas
Tikrinam ar paketas pasiekiamas:
uv run --with mano-paketas --index-url https://test.pypi.org/simple/ --no-project -- python -c "import mano_paketas; print(mano_paketas.hello())"
Publikuojame į PyPI
Kai viskas veikia su TestPyPI, publikuojame į tikrąjį PyPI:
uv publish --token tavo-pypi-api-raktas
Dabar jau tavo paketas pasiekiamas visiems!
Tikrinam ar paketas teisingai įsidiegia:
uv run --with mano-paketas --no-project -- python -c "import mano_paketas; print(mano_paketas.hello())"
--no-project vėliavėlė užtikrina, kad paketas bus instaliuotas iš PyPI, o ne iš lokalios projekto direktorijos.
Atnaujiname versiją
Norėdami išleisti naują paketo versiją, galime naudoti uv version subkomandą:
# Nustatyti konkrečią versiją
uv version 1.0.0
# Pakelti minor versiją (0.1.0 → 0.2.0)
uv version --bump minor
# Pakelti patch versiją (0.1.0 → 0.1.1)
uv version --bump patch
Pakėlus paketo versiją, ją išleisti galime ir vėl šiomis komandomis: uv build ir uv publish.
Jei nepavyko
Jei kažkas neveikia:
- Ar paketo pavadinimas laisvas? Tikrinam
https://pypi.org/project/tavo-paketas/. - Ar API raktas teisingas ir prasideda
pypi-? TestPyPI ir PyPI raktai yra skirtingi! - Ar versija nauja? PyPI neleidžia perrašyti jau publikuotos versijos — pakelk su
uv version --bump patch. - Ar
uv buildpavyksta? Patikrink, kadpyproject.tomlturi teisingą[build-system]skiltį ir kadsrc/struktūra atitinka paketo pavadinimą.
Štai ir viskas! Laukiu išbandyti tavąjį paketą!
Moksleivė
Su naujienomis, su naujienomis
Aš namo jau sugrįžau:
Aš – moksleivė, gimnazistė –
Viską, viską jau žinau:
Kad ta žemė ne kaip blynas,
Kad nesveika gerti vynas,
Kad dukart po du ne trys,
Kad diena – tai ne naktis…
Kad aukštai kitokis oras,
Kad lakštingala ne voras,
Kad šalelė prigimta
Tai yr mūsų Lietuva…
Su naujienomis, su naujienomis
Aš namo jau sugrįžau:
Aš – moksleivė, gimnazistė –
Viską, viską jau žinau:
1933 m. parašytas Matildos Olkinaitės eilėraštis.
Šaltiniai
- uv dokumentacija: Building and publishing a package https://docs.astral.sh/uv/guides/package/
- uv dokumentacija: Working on projects https://docs.astral.sh/uv/guides/projects/
- uv dokumentacija: Creating projects https://docs.astral.sh/uv/concepts/projects/init/
- PyPI: Python Package Index https://pypi.org/
- uv GitHub repozitorija https://github.com/astral-sh/uv