ilaydabeyhan's picture
Update app.py
709db90 verified
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import joblib
import re
from sentence_transformers import SentenceTransformer
from threading import Lock
import os
import sys
# Pydantic: Gelen JSON verisini doğrulamak için model
class MakaleBasligi(BaseModel):
"""API'ye gelen JSON gövdesinin yapısını tanımlar ve veri doğrulamasını yapar."""
baslik: str
# FastAPI uygulamasını başlat
app = FastAPI(
title="Makale Kategorize Etme API",
description="Hugging Face üzerinde barındırılan metin gömme ve SVC ile kategori tahmin hizmeti.",
version="1.0.0"
)
# Model yükleme işlemini sadece bir kez yapmak için global değişkenler
MODEL_LOADED = False
MODEL_LOCK = Lock()
classifier = None
embedding_model = None
# Metin ön işleme fonksiyonu
def metin_temizle(metin: str) -> str:
"""Metni küçük harfe dönüştürür, noktalama işaretlerini ve sayıları kaldırır."""
if not isinstance(metin, str):
return ""
metin = metin.lower()
metin = re.sub(r'[^\w\s]', '', metin)
metin = re.sub(r'\d+', '', metin)
return metin
# Modeli yükleme fonksiyonu (Sadece bir kez çalışacak)
def load_models():
"""Modelleri ilk çalıştırmada yükler ve kilit mekanizması kullanır."""
global classifier, embedding_model, MODEL_LOADED
with MODEL_LOCK:
if MODEL_LOADED:
return
print("Modeller ilk kez yükleniyor...")
try:
# 1. SVC sınıflandırma modelini yükle
classifier_path = 'siniflandirma_modeli.pkl'
if not os.path.exists(classifier_path):
print(f"HATA: '{classifier_path}' bulunamadı. Lütfen Spaces dosya yapısını kontrol edin.", file=sys.stderr)
raise FileNotFoundError(f"Model dosyası '{classifier_path}' bulunamadı.")
classifier = joblib.load(classifier_path)
print("SVC modeli başarıyla yüklendi.")
# 2. Gömme modelini yükle
embedding_model = SentenceTransformer('distiluse-base-multilingual-cased-v2')
print("Sentence-Transformer modeli başarıyla indirildi/yüklendi.")
MODEL_LOADED = True
print("Model yükleme tamamlandı. API hazır.")
except Exception as e:
# Model yükleme hatası olursa, uygulamanın çökmesi ve Spaces'in yeniden başlatması beklenir
print(f"KRİTİK HATA: Model yüklenirken bir sorun oluştu: {e}", file=sys.stderr)
raise e
# Uygulama başlatıldığında modelleri yükle
@app.on_event("startup")
async def startup_event():
"""Uygulama başladığında modelleri yükler."""
try:
load_models()
except Exception:
# Hata fırlatılmazsa uygulama başlatılamaz.
pass
# API'nin makale başlığını alıp kategoriyi tahmin edeceği uç nokta (endpoint)
@app.post('/kategorize-et')
async def kategorize_et_api(data: MakaleBasligi):
"""
Gelen makale başlığını kategorize eder ve sonucu döndürür.
Beklenen JSON gövdesi: {"baslik": "makale başlığı metni"}
"""
if not MODEL_LOADED:
raise HTTPException(status_code=503, detail="Hizmet kullanılamıyor: Modeller henüz yüklenmedi veya yüklenirken hata oluştu.")
try:
makale_basligi = data.baslik
# Basit bir kontrol ekleyelim
if not makale_basligi or len(makale_basligi.strip()) == 0:
raise HTTPException(status_code=400, detail="Makale başlığı boş veya geçersiz.")
temizlenmis_baslik = metin_temizle(makale_basligi)
# Başlığı vektöre dönüştür
tahmin_vektoru = embedding_model.encode([temizlenmis_baslik])
# Sınıflandırma modelini kullanarak kategoriyi tahmin et
tahmin_sonucu = classifier.predict(tahmin_vektoru)[0]
# Sonucu JSON formatında döndür
return {"kategori": tahmin_sonucu}
except HTTPException as http_e:
# Pydantic veya kendi fırlattığımız HTTP hatalarını döndür
raise http_e
except Exception as e:
# Tahmin sırasında oluşan diğer hatalar
print(f"TAHMİN SIRASINDA BEKLENMEYEN HATA: {e}", file=sys.stderr)
raise HTTPException(status_code=500, detail=f"Tahmin işlemi sırasında beklenmeyen bir hata oluştu: {e}")