Spaces:
Running
Running
Claude 3 Haiku entegresi, tüm modüller güncellendi, prod-ready
Browse files- ocr_engine.py +14 -7
- pdf_reader.py +18 -4
- summarizer.py +16 -8
- ui.py +12 -15
ocr_engine.py
CHANGED
@@ -5,13 +5,20 @@ from dotenv import load_dotenv
|
|
5 |
load_dotenv()
|
6 |
ocr_api_key = os.getenv("OCR_SPACE_API_KEY")
|
7 |
|
8 |
-
def extract_text_from_image(
|
9 |
try:
|
10 |
-
if not
|
11 |
-
return "❌
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
response = requests.post(
|
17 |
url='https://api.ocr.space/parse/image',
|
@@ -28,7 +35,7 @@ def extract_text_from_image(image_path):
|
|
28 |
try:
|
29 |
result = response.json()
|
30 |
except Exception:
|
31 |
-
return f"❌ API yanıtı JSON
|
32 |
|
33 |
if not isinstance(result, dict):
|
34 |
return f"❌ API çıktısı sözlük değil:\n{result}"
|
|
|
5 |
load_dotenv()
|
6 |
ocr_api_key = os.getenv("OCR_SPACE_API_KEY")
|
7 |
|
8 |
+
def extract_text_from_image(image_input):
|
9 |
try:
|
10 |
+
if not ocr_api_key or not ocr_api_key.strip():
|
11 |
+
return "❌ OCR API anahtarı eksik."
|
12 |
+
|
13 |
+
# Hugging Face -> Gradio upload: image_input bir dosya yoludur (str)
|
14 |
+
# Local test: image_input file-like olabilir
|
15 |
+
if hasattr(image_input, "read"):
|
16 |
+
image_data = image_input.read()
|
17 |
+
elif isinstance(image_input, str) and os.path.exists(image_input):
|
18 |
+
with open(image_input, 'rb') as f:
|
19 |
+
image_data = f.read()
|
20 |
+
else:
|
21 |
+
return "❌ Geçersiz görsel girdisi."
|
22 |
|
23 |
response = requests.post(
|
24 |
url='https://api.ocr.space/parse/image',
|
|
|
35 |
try:
|
36 |
result = response.json()
|
37 |
except Exception:
|
38 |
+
return f"❌ API yanıtı JSON değil:\n{response.text}"
|
39 |
|
40 |
if not isinstance(result, dict):
|
41 |
return f"❌ API çıktısı sözlük değil:\n{result}"
|
pdf_reader.py
CHANGED
@@ -1,15 +1,29 @@
|
|
1 |
import fitz # PyMuPDF
|
2 |
|
|
|
|
|
3 |
def extract_text_from_pdf(pdf_input):
|
4 |
try:
|
5 |
-
|
|
|
|
|
|
|
6 |
doc = fitz.open(pdf_input)
|
7 |
else:
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
text = "\n".join([page.get_text() for page in doc])
|
11 |
doc.close()
|
|
|
|
|
|
|
|
|
12 |
return text
|
13 |
|
14 |
except Exception as e:
|
15 |
-
return f"
|
|
|
1 |
import fitz # PyMuPDF
|
2 |
|
3 |
+
MAX_PAGES = 5 # fazla token yememesi için sınır
|
4 |
+
|
5 |
def extract_text_from_pdf(pdf_input):
|
6 |
try:
|
7 |
+
# Hugging Face ortamında pdf_input bir file-like objedir (upload edilen dosya)
|
8 |
+
if hasattr(pdf_input, "read"):
|
9 |
+
doc = fitz.open(stream=pdf_input.read(), filetype="pdf")
|
10 |
+
elif isinstance(pdf_input, str):
|
11 |
doc = fitz.open(pdf_input)
|
12 |
else:
|
13 |
+
return "[ERROR] Geçersiz PDF girişi"
|
14 |
+
|
15 |
+
total_pages = len(doc)
|
16 |
+
text = ""
|
17 |
+
|
18 |
+
for i in range(min(MAX_PAGES, total_pages)):
|
19 |
+
text += doc[i].get_text()
|
20 |
|
|
|
21 |
doc.close()
|
22 |
+
|
23 |
+
if total_pages > MAX_PAGES:
|
24 |
+
text += f"\n\n[INFO] PDF {total_pages} sayfa. Yalnızca ilk {MAX_PAGES} sayfa işlendi."
|
25 |
+
|
26 |
return text
|
27 |
|
28 |
except Exception as e:
|
29 |
+
return f"[ERROR] PDF İşleme Hatası: {str(e)}"
|
summarizer.py
CHANGED
@@ -3,8 +3,9 @@ import requests
|
|
3 |
from dotenv import load_dotenv
|
4 |
|
5 |
load_dotenv()
|
6 |
-
api_key = os.getenv("OPENROUTER_API_KEY")
|
7 |
-
|
|
|
8 |
|
9 |
def build_prompt(text, mode):
|
10 |
if "Sade" in mode:
|
@@ -23,17 +24,24 @@ def build_prompt(text, mode):
|
|
23 |
def summarize_text(text, mode):
|
24 |
url = "https://openrouter.ai/api/v1/chat/completions"
|
25 |
headers = {
|
26 |
-
"Authorization": f"Bearer {api_key}",
|
27 |
"Content-Type": "application/json"
|
28 |
}
|
29 |
|
30 |
-
|
31 |
-
"model": "
|
32 |
"messages": [
|
33 |
{"role": "user", "content": build_prompt(text, mode)}
|
34 |
]
|
35 |
}
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.")
|
9 |
|
10 |
def build_prompt(text, mode):
|
11 |
if "Sade" in mode:
|
|
|
24 |
def summarize_text(text, mode):
|
25 |
url = "https://openrouter.ai/api/v1/chat/completions"
|
26 |
headers = {
|
27 |
+
"Authorization": f"Bearer {api_key.strip()}",
|
28 |
"Content-Type": "application/json"
|
29 |
}
|
30 |
|
31 |
+
payload = {
|
32 |
+
"model": "anthropic/claude-3-haiku",
|
33 |
"messages": [
|
34 |
{"role": "user", "content": build_prompt(text, mode)}
|
35 |
]
|
36 |
}
|
37 |
|
38 |
+
try:
|
39 |
+
response = requests.post(url, headers=headers, json=payload)
|
40 |
+
response.raise_for_status()
|
41 |
+
result = response.json()
|
42 |
+
|
43 |
+
return result['choices'][0]['message']['content'].strip()
|
44 |
+
except requests.exceptions.HTTPError as e:
|
45 |
+
return f"❌ HTTP Hatası: {e} | Yanıt: {response.text}"
|
46 |
+
except Exception as e:
|
47 |
+
return f"❌ Sistemsel Hata: {str(e)}"
|
ui.py
CHANGED
@@ -13,42 +13,39 @@ def process_input(pdf, image, manual_text, mode):
|
|
13 |
else:
|
14 |
return "Lütfen bir giriş türü seçin.", ""
|
15 |
|
|
|
|
|
16 |
|
17 |
summary = summarize_text(text, mode)
|
18 |
return text, summary
|
19 |
|
20 |
-
|
21 |
with gr.Blocks() as demo:
|
22 |
-
gr.Markdown("##
|
23 |
|
24 |
with gr.Row():
|
25 |
-
pdf_input = gr.File(label="
|
26 |
-
image_input = gr.Image(type="filepath", label="
|
27 |
|
28 |
-
manual_input = gr.Textbox(lines=5, label="
|
29 |
|
30 |
-
# BURAYA AL
|
31 |
mode_selector = gr.Dropdown(
|
32 |
-
choices=["
|
33 |
-
label="
|
34 |
-
value="
|
35 |
)
|
36 |
|
37 |
with gr.Row():
|
38 |
submit_btn = gr.Button("Özetle")
|
39 |
|
40 |
with gr.Row():
|
41 |
-
text_output = gr.Textbox(label="
|
42 |
-
summary_output = gr.Textbox(label="
|
43 |
|
44 |
-
# EN SONDA KALACAK
|
45 |
submit_btn.click(
|
46 |
fn=process_input,
|
47 |
inputs=[pdf_input, image_input, manual_input, mode_selector],
|
48 |
outputs=[text_output, summary_output]
|
49 |
)
|
50 |
|
51 |
-
|
52 |
-
|
53 |
if __name__ == "__main__":
|
54 |
-
demo.launch(share=True)
|
|
|
13 |
else:
|
14 |
return "Lütfen bir giriş türü seçin.", ""
|
15 |
|
16 |
+
if "[ERROR]" in text or "[INFO]" in text:
|
17 |
+
return text, ""
|
18 |
|
19 |
summary = summarize_text(text, mode)
|
20 |
return text, summary
|
21 |
|
|
|
22 |
with gr.Blocks() as demo:
|
23 |
+
gr.Markdown("## VizSum Pro+: AI Destekli Özetleme Aracı")
|
24 |
|
25 |
with gr.Row():
|
26 |
+
pdf_input = gr.File(label="PDF Yükle", file_types=[".pdf"])
|
27 |
+
image_input = gr.Image(type="filepath", label="Görsel Yükle")
|
28 |
|
29 |
+
manual_input = gr.Textbox(lines=5, label="Metni Manuel Gir")
|
30 |
|
|
|
31 |
mode_selector = gr.Dropdown(
|
32 |
+
choices=["Teknik Özet", "Sade Anlatım", "Eleştir ve Değerlendir", "Başlık Çıkar", "Not Formatı"],
|
33 |
+
label="Özetleme Modu",
|
34 |
+
value="Teknik Özet"
|
35 |
)
|
36 |
|
37 |
with gr.Row():
|
38 |
submit_btn = gr.Button("Özetle")
|
39 |
|
40 |
with gr.Row():
|
41 |
+
text_output = gr.Textbox(label="Giriş Metni")
|
42 |
+
summary_output = gr.Textbox(label="AI Özeti")
|
43 |
|
|
|
44 |
submit_btn.click(
|
45 |
fn=process_input,
|
46 |
inputs=[pdf_input, image_input, manual_input, mode_selector],
|
47 |
outputs=[text_output, summary_output]
|
48 |
)
|
49 |
|
|
|
|
|
50 |
if __name__ == "__main__":
|
51 |
+
demo.launch(share=True)
|