- FastAPI tətbiqini yaratmaq və
fastapi devvə yauvicornilə lokal işə salmaq - Yol və sorğu parametrlərini tiplərlə elan etmək, JSON gövdəsini Pydantic modeli ilə yoxlamaq
- Düzgün status kodları qaytarmaq və API-ni
/docsvəTestClientilə yoxlamaq
Əvvəlki dərsdə biz müştəri idik və başqasının API-sinə sorğu göndərirdik. İndi rolları dəyişirik: öz serverimizi yazacağıq. FastAPI müasir Python freymvorkudur: funksiyanın parametrlərindəki tip annotasiyalarından (type hints) istifadə edərək gələn verilənləri özü yoxlayır, JSON-a çevirir və interaktiv sənədlər yaradır. Mobil tətbiq üçün backend, kiçik mikroservis və ya maşın öyrənməsi modelini API kimi təqdim etmək — FastAPI bunlar üçün populyar seçimdir.
İlk tətbiq və lokal işə salma
Server brauzerdə işləyə bilmir, ona görə bu dərsin kodu burada icra olunmur — onu öz kompüterində (Python 3.10 və ya daha yeni) sına. Dekorator @app.get('/yol') funksiyanı həmin ünvana gələn GET sorğularına bağlayır; funksiyanın qaytardığı lüğət avtomatik JSON cavabına çevrilir.
from fastapi import FastAPI
app = FastAPI(title='Educora Demo API')
@app.get('/')
def root():
return {'message': 'Hello from FastAPI'}
@app.get('/square/{number}')
def square(number: int):
return {'number': number, 'square': number ** 2}
@app.get('/greet')
def greet(name: str, lang: str = 'en'):
greetings = {'en': 'Hello', 'az': 'Salam', 'ru': 'Привет', 'tr': 'Merhaba'}
word = greetings.get(lang, 'Hello')
return {'text': f'{word}, {name}!'}main.py faylı. {number} — yol parametri; name və lang isə yolda olmadıqları üçün sorğu parametrləridir, lang-ın susmaya görə qiyməti var, ona görə məcburi deyil.- 1Virtual mühit yarat
Layihə qovluğunda
python -m venv .venvicra et və onu aktivləşdir: Windows-da.venv\Scripts\activate, Linux və macOS-dəsource .venv/bin/activate. - 2FastAPI-ni quraşdır
pip install "fastapi[standard]"— FastAPI ilə birlikdəuvicornserveri vəfastapiəmri də quraşdırılır. - 3Serveri işə sal
fastapi dev main.py(və yauvicorn main:app --reload). Serverhttp://127.0.0.1:8000ünvanında işləyir və fayl dəyişəndə özü yenidən başlayır. - 4Sənədləri aç
Brauzerdə
http://127.0.0.1:8000/docssəhifəsini aç — bütün ünvanlar orada görünür və onları «Try it out» düyməsi ilə birbaşa sınamaq olar.
curl http://127.0.0.1:8000/square/12
curl "http://127.0.0.1:8000/greet?name=Aysel&lang=az"
curl http://127.0.0.1:8000/square/abc{"number":12,"square":144}
{"text":"Salam, Aysel!"}
{"detail":[{"type":"int_parsing","loc":["path","number"],"msg":"Input should be a valid integer, unable to parse string as an integer","input":"abc"}]}abc tam ədəd olmadığı üçün FastAPI funksiyanı heç çağırmır və 422 kodu ilə xətanın harada olduğunu izah edən cavab qaytarır. Windows PowerShell-də curl əvəzinə curl.exe yaz.Pydantic modelləri ilə REST API
POST sorğusunun JSON gövdəsini Pydantic modeli təsvir edir: BaseModel-dən törəyən sinif sahələri və onların tiplərini sadalayır, Field isə əlavə şərtlər qoyur (məsələn, başlıq 1–100 simvol). Funksiyanın qaytarma tipi (-> Task) cavabı da yoxlayır və artıq sahələri süzür. Tapşırıqlar üçün kiçik API quraq; verilənlər sadəlik üçün yaddaşdakı lüğətdə saxlanır.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
app = FastAPI(title='Educora Tasks API')
class TaskIn(BaseModel):
title: str = Field(min_length=1, max_length=100)
subject: str = 'python'
done: bool = False
class Task(TaskIn):
id: int
tasks: dict[int, Task] = {}
@app.post('/tasks', status_code=201)
def create_task(task: TaskIn) -> Task:
new = Task(id=len(tasks) + 1, **task.model_dump())
tasks[new.id] = new
return newtasks.py, 1-ci hissə: modellər və yaratma. Müştəri id göndərmir — onu server təyin edir, ona görə giriş (TaskIn) və çıxış (Task) modelləri ayrıdır.@app.get('/tasks')
def list_tasks(subject: str | None = None, limit: int = 10) -> list[Task]:
found = [t for t in tasks.values() if subject is None or t.subject == subject]
return found[:limit]
@app.get('/tasks/{task_id}')
def get_task(task_id: int) -> Task:
if task_id not in tasks:
raise HTTPException(status_code=404, detail='Task not found')
return tasks[task_id]tasks.py, 2-ci hissə: oxuma. HTTPException funksiyanı dayandırır və müştəriyə 404 kodu ilə {"detail": "Task not found"} göndərir. Serveri fastapi dev tasks.py ilə işə sal.| Sorğu | Nə edir | Cavab |
|---|---|---|
POST /tasks | yeni tapşırıq yaradır | 201 və ya 422 (yanlış gövdə) |
GET /tasks?subject=python&limit=5 | süzgəclə siyahı qaytarır | 200 |
GET /tasks/{task_id} | bir tapşırığı qaytarır | 200 və ya 404 |
API-ni test etmək
TestClient tətbiqi real server işə salmadan birbaşa çağırır — sorğular və cavablar tamamilə həqiqi olur. Bu, pytest testləri üçün idealdır: hər dəfə kodu dəyişəndə bütün ünvanları saniyələr içində yoxlaya bilərsən.
from fastapi.testclient import TestClient
from tasks import app
client = TestClient(app)
r = client.post('/tasks', json={'title': 'Learn FastAPI'})
print(r.status_code, r.json())
client.post('/tasks', json={'title': 'Revise SQL', 'subject': 'sql'})
print(client.get('/tasks', params={'subject': 'python'}).json())
r = client.get('/tasks/99')
print(r.status_code, r.json())
r = client.post('/tasks', json={'title': ''})
print(r.status_code, r.json()['detail'][0]['msg'])201 {'title': 'Learn FastAPI', 'subject': 'python', 'done': False, 'id': 1}
[{'title': 'Learn FastAPI', 'subject': 'python', 'done': False, 'id': 1}]
404 {'detail': 'Task not found'}
422 String should have at least 1 characterField(min_length=1) şərtini pozur — Pydantic sorğunu funksiyaya çatmamış rədd edir. subject göndərilməyəndə susmaya görə 'python' qiyməti götürülür.Əsas fikirlər
app = FastAPI()və@app.get(...),@app.post(...)dekoratorları funksiyaları ünvanlara bağlayır; qaytarılan lüğət JSON olur.- Yoldakı
{ad}yol parametridir, qalan arqumentlər sorğu parametrləridir; tiplər avtomatik yoxlanılır (səhvdə 422). - Pydantic
BaseModelvəFieldJSON gövdəsini təsvir edib yoxlayır;status_code=201vəHTTPException(404)düzgün cavab verir. - Lokal işə salma:
pip install "fastapi[standard]", sonrafastapi dev main.py; sənədlər/docsvə/redocünvanlarındadır. TestClientAPI-ni server olmadan test edir; real verilənləri yaddaşda yox, verilənlər bazasında saxla.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.
@app.get('/users/{user_id}') ilə def get_user(user_id: int, full: bool = False) funksiyasında full nədir?