from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager import os, json, requests from datetime import datetime, date # ===================================================== # CONFIG - Hugging Face Spaces için optimize # ===================================================== class Config: PREMIUM_PRICE = 499 FREE_DAILY_LIMIT = 30 SHOPIER_LINK = "https://shopier.com/42153760" DB_PATH = "/tmp/zenkamind_users.json" # Hugging Face için geçici dizin # 🔥 Hugging Face Inference API HF_MODEL = "Qwen/Qwen2.5-7B-Instruct" HF_API_URL = f"https://api-inference.huggingface.co/models/{HF_MODEL}" HF_TOKEN = os.getenv("HF_TOKEN", "") # ===================================================== # DATABASE # ===================================================== class Database: def __init__(self, path): self.path = path self.data = {} self.load() def load(self): if os.path.exists(self.path): try: with open(self.path, "r", encoding="utf-8") as f: self.data = json.load(f) except: self.data = {} else: # Eğer dosya yoksa, örnek veri oluştur self.data = { "demo@example.com": { "email": "demo@example.com", "premium": True, "daily_count": 0, "daily_limit": Config.FREE_DAILY_LIMIT, "created_at": datetime.now().isoformat(), "last_reset": date.today().isoformat() } } self.save() def save(self): try: with open(self.path, "w", encoding="utf-8") as f: json.dump(self.data, f, indent=2, ensure_ascii=False) except Exception as e: print(f"DB Save Error: {e}") def get_user(self, email): email_lower = email.lower() return self.data.get(email_lower) def create_user(self, email): email_lower = email.lower() user = { "email": email_lower, "premium": False, "daily_count": 0, "daily_limit": Config.FREE_DAILY_LIMIT, "created_at": datetime.now().isoformat(), "last_reset": date.today().isoformat() } self.data[email_lower] = user self.save() return user def can_use(self, email): email_lower = email.lower() user = self.data.get(email_lower) if not user: return False today = date.today().isoformat() if user["last_reset"] != today: user["daily_count"] = 0 user["last_reset"] = today self.save() return user["premium"] or user["daily_count"] < user["daily_limit"] def inc(self, email): email_lower = email.lower() if email_lower in self.data: self.data[email_lower]["daily_count"] += 1 self.save() def remaining(self, email): email_lower = email.lower() user = self.data.get(email_lower) if not user: return 0 return "unlimited" if user["premium"] else max(0, user["daily_limit"] - user["daily_count"]) # ===================================================== # AI ENGINE - Hugging Face API için optimize # ===================================================== class AIEngine: def __init__(self): self.headers = { "Authorization": f"Bearer {Config.HF_TOKEN}", "Content-Type": "application/json" } def build_prompt(self, message, premium): system = ( "Sen ZenkaMind adlı Türkiye merkezli yapay zekasın.\n" "ASLA başka dil konuşma.\n" "Net, güçlü, öğretici cevaplar ver.\n" "Kod sorulursa eksiksiz üret.\n" ) if premium: system += "Detaylı ve profesyonel cevap ver.\n" else: system += "Kısa ve öz cevap ver.\n" return f"<|system|>\n{system}<|user|>\n{message}\n<|assistant|>" def generate(self, message, premium=False): if not Config.HF_TOKEN: return "🔧 Sistem bakımda. Lütfen daha sonra tekrar deneyin." prompt = self.build_prompt(message, premium) try: r = requests.post( Config.HF_API_URL, headers=self.headers, json={ "inputs": prompt, "parameters": { "max_new_tokens": 250, # Hugging Face için düşürüldü "temperature": 0.7, "top_p": 0.9, "do_sample": True } }, timeout=15 # Timeout süresi kısaltıldı ) if r.status_code == 200: data = r.json() if isinstance(data, list): text = data[0].get("generated_text", "") text = text.split("<|assistant|>")[-1].strip() if not premium: text += f"\n\n💎 Premium: {Config.SHOPIER_LINK}" return text else: return "Yanıt alınamadı. Lütfen tekrar deneyin." except requests.exceptions.Timeout: return "⏳ Yanıt süresi aşıldı. Lütfen daha kısa bir mesajla tekrar deneyin." except Exception as e: print(f"AI Error: {e}") return "Sunucu yoğun. Lütfen biraz sonra tekrar deneyin." # ===================================================== # APP BAŞLATMA # ===================================================== db = Database(Config.DB_PATH) ai = AIEngine() @asynccontextmanager async def lifespan(app: FastAPI): print("🚀 ZenkaMind API başladı") print(f"🤖 Model: {Config.HF_MODEL}") print(f"📁 DB Path: {Config.DB_PATH}") print(f"👥 Users: {len(db.data)}") yield print("👋 ZenkaMind API kapanıyor") app = FastAPI( title="ZenkaMind API", description="Türkiye'nin Yerli Yapay Zeka Asistanı", version="1.0.0", lifespan=lifespan ) # CORS - Hugging Face için gerekli app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ===================================================== # ROUTES # ===================================================== @app.get("/") async def root(): return { "status": "online", "service": "ZenkaMind AI", "version": "1.0.0", "model": Config.HF_MODEL } @app.get("/health") async def health(): return { "status": "ok", "model": Config.HF_MODEL, "users": len(db.data), "timestamp": datetime.now().isoformat() } @app.post("/api/user/info") async def user_info(req: Request): try: data = await req.json() email = data.get("email", "").lower().strip() if not email or "@" not in email: return JSONResponse( status_code=400, content={"error": "Geçerli bir email gerekiyor"} ) user = db.get_user(email) if not user: user = db.create_user(email) return { "email": email, "premium": user.get("premium", False), "daily_count": user.get("daily_count", 0), "daily_limit": user.get("daily_limit", Config.FREE_DAILY_LIMIT), "remaining": db.remaining(email) } except Exception as e: return JSONResponse( status_code=500, content={"error": f"Sunucu hatası: {str(e)}"} ) @app.post("/api/chat") async def chat(req: Request): try: data = await req.json() email = data.get("email", "").lower().strip() message = data.get("message", "").strip() if not email or "@" not in email: return JSONResponse( status_code=400, content={"error": "Geçerli bir email gerekiyor"} ) if not message: return JSONResponse( status_code=400, content={"error": "Mesaj boş olamaz"} ) user = db.get_user(email) if not user: user = db.create_user(email) if not db.can_use(email): return JSONResponse( status_code=402, content={ "response": f"Günlük limit doldu ({user['daily_count']}/{user['daily_limit']}).\n💎 Premium: {Config.SHOPIER_LINK}", "status": "limit", "premium": user["premium"], "remaining": 0 } ) response = ai.generate(message, user["premium"]) db.inc(email) return { "response": response, "premium": user["premium"], "remaining": db.remaining(email), "status": "success" } except Exception as e: return JSONResponse( status_code=500, content={"error": f"Sunucu hatası: {str(e)}"} ) @app.post("/api/premium/purchase") async def purchase_premium(req: Request): try: data = await req.json() email = data.get("email", "").lower().strip() if not email or "@" not in email: return JSONResponse( status_code=400, content={"error": "Geçerli bir email gerekiyor"} ) user = db.get_user(email) if not user: user = db.create_user(email) # Demo amaçlı - gerçek ödeme sistemi için Shopier entegrasyonu gerekli user["premium"] = True db.save() return { "success": True, "message": "Premium aktif edildi (Demo)", "premium": True, "payment_link": Config.SHOPIER_LINK } except Exception as e: return JSONResponse( status_code=500, content={"error": f"Sunucu hatası: {str(e)}"} ) # Hugging Face Spaces için özel endpoint @app.get("/favicon.ico") async def favicon(): return JSONResponse(status_code=204) if __name__ == "__main__": import uvicorn uvicorn.run( "app:app", host="0.0.0.0", port=7860, # Hugging Face Spaces standart portu reload=False )