לפני קריאת פוסט זה מוטב לעבור על הפוסטים הקודמים בסדרה – הפוסט על pyenv, שעוזר לנו לנהל את גרסת הפייתון במחשב עצמו (3.11? 3.9? 3.7? אפשר לנהל, לעבור ולשדרג בקלות עם pyenv). בפוסט ההמשך דיברנו על pip + venv, שזה מנהל החבילות הראשון של פייתון ובפוסט הקודם דיברנו על pipenv, שזה מנהל חבילות מודרני. בפוסט הזה אנחנו נדבר על Poetry, שזה מנהל החבילות הפופולרי ביותר של פייתון שדומה ל pipenv אבל שונה ממנו בכמה אספקטים חשובים:
- פיצ׳רים ונוחות שימוש – קובץ הקונפיגורציה והניהול של פואטרי הרבה הרבה יותר קלים ופשוטים לשימוש מצד אחד וגם מכילים הרבה יותר פונקציונליות מהצד השני.
- טיפול ב depenency hell שאיזכרתי במאמר הקודם. למשל שיש חבילה A שצריכה את C מגרסה 1 וחבילה B שצריכה את C מגרסה 2. במה לבחור? אז בפואטרי יש את libpoetry שעושה עבודה יותר טובה ביישוב סתירות כאלו מ-pipenv.
- ביצועים ומהירות.
ובגדול, הקונספט של פואטרי לא שונה מהותית מpipenv והוא קל לשימוש. מכירים pipenv? תוך דקות תוכלו להסתדר עם פואטרי. באופן אישי? אני משתמש בו.
התקנה
הדוקומנטציה של פואטרי ממש מוצלחת! יש הוראות להתקנה פשוטה וקלה גם בחלונות וגם בסביבות אחרות. במק זה ממש פשוט! מקלידים:
curl -sSL https://install.python-poetry.org | python3 -
ואז מוודאים שיש הפניה ל-PATH המתאים ב zshrc שלכם (אם אתם משתמשים ב-zsh ואתם משתמשים בו). אם זה נשמע לכם כמו סינית – אם אתם צריכים, ה-install script יגיד לכם מה לעשות:
כדי לבדוק שהכל עובד, אנו נקליד:
poetry --version
אם מקבלים תוצאה? הכל טוב ואפשר להתחיל לעבוד. אם לא – אז שימו לב:
- לוודא שבאמת ה-PATH שלכם מעודכן.
- לעשות omz reload אחרי העדכון (אם אתם משתמשים ב-OMZ) או לסגור ולפתוח את הטאב של הקונסולה.
עבודה ראשונית עם pyproject.toml
פואטרי עובד עם קובץ הגדרה בפורמט שנקרא toml. זה פורמט די מוכר שמשתמשים בו בלא מעט מקומות ומגדיר את הפרויקט – מי מנהל אותו, מה התלויות שלו, מה גרסת הפייתון שלו וכו׳ וכו׳. אפשר ליצור את הקובץ הזה, שהוא קובץ טקסטואלי עם כל עורך קוד או להשתמש בפקודה poetry init על מנת ליצור קובץ כזה – בפרויקט קיים או פרויקט חדש. הכלי שרץ ב poetry init ישאל אותנו כל מיני שאלות ואז יצור pyproject.toml. מתכנתי Node.js? זה בדיוק כמו npm init ו-package.json.
הנה למשל קובץ לדוגמה. אין פה מדע טילים ואני חושב שהוא די ברור:
[tool.poetry]
name = "python-poetry-demo"
version = "0.1.0"
description = "This is a demo project"
authors = ["Ran Bar-Zik <[email protected]>"]
license = "BSD"
readme = "README.md"
packages = [{include = "python_poetry_demo"}]
[tool.poetry.dependencies]
python = "^3.9"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
מה שמעניין אותנו הוא ה-tool.poetry.dependencies. שהוא מכיל את החבילות התלויות והגרסאות. בפרויקט חדש יהיה לנו את פייתון בלבד (שזה די ברור, לא?) ואת הגרסה. למי שלא עבר על המאמר הקודם – הגרסאות פה ובכל מקום אחר הן לפי Semantic Versions והסימנים שלהן. אם יש רק מספר, זה אומר את הגרסה הזו בלבד.
גרסה עם כובע ^ זה אומר מיינור ומייג׳ור. למשל 3.9 עם ^ זה אומר 3.9 ומעלה אבל לא 4 (אין עדיין 4 בפייתון אבל תזרמו איתי). גרסה עם ~ זה אומר רק פאצ׳ים. למשל 3.9~ זה אומר 3.9 ומעלה – כלומר 3.9.0, 3.9.10 או 3.9.35 אבל לא 3.10 או 3.12 ובטח שלא 4. מי שצריך עוד הסבר – יש את האתר של semver שמסביר.
בואו ונתקין חבילת תוכנה ראשונה! נתקין את חבילת requests! זה פשוט. מקלידים poetry add requests. אחרי ההתקנה, אנו נראה שהיא התווספה ל-pyproject.toml:
[tool.poetry.dependencies]
python = "^3.9"
requests = "^2.28.2"
כמובן של-requests יש את התלויות שלה – הכל יופיע בקובץ poetry.lock שמכיל את הגרסאות המדויקות של כל החבילות במועד ההתקנה. בכל התקנה של חבילה חדשה, קובץ poetry.lock יתעדכן. אם יש התנגשות בין גרסאות – אז Poetry ינסה לפשר בינהם עם אלגוריתם מחוכם יותר.
הקובץ poetry.lock ו-pyproject.toml נכנסים לגיט.
אם יש קובץ poetry.lock ואנו מקלידים poetry install – תבוצע התקנה ישירות לפי הגרסאות שיש ב poetry.lock – שימו לב שזה שונה פה מ-pipenv.
כדי לעדכן את poetry.lock אנו צריכים לעשות poetry update ואז poetry.lock יתעדכן לפי הגרסאות שהגדרנו ב pyproject.toml.
הסרה של חבילות תוכנה נעשית עם
poetry remove
ושם החבילה.
הרצה
החבילות וה-bin של גרסת פייתון הרלוונטית מותקנות ב-״סביבה וירטואלית״ (אין קשר למחשב וירטואלי, אני יודע שזה מבלבל) כמובן. בדיוק כמו pipenv ו pip + venv. איפה מיקום תיקית ה-venv.? אני יכול להקליד:
poetry show -v
ולראות היכן הסביבה מותקנת. אם אני לא עושה שום דבר, הסביבה מותקנת בתיקיה גלובלית ב-cache:
זו התנהגות שיש גם ב-venv. אני פחות מתלהב מזה ואוהב שהסביבה הוירטואלית נמצאת מתחת לפרויקט. על מנת לשנות את זה אני משתמש בקונפיגורציה של פואטרי שהיא ממש מוצלחת. אני מקליד את השורה:
poetry config virtualenvs.create true
ואז מפעיל מחדש את הטרמינל. מהנקודה הזו כל פרויקט שמותקן מחדש, יצור את תיקית ה-venv בפרויקט עצמו.
לא משנה איפה קבצי הספריה הוירטואלית מופעלים. על מנת להשתמש בהם, אני משתמש ב-shell. אני מקליד poetry shell בקונסולה ואז נכנס ל״קונטקסט״ של הסביבה הוירטואלית ויכול להפעיל את הפרויקט ותהיה לו גישה את המודולים והוא ירוץ כמובן בסביבת ההרצה של גרסת פייתון שהגדרנו לו. בדרך כלל תהיה אינדיקציה גרפית כלשהי בקונסולה לכך. אני משתמש ב-powerlevel10k אז האינדיקציה תהיה python-poetry-demo py מצד ימין. אם זה zsh רגיל אז יהיו סוגריים מסביב לטרמינל.
עבודה עם קבוצות/ מוד פיתוח
בניגוד ל-pipenv שמאפשר לי רק dev ופרודקשן, בפואטרי יש לי יכולת ליצור קבוצות של תלויות בהתאם לסביבה. למשל אם אני רוצה תלויות שעובדות רק בסביבת פיתוח. אני יוצר קבוצה שנקראת dev. אם אני רוצה, מכל מיני סיבות, ליצור תלויות שעובדות רק בסביבת stage, אני יכול ליצור קבוצה שנקראת stage.
בואו ונדגים. נניח שאני רוצה להתקין רק חבילות שצריך במהלך פיתוח. אני מתקין כרגיל אבל באמצעות הוספת הפקודה –group dev:
poetry add --group dev pylint
אני אראה שיש לי פתאום קבוצה חדשה בקובץ ה-pyproject.toml
[tool.poetry]
name = "python-poetry-demo"
version = "0.1.0"
description = "This is a demo project"
authors = ["Ran Bar-Zik <[email protected]>"]
license = "BSD"
readme = "README.md"
packages = [{include = "python_poetry_demo"}]
[tool.poetry.dependencies]
python = "^3.9"
requests = "^2.28.2"
[tool.poetry.group.dev.dependencies]
pytest = "^7.2.2"
pylint = "^2.17.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
אני חושב שהפוסט הזה התארך ויש בהחלט מקום לפוסט המשך שיגיע על יכולות נוספות של פואטרי ועבודה מתקדמת איתו. אבל אם אתם משתמשים ב-pipenv או שיש לכם פרויקט חדש, בהחלט כדאי לקחת את פואטרי לסיבוב ולהתנסות איתו. העבודה דומה, כפי שאמרנו ואפשר גם לראות, לpipenv. יש יכולות חדשות, הביצועים טובים בהרבה ובכלל הוא מרגיש יותר אינטואטיבי. כמתכנת שמכיר היטב גם ג׳אווהסקריפט ו-Node.js, העבודה איתו הרבה יותר אינטואיטיבית.
5 תגובות
כדי שהסביבה תיבנה בספריה המקומית מצאתי שיש לשנות את הקונפיגורציה הבאה:
"`
poetry config virtualenvs.in-project true
"`
מקור: https://python-poetry.org/docs/configuration/#virtualenvsin-project
ניסיתי להשתמש בפקודה poetry config virtualenvs.create true
אבל עדיין בכל פרוייקט חדש אני מקבל את ה venv תחת תיקיית הקאש בווינדוס
הפקודה הנכונה היא לשנות את virtualenvs.in-project. תנסה את:
poetry config virtualenvs.in-project true
https://python-poetry.org/docs/configuration/#virtualenvsin-project
תכל להסביר על ההבדל בין פואטרי לבין קונדה כתובנה לניהול סביבות וירטואליות?
לצערי אני לא מכיר כל כך את קונדה כדי לומר משהו משמעותי.