Jedi09 commited on
Commit
b590dfd
·
verified ·
1 Parent(s): b742bb7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -41
app.py CHANGED
@@ -1,43 +1,121 @@
1
- # --- GÜNCELLENMİŞ GEMINI FONKSİYONLARI (RETRY MEKANİZMALI) ---
 
 
 
 
2
 
3
- def call_gemini_api_with_retry(url, headers, payload, max_retries=3):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  """
5
- API 429 hatası verirse bekleyip tekrar dener.
6
  """
7
- import time
8
-
9
- for attempt in range(max_retries):
10
- try:
11
- response = requests.post(url, headers=headers, json=payload, timeout=60)
12
-
13
- # Eğer başarılıysa hemen döndür
14
- if response.status_code == 200:
15
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- # Eğer 429 (Kota) hatasıysa bekle
18
- if response.status_code == 429:
19
- wait_time = (attempt + 1) * 5 # 5sn, 10sn, 15sn bekle
20
- print(f"⚠️ Kota dolu (429). {wait_time} saniye bekleniyor...")
21
- time.sleep(wait_time)
22
- continue # Döngü başa döner ve tekrar dener
23
 
24
- # Diğer hatalarda direkt döndür
25
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- except Exception as e:
28
- if attempt == max_retries - 1:
29
- raise e
30
- time.sleep(2)
31
- return response
32
 
33
  def summarize_with_gemini(text: str, user_api_key: str, custom_prompt: str = "") -> str:
 
34
  api_key = get_api_key(user_api_key)
35
 
36
- if not api_key: return "⚠️ API Anahtarı eksik."
37
- if not text or "⚠️" in text: return "⚠️ Önce metin oluşturun."
 
 
 
38
 
39
  clean_text = text.split("───────────────────────────────────")[0].strip()
40
- full_prompt = f"{custom_prompt or 'Bu metni Türkçe özetle:'}\n\n{clean_text}"
 
 
41
 
42
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}"
43
  headers = {"Content-Type": "application/json"}
@@ -47,37 +125,86 @@ def summarize_with_gemini(text: str, user_api_key: str, custom_prompt: str = "")
47
  }
48
 
49
  try:
50
- # YENİ RETRY FONKSİYONUNU KULLANIYORUZ
51
- response = call_gemini_api_with_retry(url, headers, payload)
52
-
53
  if response.status_code == 200:
54
  return response.json()["candidates"][0]["content"]["parts"][0]["text"]
55
- elif response.status_code == 429:
56
- return "⏳ Sistem çok yoğun (429). Lütfen 1 dakika bekleyip tekrar deneyin veya kendi API anahtarınızı girin."
57
  return f"❌ API Hatası: {response.status_code}"
58
  except Exception as e:
59
  return f"❌ Hata: {str(e)}"
60
 
61
  def translate_with_gemini(text: str, user_api_key: str, target_language: str) -> str:
 
62
  api_key = get_api_key(user_api_key)
63
- if not api_key: return "⚠️ API Anahtarı eksik."
64
 
 
 
 
65
  clean_text = text.split("───────────────────────────────────")[0].strip()
66
  target_lang_eng = {"Türkçe": "Turkish", "İngilizce": "English", "Almanca": "German", "Fransızca": "French"}.get(target_language, "English")
67
 
68
- full_prompt = f"Translate to {target_lang_eng}:\n{clean_text}"
69
 
70
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}"
71
  payload = {"contents": [{"parts": [{"text": full_prompt}]}]}
72
 
73
  try:
74
- # YENİ RETRY FONKSİYONUNU KULLANIYORUZ
75
- response = call_gemini_api_with_retry(url, {"Content-Type": "application/json"}, payload)
76
-
77
  if response.status_code == 200:
78
  return response.json()["candidates"][0]["content"]["parts"][0]["text"]
79
- elif response.status_code == 429:
80
- return "⏳ Kota dolu (429). Lütfen kendi API anahtarınızı girerek deneyin."
81
  return f"❌ Hata: {response.status_code}"
82
  except Exception as e:
83
- return f"❌ Hata: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Ses Deşifre Pro - Türkçe Ses-Metin Dönüştürme
3
+ Hugging Face Spaces için profesyonel arayüz.
4
+ Gradio 6.x uyumlu + Gemini AI Özet Desteği + Streaming Output.
5
+ """
6
 
7
+ import gradio as gr
8
+ from faster_whisper import WhisperModel
9
+ import tempfile
10
+ import time
11
+ import requests
12
+ import os
13
+
14
+ # ==================== CONFIGURATION ====================
15
+ MODEL_SIZE = "medium" # Options: tiny, base, small, medium, large-v3
16
+ # Buraya kendi Gemini API Anahtarını yazabilirsin veya
17
+ # Hugging Face Settings -> Secrets kısmına "GEMINI_API_KEY" adıyla ekleyebilirsin (Daha güvenli).
18
+ DEFAULT_GEMINI_KEY = os.environ.get("GEMINI_API_KEY")
19
+ # =======================================================
20
+
21
+ # Load model once at startup
22
+ print(f"🔄 Model yükleniyor ({MODEL_SIZE})... (Bu işlem birkaç dakika sürebilir)")
23
+ try:
24
+ model = WhisperModel(
25
+ MODEL_SIZE,
26
+ device="cpu",
27
+ compute_type="int8"
28
+ )
29
+ print("✅ Model yüklendi!")
30
+ except Exception as e:
31
+ print(f"❌ Model yükleme hatası: {e}")
32
+ model = None
33
+
34
+ def get_api_key(user_key):
35
  """
36
+ Kullanıcı anahtar girdiyse onu kullan, yoksa sistemdeki gizli anahtarı kullan.
37
  """
38
+ if user_key and user_key.strip():
39
+ return user_key.strip()
40
+ return DEFAULT_GEMINI_KEY
41
+
42
+ def transcribe(audio_path: str, progress=gr.Progress()):
43
+ """
44
+ Transcribe audio file with streaming output.
45
+ """
46
+ if model is None:
47
+ yield "❌ Hata: Model yüklenemedi.", None
48
+ return
49
+
50
+ if audio_path is None:
51
+ yield "⚠️ Lütfen bir ses dosyası yükleyin.", None
52
+ return
53
+
54
+ try:
55
+ start_time = time.time()
56
+ progress(0, desc="Ses işleniyor...")
57
+
58
+ # 1. Transkripsiyon (Hızlandırılmış Ayarlar)
59
+ segments, info = model.transcribe(
60
+ audio_path,
61
+ language="tr",
62
+ beam_size=1, # Hız için 1 (Streaming ile uyumlu)
63
+ vad_filter=True, # Sessizliği atla
64
+ word_timestamps=False
65
+ )
66
+
67
+ duration = info.duration
68
+ full_text = ""
69
+
70
+ # 2. Streaming Döngüsü
71
+ for segment in segments:
72
+ full_text += segment.text + " "
73
 
74
+ # İlerleme Çubuğu
75
+ if duration > 0:
76
+ prog = min(segment.end / duration, 0.99)
77
+ progress(prog, desc=f"Çevriliyor... ({int(segment.end)}/{int(duration)} sn)")
 
 
78
 
79
+ # Anlık Çıktı (Henüz dosya yok)
80
+ yield full_text.strip(), None
81
+
82
+ elapsed = time.time() - start_time
83
+ final_result = full_text.strip()
84
+
85
+ if not final_result:
86
+ yield "⚠️ Ses anlaşılamadı.", None
87
+ return
88
+
89
+ # 3. Dosya Kaydetme
90
+ progress(0.99, desc="Dosya kaydediliyor...")
91
+ txt_file = tempfile.NamedTemporaryFile(
92
+ mode='w', suffix='.txt', delete=False, encoding='utf-8'
93
+ )
94
+ txt_file.write(final_result)
95
+ txt_file.close()
96
+
97
+ # İstatistik Ekleme
98
+ stats = f"\n\n───────────────────────────────────\n📊 İstatistikler\n• Süre: {duration:.1f} sn\n• İşlem: {elapsed:.1f} sn\n• Hız: {duration/elapsed:.1f}x\n───────────────────────────────────"
99
+
100
+ yield final_result + stats, txt_file.name
101
 
102
+ except Exception as e:
103
+ yield f"❌ Hata: {str(e)}", None
 
 
 
104
 
105
  def summarize_with_gemini(text: str, user_api_key: str, custom_prompt: str = "") -> str:
106
+ """Gemini ile özetle."""
107
  api_key = get_api_key(user_api_key)
108
 
109
+ if not api_key:
110
+ return "⚠️ API Anahtarı bulunamadı. Lütfen ayarlardan ekleyin veya kutucuğa girin."
111
+
112
+ if not text or "⚠️" in text or "❌" in text:
113
+ return "⚠️ Önce geçerli bir metin oluşturun."
114
 
115
  clean_text = text.split("───────────────────────────────────")[0].strip()
116
+
117
+ base_instruction = "Aşağıdaki Türkçe metni analiz et, ana başlıkları çıkar ve detaylıca özetle."
118
+ full_prompt = f"{custom_prompt if custom_prompt else base_instruction}\n\nMetin:\n{clean_text}"
119
 
120
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}"
121
  headers = {"Content-Type": "application/json"}
 
125
  }
126
 
127
  try:
128
+ response = requests.post(url, headers=headers, json=payload, timeout=60)
 
 
129
  if response.status_code == 200:
130
  return response.json()["candidates"][0]["content"]["parts"][0]["text"]
 
 
131
  return f"❌ API Hatası: {response.status_code}"
132
  except Exception as e:
133
  return f"❌ Hata: {str(e)}"
134
 
135
  def translate_with_gemini(text: str, user_api_key: str, target_language: str) -> str:
136
+ """Gemini ile çevir."""
137
  api_key = get_api_key(user_api_key)
 
138
 
139
+ if not api_key:
140
+ return "⚠️ API Anahtarı eksik."
141
+
142
  clean_text = text.split("───────────────────────────────────")[0].strip()
143
  target_lang_eng = {"Türkçe": "Turkish", "İngilizce": "English", "Almanca": "German", "Fransızca": "French"}.get(target_language, "English")
144
 
145
+ full_prompt = f"Translate the following text to {target_lang_eng}. Only provide the translation.\n\nText:\n{clean_text}"
146
 
147
  url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}"
148
  payload = {"contents": [{"parts": [{"text": full_prompt}]}]}
149
 
150
  try:
151
+ response = requests.post(url, json=payload, timeout=60)
 
 
152
  if response.status_code == 200:
153
  return response.json()["candidates"][0]["content"]["parts"][0]["text"]
 
 
154
  return f"❌ Hata: {response.status_code}"
155
  except Exception as e:
156
+ return f"❌ Hata: {str(e)}"
157
+
158
+ # --- ARAYÜZ ---
159
+ with gr.Blocks(title="Ses Deşifre Pro") as demo:
160
+
161
+ gr.HTML("""
162
+ <style>
163
+ footer { display: none !important; }
164
+ .gradio-container { max-width: 900px !important; margin: auto !important; }
165
+ </style>
166
+ <div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); border-radius: 20px; margin-bottom: 20px; color: white;">
167
+ <h1 style="font-size: 2.2rem; margin: 0;">🎙️ Ses Deşifre & AI Asistan</h1>
168
+ <p style="opacity: 0.9;">Canlı Transkripsiyon • Özetleme • Çeviri</p>
169
+ </div>
170
+ """)
171
+
172
+ with gr.Row():
173
+ with gr.Column():
174
+ audio_input = gr.Audio(label="Ses Kaynağı", type="filepath", sources=["upload", "microphone"])
175
+ submit_btn = gr.Button("✨ Başlat (Canlı)", variant="primary", size="lg")
176
+
177
+ with gr.Row():
178
+ with gr.Column():
179
+ output_text = gr.Textbox(label="Sonuç (Canlı Akış)", placeholder="Konuşmalar buraya akacak...", lines=12, interactive=False)
180
+ download_file = gr.File(label="İndir (.txt)")
181
+
182
+ # --- GEMINI ARAÇLARI ---
183
+ gr.HTML("<h3 style='margin-top: 20px; border-bottom: 1px solid #ddd; padding-bottom: 10px;'>🧠 Yapay Zeka Araçları</h3>")
184
+
185
+ with gr.Row():
186
+ with gr.Column():
187
+ api_key_input = gr.Textbox(
188
+ label="🔑 Kendi API Anahtarınız (Opsiyonel)",
189
+ placeholder="Boş bırakırsanız sistem anahtarı kullanılır",
190
+ type="password"
191
+ )
192
+
193
+ with gr.Tabs():
194
+ with gr.TabItem("✨ Özetle"):
195
+ gemini_prompt = gr.Textbox(label="Komut (Opsiyonel)", placeholder="Örn: Madde madde özetle...")
196
+ gemini_btn = gr.Button("🤖 Özetle")
197
+ gemini_output = gr.Textbox(label="Özet", lines=8)
198
+
199
+ with gr.TabItem("🌍 Çevir"):
200
+ target_lang = gr.Dropdown(["İngilizce", "Almanca", "Fransızca", "Türkçe"], label="Hedef Dil", value="İngilizce")
201
+ translate_btn = gr.Button("A Çevir")
202
+ translate_output = gr.Textbox(label="Çeviri", lines=8)
203
+
204
+ # --- BAĞLANTILAR ---
205
+ submit_btn.click(transcribe, inputs=[audio_input], outputs=[output_text, download_file])
206
+ gemini_btn.click(summarize_with_gemini, inputs=[output_text, api_key_input, gemini_prompt], outputs=gemini_output)
207
+ translate_btn.click(translate_with_gemini, inputs=[output_text, api_key_input, target_lang], outputs=translate_output)
208
+
209
+ if __name__ == "__main__":
210
+ demo.launch(share=False)