FastAPI מאפס: התקנה, app = FastAPI(), Route ראשון והרצת השרת

מטרות השיעור
  • ליצור ולהפעיל סביבה וירטואלית (venv) ולהתקין בה את FastAPI
  • לכתוב main.py עם app = FastAPI() ו-Route ראשון, ולהבין כל שורה
  • להריץ את השרת עם uvicorn, ולהבין כל חלק בפקודה ובפלט
  • לבדוק את השרת בדפדפן, ב-curl ובדף /docs

מה נלמד?

השיעור הזה הוא הקמה מלאה, מאפס, של שרת אמיתי:

  1. סביבה וירטואלית (venv): איפה מתקינים ספריות.
  2. התקנת FastAPI עם pip.
  3. main.py: ייבוא, יצירת app, ו-Route ראשון.
  4. הרצה עם uvicorn.
  5. בדיקה: דפדפן, curl, ודף התיעוד האוטומטי /docs.

למה צריך את זה?

בנושא מחשב, מערכת הפעלה ורשת כתבנו שרת “ידני” עם socket: bind, listen, accept, ופענוח של טקסט. ראינו כמה עבודה זה, וכמה קל לקרוס על קלט רע. FastAPI עושה את כל זה בשבילנו: מקבל את הבקשה, מפענח HTTP, מוצא את הפונקציה הנכונה, ממיר את התשובה ל-JSON, ובודק טיפוסים. אנחנו כותבים רק את הלוגיקה.

FastAPI היא מהספריות הנפוצות ביותר ל-Backend ב-Python, בעיקר ב-APIs ובעולמות ה-Data וה-AI.

הסבר מהבסיס

מהו FastAPI?

FastAPI היא Framework (מסגרת עבודה) לבניית Web APIs ב-Python. Framework = ספרייה שמכתיבה מבנה: “אתה כותב פונקציות, ואני קורא להן כשמגיעה בקשה מתאימה”.

Uvicorn הוא שרת ה-HTTP עצמו: התוכנה שמאזינה על פורט (נושא מחשב, מערכת הפעלה ורשת: listen), מקבלת חיבורים, ומעבירה כל בקשה ל-FastAPI. FastAPI = מה לענות. Uvicorn = הקבלה בכניסה.

Browser ──HTTP──► Uvicorn (listens on port 8000) ──► FastAPI (finds the right function) ──► your function
        ◄──JSON── Uvicorn ◄── FastAPI (converts dict to JSON) ◄──────────────────────── return {...}

ספרייה חיצונית ו-pip

עד עכשיו השתמשנו רק במודולים שמגיעים עם Python (os, json, logging). FastAPI היא ספרייה חיצונית (Third-party Package), ולכן צריך להתקין אותה.

pip הוא מנהל החבילות של Python: מוריד ספריות מ-PyPI (מאגר הספריות הציבורי של Python) ומתקין אותן.

סביבה וירטואלית (venv) — ולמה צריך אותה

אם מתקינים ספריות “גלובלית” (לכל המחשב), פרויקט אחד צריך FastAPI בגרסה 0.100, ופרויקט אחר צריך 0.142, ויש התנגשות. Virtual Environment (venv) = תיקייה פרטית לפרויקט, עם עותק משלה של Python ושל הספריות שלו. כל פרויקט עם הספריות שלו, בלי התנגשויות.

אנלוגיה: ארגז כלים לכל פרויקט

שיפוצניק שעובד על שלושה בתים לא מחזיק את כל הכלים בערימה אחת בבית. לכל אתר עבודה יש ארגז כלים משלו, עם בדיוק מה שהאתר צריך. venv = ארגז הכלים של הפרויקט. ו"הפעלה" (activate) = “אני עובד עכשיו עם הארגז הזה”.

Decorator — @app.get("/")

שורה שמתחילה ב-@ מעל def היא Decorator (ראינו @property בנושא OOP). ב-FastAPI, @app.get("/") אומר: “רשום את הפונקציה שמתחת כמטפלת בבקשות GET לנתיב /”.

זוכרים את המחשבון מנושא Python, עם dict של פונקציות (OPERATIONS = {"+": add, ...})? FastAPI בונה בדיוק טבלה כזו: (Method, Path) ‏←‏ פונקציה. כל @app.get(...) מוסיף שורה לטבלה. כשמגיעה בקשה, FastAPI מחפש בטבלה וקורא לפונקציה. (זה Functions as Objects בפעולה!)

Route (מסלול) = הקישור בין Endpoint (Method + Path) לבין הפונקציה שמטפלת בו.

תחביר

שלב 1 — תיקייה וסביבה וירטואלית

mkdir ~\dev\kodkod6\week-4\hello-api
cd ~\dev\kodkod6\week-4\hello-api
python -m venv .venv

שלב 2 — הפעלת הסביבה

Windows (PowerShell):

.venv\Scripts\Activate.ps1

Mac / Linux:

source .venv/bin/activate

ה-Prompt משתנה ומתחיל ב-(.venv). מעכשיו python ו-pip הם של הפרויקט.

שלב 3 — התקנה

pip install "fastapi[standard]"

[standard] מתקין את FastAPI יחד עם Uvicorn ועוד כמה כלים שימושיים. בדיקה:

pip list

שלב 4 — main.py

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def home():
    return {"message": "Hello from my first server!"}

שלב 5 — הרצה

uvicorn main:app --reload

שלב 6 — בדיקה

  • דפדפן: http://127.0.0.1:8000/
  • תיעוד: http://127.0.0.1:8000/docs
  • עצירה: Ctrl + C

דוגמת קוד ראשונה

אחרי שלבים 1–5, ה-Terminal מציג:

INFO:     Will watch for changes in these directories: ['C:\\Users\\dana\\dev\\kodkod6\\week-4\\hello-api']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [43864] using StatReload
INFO:     Started server process [29224]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

בדפדפן, http://127.0.0.1:8000/:

{"message":"Hello from my first server!"}

וב-Terminal נוספת שורה על הבקשה:

INFO:     127.0.0.1:52311 - "GET / HTTP/1.1" 200 OK

פירוק הקוד שורה אחר שורה

main.py:

שורההסבר
from fastapi import FastAPIמייבא את ה-Class בשם FastAPI מתוך הספרייה (נושא Python: from ... import).
app = FastAPI()יוצר אובייקט מה-Class (נושא OOP!). app הוא האפליקציה: הוא מחזיק את טבלת ה-Routes, ו-Uvicorn ידבר איתו.
@app.get("/")Decorator: “רשום את home כמטפלת ב-GET /”. get היא מתודה של האובייקט app.
def home():פונקציה רגילה. השם חופשי. FastAPI מזהה אותה לפי ה-Decorator, ולא לפי השם.
return {"message": "..."}מחזירים dict, ו-FastAPI ממיר אותו ל-JSON אוטומטית (Serialization, נושא Python) ומחזיר Status 200.

הפקודה uvicorn main:app --reload:

חלקהסבר
uvicornהפעלת שרת ה-HTTP.
mainהמודול: הקובץ main.py (בלי .py).
:appהאובייקט בתוך המודול: המשתנה app. “תריץ את האפליקציה שנקראת app, שנמצאת ב-main”.
--reloadמצב פיתוח: כששומרים שינוי בקוד, השרת מאתחל את עצמו אוטומטית. רק לפיתוח, לא בשרת אמיתי.

שורות הפלט:

שורהמשמעות (וחיבור לנושא מחשב, מערכת הפעלה ורשת)
Will watch for changes...מצב --reload: מעקב אחרי קבצים בתיקייה.
Uvicorn running on http://127.0.0.1:8000השרת מאזין (listen) על localhost, פורט 8000.
Started reloader process [43864]תהליך “שומר” שמזהה שינויים. PID.
Started server process [29224]התהליך שבאמת מטפל בבקשות. PID נוסף.
"GET / HTTP/1.1" 200 OKלוג של כל בקשה: Method, Path, גרסה ו-Status Code.

דוגמה נוספת

עוד Routes, ו-/docs. עדכנו את main.py (עם --reload, השרת מתעדכן לבד ברגע שתשמרו):

from fastapi import FastAPI

app = FastAPI(title="Kodkod Hello API")

COURSE = {"name": "Kodkod 6", "weeks": 5, "topics": ["OS", "Python", "OOP", "Backend", "DB"]}


@app.get("/")
def home():
    return {"message": "Hello from my first server!"}


@app.get("/course")
def course_info():
    return COURSE


@app.get("/course/topics")
def course_topics():
    return COURSE["topics"]


@app.get("/health")
def health():
    return {"status": "ok"}

בדיקות עם curl (ב-Terminal נוסף, כי הראשון תפוס בשרת):

curl.exe http://127.0.0.1:8000/course
curl.exe http://127.0.0.1:8000/course/topics
curl.exe -i http://127.0.0.1:8000/nothing

פלט:

{"name":"Kodkod 6","weeks":5,"topics":["OS","Python","OOP","Backend","DB"]}
["OS","Python","OOP","Backend","DB"]
HTTP/1.1 404 Not Found
date: Tue, 06 Oct 2026 14:30:00 GMT
server: uvicorn
content-length: 22
content-type: application/json

{"detail":"Not Found"}

פירוק:

  • FastAPI(title="Kodkod Hello API") — שם לאפליקציה, שיופיע בדף התיעוד.
  • אפשר להחזיר כל מה ש-JSON יודע לייצג: dict (/course), רשימה (/course/topics), מחרוזת או מספר.
  • נתיב שלא הוגדר (/nothing): FastAPI מחזיר לבד 404, עם JSON של שגיאה. לא כתבנו לזה שורה אחת.
  • /health — Endpoint מקובל בשרתים אמיתיים: מערכות ניטור בודקות אותו כל כמה שניות, כדי לדעת שהשרת חי.

/docs — התיעוד האוטומטי

פתחו http://127.0.0.1:8000/docs. FastAPI בנה לבד דף תיעוד אינטראקטיבי (נקרא Swagger UI):

  • רשימה של כל ה-Endpoints, עם Method ו-Path.
  • לחיצה על Endpoint → Try it out → Execute: שולח בקשה אמיתית ומציג את התשובה.
  • התיעוד מתעדכן אוטומטית עם כל Route חדש.

בנושא Students API – שרת עם מסד נתונים נשתמש בו ככלי הבדיקה המרכזי של השרת.

טעות נפוצה

הטעות 1: להתקין בלי להפעיל את ה-venv, או לפתוח Terminal חדש ולשכוח להפעיל אותו.

uvicorn : The term 'uvicorn' is not recognized ...

או:

ModuleNotFoundError: No module named 'fastapi'

בדיקה: האם ה-Prompt מתחיל ב-(.venv)? אם לא, .venv\Scripts\Activate.ps1. בכל Terminal חדש מפעילים מחדש. (חלופה שתמיד עובדת: python -m uvicorn main:app --reload.)

הטעות 2: ב-Windows, הפעלה נחסמת.

.venv\Scripts\Activate.ps1 cannot be loaded because running scripts is disabled on this system.

PowerShell חוסם הרצת סקריפטים כברירת מחדל. פותחים PowerShell ומריצים פעם אחת:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

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

הטעות 3: main:app לא תואם לקוד.

ERROR:    Error loading ASGI app. Attribute "app" not found in module "main".

הקובץ לא נקרא main.py, או שהמשתנה לא נקרא app (למשל application = FastAPI()). הפורמט הוא תמיד <file>:<variable>. ומריצים מהתיקייה שבה הקובץ נמצא (Current Working Directory, נושא מחשב, מערכת הפעלה ורשת!).

הטעות 4: פורט תפוס.

ERROR:    [WinError 10048] error while attempting to bind on address ('127.0.0.1', 8000): only one usage of each socket address (protocol/network address/port) is normally permitted

שרת אחר (או עותק קודם של אותו שרת) כבר מאזין על 8000 (נושא מחשב, מערכת הפעלה ורשת!). עוצרים אותו עם Ctrl + C ב-Terminal שלו, או מריצים על פורט אחר: uvicorn main:app --reload --port 8001.

הטעות 5: להכניס את .venv ל-Git. התיקייה ענקית ומכילה אלפי קבצים, שתלויים במחשב שלכם. מוסיפים ל-.gitignore:

.venv/
__pycache__/

ובמקום זה, שומרים רשימה של הספריות: pip freeze > requirements.txt. מי שמוריד את הפרויקט מריץ pip install -r requirements.txt.

תרגול

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

תרגיל 1: הקמת פרויקט

כתבו את רצף הפקודות שמקים פרויקט hello-api: תיקייה, סביבה וירטואלית, הפעלה שלה (Windows), והתקנת FastAPI. מה התפקיד של הסביבה הווירטואלית?

הצג פתרון
mkdir hello-api
cd hello-api
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install "fastapi[standard]"
pip list

(ב-Mac: source .venv/bin/activate.)

סביבה וירטואלית (venv) מבודדת את החבילות של הפרויקט: כל פרויקט עם הגרסאות שלו, בלי להתנגש בפרויקטים אחרים או ב-Python של המחשב. את התיקייה .venv לא מכניסים ל-Git.

תרגיל 2: Route ראשון

כתבו main.py עם אפליקציית FastAPI ו-Route ל-/ שמחזיר {"message": "Hello from my first server!"}. איך מריצים, ולאיזו כתובת גולשים?

הצג פתרון
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def home():
    return {"message": "Hello from my first server!"}

מריצים:

uvicorn main:app --reload

וגולשים ל-http://127.0.0.1:8000. main:app = הקובץ main.py, המשתנה app. --reload מפעיל מחדש את השרת אחרי כל שמירה.

תרגיל 3: מבקשה לפונקציה

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

  • (א) FastAPI ממיר את ה-dict ל-JSON
  • (ב) הדפדפן שולח GET /
  • (ג) הפונקציה home() מחזירה dict
  • (ד) Uvicorn מקבל את הבקשה בפורט 8000
  • (ה) FastAPI מוצא את הפונקציה שמתאימה ל-GET /
הצג פתרון

הסדר: (ב), (ד), (ה), (ג), (א)

  1. הדפדפן שולח GET /.
  2. Uvicorn — השרת עצמו — מקבל את הבקשה בפורט 8000.
  3. FastAPI מוצא את ה-Route שמתאים ל-Method ולנתיב.
  4. הפונקציה שלנו מחזירה dict רגיל.
  5. FastAPI ממיר אותו ל-JSON ומחזיר תשובה עם 200.

תרגיל 4: Quotes API

כתבו API של ציטוטים עם רשימת ציטוטים (מילונים עם text ו-author), ושני Routes:

  • GET /quotes — כל הציטוטים;
  • GET /quotes/count — {"count": <number>}.

תנו לאפליקציה כותרת "Quotes API".

הצג פתרון
from fastapi import FastAPI

app = FastAPI(title="Quotes API")

QUOTES = [
    {"text": "Simple is better than complex.", "author": "The Zen of Python"},
    {"text": "Readability counts.", "author": "The Zen of Python"},
    {"text": "Talk is cheap. Show me the code.", "author": "Linus Torvalds"},
]


@app.get("/quotes")
def all_quotes():
    return QUOTES


@app.get("/quotes/count")
def count_quotes():
    return {"count": len(QUOTES)}

GET /quotes/count מחזיר {"count": 3}. FastAPI ממיר גם רשימה ל-JSON. הכותרת מופיעה בדף התיעוד ב-/docs.

תרגיל 5: Swagger UI

  1. מה יש בכתובת http://127.0.0.1:8000/docs?
  2. איך משתמשים בו כדי לבדוק Route?
הצג פתרון
  1. Swagger UI — דף תיעוד ש-FastAPI בונה אוטומטית מהקוד: כל ה-Routes, ה-Method של כל אחד, הפרמטרים והתשובות.
  2. פותחים Route, לוחצים Try it out, ממלאים פרמטרים אם יש, ולוחצים Execute. רואים את הבקשה שנשלחה, את ה-Status Code ואת גוף התשובה — בלי לכתוב Client.

סיכום

  • FastAPI = Framework שמגדירים בו Routes. Uvicorn = שרת ה-HTTP שמאזין על הפורט ומעביר בקשות ל-FastAPI.
  • venv: python -m venv .venv, הפעלה (Activate.ps1 / source .venv/bin/activate), ואז pip install "fastapi[standard]". בכל Terminal חדש מפעילים מחדש.
  • app = FastAPI() = אובייקט האפליקציה. @app.get("/path") רושם פונקציה כמטפלת ב-GET /path.
  • מחזירים dict או list, ו-FastAPI ממיר ל-JSON עם 200. נתיב לא קיים מקבל 404 אוטומטית.
  • הרצה: uvicorn main:app --reload (קובץ:משתנה), מהתיקייה של הקובץ. עצירה: Ctrl + C.
  • /docs = תיעוד ובדיקה אינטראקטיביים, אוטומטיים.
  • .venv/ ב-.gitignore. requirements.txt ב-Git.

דוקומנטציה רשמית