Spaces:
Sleeping
Sleeping
| 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() | |
| 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 | |
| # ===================================================== | |
| async def root(): | |
| return { | |
| "status": "online", | |
| "service": "ZenkaMind AI", | |
| "version": "1.0.0", | |
| "model": Config.HF_MODEL | |
| } | |
| async def health(): | |
| return { | |
| "status": "ok", | |
| "model": Config.HF_MODEL, | |
| "users": len(db.data), | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| 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)}"} | |
| ) | |
| 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)}"} | |
| ) | |
| 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 | |
| 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 | |
| ) |