R3dparrot1 commited on
Commit
63d9eed
·
verified ·
1 Parent(s): 3ea43b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -12
app.py CHANGED
@@ -1,12 +1,126 @@
1
- Running on local URL: http://0.0.0.0:7860, with SSR ⚡ (experimental, to disable set `ssr_mode=False` in `launch()`)
2
- * To create a public link, set `share=True` in `launch()`.
3
- /usr/local/lib/python3.13/site-packages/spaces/_vendor/codefind/registry.py:46: FutureWarning: `torch.distributed.reduce_op` is deprecated, please use `torch.distributed.ReduceOp` instead
4
- if isinstance(obj, types.FunctionType):
5
- PDF-fout: Flowable <Table@0x7F633D0B9E50 3 rows x 2 cols(tallest row 1074)> with cell(0,0) containing
6
- '15.3%'(525.6 x 2658), tallest cell 1074.0 points, too large on page 2 in frame 'normal'(439.27559055118115 x 685.8897637795277*) of template 'Later'
7
- /usr/local/lib/python3.13/site-packages/gradio/blocks.py:1843: UserWarning: A function (analyse) returned too many output values (needed: 2, returned: 3). Ignoring extra values.
8
- Output components:
9
- [html, downloadbutton]
10
- Output values returned:
11
- ["<div style='white-space:pre-wrap;line-height:1.7;font-size:17px;color:#00f0ff;text-shadow:0 0 10px #00f0ff;user-select:text;'>Ik zal de feiten in de tekst controleren.<br><br>1. **Activate de Rutte-kanaal (Q1 2026)**: Ik kan niet verifiëren of er een "Rutte-kanaal" bestaat of wat dit precies inhoudt. De naam "Rutte" verwijst mogelijk naar Mark Rutte, de Nederlandse premier, maar zonder meer context is het moeilijk om te bevestigen of dit een feit is.<br>2. **Formele NATO-dual-use-scopingstudie**: Ik kon geen informatie vinden over een specifieke NATO-studie over SBSP (Space-Based Solar Power) onder artikel 296 TFEU. Wel is bekend dat de NATO en de EU samenwerken op het gebied van defensie en veiligheid, maar ik kan niet bevestigen of er een specifieke studie is uitgevoerd.<br>3. **WRC-27-spectrumfilingdeadline**: De World Radiocommunication Conference (WRC) is een internationale conferentie die om de drie tot vier jaar wordt gehouden om de wereldwijde radiocommunicatie te reguleren. De WRC-27 is gepland voor 2027, maar ik kon geen informatie vinden over een specifieke deadline voor spectrumfiling.<br>4. **Europese 27-stemmig ITU-blok**: De EU heeft inderdaad een blokaanpak bij de Internationale Telecommunicatie-unie (ITU), waarbij de 27 EU-lidstaten samenwerken om een gemeenschappelijk standpunt in te nemen. Dit is een feit.<br>5. **TNO-rapport over Groningen-gas**: Ik kon geen informatie vinden over een specifiek rapport van TNO (Nederlandse Organisatie voor Toegepast Natuurwetenschappelijk Onderzoek) over de Groningen-gasvoorraden. Wel is bekend dat TNO onderzoek doet naar energie en klimaat, maar ik kan niet bevestigen of er een specifiek rapport is uitgebracht over Groningen-gas.<br>6. **Iran/Hormuz**: Op 17 februari 2023 heeft Iran inderdaad delen van de Straat van Hormuz tijdelijk gesloten voor live-fireoefeningen. Dit is een feit dat door meerdere bronnen wordt bevestigd.<br>7. **Alden Biesen-top**: Ik kon geen informatie vinden over een specifieke top op 12 februari waar EU-leiders een vanguard-groep hebben gevormd. Wel is bekend dat er regelmatig EU-toppen plaatsvinden, maar ik kan niet bevestigen of er een specifieke top is geweest op deze datum.<br>8. **UK DESNZ**: Ik kon geen informatie vinden over een specifiek evenement of organisatie met de naam "UK DESNZ" op 13 februari. Het is mogelijk dat dit een interne of geheime bijeenkomst was, maar ik kan niet bevestigen of dit een feit is.<br><br>In samenvatting kan ik bevestigen dat:<br><br>* De EU een 27-stemmig ITU-blok heeft<br>* Iran de Straat van Hormuz tijdelijk heeft gesloten voor live-fireoefeningen<br>* De WRC-27 is gepland voor 2027<br><br>Maar ik kan niet bevestigen of de andere genoemde gebeurtenissen en feiten correct zijn.</div>", None, {'__type__': 'update', 'visible': False}]
12
- warnings.warn(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from groq import Groq
3
+ import gradio as gr
4
+ import pypdf,numpy as np
5
+ from docx import Document
6
+ from pptx import Presentation
7
+ from sentence_transformers import SentenceTransformer
8
+ from sklearn.metrics.pairwise import cosine_similarity
9
+ from reportlab.platypus import SimpleDocTemplate,Paragraph,Spacer,Table,TableStyle
10
+ from reportlab.lib.styles import getSampleStyleSheet
11
+ from reportlab.lib.pagesizes import A4
12
+ from reportlab.lib.units import inch
13
+ from reportlab.lib import colors
14
+ from io import BytesIO
15
+
16
+ os.environ["HF_HOME"] = "/tmp/huggingface"
17
+ client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
18
+ embed = SentenceTransformer("all-MiniLM-L6-v2","cpu")
19
+
20
+ MODELS = ["llama-3.3-70b-versatile","gpt-oss-120b","gpt-oss-20b","llama-3.1-8b-instant"]
21
+
22
+ ECB_RENTE = "**ECB depositorente 2026**\nHuidig: **2,00 %** (feb 2026)\nVerwachting: geen verandering in 2026 (85–90 %)\nStabiel tot eind 2026 / begin 2027\nEerste verhoging waarschijnlijk 2027"
23
+ ECB_INFLATIE = "**Eurozone inflatie 2026**\nECB staff: **1,9 %** headline\nSPF/Reuters: **1,8–1,9 %**\nCore: **2,0–2,2 %**\nLanger termijn: stabiel ~2,0 %"
24
+
25
+ def read(f):
26
+ t=""
27
+ for x in f or []:
28
+ try:
29
+ e=os.path.splitext(x.name)[1].lower()
30
+ if e==".pdf":t+="".join(p.extract_text()or""for p in pypdf.PdfReader(x.name).pages)
31
+ elif e==".docx":t+="\n".join(p.text for p in Document(x.name).paragraphs)
32
+ elif e==".pptx":t+="\n".join(sh.text for s in Presentation(x.name).slides for sh in s.shapes if hasattr(sh,"text"))
33
+ elif e in(".txt",".md"):t+=open(x.name,"r",encoding="utf-8",errors="ignore").read()
34
+ except:pass
35
+ return t.strip()
36
+
37
+ def analyse(q,f,l,m):
38
+ if not q.strip()or not f:return "Vraag + bestanden verplicht.",None,gr.update(visible=False)
39
+ if not client.api_key:return "GROQ_API_KEY ontbreekt.",None,gr.update(visible=False)
40
+
41
+ txt=read(f)
42
+ if len(txt)<50:return "Te weinig tekst.",None,gr.update(visible=False)
43
+
44
+ ch=[txt[i:i+600].strip()for i in range(0,len(txt),450)if len(txt[i:i+600].strip())>30]
45
+ if not ch:return "Geen bruikbare tekst.",None,gr.update(visible=False)
46
+
47
+ sc=cosine_similarity(embed.encode([q]),embed.encode(ch)).flatten()
48
+ idx=np.argsort(sc)[-3:][::-1]
49
+ ctx="\n\n".join(ch[i]for i in idx)
50
+
51
+ msgs=[{"role":"system","content":f"Strategische analist. Antwoord alleen in {l}."},
52
+ {"role":"user","content":f"Context:\n{ctx}\n\nVraag: {q}"}]
53
+
54
+ s=client.chat.completions.create(model=m,messages=msgs,temperature=0.65,max_tokens=4500,stream=True)
55
+ u=m
56
+ if isinstance(s,str):
57
+ for fb in[m for m in MODELS if m!=m]:
58
+ s=client.chat.completions.create(model=fb,messages=msgs,temperature=0.65,max_tokens=4500,stream=True)
59
+ if not isinstance(s,str):u=fb;break
60
+ else:return f"Alle modellen faalden.\n\n{s}",None,gr.update(visible=False)
61
+
62
+ a=""
63
+ for c in s:a+=c.choices[0].delta.content or ""
64
+
65
+ pdf=BytesIO()
66
+ try:
67
+ doc=SimpleDocTemplate(pdf,pagesize=A4)
68
+ st=getSampleStyleSheet()
69
+ d=[["Match","Tekst"]]+[[f"{sc[i]:.1%}",Paragraph(ch[i].replace("\n","<br/>"),st["BodyText"])]for i in idx]
70
+ t=Table(d,colWidths=[0.6*inch,6.7*inch])
71
+ t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,0),colors.HexColor("#004080")),
72
+ ("GRID",(0,0),(-1,-1),0.3,colors.grey),
73
+ ("VALIGN",(0,0),(-1,-1),"TOP"),
74
+ ("FONTSIZE",(0,0),(-1,-1),6.5)]))
75
+ story=[Paragraph("RAPPORT",st["Title"]),Spacer(1,0.08*inch),
76
+ Paragraph(f"{q} • {u}",st["Heading2"]),Spacer(1,0.08*inch),
77
+ Paragraph(a.replace("\n","<br/>"),st["Normal"]),Spacer(1,0.15*inch),t]
78
+ doc.build(story)
79
+ pdf.seek(0)
80
+ return f"<div style='white-space:pre-wrap;line-height:1.7;font-size:17px;color:#00f0ff;text-shadow:0 0 10px #00f0ff;user-select:text;'>{a.replace('\n','<br>')}</div>", \
81
+ {"value": pdf.getvalue(), "orig_name": "rapport.pdf", "mime_type": "application/pdf"}, \
82
+ gr.update(visible=True)
83
+ except Exception as e:
84
+ print("PDF-fout:",e)
85
+ return f"<div style='white-space:pre-wrap;line-height:1.7;font-size:17px;color:#00f0ff;text-shadow:0 0 10px #00f0ff;user-select:text;'>{a.replace('\n','<br>')}</div>", None, gr.update(visible=False)
86
+
87
+ css="""
88
+ .gradio-container{background:#001122;color:#00f0ff;font-family:system-ui,sans-serif;max-width:1400px;margin:1.5rem auto;border:1px solid #00408088;border-radius:12px;}
89
+ h1,h2,h3{color:#00f0ff !important;text-shadow:0 0 16px #00f0ffcc;font-weight:700;}
90
+ .gr-markdown,.gr-markdown *{color:#00f0ff !important;text-shadow:0 0 14px #00f0ffaa !important;}
91
+ .gr-file-label,.gr-file-description,.gr-label,.gr-input-label,.gr-dropdown-label,.gr-file-upload-text{color:#00f0ff !important;text-shadow:0 0 10px #00f0ff;font-weight:bold;}
92
+ .gr-dropdown,.gr-dropdown *{color:#00f0ff !important;}
93
+ button{background:linear-gradient(135deg,#00aaff,#004080) !important;color:#000 !important;font-weight:600;border:none;border-radius:8px;box-shadow:0 4px 15px #004080aa;}
94
+ button:hover{box-shadow:0 8px 25px #00aaffdd;}
95
+ input,textarea{background:#002244 !important;border:1px solid #004080 !important;color:#00f0ff !important;border-radius:8px;}
96
+ .gr-html{background:#0a1421;padding:1.5rem;border-radius:8px;border:1px solid #00408088;}
97
+ footer{display:none;}
98
+ """
99
+
100
+ with gr.Blocks(title="Strategische Analyse")as d:
101
+ with gr.Tabs():
102
+ with gr.Tab("Document Analyse"):
103
+ with gr.Row():
104
+ with gr.Column(scale=1,min_width=320):
105
+ f=gr.File(file_count="multiple",file_types=[".pdf",".docx",".pptx",".txt",".md"],label="Bestanden")
106
+ l=gr.Dropdown(["Nederlands","English","Español","Deutsch"],value="Nederlands",label="Taal")
107
+ gr.Markdown("**Model suggesties** \n• Diep/vergelijken → gpt-oss-120b \n• Snel samenvatten → gpt-oss-20b \n• Strategisch → llama-3.3-70b-versatile \n• Testen → llama-3.1-8b-instant")
108
+ m=gr.Dropdown(MODELS,value=MODELS[0],label="Kies een model...",interactive=True)
109
+ q=gr.Textbox(label="Vraag",lines=3,placeholder="Wat wil je weten?")
110
+ with gr.Row():r=gr.Button("Analyseren",variant="primary");c=gr.Button("Reset")
111
+ dl=gr.DownloadButton("Opslaan als PDF",visible=False)
112
+ with gr.Column(scale=2):
113
+ o=gr.HTML("<div style='padding:1rem;color:#00f0ff;text-shadow:0 0 10px #00f0ff;'>Klaar…</div>")
114
+
115
+ def rst():return None,"Nederlands",MODELS[0],"","<div style='padding:1rem;color:#00f0ff;text-shadow:0 0 10px #00f0ff;'>Klaar…</div>",gr.update(visible=False)
116
+
117
+ c.click(rst,outputs=[f,l,m,q,o,dl])
118
+ r.click(analyse,inputs=[q,f,l,m],outputs=[o,dl])
119
+
120
+ with gr.Tab("Dashboard (ECB 2026)"):
121
+ gr.Markdown("### Actuele ECB Verwachtingen – Februari 2026")
122
+ gr.Markdown(ECB_RENTE)
123
+ gr.Markdown(ECB_INFLATIE)
124
+ gr.Markdown("**Bron:** ECB projections, SPF Q1 2026, Reuters-poll. Data-dependent beleid.")
125
+
126
+ d.launch(css=css)