Spaces:
Running
Running
Update: Chunklama destekli özetleme eklendi
Browse files- .env.example +1 -1
- .py +5 -0
- summarizer.py +24 -0
- ui.py +12 -6
- utils.py +21 -0
.env.example
CHANGED
@@ -1 +1 @@
|
|
1 |
-
OPENROUTER_API_KEY=sk-or-v1-
|
|
|
1 |
+
OPENROUTER_API_KEY=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
|
.py
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dotenv import load_dotenv
|
2 |
+
import os
|
3 |
+
|
4 |
+
load_dotenv()
|
5 |
+
print("KEY", os.getenv("OPENROUTER_API_KEY"))
|
summarizer.py
CHANGED
@@ -1,8 +1,12 @@
|
|
1 |
import os
|
2 |
import requests
|
3 |
from dotenv import load_dotenv
|
|
|
4 |
|
5 |
load_dotenv()
|
|
|
|
|
|
|
6 |
api_key = os.getenv("OPENROUTER_API_KEY")
|
7 |
if not api_key or not api_key.strip():
|
8 |
raise RuntimeError("❌ OPENROUTER_API_KEY bulunamadı. Hugging Face Secrets kısmına eklenmeli.")
|
@@ -37,6 +41,16 @@ Aşağıdaki metni 3 ayrı biçimde özetle:
|
|
37 |
instruction = "Metne uygun başlık önerileri üret."
|
38 |
elif "Not" in mode:
|
39 |
instruction = "Bu metinden önemli notlar çıkar."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
else:
|
41 |
instruction = "Metni kısa ve teknik bir şekilde özetle."
|
42 |
|
@@ -67,3 +81,13 @@ def summarize_text(text, mode, model_name="anthropic/claude-3-haiku", lang_mode=
|
|
67 |
return f"❌ HTTP Hatası: {e} | Yanıt: {response.text}"
|
68 |
except Exception as e:
|
69 |
return f"❌ Sistemsel Hata: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
import requests
|
3 |
from dotenv import load_dotenv
|
4 |
+
from utils import chunk_text_by_tokens # type: ignore
|
5 |
|
6 |
load_dotenv()
|
7 |
+
print("KEY IN SUMMARIZER:", os.getenv("OPENROUTER_API_KEY")) # <<< bunu ekle
|
8 |
+
api_key = os.getenv("OPENROUTER_API_KEY")
|
9 |
+
|
10 |
api_key = os.getenv("OPENROUTER_API_KEY")
|
11 |
if not api_key or not api_key.strip():
|
12 |
raise RuntimeError("❌ OPENROUTER_API_KEY bulunamadı. Hugging Face Secrets kısmına eklenmeli.")
|
|
|
41 |
instruction = "Metne uygun başlık önerileri üret."
|
42 |
elif "Not" in mode:
|
43 |
instruction = "Bu metinden önemli notlar çıkar."
|
44 |
+
elif "Chat" in mode:
|
45 |
+
instruction = """
|
46 |
+
Aşağıdaki yazışmalıarı veya serbest notları oku ve şunları çıkar:
|
47 |
+
|
48 |
+
- Ana konuşma başlıkları
|
49 |
+
- Varsa karar verilen noktalar
|
50 |
+
- Belirgin fikir veya öneriler
|
51 |
+
|
52 |
+
Yazım sade ve maddeli olsun.
|
53 |
+
"""
|
54 |
else:
|
55 |
instruction = "Metni kısa ve teknik bir şekilde özetle."
|
56 |
|
|
|
81 |
return f"❌ HTTP Hatası: {e} | Yanıt: {response.text}"
|
82 |
except Exception as e:
|
83 |
return f"❌ Sistemsel Hata: {str(e)}"
|
84 |
+
|
85 |
+
def summarize_long_text(text, mode, model_name="anthropic/claude-3-haiku", lang_mode="Otomatik", is_table=False):
|
86 |
+
chunks = chunk_text_by_tokens(text, max_tokens=1300)
|
87 |
+
|
88 |
+
summaries = []
|
89 |
+
for chunk in chunks:
|
90 |
+
summary = summarize_text(chunk, mode, model_name, lang_mode, is_table)
|
91 |
+
summaries.append(summary)
|
92 |
+
|
93 |
+
return "\n\n".join(summaries)
|
ui.py
CHANGED
@@ -2,11 +2,13 @@ import gradio as gr
|
|
2 |
import tempfile
|
3 |
from ocr_engine import extract_text_from_image
|
4 |
from pdf_reader import extract_text_chunks_from_pdf
|
5 |
-
from summarizer import
|
|
|
6 |
|
7 |
def process_input(pdf, image, manual_text, mode, model_name, start_page, end_page, lang_mode, is_table):
|
8 |
if is_table and model_name != "anthropic/claude-3-haiku":
|
9 |
return "Tablo içeriği için yalnızca Claude önerilir.","",None
|
|
|
10 |
if pdf is not None:
|
11 |
text_chunks = extract_text_chunks_from_pdf(pdf, start=int(start_page), end=int(end_page))
|
12 |
if any("[ERROR]" in chunk for chunk in text_chunks):
|
@@ -22,13 +24,16 @@ def process_input(pdf, image, manual_text, mode, model_name, start_page, end_pag
|
|
22 |
return "Lütfen bir giriş türü seçin.", "", None
|
23 |
|
24 |
all_text = "\n\n".join(text_chunks)
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
30 |
|
31 |
-
full_summary =
|
|
|
32 |
|
33 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w', encoding='utf-8')
|
34 |
temp_file.write(full_summary)
|
@@ -36,6 +41,7 @@ def process_input(pdf, image, manual_text, mode, model_name, start_page, end_pag
|
|
36 |
|
37 |
return all_text, full_summary, temp_file.name
|
38 |
|
|
|
39 |
with gr.Blocks() as demo:
|
40 |
gr.Markdown("## VizSum")
|
41 |
|
|
|
2 |
import tempfile
|
3 |
from ocr_engine import extract_text_from_image
|
4 |
from pdf_reader import extract_text_chunks_from_pdf
|
5 |
+
from summarizer import summarize_long_text
|
6 |
+
from utils import chunk_text_by_tokens
|
7 |
|
8 |
def process_input(pdf, image, manual_text, mode, model_name, start_page, end_page, lang_mode, is_table):
|
9 |
if is_table and model_name != "anthropic/claude-3-haiku":
|
10 |
return "Tablo içeriği için yalnızca Claude önerilir.","",None
|
11 |
+
|
12 |
if pdf is not None:
|
13 |
text_chunks = extract_text_chunks_from_pdf(pdf, start=int(start_page), end=int(end_page))
|
14 |
if any("[ERROR]" in chunk for chunk in text_chunks):
|
|
|
24 |
return "Lütfen bir giriş türü seçin.", "", None
|
25 |
|
26 |
all_text = "\n\n".join(text_chunks)
|
27 |
+
chunk_count = len(chunk_text_by_tokens(all_text, max_tokens=1300))
|
28 |
|
29 |
+
info_block = f"""
|
30 |
+
Sayfa Aralığı: {start_page}–{end_page}
|
31 |
+
Model: {model_name}
|
32 |
+
Chunk Sayısı: {chunk_count}
|
33 |
+
""".strip()
|
34 |
|
35 |
+
full_summary = summarize_long_text(all_text, mode, model_name, lang_mode, is_table)
|
36 |
+
full_summary = f"{info_block}\n\n{full_summary}"
|
37 |
|
38 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w', encoding='utf-8')
|
39 |
temp_file.write(full_summary)
|
|
|
41 |
|
42 |
return all_text, full_summary, temp_file.name
|
43 |
|
44 |
+
|
45 |
with gr.Blocks() as demo:
|
46 |
gr.Markdown("## VizSum")
|
47 |
|
utils.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def chunk_text_by_tokens(text, max_tokens=1300, approx_tokens_per_word=1.3):
|
2 |
+
"""
|
3 |
+
Metni yaklaşık token sayısına göre parçalara böler.
|
4 |
+
|
5 |
+
Args:
|
6 |
+
text (str): Bölünecek uzun metin.
|
7 |
+
max_tokens (int): Her bir parçanın tahmini token limiti.
|
8 |
+
approx_tokens_per_word (float): Kelime başına ortalama token sayısı.
|
9 |
+
|
10 |
+
Returns:
|
11 |
+
List[str]: Token limitine uygun metin parçaları.
|
12 |
+
"""
|
13 |
+
words = text.split()
|
14 |
+
max_words = int(max_tokens / approx_tokens_per_word)
|
15 |
+
|
16 |
+
chunks = []
|
17 |
+
for i in range(0, len(words), max_words):
|
18 |
+
chunk = " ".join(words[i:i + max_words])
|
19 |
+
chunks.append(chunk)
|
20 |
+
|
21 |
+
return chunks
|