Opera8 commited on
Commit
0c994eb
·
verified ·
1 Parent(s): 1ee66d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -20
app.py CHANGED
@@ -1,11 +1,31 @@
1
  import os
2
  import json
3
- from fastapi import FastAPI
 
 
 
4
  from fastapi.responses import HTMLResponse, JSONResponse
5
  from pydantic import BaseModel
 
 
 
 
6
 
7
  app = FastAPI()
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  class IdeaRequest(BaseModel):
10
  idea: str
11
 
@@ -17,29 +37,85 @@ async def read_root():
17
  except FileNotFoundError:
18
  return "<h1>Error: index.html not found</h1>"
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  @app.post("/api/refine")
21
  async def refine_text(request: IdeaRequest):
22
- # چون جیمینای نداریم، فرض می‌کنیم ورودی کاربر همان متن آهنگ است
23
- user_input = request.idea.strip()
 
 
 
 
 
 
24
 
25
- # تشخیص ساده برای اینکه آیا ورودی فارسی است یا انگلیسی (برای جهت متن)
26
- is_persian = any("\u0600" <= c <= "\u06FF" for c in user_input)
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- # ساختاردهی دستی (چون هوش مصنوعی نداریم که ورس و کورس بسازد)
29
- # کل متن کاربر را در یک بخش [Verse] قرار می‌دهیم
30
- lyrics = f"""[Verse]
31
- {user_input}
 
 
 
 
 
 
 
 
32
  """
33
 
34
- # پرامپت موسیقی پیش‌فرض (چون نمی‌توانیم سبک را از متن استخراج کنیم)
35
- # اگر متن فارسی بود، سبک پاپ ایرانی در نظر میگیریم
36
- if is_persian:
37
- music_prompt = "Persian Pop song, emotional, clear vocals, high quality, 120 bpm"
 
 
 
38
  else:
39
- music_prompt = "Pop song, catchy melody, clear vocals, high quality, 120 bpm"
40
-
41
- # خروجی استاندارد که فرانت‌اند انتظار دارد
42
- return JSONResponse(content={
43
- "music_prompt": music_prompt,
44
- "lyrics": lyrics
45
- })
 
1
  import os
2
  import json
3
+ import random
4
+ import asyncio
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from fastapi import FastAPI, HTTPException
7
  from fastapi.responses import HTMLResponse, JSONResponse
8
  from pydantic import BaseModel
9
+ import google.generativeai as genai
10
+ from dotenv import load_dotenv
11
+
12
+ load_dotenv()
13
 
14
  app = FastAPI()
15
 
16
+ # 1. بارگذاری تمام کلیدها در حافظه
17
+ all_keys_str = os.getenv("ALL_GEMINI_API_KEYS", "")
18
+ # تمیز کردن لیست کلیدها
19
+ GEMINI_KEYS = [k.strip() for k in all_keys_str.split(",") if k.strip()]
20
+
21
+ if GEMINI_KEYS:
22
+ print(f"تعداد {len(GEMINI_KEYS)} کلید جیمینای بارگذاری شد.")
23
+ else:
24
+ print("هشدار: هیچ کلید جیمینای یافت نشد.")
25
+
26
+ # 2. ایجاد ThreadPool برای اجرای موازی درخواست‌ها (دست‌های زیاد)
27
+ executor = ThreadPoolExecutor(max_workers=10)
28
+
29
  class IdeaRequest(BaseModel):
30
  idea: str
31
 
 
37
  except FileNotFoundError:
38
  return "<h1>Error: index.html not found</h1>"
39
 
40
+ def sync_generate_content(prompt):
41
+ """
42
+ این تابع همگام است و در یک ترد جداگانه اجرا می‌شود تا سرور اصلی را قفل نکند.
43
+ تلاش می‌کند تا 100 بار با کلیدهای مختلف محتوا تولید کند.
44
+ """
45
+ max_retries = 100 # درخواست شما: 100 بار تلاش تصادفی
46
+
47
+ for _ in range(max_retries):
48
+ try:
49
+ # انتخاب کاملاً تصادفی یک کلید در هر بار تلاش
50
+ current_key = random.choice(GEMINI_KEYS)
51
+
52
+ genai.configure(api_key=current_key)
53
+ model = genai.GenerativeModel('gemini-2.5-flash')
54
+
55
+ # تولید محتوا (این عملیات ممکن است طول بکشد)
56
+ response = model.generate_content(prompt)
57
+
58
+ clean_json = response.text.replace("```json", "").replace("```", "").strip()
59
+ data = json.loads(clean_json)
60
+
61
+ return data # موفقیت! خروجی را برگردان
62
+
63
+ except Exception as e:
64
+ # خطا را نادیده بگیر و دوباره تلاش کن (حلقه بعدی)
65
+ # print(f"Key failed: {str(e)[:50]}...")
66
+ continue
67
+
68
+ # اگر بعد از 100 تلاش نشد
69
+ return None
70
+
71
  @app.post("/api/refine")
72
  async def refine_text(request: IdeaRequest):
73
+ if not GEMINI_KEYS:
74
+ raise HTTPException(status_code=500, detail="کلید API تنظیم نشده است.")
75
+
76
+ prompt = f"""
77
+ You are a professional songwriter and music producer.
78
+ Task: Convert the user's input into a COMPLETE song structure and a music generation prompt.
79
+
80
+ 1. **Music Prompt (English):** Describe the mood, instruments, BPM, and style suitable for an AI music generator.
81
 
82
+ 2. **Lyrics (Match User's Language):**
83
+ - **Language Detection:** Detect the language of the "User Input".
84
+ - **Write the lyrics entirely in that detected language.**
85
+ - The song MUST be long enough for **3 to 5 minutes**.
86
+ - If the language is Persian/Arabic, do **NOT** use diacritics (اعراب نگذار).
87
+ - You MUST use the following structure tags exactly:
88
+ [Verse 1]
89
+ [Pre-Chorus]
90
+ [Chorus]
91
+ [Verse 2]
92
+ [Chorus]
93
+ [Bridge]
94
+ [Guitar Solo]
95
+ [Chorus]
96
+ [Outro]
97
 
98
+ **CRITICAL RULES FOR LYRICS content:**
99
+ - The "lyrics" field must contain **ONLY the words to be sung**.
100
+ - **ABSOLUTELY NO** descriptive text inside the lyrics.
101
+ - For instrumental sections, leave the content empty.
102
+
103
+ Output strictly in JSON format:
104
+ {{
105
+ "music_prompt": "YOUR ENGLISH PROMPT HERE",
106
+ "lyrics": "YOUR FULL LYRICS HERE"
107
+ }}
108
+
109
+ User Input: {request.idea}
110
  """
111
 
112
+ # 3. اجرای درخواست سنگین در پس‌زمینه (Non-blocking)
113
+ # این باعث می‌شود سرور اصلی آزاد باشد و بتواند درخواست‌های جدید بگیرد
114
+ loop = asyncio.get_running_loop()
115
+ result = await loop.run_in_executor(executor, sync_generate_content, prompt)
116
+
117
+ if result:
118
+ return JSONResponse(content=result)
119
  else:
120
+ # اگر بعد از 100 تلاش هیچ کلیدی کار نکرد
121
+ return JSONResponse(content={"error": "Server busy (100 retries failed). Please try again later."}, status_code=503)