Merge pull request 'exxeta_neu_kennzahl #25' (#96) from exxeta_neue_Kennzahl_clean into main

Reviewed-on: #96
pull/108/head
Anastasia Hanna Ougolnikova 2025-06-26 07:06:19 +02:00
commit 23f047df4e
1 changed files with 29 additions and 37 deletions

View File

@ -1,7 +1,6 @@
import requests
import json
import os
import time
import logging
from dotenv import load_dotenv
@ -17,6 +16,18 @@ TIMEOUT = 180
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def get_dynamic_labels():
url = f"{COORDINATOR_URL}/api/kpi_setting/"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
kpi_list = response.json()
labels = [kpi["name"].upper() for kpi in kpi_list if kpi.get("active", False)]
return labels
except Exception as e:
logger.warning(f"Konnte dynamische Labels nicht laden: {e}")
return []
def extract_with_exxeta(pages_json, pitchbook_id):
results = []
@ -30,9 +41,7 @@ def extract_with_exxeta(pages_json, pitchbook_id):
if i % 8 == 0:
requests.post(COORDINATOR_URL + "/api/progress", json={"id": pitchbook_id, "progress": 35 + 60/len(pages_json)*i})
page_num = page_data.get("page")
page_data.get("page")
text = page_data.get("text", "")
if not text:
@ -51,9 +60,9 @@ def extract_with_exxeta(pages_json, pitchbook_id):
"- Gib die Antwort als **JSON-Array** im folgenden Format zurück:\n\n"
"[\n"
" {\n"
" \"label\": \"FONDSNAME\",\n"
" \"entity\": \"...\",\n"
f" \"page\": {page_num},\n"
' "label": "FONDSNAME",\n'
' "entity": "...",\n'
f' "page": {page_num},\n'
" },\n"
" ...\n"
"]\n\n"
@ -61,45 +70,29 @@ def extract_with_exxeta(pages_json, pitchbook_id):
f"TEXT:\n{text}"
)
else:
labels = get_dynamic_labels()
prompt_kennzahlen = "".join([f"- {label}\n" for label in labels])
prompt = (
"Bitte extrahiere relevante Fondskennzahlen aus dem folgenden Pitchbook-Text. "
"Analysiere den Text sorgfältig, um **nur exakt benannte und relevante Werte** zu extrahieren.\n\n"
"ZU EXTRAHIERENDE KENNZAHLEN (immer exakt wie unten angegeben):\n"
"- FONDSNAME\n"
"- FONDSMANAGER\n"
"- AIFM (z. B. Name Kapitalverwaltungsgesellschaft)\n"
"- DATUM\n"
"- RISIKOPROFIL (z. B. CORE, CORE+, VALUE-ADDED, OPPORTUNISTISCH)\n"
"- ARTIKEL (z. B. ARTIKEL 6, 8, 9)\n"
"- ZIELRENDITE\n"
"- RENDITE\n"
"- ZIELAUSSCHÜTTUNG\n"
"- AUSSCHÜTTUNG\n"
"- LAUFZEIT\n"
"- LTV\n"
"- MANAGEMENTGEBÜHREN (ggf. mit Staffelung und Bezug auf NAV/GAV)\n"
"- SEKTORENALLOKATION (z. B. BÜRO, LOGISTIK, WOHNEN... inkl. %-Angaben)\n"
"- LÄNDERALLOKATION (z. B. DEUTSCHLAND, FRANKREICH, etc. inkl. %-Angaben)\n\n"
f"{prompt_kennzahlen}\n"
"WICHTIG:\n"
"- Gib **nur eine Entität pro Kennzahl** an - keine Listen oder Interpretationen.\n"
"- Wenn mehrere Varianten genannt werden (z. B. \"Core und Core+\"), gib sie im Originalformat als **eine entity** an.\n"
'- Wenn mehrere Varianten genannt werden (z. B. "Core und Core+"), gib sie im Originalformat als **eine entity** an.\n'
"- **Keine Vermutungen oder Ergänzungen**. Wenn keine Information enthalten ist, gib die Kennzahl **nicht aus**.\n"
"- Extrahiere **nur wörtlich vorkommende Inhalte** (keine Berechnungen, keine Zusammenfassungen).\n"
"- Jeder gefundene Wert muss einem der obigen Label **eindeutig zuordenbar** sein.\n\n"
"FORMAT:\n"
"Antworte als **reines JSON-Array** mit folgendem Format:\n"
"[\n"
" {\n"
" \"label\": \"Kennzahlname (exakt wie oben)\",\n"
" \"entity\": \"Wert aus dem Text (exakt im Original)\",\n"
f" \"page\": {page_num},\n"
' "label": "Kennzahlname (exakt wie oben)",\n'
' "entity": "Wert aus dem Text (exakt im Original)",\n'
f' "page": {page_num},\n'
" },\n"
" ...\n"
"]\n\n"
f"Falls keine Kennzahl enthalten ist, gib ein leeres Array [] zurück.\n\n"
f"Nur JSON-Antwort - keine Kommentare, keine Erklärungen, kein Text außerhalb des JSON.\n\n"
f"TEXT:\n{text}"
@ -125,10 +118,7 @@ def extract_with_exxeta(pages_json, pitchbook_id):
try:
response = requests.post(url, headers=headers, json=payload, timeout=TIMEOUT)
response.raise_for_status()
content = response.json()["choices"][0]["message"]["content"]
content = content.strip()
content = response.json()["choices"][0]["message"]["content"].strip()
if content.startswith("```json"):
content = content.split("```json")[1]
if content.endswith("```"):
@ -143,14 +133,16 @@ def extract_with_exxeta(pages_json, pitchbook_id):
if isinstance(page_results, list):
results.extend(page_results)
break
except requests.exceptions.RequestException as e:
except requests.exceptions.RequestException:
if attempt == MAX_RETRIES:
results.extend([])
except Exception as e:
except Exception:
if attempt == MAX_RETRIES:
results.extend([])
requests.post(COORDINATOR_URL + "/api/progress", json={"id": pitchbook_id, "progress": 95})
return json.dumps(results, indent=2, ensure_ascii=False)
if __name__ == "__main__":
print("📡 Test-Aufruf get_dynamic_labels:")
print(get_dynamic_labels())