FastAPI - היכרות עם ספרית הקוד הטובה ביותר של פיתון להקמת אפליקציות אינטרנט

מחבר:
בתאריך:

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

בין יתרונותיו:

  • מהירות גבוהה של השרת (ביחס לפריימוורקים הותיקים כדוגמת: django ו-flask).
  • תפיסת עולם שמתרכזת בצרכים של המפתחים ולכן הקוד פשוט וברור יותר מה שמאיץ את הכתיבה ומפחית את כמות השגיאות.
  • תיעוד מעולה וקהילת מפתחים גדולה ונלהבת במיוחד כך שתמיד יש את מי לשאול.

fastapi - is it the best python web framework

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

להורדת הקוד אותו נפתח במדריך

תקציר ה-API בשני משפטים: משמש להעברת מידע בין מחשבים. המחשב השואל שולח בקשה request והמחשב העונה מחזיר response. העברת המידע מתבצעת ב-4 שיטות שכל המחשבים בעולם יודעים להשתמש בהם כדי לעבוד בתוך רשת האינטרנט באמצעות פרוטוקול מוסכם ששמו HTTP. המידע מועבר, בדרך כלל, בפורמט JSON.

4 השיטות (מתודות) הם:

GET

מבקש מידע משרת מרוחק

POST

שולח מידע למחשב מרוחק

PUT

מעדכן את המידע בשרת המרוחק

DELETE

מוחק מידע מהשרת המרוחק

התרשים הבא מסכם את נושא ה-REST API:

REST API

כשאנחנו משתמשים ב-FastAPI הקוד החכם שלו יודע לתרגם את הפונקציות שאנחנו כותבים למתודות בהם משתמש פרוטוקול HTTP.

 

1. התקנת סביבת העבודה והרצת השרת

הדרישה היא לפייתון גרסה 3.6 ומעלה.

נשתמש בשורת הפקודות / טרמינל כדי ליצור את תיקיית הפרויקט:

$ mkdir hello_fastapi

תמיד כדאי לעבוד בתוך סביבה וירטואלית כדי להתקין אותה נכנס לתיקיית הפרויקט ונקליד אל תוך הטרמינל:

$ python3 -m venv venv

מה שיצור סביבה וירטואלית ששמה venv.

נפעיל את הסביבה:

$ source venv/bin/activate

ונתקין בתוכה את הפריימוורק והשרת:

(venv) $ pip3 install fastapi uvicorn[standard]

מלבד הפריימוורק, FastAPI, הורדנו את השרת, uvicorn, המצוייד בטכנולוגית ASGI אסינכרונית המאפשרת טיפול במספר פניות במקביל.

נוסיף לתיקיית הפרויקט את הקובץ main.py בתוכו נכתוב את הקוד.

ראשית, נייבא את החבילות בהם תלויה האפליקציה:

main.py

# core packages
import uvicorn
from fastapi import FastAPI

# set the type of objects that app uses
from pydantic import BaseModel
  • uvicorn - הוא השרת.
  • fastapi - הוא הפריימוורק בו נשתמש לכתיבת ה-api.
  • pydantic - באמצעותו נגדיר את האובייקטים של המידע איתם האפליקציה עובדת (לדוגמה: User או Car).

נוסיף את השורה הבאה שמאתחלת את האפליקציה:

main.py

# init app
app = FastAPI()

כדי לבחון עם האפליקציה נוסיף את הנתיב והפונקציה הבאה:

main.py

@app.get('/')
def index():
  return {'hello': 'fastapi'}

ובתחתית הדף נוסיף קוד שיאתחל את השרת כשנריץ את הסקריפט:

if __name__ == '__main__':
  uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True, access_log=False)
  • הגדרנו את השרת המארח (127.0.0.1 כדי להריץ על המחשב האישי) ואת מספר הפורט.
  • הפרמטר reload מעדכן את השרת בכל פעם שאנחנו משנים את הקוד בזמן הפיתוח.

נריץ את השרת מהטרמינל:

(venv) $ python3 main.py

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

{
  "hello": "fastapi"
}

יופי! עכשיו אחרי שראינו את האפליקציה בפעולה נוסיף לה יכולות של CRUD - קריאה, כתיבה, עדכון ומחיקה.

 

2. המודל ומסד הנתונים

כדי לעבוד עם FastAPI צריך להגדיר מודלים של מידע. המערכת שלנו תנהל מידע אודות מכוניות אז נקרא לאובייקט המידע Car. בתוך קובץ האפליקציה נכתוב:

main.py

class Car(BaseModel):
  name: str
  price: int
  • שמו של האובייקט Car ואנחנו יוצרים אותו על ידי הרחבה של BaseModel של pydantic.
  • הוא כולל שני שדות: name ו-price.
  • השדה price מצפה לקבל מספרים שלמים בלבד int בעוד השדה name רשאי לקבל מחרוזות str.

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

למען הפשטות, נשתמש הפעם במערך שידמה מסד נתונים (במדריכים הבאים בסדרה נשתמש במסד נתונים אמיתי).

main.py

# in memory db
cars = [
  {"name": "Tesla", "price": 180000},
  {"name": "BMW", "price": 260000}
]

 

3. הבאת כל המידע באמצעות GET

כדי להביא את כל המידע במערך נגדיר נתיב ופונקציה המחזירה את המערך מהסעיף הקודם באמצעות המתודה get:

main.py

@app.get('/cars')
def get_cars():
  return cars

ועכשיו כשנלך לדפדפן לכתובת: 127.0.0.1:8000/cars נוכל לראות את רשימת המכוניות בפורמט json כי ל-FastAPI אין כל בעיה לקחת רשימה ולהציג אותה כאובייקט של json.

באמת מגניב! אבל FastAPI מציע דרך מאוד מסודרת לגשת ל- api על יד כניסה לכתובת: 127.0.0.1:8000/docs מה שיציג את רשימת הפונקציות שכתבנו:

צפייה בתגובה ב-GET של fastapi

לחיצה על אחת הפונקציות תפתח אותה כדי שנוכל לנסות אותה. לדוגמה, נפתח את הפונקציה cars:

ממשק API של fastapi

לחיצה על כפתור Try it out בפינה הימנית העליונה תחשוף כפתור Execute:

code execution in fastapi docs

לחיצה על כפתור Execute תקרא לפונקציה ותציג את התגובה Response:

received api response

במקרה שלנו, הקוד המוחזר status code הוא 200. מה שאומר שלא היו שגיאות שרת. ואנחנו יכולים לראות גם את גוף התגובה בפורמט json:

[
  {
    "name": "Tesla",
    "price": 180000
  },
  {
    "name": "BMW",
    "price": 260000
  }
]

בנוסף, אפשר לראות את ה-headers של התגובה ואיזו פקודה של curl צריך להפעיל כדי לקבל אותה.

 

4. בחירת המידע המוחזר גם כן באמצעות GET

כפי שאנחנו יכולים להביא את כל מערך המידע ב-GET אנחנו יכולים לבחור להביא פריט אחד מסוים ולשם כך נספק את המספר הסודר (האינדקס) של הפריט כפרמטר:

main.py

@app.get('/cars/{id}')
def get_car(id: int):
  return cars[id-1]

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

נרענן את דף התיעוד בכתובת : 127.0.0.1:8000/docs כדי שנוכל לראות את הפונקציה החדשה שהוספנו.

נפתח את תיעוד הפונקציה ואז על כפתור Try it out. נזין את ה-id שמעניין אותנו, לדוגמה 1 (בשביל הפריט הראשון במערך). נלחץ על Execute. התוצאה היא:

response get api

הקוד שמחזיר השרת הוא 200 במקרה של של מעבר מידע מוצלח, וגוף התגובה הוא הפריט הראשון במערך:

{
  "name": "Tesla",
  "price": 180000
}

 

5. הוספת מידע באמצעות POST

נוסיף פריט באמצעות מתודת post:

@app.post('/cars')
def create_car(car: Car):
  cars.append(car.dict())
  return cars[-1]

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

נרענן את הדף : 127.0.0.1:8000/docs

נפתח את תיעוד הפונקציה ואז על כפתור Try it out. נזין את המידע עבור הפריט לתוך התיבה Request body:

{
  "name": "Mercedes",
  "price": 255000
}

לחיצה על Execute תשלח את הבקשה לצד השרת, ותציג את התגובה:

post request response

הקוד שמחזיר השרת הוא 200 במקרה של של מעבר מידע מוצלח, וגוף התגובה הוא הפריט שהוספנו:

{
  "name": "Mercedes",
  "price": 255000
}

נפעיל את הפונקציה ששולפת את כל הנתונים, כדי לוודא שאכן נוסף פריט שלישי למערך:

[
  {
    "name": "Tesla",
    "price": 180000
  },
  {
    "name": "BMW",
    "price": 260000
  },
  {
    "name": "Mercedes",
    "price": 255000
  }
]

כך זה נראה בדף docs:

list of items following the creation of a new item

 

6. עדכון פריט מידע באמצעות PUT

main.py

@app.put("/cars/{id}")
def update_car(id: int, car: Car):
  cars[id-1] = car
  return cars[id-1]

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

המתודה מקבלת כפרמטר את האינדקס של הפריט ואת המידע של המכונית, ומחזיר את המידע של הפריט אחרי ההחלפה.

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

using the put method of fast api

מה שאפשר לראות בתמונה הוא שההוראה היתה להחליף את הפריט הראשון של הרשימה בפרארי במחיר 500000.

נלחץ על Execute כדי לבצע את הבקשה, ונוודא באמצעות הפונקציה GET שאכן הפריט עודכן כרצוננו. התוצאה:

[
  {
    "name": "Ferrari",
    "price": 500000
  },
  {
    "name": "BMW",
    "price": 260000
  },
  {
    "name": "Mercedes",
    "price": 225000
  }
]

 

7. מחיקת פריט באמצעות DELETE

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

main.py

@app.delete('/cars/{id}')
def delete_car(id: int):
  cars.pop(id-1)
  return {}

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

נמחק את הפריט השני של המערך:

using delete method of fastapi

נשלוף את המערך ב-GET כדי לגלות שנגרע מתוכו הפריט השני:

[
  {
    "name": "Ferrari",
    "price": 500000
  },
  {
    "name": "Mercedes",
    "price": 225000
  }
]

להורדת הקוד אותו פיתחנו במדריך

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

הוסף תגובה חדשה

 

= 5 + 4