איך בוחרים web framework בפייתון

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

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

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

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

הכל שאלה של עלות ותועלת

ניתן לסכם את כל הנושא של בחירת תשתית בהשוואה בין עלות ותועלת.

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

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

  • עקומת הלמידה של החבילה החדשה; האם התנסו בה בעבר? האם התיעוד שלה מקיף ואיכותי?
  • הקושי של התחלת פרוייקט חדש.
  • כמה קוד נצטרך לכתוב כדי לממש את הפרוייקט שלנו? או במילים אחרות – אילו שירותים מספקת התשתית שיחסכו לנו קוד וזמן? שימו לב שחלק מהחבילות מכילות שירותים כמו ניהול בסיס נתונים, cache, ניהול משתמשים ו-sessions, וכדומה, ועבור חבילות אחרות השירותים האלו קיימים כתוספים (פלאגינים).
  • כמה קשה יהיה לתחזק את הקוד לאורך זמן?
  • באיזה שרת נשתמש ב-production? האם קיימת אינטגרציה בין תשתית ה-web לשרת?

נדמיין לדוגמה שאנו ניגשים לפתח אפליקציה שממומשת כמעט כולה ב-client וצד השרת שלה פשוט במיוחד. במקרה זה העלות של שימוש בספרייה כמו django, המכילה מעל 3000 קבצים ודורשת לפחות 10 קבצים בפרוייקט שלנו רק כדי להתחיל לעבוד, היא גבוהה ביחס לתועלת הנמוכה שנקבל מכיוון שלא נשתמש בכמעט כלום ממה שיש ל-django להציע.

חלק נוסף מהעלות נגזר גם מגודל קהילת המפתחים שמשתמשים בה, שואלים ועונים על שאלות ומפתחים עבורה תוספים והרחבות. למשל נכון לכתיבת שורות אלו לחבילת flask יש כ-10,000 שאלות ב-Stack Overflow, ולעומתה על CherryPy נשאלו 960 בלבד.

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

  • מנוע templates
  • ORM – מידול וגישה לבסיסי נתונים (SQL או NoSQL)
  • ניהול משתמשים והרשאות
  • מנוע cache
  • תמיכה במספר שפות
  • Authentication
  • Multitheading
  • תמיכה בקבצים סטאטיים.
  • DB Migrations
  • ניהול קבצים סטאטיים
  • כלי בדיקה

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

לפרוייקטים קטנים – Bottle

הרבה פעמים אני מוצא את עצמי צריך לכתוב אפליקציה מבוססת javascript הדורשת מעט מאוד צד שרת, או אפילו סתם קוד python שהפלט שלו הוא טקסט בעברית שלא ניתן להציג על command line בצורה נוחה. במקרים כאלו אני רוצה להרים שרת web בפחות מדקה, ואין כמו bottle עבור משימה זאת.

חבילת Bottle היא מיקרו תשתית (micro-framework), המכילה למעשה קובץ אחד בלבד – bottle.py, שבו ממומשת תשתית web שלמה ואפילו שרת לבדיקה. כדי לכתוב תוכנית בסיסית בעזרת bottle, לא נדרשות יותר מחמש שורות הקוד הבאות:

from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

run(host='localhost', port=8080)

למרות היותה מיקרו-תשתית, bottle תומכת בכל מה שצריך כדי לבנות פרוייקטים קטנים: מנוע routing, מנגנון templating, גישה לאובייקטי request ו-response ותמיכה בהעלאת קבצים. בנוסף מכילה bottle לא מעט adapters שיעזרו להתממשק עם חבילות מפורסמות כמו Jinja2, ומעל 15 שרתי http. להלן דוגמה איך בתוספת של שורת קוד אחת בלבד ניתן להשתמש בתבניות של Jinja2:

from bottle import jinja2_view, route
 
 @route('/', name='home')
 @jinja2_view('home.html', template_lookup=['templates'])
 def home():
     return {'title': 'Hello world'}

עבור bottle נכתב גם אוסף קטן ויעיל של פלאגינים המתממשקים לשירותים כמו memcached, mongodb, SQLAlchemy, SQLite ועוד. כל אלו הופכים את bottle למתאימה מאוד עבור פרויקטים בסיסיים הדורשים מספר מצומצם של שירותים חיצוניים.

העצה שלי היא להשתמש ב-bottle לפרוייקטים שאתם לא צופים שיהפכו למפלצות. אבל גם אם כן – כל עוד תקפידו להשתמש בחבילות צד שלישי נפוצות כמו Jinja2 ו-memcached, לא אמורה להיות בעיה לשדרג בעתיד לתשתית מתקדמת יותר.

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

חלופה נפוצה וטובה לא פחות ל-bottle היא Flask, שגם היא micro framework, והקהילה שלה גדולה יותר. הנה השוואה של עוד כמה מיקרו תשתיות.

לפרוייקטים בינוניים וגדולים – Django – המלכה הבלתי מעורערת

Django היא ללא ספק גולת הכתר של חבילות תשתיות ה-web הפייתוניות. עם היסטוריה של 12 שנים, מעל 100k (!) שאלות ב-SO וקהילת מפתחים ותורמים ענקית ופעילה, תוכלו למצוא מענה מיידי כמעט לכל שאלה. מערכת ה-ORM של Django ידועה כמקיפה ביותר, תומכת במספר נאה של בסיסי נתונים מבוססי SQL, ומשמשת תמיד כדוגמה לשימוש מופתי ב-Metaclasses.

בדיוק כמו ההוא מהסרט, Django משוחררת מכל מעצורים ומאפשרת לפתח כמעט כל סוג של פרוייקט רשת, גם בקנה מידה ענקי. הגישה של Django היא "הסוללות כלולות", כלומר מפתחיה משתדלים להכניס לתוכה את כל מה שצריך בשביל רוב הפרוייקטים: ORM מפואר, cache, שפת templates שלמה, מערכת ניהול DB, ניהול sessions, ניהול משתמשים ואותנטיקציה, יכולות אבטחה, תמיכה במספר אתרים במקביל, תמיכה בקבצים סטאטיים, תמיכה במספר שפות, ועוד. ואם בכל זאת מצאתם משהו שלא כלול, בוודאי תשמחו לדעת שבמשך השנים פותחו ל-Django מאות, אם לא אלפי "אפליקציות" הרחבה, ביניהן NoSQL DB Backends, תשתיות REST API, חבילות אותנטיקציה מסוגים שונים, חבילות אבטחה, ואפילו מערכות CMS ובלוגים שלמות.

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

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