A 3.3 után a lab projektnek már van feloldott függőségi környezete,
de a Jupyter-notebook még nincs összekötve ezzel a környezettel. Az a
feladat, hogy a notebook ne egy bizonytalan, korábbi Python-telepítést
használjon, hanem pontosan azt az interpretert és csomagkészletet,
amelyet a terminálban a uv run elindít. A bemenet a lab
könyvtár pyproject.toml-ja, a uv sync --locked
után létrejött .venv és egy telepített JupyterLab. A
megfigyelési egység egy notebook-kernel indítása: ugyanabból a
projektből többször is indítható, ezért ismételhetően ellenőrizhető. A
cél: a notebook és a CLI ugyanazt a Python-útvonalat és ugyanazokat a
csomagverziókat jelentse, és a „Restart and Run All” után lineárisan
lefusson. A hibás állapotra vonatkozó előzetes becslés: ha a notebook
egy globális vagy másik projekt kernelét használja, a notebookból kiírt
sys.executable eltér a .venv-beli
Python-útvonaltól, és az importelt verziók sem egyeznek a lock szerinti
környezettel.
A JupyterLab (böngészőben futó munkakörnyezet) csak a
notebook-dokumentumot, .ipynb-t szerkeszti és jeleníti meg.
A Python-kódot nem a JupyterLab, hanem egy külön kernel folyamat hajtja
végre. A Jupyter ezt a kernel folyamatot a Jupyter kernel protokollon
keresztül éri el; a Python oldali implementáció az
ipykernel (interactive Python kernel). A JupyterLab
tehát elküldi a cella kódját a kernelnek, a kernel végrehajtja, és az
eredményt visszaküldi a felületnek. A cellakimenet a
.ipynb-ben meg is marad, de ez a kimenet csak az adott
kernelállapot múltját rögzíti — önmagában nem bizonyítja, hogy a
jelenlegi kód a jelenlegi környezetben sikeresen lefutott.
A kernelspec a kernel regisztrációs bejegyzése: egy
rövid JSON-fájl, amely leírja, hogy a Jupyter milyen parancsot indítson
az adott kernel elindításakor. A --name a belső azonosító,
a --display-name pedig a Jupyter felületén látható felirat.
A két név különbözhet; a regisztrációt követően a felület a
megjelenített nevet, a parancsok és a fájlok a belső nevet használják.
Egy tipikus kernelspec a következő alakú:
{
"argv": [
"/felhasznalo/northstar/lab/.venv/bin/python",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
],
"display_name": "Northstar labs (Python 3.12)",
"language": "python"
}Az argv lista első eleme a tényleges Python-interpreter.
A {connection_file} helyére a Jupyter a kernel indításakor
egy kapcsolati fájl útvonalát írja, amelyen a notebook és a kernel
kommunikál. Ha az argv[0] a lab .venv-jére
mutat, a notebook a projekt környezetét használja; ha egy globális
python bejegyzésre, akkor nem. Ezért a regisztrációt nem
szabad globális python -m ipykernel install paranccsal
elvégezni, mert az a globális interpretert rögzíti. A
uv run python -m ipykernel install viszont a projekt
.venv Pythonját indítja, és az ipykernel
installáló ezt az abszolút útvonalat írja be a kernelspecbe.
A Restart and Run All a notebook tiszta
újrafuttatása: a kernel leáll, a Jupyter a kernelspecből vadonatúj
folyamatot indít, majd minden cellát felülről lefelé végrehajt. Ennek
fontos része, hogy a cellák között rejtett összefüggések is felszínre
kerüljenek. Ha egy későbbi cella egy korábbi cella által létrehozott
változóra támaszkodik, de a korábbi cella most hibát dob, a Restart and
Run All ezt megmutatja. Az újraindított kernelben a cellák végrehajtási
sorszáma [1], [2], [3] szerint
halad. A böngésző egyszerű frissítése ezzel szemben nem indítja újra a
kernelt; csak újratölti a notebook kimeneti állapotát.
A csomagverziók ellenőrzésének két független rétege
van. A lockfájl rögzíti, mit kellett telepíteni; a futó környezetben az
importlib.metadata.version vagy a uv pip list
mutatja, mi van ténylegesen az adott interpreterhez kötve. A notebook és
a CLI összehasonlításakor a verziószövegnek pontosan egyeznie kell. A
könyv keretjegyzete szerint a kezdőprojekt pandas 2.2.3-mal futott,
ezért ez a konkrét verzió használható ellenőrzési példaként. Ha a
notebookban más verzió jelenik meg, az azonnali jele a környezeti
eltérésnek.
A munkamenetet Linuxon vagy macOS-en mutatom be; a Windows-eltérést a
parancsok után jelölöm. A munkakönyvtár a lab projekt gyökere, például
~/northstar/lab. A könyv írásakor ezeket a parancsokat nem
futtattam, ezért az alábbi kimenetek a várt alakot szemléltetik, nem
rögzített futási jegyzékek.
Először a lab környezetét frissítjük a lock szerint:
# Munkakönyvtár: ~/northstar/lab (Linux/macOS)
uv lock
uv sync --lockedA uv lock elkészíti a feloldott uv.lock-ot,
ha a projektmappa még nem tartalmazza; a uv sync --locked a
lockkal összhangban telepíti a .venv-be. A
--locked itt nem csak kényelmi kapcsoló: hibát ad, ha a
pyproject.toml és a lock nincs összhangban. Ezután a
terminálból ellenőrizzük a környezetet:
uv run python -c "import sys; print(sys.executable)"
# Várt, szemléltető kimenet:
# /home/felhasznalo/northstar/lab/.venv/bin/pythonA következő lépés a kernelspec regisztrálása. A --user
kapcsoló a felhasználói Jupyter-könyvtárba helyezi a bejegyzést, így a
JupyterLab a felhasználó bármely projektjéből megtalálja:
uv run python -m ipykernel install --user \
--name "northstar-labs" \
--display-name "Northstar labs (Python 3.12)"A regisztráció után a JupyterLab megnyitása a projektkörnyezetből történik:
uv run jupyter labHa a lab pyproject.toml dev függőségei között a
JupyterLab nem szerepelne, az
uv run --with jupyterlab jupyter lab ideiglenesen
elérhetővé teszi a parancs idejére. A notebookban a kernelválasztónál a
„Northstar labs (Python 3.12)” feliratot kell választani. Indítás után
két cellát teszünk a notebookba. Az első a futó interpretert és a
környezethez tartozó csomagverziókat írja ki:
import os
import sys
from importlib.metadata import version
print("executable:", os.path.realpath(sys.executable))
for package in ["ipykernel", "numpy", "pandas"]:
print(package, version(package))A második cella szándékosan egy egyszerű számítást végez, hogy a kernel valódi végrehajtása is látszódjon:
print("sum check:", 1 + 2)Ezután a JupyterLab menüben a Kernel → Restart Kernel and Run
All Cells… parancsot adjuk. A kernelt a regisztrált kernelspec
indítja el, minden cella újra lefut, és a notebook kimenete a jelenlegi
környezetből származik. A cellák mellett [1],
[2] sorszámok jelennek meg. Ugyanezt a kódot a terminálból
is lefuttatjuk:
uv run python -c "import os, sys; from importlib.metadata import version; print('executable:', os.path.realpath(sys.executable)); print('pandas', version('pandas'))"A két kimenetet egymás mellé téve ellenőrizzük. A notebook és a CLI
akkor van összekötve, ha mindkét oldal ugyanazt a
.venv-beli Python-útvonalat írja ki, és a
pandas verziója mindkét helyen pontosan
2.2.3.
Windows PowerShellben ugyanez a munkamenet a következő alakú:
# Munkakönyvtár: a lab könyvtár
uv lock
uv sync --locked
uv run python -c "import sys; print(sys.executable)"
# Várt alak: C:\Users\felhasznalo\northstar\lab\.venv\Scripts\python.exe
uv run python -m ipykernel install --user --name "northstar-labs" --display-name "Northstar labs (Python 3.12)"
uv run jupyter labAz eltérés lényeges része a 2.4-ban tárgyalt útvonalkép: a Windows
bináris könyvtár neve Scripts, a Linux/macOS bináris
könyvtár neve bin. A kernelspec fájl ezért gépenként újra
regisztrálandó; a .venv nyers másolása vagy a logikai
.. relatív útvonalak nem garantálják ugyanazt a
regisztrációt.
A létrejött kernelspec ellenőrzése parancssorból:
uv run jupyter kernelspec list
# Szemléltető, várható sor a bejegyzések között:
# northstar-labs /home/felhasznalo/.local/share/jupyter/kernels/northstar-labsLinuxon vagy macOS-en a fájl:
cat ~/.local/share/jupyter/kernels/northstar-labs/kernel.jsonWindowson:
Get-Content $env:APPDATA\jupyter\kernels\northstar-labs\kernel.jsonA JSON argv[0] elemének a lab .venv
Pythonjára kell mutatnia. Ha itt rövid, csupasz python név
állna, az a PATH-tól függő indítást jelentene; a uv run-nal
végzett regisztráció ezt elkerüli, mert az abszolút útvonalat
rögzíti.
Az ellenőrzési invariant: a notebookból kiírt
os.path.realpath(sys.executable) és a terminálparancs
uv run python által kiírt realpath ugyanazt a fájlt jelöli,
és a lekérdezett csomagverziók pontosan egyeznek. A verziószövegben
nincs érdemi tolerancia; egy numpy verzióeltérés már azt
jelenti, hogy a két folyamat más csomagkészletet lát. Az
útvonalkiírásban lehet minimális formai eltérés a szimbolikus linkek
feloldása előtt, ezért használunk os.path.realpath-ot. A
Restart and Run All után a cellák [1],
[2] sorszámai mutatják, hogy a kernel tényleg újraindult. A
sum check: 3 kimenet önmagában triviális, de a friss
cellakimenettel együtt azt bizonyítja, hogy a notebook jelenlegi
végrehajtása sikeres volt; a régi, felülírt kimenet nem maradhat a
notebookban. A regisztrált kernelspec és a notebook környezet közötti
kapcsolat érvényességi korlátja: a --user bejegyzés
gépszintű felhasználói állapot, ezért másik gépen újra kell
regisztrálni, és a .venv törlése után a bejegyzés nem
automatikusan frissül.
Kernel-életciklus. A kernelspec neve és a kernelen belül futó Python
két külön azonosító. A notebookban mindig ellenőrizni kell a
sys.executable értékét és az importált csomag tényleges
verzióját. Egy régi kernelregisztráció a virtuális környezet törlése
után is hátramaradhat.
Takarítás és visszaellenőrzés: a kernelspecek
felsorolása jupyter kernelspec list, az elavult
regisztráció eltávolítása
jupyter kernelspec remove <név> (csak a megfelelő név
megerősítése után). Új kernelbe történő bejelentkezés után a notebook
Restart & Run All próba adja a záró kontrollt.
Értelmezés. Mi a különbség a kernelspec
--name és --display-name értéke között? Miért
nem elég a JupyterLab felületén kiírni egy „Python 3” nevű kernelre, ha
a lab .venv-et akarjuk használni?
Implementálás. Regisztrálj egy második kernelt
--name "northstar-check" néven, „Northstar check”
megjelenített névvel. Indítsd el a kernelt egy notebookban, és futtasd
le a sys.executable-t és a pandas verzióját
kiíró cellát. Hasonlítsd össze a terminál uv run python
kimenetével. Mi a minimális ellenőrzési feltétel, és milyen parancsot
használsz a tesztkernel eltávolítására?
Hibadiagnózis. Egy tanuló notebookja az
import scipy cellánál ModuleNotFoundError-t
ad, miközben a terminálban az
uv run python -c "import scipy" sikeres. Adj három
lehetséges okot, és mindegyikhez egy konkrét diagnosztikai parancsot
vagy notebook-lépést.
Megváltozott feltételű továbbvitel. Ugyanazon
projektet egy második, Windows-gépen uv sync --locked után
megnyitják, de a JupyterLab kernelválasztója nem kínálja a lab kernelt.
Mi a hiányzó lépés, és hogyan ellenőrzöd, hogy a regisztráció a Windows
.venv\Scripts\python.exe útvonalat rögzítette? Mutass egy
--sys-prefix változatot is, ha a környezetet csak ehhez a
projekthez akarjuk kötni.
1. feladat. A --name a kernelspec
könyvtár- és parancsazonosítója, például northstar-labs; a
Jupyter ezen a néven hivatkozik a JSON-bejegyzésre, és ezzel távolítható
el. A --display-name a JupyterLab felületén megjelenő,
ember által olvasható felirat, például „Northstar labs (Python 3.12)”;
kizárólag vizuális szerepe van. Egy „Python 3” feliratú kernel mögött
bármelyik regisztráció állhat; a notebook kiválasztásakor a felirat nem
árulja el, melyik interpreterhez mutat. Ezért a kiválasztás után a
notebookban le kell futtatni a sys.executable-t kiíró
cellát is, mert az azonosító csak a háttérben tárolt bejegyzést
egyértelműsíti.
2. feladat. A regisztráció:
uv run python -m ipykernel install --user --name "northstar-check" --display-name "Northstar check"A notebookban a „Northstar check” kernelt választjuk, majd futtatjuk:
import os
import sys
from importlib.metadata import version
print(os.path.realpath(sys.executable))
print(version("pandas"))A terminálból:
uv run python -c "import os, sys; from importlib.metadata import version; print(os.path.realpath(sys.executable)); print(version('pandas'))"A minimális ellenőrzési feltétel: a két realpath-útvonal megegyezik,
és a pandas verziószövege pontosan azonos; a tárgyalt
laborban a várt érték 2.2.3. A tesztkernel
eltávolítása:
uv run jupyter kernelspec remove northstar-checkA törlés után a uv run jupyter kernelspec list már nem
tartalmazza a bejegyzést.
3. feladat. Lehetséges okok és ellenőrzésük:
print(sys.executable); ha az útvonal nem a lab
.venv-re mutat, akkor a kernelválasztóban másik kernel van
kiválasztva.python -m ipykernel install-t futtatott.
Diagnózis: uv run jupyter kernelspec list, majd a listázott
útvonalon a kernel.json argv[0] elemének
megnézése.scipy a terminálban a lab .venv-ben
elérhető, de a notebook kernel folyamata még a uv sync
előtti, régi környezetből fut. Diagnózis: Restart Kernel and Run All
Cells a notebookban, majd print(sys.executable) újra; ez a
régi folyamatot megszakítja és a kernelspecből friss folyamatot
indít.4. feladat. A uv sync --locked a lock
szerinti környezetet telepíti, de a kernelspec felhasználói regisztráció
nem a lock része, ezért a második gépen a notebook nem ismeri a kernelt.
A hiányzó lépés:
uv run python -m ipykernel install --user --name "northstar-labs" --display-name "Northstar labs (Python 3.12)"A Windows-útvonal ellenőrzése:
Get-Content $env:APPDATA\jupyter\kernels\northstar-labs\kernel.jsonA JSON argv[0] elemének a
C:\Users\felhasznalo\northstar\lab\.venv\Scripts\python.exe
alakot kell mutatnia. A projekthez kötött --sys-prefix
változat:
uv run python -m ipykernel install --sys-prefix --name "northstar-labs" --display-name "Northstar labs (Python 3.12)"Ez a bejegyzést a projekt .venv alá helyezi, például a
.venv\share\jupyter\kernels\northstar-labs könyvtárba, így
a kernelválasztóban akkor jelenik meg, ha a JupyterLab ebből a
környezetből indul; a felhasználói kernelspec-tár rendszerszintű
állapotát nem terheli.
Egy régi cellakimenet nem igazolja az aktuális kód sikeres futását. Tegyük fel, hogy a notebookban a következő cella korábban sikeresen futott:
print(version("pandas"))
# korábbi kimenet: 2.2.3Ezután a tanuló a pyproject.toml-ban módosítja a
pandas-verziót, lefuttatja a uv lock és
uv sync --locked parancsot, majd a notebook celláját
átírja:
print(version("pandas").upper())Ha a cellát nem futtatja újra, a notebook továbbra is a régi
2.2.3 kimenetet mutatja, miközben a kód már más utasítást
tartalmaz. A régi kimenet hamis bizonyíték: úgy tűnik, a notebook
sikeres volt, pedig az aktuális kódot senki sem hajtotta végre. A
Restart Kernel and Run All Cells ezt a csapdát oldja fel, mert a régi
kernel megszűnik, és minden cellát az aktuális kernelspec szerint indít
újra. Ez a jelenség ugyanaz a gép- és környezetfüggő állapotprobléma,
mint a 2.4-ban a másik gépen való futtatás: a notebook dokumentumon
kívüli állapotot nem másolja a verziókezelés. Emellett a 3.3 határa is
érvényes: ha a projekt környezetét uv kezeli, a kernel regisztrációját
is uv run-nal érdemes végezni, nehogy a kernelspec egy
conda- vagy globális Pythonra mutasson.
Önellenőrzésként nyissunk egy új notebookot, indítsuk el a „Northstar
labs” kernelt, futtassuk a Restart and Run All-t, majd
hasonlítsuk össze a kiírt os.path.realpath(sys.executable)
értéket a terminál uv run python kimenetével. Ha a két
útvonal megegyezik, a regisztráció helyes; ha nem, a kernelspec
argv[0] elemét kell javítani, vagy a rossz kernelbejegyzést
eltávolítani.
A notebook csak akkor reprodukálható, ha a Jupyter-kernel pontosan a
projekt .venv-jére mutat. A kernelspec egy JSON-bejegyzés,
amelynek argv[0] eleme a tényleges Python-útvonal; a
--name az azonosító, a --display-name a
felületi felirat. A
uv run python -m ipykernel install --user a lab környezetét
regisztrálja. A Restart and Run All új kernelt indít, és minden cellát
lineárisan futtat; a régi cellakimenet nem bizonyítja az aktuális kód
sikerét. A notebook és a CLI ellenőrzésekor a realpath-útvonalnak és a
csomagverzióknak pontosan egyezniük kell. A következő alfejezetben ezt a
munkaasztalt notebook-végrehajtási gráfként használjuk: cellák közötti
függőség, hibakeresés és notebookból script átalakítás kerül sorra.