Opera8 commited on
Commit
b7c77a2
·
verified ·
1 Parent(s): c5e1f7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -4
app.py CHANGED
@@ -3,8 +3,9 @@ import json
3
  import random
4
  import asyncio
5
  import re
 
6
  from concurrent.futures import ThreadPoolExecutor
7
- from fastapi import FastAPI, HTTPException
8
  from fastapi.responses import HTMLResponse, JSONResponse
9
  from pydantic import BaseModel
10
  import google.generativeai as genai
@@ -14,11 +15,15 @@ load_dotenv()
14
 
15
  app = FastAPI()
16
 
 
 
 
 
 
17
  # --- بخش اصلاح شده برای بارگذاری تمیز کلیدها ---
18
  all_keys_str = os.getenv("ALL_GEMINI_API_KEYS", "")
19
 
20
  # استفاده از Regex برای جدا کردن کلیدها بر اساس کاما، خط جدید یا فاصله
21
- # این کار باعث می‌شود اگر کلیدها پشت سر هم با اینتر جدا شده باشند هم درست کار کند
22
  raw_keys = re.split(r'[,\s\n]+', all_keys_str)
23
 
24
  GEMINI_KEYS = []
@@ -42,6 +47,8 @@ executor = ThreadPoolExecutor(max_workers=10)
42
 
43
  class IdeaRequest(BaseModel):
44
  idea: str
 
 
45
 
46
  @app.get("/", response_class=HTMLResponse)
47
  async def read_root():
@@ -67,7 +74,7 @@ def sync_generate_content(prompt):
67
  current_key = random.choice(GEMINI_KEYS)
68
 
69
  genai.configure(api_key=current_key)
70
- model = genai.GenerativeModel('gemini-2.5-flash') # استفاده از مدل جدیدتر و سریعتر
71
 
72
  response = model.generate_content(prompt)
73
 
@@ -82,11 +89,57 @@ def sync_generate_content(prompt):
82
 
83
  return None
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  @app.post("/api/refine")
86
- async def refine_text(request: IdeaRequest):
87
  if not GEMINI_KEYS:
88
  raise HTTPException(status_code=500, detail="کلید API تنظیم نشده است.")
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  prompt = f"""
91
  You are a professional songwriter and music producer.
92
  Task: Convert the user's input into a COMPLETE song structure and a music generation prompt.
 
3
  import random
4
  import asyncio
5
  import re
6
+ from datetime import datetime
7
  from concurrent.futures import ThreadPoolExecutor
8
+ from fastapi import FastAPI, HTTPException, Request
9
  from fastapi.responses import HTMLResponse, JSONResponse
10
  from pydantic import BaseModel
11
  import google.generativeai as genai
 
15
 
16
  app = FastAPI()
17
 
18
+ # --- حافظه موقت برای محدودیت روزانه ---
19
+ # ساختار: { "identifier_string": { "date": "YYYY-MM-DD", "count": int } }
20
+ DAILY_LIMITS = {}
21
+ MAX_FREE_DAILY_REQUESTS = 5
22
+
23
  # --- بخش اصلاح شده برای بارگذاری تمیز کلیدها ---
24
  all_keys_str = os.getenv("ALL_GEMINI_API_KEYS", "")
25
 
26
  # استفاده از Regex برای جدا کردن کلیدها بر اساس کاما، خط جدید یا فاصله
 
27
  raw_keys = re.split(r'[,\s\n]+', all_keys_str)
28
 
29
  GEMINI_KEYS = []
 
47
 
48
  class IdeaRequest(BaseModel):
49
  idea: str
50
+ fingerprint: str # شناسه مرورگر کاربر
51
+ is_premium: bool = False # وضعیت اشتراک
52
 
53
  @app.get("/", response_class=HTMLResponse)
54
  async def read_root():
 
74
  current_key = random.choice(GEMINI_KEYS)
75
 
76
  genai.configure(api_key=current_key)
77
+ model = genai.GenerativeModel('gemini-2.0-flash') # استفاده از مدل جدیدتر و سریعتر
78
 
79
  response = model.generate_content(prompt)
80
 
 
89
 
90
  return None
91
 
92
+ def check_and_update_limit(identifier: str):
93
+ """
94
+ بررسی محدودیت روزانه برای یک شناسه (آی‌پی یا فینگرپرینت).
95
+ اگر محدودیت رد شده باشد False برمی‌گرداند.
96
+ """
97
+ today = datetime.now().strftime("%Y-%m-%d")
98
+
99
+ if identifier not in DAILY_LIMITS:
100
+ DAILY_LIMITS[identifier] = {"date": today, "count": 1}
101
+ return True
102
+
103
+ record = DAILY_LIMITS[identifier]
104
+
105
+ # اگر تاریخ رکورد قدیمی است، ریست کن
106
+ if record["date"] != today:
107
+ DAILY_LIMITS[identifier] = {"date": today, "count": 1}
108
+ return True
109
+
110
+ # بررسی تعداد
111
+ if record["count"] >= MAX_FREE_DAILY_REQUESTS:
112
+ return False
113
+
114
+ # افزایش شمارنده
115
+ DAILY_LIMITS[identifier]["count"] += 1
116
+ return True
117
+
118
  @app.post("/api/refine")
119
+ async def refine_text(request: IdeaRequest, req: Request):
120
  if not GEMINI_KEYS:
121
  raise HTTPException(status_code=500, detail="کلید API تنظیم نشده است.")
122
 
123
+ # --- بررسی محدودیت روزانه ---
124
+ if not request.is_premium:
125
+ client_ip = req.client.host
126
+ client_fingerprint = request.fingerprint
127
+
128
+ # بررسی آی‌پی
129
+ if not check_and_update_limit(client_ip):
130
+ return JSONResponse(content={"error": "LIMIT_REACHED"}, status_code=429)
131
+
132
+ # بررسی فینگرپرینت (اگر متفاوت از آی‌پی باشد)
133
+ # نکته: ما هر دو را جداگانه می‌شماریم تا دور زدن سخت‌تر شود
134
+ # اما چون تابع check_and_update_limit شمارنده را زیاد می‌کند،
135
+ # اگر کاربر با یک آی‌پی و فینگرپرینت بیاید، عملاً دوبار چک می‌شود که مشکلی نیست،
136
+ # ولی برای دقت بیشتر، اگر یکی از این دو بسته شده باشد، کل درخواست رد می‌شود.
137
+ # اینجا صرفاً اگر لیمیت آی‌پی پر نشده بود، فینگرپرینت را هم چک و آپدیت می‌کنیم.
138
+ if client_fingerprint and client_fingerprint != client_ip:
139
+ if not check_and_update_limit(client_fingerprint):
140
+ return JSONResponse(content={"error": "LIMIT_REACHED"}, status_code=429)
141
+ # ---------------------------
142
+
143
  prompt = f"""
144
  You are a professional songwriter and music producer.
145
  Task: Convert the user's input into a COMPLETE song structure and a music generation prompt.