Məzmuna keç
Educora
İrəli20 dəq27 / 42

FastAPI ilə veb servis

FastAPI ilə kiçik REST API qur: yol və sorğu parametrləri, Pydantic modelləri ilə yoxlama, 201 və 404 cavabları, avtomatik sənədlər (`/docs`), serveri kompüterində işə salmaq və `TestClient` ilə test etmək.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • FastAPI tətbiqini yaratmaq və fastapi dev və ya uvicorn ilə 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 /docs və TestClient ilə 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.

Python
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.
  1. 1
    Virtual mühit yarat

    Layihə qovluğunda python -m venv .venv icra et və onu aktivləşdir: Windows-da .venv\Scripts\activate, Linux və macOS-də source .venv/bin/activate.

  2. 2
    FastAPI-ni quraşdır

    pip install "fastapi[standard]" — FastAPI ilə birlikdə uvicorn serveri və fastapi əmri də quraşdırılır.

  3. 3
    Serveri işə sal

    fastapi dev main.py (və ya uvicorn main:app --reload). Server http://127.0.0.1:8000 ünvanında işləyir və fayl dəyişəndə özü yenidən başlayır.

  4. 4
    Sənədləri aç

    Brauzerdə http://127.0.0.1:8000/docs sə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.

Terminal
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
Gözlənilən nəticə
{"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.

Python
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 new
tasks.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.
Python
@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ğuNə edirCavab
POST /tasksyeni tapşırıq yaradır201 və ya 422 (yanlış gövdə)
GET /tasks?subject=python&limit=5süzgəclə siyahı qaytarır200
GET /tasks/{task_id}bir tapşırığı qaytarır200 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.

Python
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'])
Gözlənilən nəticə
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 character
Boş başlıq Field(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 BaseModel və Field JSON gövdəsini təsvir edib yoxlayır; status_code=201 və HTTPException(404) düzgün cavab verir.
  • Lokal işə salma: pip install "fastapi[standard]", sonra fastapi dev main.py; sənədlər /docs və /redoc ünvanlarındadır.
  • TestClient API-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.

1 / 10
@app.get('/users/{user_id}') ilə def get_user(user_id: int, full: bool = False) funksiyasında full nədir?