מנהל חבילות לפייתון: pip ו-venv

הבסיס של ניהול החבילות בפייתון 3 ומעלה: pip ו-venv.

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

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

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

למה?

אז הנה דוגמה לסקריפט ששולח בקשה ל example.com בלי שום מודול:

import http.client

# Set up the connection
conn = http.client.HTTPSConnection("www.example.com")

# Send the request
conn.request("GET", "/")

# Get the response
res = conn.getresponse()

# Print the response status code and content
print(f"Status code: {res.status}")
print(f"Content:\n{res.read().decode('utf-8')}")

והנה דוגמה לסקריפט פייתון שמשתמש ב-requests:

import requests

# Make the request
response = requests.get("https://www.example.com")

# Print the response status code and content
print(f"Status code: {response.status_code}")
print(f"Content:\n{response.text}")

אני חושב שדי ברור מה קל יותר גם לכתיבה וגם למימוש וזו דוגמה קטנה בלבד.

אז כיוון שבחלק גדול מהתוכנות אנחנו משתמשים במודולים חיצוניים כדי לחסוך הרבה קוד ולקבל פשטות וקלות – נשאלת השאלה: ״איך מתקינים חבילה? מן הסתם כל החבילות בפייתון מותקנות באמצעות pip (שיכול לקבל את החבילות שלו מ-PyPi או מארטיפקטורי פרטי). אז אנו מתקינים עם pip install ושם החבילה.

מה קורה כשמתקינים חבילה? בואו ונראה:

pip הוא שהוא מותקן עם פייתון מגרסה 3.4. כדי לבדוק אם יש לכם אותו, הקלידו בטרמינל:

pip --version

סביר להניח שיש לכם אותו. במיוחד אם התקנתם גרסה של pyenv לניהול גרסת פייתון במערכת ההפעלה.

כשאני משתמש ב-pip install להתקין חבילה, למשל pip install requests, ההתקנה נעשית גלובלית. אפשר לראות את זה בקלות באמצעות הפקודה pip show ואז שם החבילה.

pip show requests                                                                         ok
Name: requests
Version: 2.28.2
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache 2.0
Location: /Users/barzik/.pyenv/versions/3.11.0/lib/python3.11/site-packages
Requires: certifi, charset-normalizer, idna, urllib3
Required-by:

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

אגב, זו לא בעיה שמתרחשת רק בפייתון. גם ב-Node.js יש אותה.

הפתרון של פייתון הוא סביבה וירטואלית. חשוב להבהיר שלא מדובר במכונה וירטואלית (אני תמיד מתבלבל) אלא במונח שונה. באנגלית Virtual Environment או venv. מה שזה אומר – סביבה מבודדת מהמחשב הגלובלי/המכונה הגלובלית שייחודית אך ורק לפרויקט שלי. מגרסה 3.3 של פייתון יש לנו venv באופן אוטומטי.

שימו לב: יש את venv ויש את virtualenv שנפוץ בגרסאות פייתון ישנות יותר שזה משהו אחר לגמרי ואני לא כותב עליו כאן.

איך מפעילים את זה? בקלות. בפרויקט שלי, אני אכתוב בטרמינל את השורה:

python -m venv .venv

ואז יקרה פלא – תהיה לנו תיקית venv.

 ~/local/demos/demo-python-project  python -m venv .venv                                                                      ok
 ~/local/demos/demo-python-project  l                                                                                    ok | 4s
total 8
drwxr-xr-x   4 barzik  staff   128B Mar 11 11:14 .
drwxr-xr-x  12 barzik  staff   384B Mar 11 11:02 ..
drwxr-xr-x   6 barzik  staff   192B Mar 11 11:14 .venv
-rw-r--r--   1 barzik  staff    22B Mar 11 11:03 main.py

התיקיה הזו לא תופעל ולא תכנס לפעולה עד שאקליד:

# In mac
source .venv/bin/activate

# In Windows
.venv\Scripts\activate.bat

מהרגע הזה, ועד שאקליד deactivae ב-shell, אני בתוך סביבה מבודדת. אם אני אתקין את requests עם pip, אני אגלה להפתעתי שכשאני משתמש ב pip show requests, המקור של החבילה יהיה דווקא בתוך תיקית venv!

pip show requests                                                   ok | 5s | demo-python-project py
Name: requests
Version: 2.28.2
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache 2.0
Location: /Users/barzik/local/demos/demo-python-project/.venv/lib/python3.11/site-packages
Requires: certifi, charset-normalizer, idna, urllib3
Required-by:

אבל מה יקרה אם אני ארצה לשכפל את הסביבה? למשל למתכנת אחר – איך אני יכול לומר למתכנת אחר שהוא צריך להתקין את requests? או חבילה אחרת? במקרה הזה אני יכול להקליד pip freeze כדי שיציג לי את כל החבילות שיש לי בפרויקט עם הגרסאות הרלוונטיות להן ואם אני רוצה לשמור את זה בקובץ אז:

pip freeze > requirements.txt

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

pip install -r requirements.txt

וככה בעצם עבדו בפייתון. אבל יש כמה בעיות עם זה – למשל, אם אני רוצה להסיר חבילה אני צריך לכתוב pip uninstall ואז את שם החבילה ולייצר מחדש את ה-requirements.txt ואז להכניס אותו לתוך הריפו מחדש.

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

פוסטים נוספים שכדאי לקרוא

DALL·E 2023-10-21 22.28.58 - Photo of a computer server room with red warning lights flashing, indicating a potential cyber threat. Multiple screens display graphs showing a sudde
יסודות בתכנות

מבוא לאבטחת מידע: IDOR

הסבר על התקפה אהובה ומוצלחת שבאמצעותה שואבים מידע מאתרים

פתרונות ומאמרים על פיתוח אינטרנט

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

גלילה לראש העמוד