Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, File, UploadFile, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from PIL import Image | |
| import io | |
| import torch | |
| from transformers import AutoImageProcessor, AutoModelForImageClassification | |
| import numpy as np | |
| app = FastAPI() | |
| # CORS ayarları - Tüm kaynaklardan gelen isteklere izin ver | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Model ve processor'ı yükle | |
| MODEL_NAME = "Pavarissy/ConvNextV2-large-DogBreed" | |
| print(f"🔄 Loading model: {MODEL_NAME}") | |
| try: | |
| processor = AutoImageProcessor.from_pretrained(MODEL_NAME) | |
| model = AutoModelForImageClassification.from_pretrained(MODEL_NAME) | |
| model.eval() | |
| print("✅ Model loaded successfully!") | |
| except Exception as e: | |
| print(f"❌ Error loading model: {e}") | |
| raise e | |
| async def root(): | |
| """Ana endpoint - API durumunu gösterir""" | |
| return { | |
| "message": "Dog Breed Classification API", | |
| "model": MODEL_NAME, | |
| "status": "ready", | |
| "endpoints": { | |
| "predict": "/predict_pet (POST)", | |
| "health": "/health (GET)" | |
| } | |
| } | |
| async def predict_pet(image: UploadFile = File(...)): | |
| """ | |
| Pet (köpek ırkı) tahmini endpoint'i | |
| Expected response format: | |
| { | |
| "predicted_label": "n02085620-Chihuahua", | |
| "confidence": 0.95, | |
| "detection": { | |
| "box": {"x": 50, "y": 50, "width": 400, "height": 400} | |
| } | |
| } | |
| """ | |
| try: | |
| # Resmi oku ve RGB'ye çevir | |
| image_bytes = await image.read() | |
| img = Image.open(io.BytesIO(image_bytes)).convert('RGB') | |
| # Orijinal görüntü boyutları | |
| width, height = img.size | |
| print(f"📸 Image received: {width}x{height}") | |
| # Model için preprocessing | |
| inputs = processor(images=img, return_tensors="pt") | |
| # Tahmin yap | |
| with torch.no_grad(): | |
| outputs = model(**inputs) | |
| logits = outputs.logits | |
| # Softmax ile olasılıkları hesapla | |
| probabilities = torch.nn.functional.softmax(logits, dim=-1) | |
| confidence, predicted_idx = torch.max(probabilities, dim=-1) | |
| # Tahmin edilen sınıfı al | |
| predicted_label = model.config.id2label[predicted_idx.item()] | |
| confidence_score = confidence.item() | |
| # Basit bir detection box oluştur (görüntünün %80'i merkeze yerleştirilmiş) | |
| box_margin = 0.1 | |
| detection_box = { | |
| "x": float(width * box_margin), | |
| "y": float(height * box_margin), | |
| "width": float(width * (1 - 2 * box_margin)), | |
| "height": float(height * (1 - 2 * box_margin)) | |
| } | |
| # Yanıt hazırla (React Native app'in beklediği formatta) | |
| response = { | |
| "predicted_label": predicted_label, | |
| "confidence": float(confidence_score), | |
| "detection": { | |
| "box": detection_box | |
| }, | |
| "imageDimensions": { | |
| "width": width, | |
| "height": height | |
| } | |
| } | |
| print(f"✅ Prediction: {predicted_label} (confidence: {confidence_score:.4f})") | |
| return response | |
| except Exception as e: | |
| print(f"❌ Error during prediction: {str(e)}") | |
| raise HTTPException(status_code=500, detail=f"Prediction error: {str(e)}") | |
| async def health_check(): | |
| """Sağlık kontrolü endpoint'i""" | |
| return { | |
| "status": "healthy", | |
| "model_loaded": model is not None, | |
| "model_name": MODEL_NAME | |
| } | |
| # Hugging Face Space'te uvicorn otomatik çalışır | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |