pexels_temp

FastAPI ile Modern API Geliştirme

FastAPI ile Modern API Geliştirme: Başlangıçtan İleri Seviyeye

Günümüzde modern web uygulamaları ve servisler, hızlı, güvenilir ve ölçeklenebilir API’ler üzerine inşa edilmektedir. Python programlama dilinin popülaritesi ve kullanım alanlarının genişlemesiyle birlikte, API geliştirme araçları da önem kazanmıştır. İşte tam bu noktada FastAPI devreye giriyor. FastAPI, Python 3.6+ ile geliştirilen, yüksek performanslı, kullanımı kolay ve hızlı bir web framework’üdür. Bu makalede, FastAPI’nin temel prensiplerinden başlayarak, ileri seviye konulara kadar uzanan kapsamlı bir yolculuğa çıkacağız.

İçindekiler

FastAPI Nedir?

FastAPI, Philippe Choppin tarafından geliştirilen ve açık kaynaklı bir projedir. Diğer web framework’lerine kıyasla (örneğin Flask veya Django REST framework), FastAPI’nin öne çıkan bazı özellikleri şunlardır:

  • Hız: Starlette ve Pydantic gibi yüksek performanslı kütüphaneler üzerine inşa edilmiştir.
  • Kolay Kullanım: Öğrenmesi ve kullanması kolay bir API’ye sahiptir.
  • Az Kod: Tekrar eden kod miktarını azaltır.
  • Veri Doğrulama: Pydantic sayesinde veri doğrulama işlemleri kolaylıkla yapılabilir.
  • Otomatik Dokümantasyon: Swagger UI ve ReDoc gibi araçlar sayesinde API dokümantasyonu otomatik olarak oluşturulur.
  • Asenkron Desteği: Asenkron programlama (async/await) desteği sunar.

FastAPI Kurulumu ve Temel Yapılandırma

FastAPI’yi kullanmaya başlamak için öncelikle Python’ın kurulu olduğundan emin olun. Ardından, aşağıdaki komutu kullanarak FastAPI ve Uvicorn’u (bir ASGI sunucusu) kurun:

pip install fastapi uvicorn

Uvicorn, FastAPI uygulamanızı çalıştırmak için kullanılan bir ASGI sunucusudur. Kurulum tamamlandıktan sonra, temel bir FastAPI uygulaması oluşturabilirsiniz:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"message": "Merhaba Dünya!"}

Bu kodu `main.py` adında bir dosyaya kaydedin ve aşağıdaki komutu kullanarak uygulamayı çalıştırın:

uvicorn main:app --reload

`–reload` parametresi, kodda yapılan değişikliklerin otomatik olarak yeniden yüklenmesini sağlar. Tarayıcınızda `http://127.0.0.1:8000` adresine giderek uygulamanızı görüntüleyebilirsiniz.

İlk API Endpoint’inizi Oluşturma

FastAPI’de bir endpoint oluşturmak için, `@app` dekoratörünü ve HTTP metodunu (GET, POST, PUT, DELETE vb.) kullanmanız gerekir. Örneğin, bir GET endpoint’i oluşturmak için:

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

Bu örnekte, `/items/{item_id}` endpoint’i oluşturulmuştur. `item_id` bir path parametresidir ve `q` ise bir query parametresidir. FastAPI, tip ipuçlarını kullanarak otomatik olarak veri doğrulama yapar. Örneğin, `item_id`’nin bir integer olması beklenir.

Veri Doğrulama ve Serileştirme: Pydantic Entegrasyonu

Pydantic, Python’da veri doğrulama ve serileştirme için kullanılan bir kütüphanedir. FastAPI, Pydantic ile mükemmel bir şekilde entegre olmuştur. Bir Pydantic modeli tanımlayarak, API endpoint’lerinizdeki verilerin doğru formatta olmasını sağlayabilirsiniz:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.dict()
    if item.tax:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

Bu örnekte, `Item` adında bir Pydantic modeli tanımlanmıştır. `name`, `description`, `price` ve `tax` alanları bulunmaktadır. FastAPI, bu modeli kullanarak request body’deki verilerin doğru formatta olup olmadığını otomatik olarak doğrular.

Request Body ile Çalışma

POST, PUT ve PATCH gibi HTTP metodları genellikle request body ile veri gönderirler. FastAPI, request body’deki verileri kolayca alıp işleyebilir. Yukarıdaki örnekte, `create_item` endpoint’i, `Item` modelini kullanarak request body’deki verileri alır ve işler.

Path Parametreleri ve Query Parametreleri

Path parametreleri, endpoint URL’sinde yer alan değişkenlerdir. Query parametreleri ise, URL’nin sonuna eklenen anahtar-değer çiftleridir. FastAPI, hem path parametrelerini hem de query parametrelerini kolayca işleyebilir:

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(user_id: int, item_id: str, q: str = None, short: bool = False):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "Bu, harika bir ürün."} 
        )
    return item

Bu örnekte, `user_id` ve `item_id` path parametreleridir, `q` ve `short` ise query parametreleridir. FastAPI, veri tiplerini otomatik olarak dönüştürür ve doğrular.

Dependency Injection (Bağımlılık Enjeksiyonu)

Dependency Injection, bir nesnenin bağımlılıklarını dışarıdan almasıdır. FastAPI, bağımlılık enjeksiyonunu destekler ve bu sayede kodunuzu daha modüler ve test edilebilir hale getirebilirsiniz:

from typing import Optional

from fastapi import Depends, FastAPI, Query

app = FastAPI()

async def common_parameters(q: Optional[str] = Query(None, max_length=50), skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}


@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons

@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons

Bu örnekte, `common_parameters` fonksiyonu, `q`, `skip` ve `limit` parametrelerini alır ve bir sözlük olarak döndürür. `read_items` ve `read_users` endpoint’leri, `Depends` kullanarak bu fonksiyonu çağırır ve sonuçları kullanır.

Güvenlik: Kimlik Doğrulama ve Yetkilendirme

API’lerin güvenliği büyük önem taşır. FastAPI, OAuth2, JWT (JSON Web Tokens) gibi kimlik doğrulama ve yetkilendirme yöntemlerini destekler. Örneğin, JWT ile kimlik doğrulama yapmak için:

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt


SECRET_KEY = "YOUR_SECRET_KEY"  # Güçlü bir anahtar kullanın
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

app = FastAPI()


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


async def authenticate_user(username: str, password: str) -> Optional[dict]:
    # Burada kullanıcıyı veritabanında kontrol edin.
    # Örnek olarak, sabit bir kullanıcı verisi kullanılıyor.
    if username == "testuser" and password == "testpassword":
        return {"username": username}
    return None


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Kimlik doğrulama başarısız.",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("username")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = {"username": username}
    if user is None:
        raise credentials_exception
    return user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = await authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Yanlış kullanıcı adı veya şifre",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"username": user["username"]}, expires_delta=access_token_expires)
    return {"access_token": access_token, "token_type": "bearer"}


@app.get("/users/me/")
async def read_users_me(current_user: dict = Depends(get_current_user)):
    return current_user

Bu örnek, basit bir JWT kimlik doğrulama örneğidir. Gerçek bir uygulamada, kullanıcı verilerini bir veritabanında saklamanız ve daha güvenli bir anahtar kullanmanız gerekir.

Middleware Kullanımı

Middleware, gelen ve giden request’leri işleyen fonksiyonlardır. FastAPI, middleware kullanımını destekler ve bu sayede request’leri loglama, yetkilendirme kontrolü gibi işlemleri kolayca yapabilirsiniz:

from fastapi import FastAPI, Request
from fastapi.responses import Response
import time

app = FastAPI()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

@app.get("/")
async def read_root():
    return {"message": "Merhaba Dünya!"}

Bu örnekte, `add_process_time_header` middleware’i, her request’in işlenme süresini hesaplar ve `X-Process-Time` header’ı olarak response’a ekler.

FastAPI Uygulamalarını Test Etme

FastAPI uygulamalarını test etmek için, `pytest` ve `httpx` gibi araçları kullanabilirsiniz:

from fastapi.testclient import TestClient
from .main import app  # main.py dosyanızdan app örneğini içe aktarın

client = TestClient(app)


def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Merhaba Dünya!"}


def test_create_item():
    response = client.post(
        "/items/",
        json={"name": "Foo", "description": "", "price": 50.2, "tax": 2.0},
    )
    assert response.status_code == 200
    assert response.json() == {"name": "Foo", "description": "", "price": 50.2, "tax": 2.0}

Bu örnekte, `TestClient` kullanılarak API endpoint’lerine istekler gönderilir ve response’lar doğrulanır.

Otomatik API Dokümantasyonu (Swagger UI)

FastAPI, Swagger UI ve ReDoc gibi araçlar sayesinde API dokümantasyonunu otomatik olarak oluşturur. Uygulamanızı çalıştırdıktan sonra, `http://127.0.0.1:8000/docs` adresine giderek Swagger UI’ı görüntüleyebilirsiniz. `http://127.0.0.1:8000/redoc` adresinde ise ReDoc dokümantasyonunu görüntüleyebilirsiniz.

FastAPI Uygulamasını Dağıtma

FastAPI uygulamasını dağıtmak için, çeşitli platformları kullanabilirsiniz. Örneğin, Docker kullanarak bir konteyner oluşturabilir ve bu konteyneri bulut platformlarına (AWS, Google Cloud, Azure) veya sunucularınıza dağıtabilirsiniz. Ayrıca, Heroku, Render gibi platformlar da FastAPI uygulamalarını kolayca dağıtmanıza olanak tanır.

Sonuç

FastAPI, modern API geliştirme için güçlü ve kullanışlı bir araçtır. Hızlı performansı, kolay kullanımı, veri doğrulama özellikleri ve otomatik dokümantasyon desteği sayesinde, API geliştirme sürecini önemli ölçüde hızlandırır ve kolaylaştırır. Bu makalede, FastAPI’nin temel prensiplerinden başlayarak, ileri seviye konulara kadar birçok konuya değindik. Artık siz de FastAPI ile modern API’ler geliştirmeye başlayabilirsiniz. FastAPI ile Modern API geliştirme dünyasına hoş geldiniz!

Leave A Comment

Your email address will not be published. Required fields are marked *