סביבות מבודדות בפייתון - venv & pip

הקדמה

כשאנחנו עובדים עם פייתון ורוצים להשתמש ביכולות הקהילה העצומות שלה, נרצה להשתמש בחבילות שאנשים אחרים כתבו.
לשם שיתוף החבילות, מפתחי פייתון יצרו את pip package installer for python שמטרתו לאפשר התקנה ושדרוג פשוטים של חבילות פייתון אל מול מקור מסוים.

מי שכותב חבילה מסוימת יכול להעלות אותה אל שרת החבילות של פייתון pypi - python package index. ואז על מנת להתקין את החבילה כל מה שהמשתמש יצטרך לעשות זה לכתוב pip install package_name.

בפרויקט בוגר בפייתון נוכל לראות שימוש גם בעשרות של חבילות, ולכל חבילה יכולות תלויות משל עצמה.

מטרת הפוסט לדבר על איך סביבה וירטואלית עוזרת לנו להישאר שפויים תוך שימוש בספריות פייתון חיצוניות בתוך הקוד שלנו.

למה צריך סביבה וירטואלית?

דמיינו את המקרה הבא - התחלתי לכתוב את הפרויקט שלי ובמהלך כתיבתו הבנתי שעליי להתשמש בספריה requests בגרסה 1.0.0. אני עובד עם הגרסה הזו ומשתמש ב requests ואז לאחר כמה חודשים אני פותח פרויקט נוסף שבו עליי להשתמש ב requests בגרסה עד 0.8 משום שהחל מגרסה זו כבר אין תמיכה בפיצ׳ר מסוים בו אני משתמש (אל תנסו את זה בבית).

תחת התיקייה של פייתון בתת התיקייה site-pakcages אראה את כל החבילות שהתקנתי ושם אוכל לראות את requests רק בגרסה אחת ספציפית. כלומר - בכל פעם שארצה להריץ את אחת האפליקציות אצטרך לוודא שהגרסה הנכונה של requests מותקנת בסביבת הפייתון שלי.

כאשר משתמשים בסביבה וירטואלית, נוצרת תיקייה אשר מכילה את קובץ ההרצה של python ועוד כל קבצים שימושיים בפייתון (כמו setup, pip וכו׳), וכאשר אני עובד מתוך הסביבה ומתקין חבילות, python מכיר רק את החבילות אותן התקנתי תחת אותה הסביבה.

כלומר, באמצעות סביבה וירטואלית אני יכול להחזיק מספר סביבות פייתון (אפילו בגרסאות שונות) ועל כל סביבה יכולות להיות חבילות שונות לגמרי.

יתרון גדול נוסף הוא שאפשר לבנות כך אפליקציות קלות יותר, משום שאינני צריך להחזיק בסביבה שלי את כל החבילות שהתקנתי אי פעם, אלא רק את הרלוונטיות להרצת התכנית שלי.

כאשר אני עובד בסביבה וירטואלית, אוכל לייצר תמונת מצב של הספריות המותקנות על הסביבה שלי באותו הרגע ולשמור קובץ עם השמות והגרסאות שלהן.
לאחר מכן, מתי שרק ארצה, אוכל פשוט להתקין את הספריות בדיוק כמו שהן כתובות בקובץ על סביבה אחרת וכך להבטיח שהסביבה בה אני עובד נראית בדיוק כמו הסביבה הקודמת ושלא אמורות להיות לי בעיות תאימות גרסאות של חבילות.

venv

venv היא החבילה הנפוצה ביותר והפשוטה ביותר שמאפשרת לנו לייצר סביבה וירטואלית בפייתון.
החל מגרסה 3.3, venv נכנס באופן מובנה לשפה ואין צורך להתקינו.

אז איך מייצרים סביבה וירטאלית?
כאשר פייתון מותקן על המחשב שלנו, כל מה שצריך לעשות להריץ את הפקודה הבאה:
python -m venv /path/to/virtual/environment

אחרי שהרצנו את הפקודה נוכל להכנס לנתיב בו יצרנו את הסביבה ולראות שם שיש ממש את כל הספריות והקבצים הבינאריים הרלוונטיים להרצת פייתון (bin ו lib).

כעת, אם נרצה להריץ קוד או להתקין ספריות דרך אותה הסביבה נוכל לעשות זאת באמצעות הרצת ה interperter מתוך הסביבה בנתיב - path/to/virtual/environment/bin/python3.

דרך נוספת (ומומלצת) להריץ מתוך הסביבה הוירטואלית היא לעשות אקטיבציה לסביבה באופן הבא:
source /path/to/virtual/environment/bin/activate

מהרגע שעשינו אקטיבציה לסביבה הוירטואלית, כל דבר שנריץ (לא משנה מאיזה תיקייה) יעבור דרך אותה הסביבה.

requirements.txt

דרך מקובלת ופשוטה לשמור את כל התלויות והגרסאות בסביבה שלנו על מנת שנוכל להשתמש בהן לאחר מכן היא באמצעות הקובץ requirements.txt.

במידה ואני עובד עם venv במקום מסוים, והתקנתי כל מיני חבילות על אותה הסביבה באמצעות pip install, אני יכול לשמור תמונת מצב של כל הספריות בהן אני משתמש לתוך קובץ ה requirements
באמצעות הפקודה:
pip freeze > requirements.txt
את קובץ ה requirements ארצה לשמור בתיקייה הראשית של הפרויקט שלי וכך אוכל להבטיח שלא משנה באיזו סביבה אני נמצא על שעליי יהיה לעשות זה רק להתקין את התלויות מתוך הקובץ, ואז הסביבה מוכנה לפעולה.
pip install -r requirements.txt

התהליך יראה כך:
[tomer@localhost ~]$ python3 -m venv /tmp/myvenv1 (myvenv1 יצירת הסביבה)

[tomer@localhost ~]$ source /tmp/myvenv1/bin/activate (אקטיבציה לסביבה)


שימו לב לסוגריים שיתווספו כעת משמאל שמציינים שאני נמצא בתוך הסביבה


(myvenv1) [tomer@localhost ~]$ pip install requests (התקנת חבילה)

(myvenv1) [tomer@localhost ~]$ ....... (תהליך ההתקנה)

(myvenv1) [tomer@localhost ~]$ pip freeze > /tmp/requirements.txt (שמירת תמונת המצב של החבילות)

(myvenv1) [tomer@localhost ~]$ cat /tmp/requirements.txt (הדפסת החבילות שנשמרו)

certifi==2020.6.20

chardet==3.0.4

idna==2.10

requests==2.24.0

urllib3==1.25.11


וכעת נוכל ליצור סביבה חדשה ולהתקין עליה בקלות את החבילות מהסביבה הקודמת באופן הבא:

(myvenv1) [tomer@localhost ~]$ deactivate (יציאה מהסביבה הראשונה)

[tomer@localhost ~]$ python3 -m venv /tmp/myvenv2 (myvenv2 יצירת הסביבה השניה)

[tomer@localhost ~]$ source /tmp/myvenv2/bin/activate (אקטיבציה לסביבה השניה)

(myvenv2) [tomer@localhost ~]$ pip freeze (לא ידפיס כלום משום שכרגע אין חבילות מותקנות)

(myvenv2) [tomer@localhost ~]$ pip install -r /tmp/requirements.txt (התקנת)

(myvenv2) [tomer@localhost ~]$ pip freeze

certifi==2020.6.20

chardet==3.0.4

idna==2.10

requests==2.24.0

urllib3==1.25.11


סיכום

סביבות וירטואליות זה קונספט מאוד פשוט אך עוצמתי שעוזר לנו להתמודד עם ניהול הספריות של פייתון בצורה פשוטה וגורם לכך שכשנרצה להריץ את הפרויקט שלנו במחשב אחר, נוכל לעשות זאת בקלות רבה יותר.

בפוסט הסברתי על הצורך בשימוש בסביבות וירטואליות ונתתי דוגמה לאחד מסוגי הסביבות הנפוצים בפייתון - venv.

בפוסט הבא אדבר על pipenv, האח הצעיר והמוצלח של venv ואסביר מה הוא נותן שאנחנו לא יכולים לקבל מ venv.

נתראה :)

תגובות

  1. ממש מועיל וכתוב סופר ברור, תודה רבה!
    אתה ממליץ לפתוח venv חדש לכל פרויקט שעובדים עליו בנפרד? יש בזה ערך?

    השבמחק
    תשובות
    1. בסוף המטרה היא לעבוד באופן מבודד מבלי להתקין תלויות שלא צריך, אז כן, יש בזה הרבה ערך. מחר ניקח את הפרויקט ונרצה להריץ אותו במכונה נפרדת ואז נגלה שפספנו איזו תלות כי היא פשוט הייתה מותקנת על המחשב ולא היינו צריכים אותה קודם

      מחק
  2. אני חושב שיש לי הרחבה / תוספת מעניינת לנושא שכדאי להוסיף :) אם רלוונטי, אשמח שתיצור קשר ואשלח לך במייל את הסיכומון האישי שלי שמוסיף טיפ טיפה אקסטרה + המקורות שהסתמכתי עליהם. בכל אופן, אחלה תקציר והסבר במילים שלך.

    השבמחק
  3. תודה על ההסבר, עכשיו זה מובן לי.

    השבמחק

הוסף רשומת תגובה

פוסטים פופולריים מהבלוג הזה

תכנות מונחה עצמים | Dependency Inversion Principle

מהם קבצי DLL ואיך להשתמש בהם?

מה ההבדל בין אוטומציה לפיתוח רגיל