blazingbunny commited on
Commit
e02e83a
Β·
verified Β·
1 Parent(s): c164275

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -22
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import os
2
- import tempfile
3
  import streamlit as st
4
  import pandas as pd
5
  from pypdf import PdfReader
@@ -9,14 +8,15 @@ from knowledge_graph_maker import (
9
  GraphMaker, Ontology, Document, OpenAIClient
10
  )
11
 
 
12
  st.set_page_config(page_title="Knowledge Graph (OpenRouter)", layout="wide")
13
  st.title("Knowledge Graph from Text/PDF β€” OpenRouter")
14
- st.caption("Uses knowledge-graph-maker via OpenRouter. Paste text or upload a PDF; choose an OpenRouter model.")
15
 
16
- # --- OpenRouter only ---
17
  OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")
18
 
19
- # Model choices
20
  OPENROUTER_MODELS = [
21
  "openai/gpt-oss-20b:free",
22
  "moonshotai/kimi-k2:free",
@@ -24,7 +24,7 @@ OPENROUTER_MODELS = [
24
  "google/gemma-3-27b-it:free",
25
  ]
26
 
27
- # Sidebar controls
28
  with st.sidebar:
29
  st.subheader("Model & Generation Settings")
30
  model_choice = st.selectbox("OpenRouter model", OPENROUTER_MODELS, index=0)
@@ -43,9 +43,10 @@ with st.sidebar:
43
  value="Relation between any pair of Entities",
44
  )
45
 
46
- def parse_labels(text):
 
47
  return [lbl.strip() for lbl in text.split(",") if lbl.strip()] or [
48
- "Person","Object","Event","Place","Document","Organisation","Action","Miscellanous"
49
  ]
50
 
51
  def pdf_to_text(file) -> str:
@@ -63,11 +64,20 @@ def chunk_text(text: str, chars: int = 3500) -> list[Document]:
63
  for i in range(0, len(text), chars):
64
  chunk = text[i:i+chars].strip()
65
  if chunk:
66
- docs.append(Document(text=chunk, metadata={"chunk_id": i//chars}))
67
  return docs
68
 
69
  def edges_to_pyvis(edges):
70
- net = Network(height="700px", width="100%", bgcolor="#ffffff", font_color="#222222", notebook=False, directed=False)
 
 
 
 
 
 
 
 
 
71
  node_ids = {}
72
  for e in edges:
73
  n1 = f"{e.node_1.label}:{e.node_1.name}"
@@ -82,7 +92,7 @@ def edges_to_pyvis(edges):
82
  net.toggle_physics(True)
83
  return net
84
 
85
- # Input tabs
86
  tab_text, tab_pdf = st.tabs(["πŸ“ Paste Text", "πŸ“„ Upload PDF"])
87
  input_text = ""
88
  with tab_text:
@@ -92,6 +102,7 @@ with tab_pdf:
92
  if pdf_file:
93
  input_text = pdf_to_text(pdf_file)
94
 
 
95
  if st.button("Generate Knowledge Graph", type="primary"):
96
  if not input_text.strip():
97
  st.warning("Please provide text or a PDF.")
@@ -100,11 +111,10 @@ if st.button("Generate Knowledge Graph", type="primary"):
100
  st.error("OPENROUTER_API_KEY is not set in Space Secrets.")
101
  st.stop()
102
 
103
- # Point OpenAI SDK at OpenRouter
104
  os.environ["OPENAI_API_KEY"] = OPENROUTER_API_KEY
105
  os.environ["OPENAI_BASE_URL"] = "https://openrouter.ai/api/v1"
106
-
107
- # Optional: attribution headers for OpenRouter
108
  os.environ["OPENAI_DEFAULT_HEADERS"] = (
109
  '{"HTTP-Referer":"https://huggingface.co/spaces/blazingbunny/rahulnyk_knowledge_graph",'
110
  '"X-Title":"Knowledge Graph (OpenRouter)"}'
@@ -116,20 +126,21 @@ if st.button("Generate Knowledge Graph", type="primary"):
116
  ontology = Ontology(
117
  labels=parse_labels(labels_text),
118
  relationships=[r.strip() for r in relationships_text.split(",") if r.strip()] or
119
- ["Relation between any pair of Entities"]
120
  )
121
 
122
  st.info("Chunking input and building graph…")
123
  docs = chunk_text(input_text)
124
 
125
- # LLM client (OpenRouter through OpenAI-compatible client)
126
  llm = OpenAIClient(model=selected_model, temperature=temperature, top_p=top_p)
127
 
128
  gm = GraphMaker(ontology=ontology, llm_client=llm, verbose=False)
129
- edges = gm.from_documents(docs, delay_s_between=0)
130
 
131
  st.success(f"Graph built with {len(edges)} edges.")
132
 
 
133
  df = pd.DataFrame([{
134
  "node_1_label": e.node_1.label, "node_1": e.node_1.name,
135
  "node_2_label": e.node_2.label, "node_2": e.node_2.name,
@@ -137,13 +148,10 @@ if st.button("Generate Knowledge Graph", type="primary"):
137
  } for e in edges])
138
  st.dataframe(df, use_container_width=True)
139
 
 
140
  net = edges_to_pyvis(edges)
141
- with tempfile.TemporaryDirectory() as td:
142
- html_path = os.path.join(td, "graph.html")
143
- net.save_graph(html_path)
144
- with open(html_path, "r", encoding="utf-8") as f:
145
- html = f.read()
146
- st.components.v1.html(html, height=750, scrolling=True)
147
 
148
  st.markdown("---")
149
  st.caption("Powered by knowledge-graph-maker via OpenRouter.")
 
1
  import os
 
2
  import streamlit as st
3
  import pandas as pd
4
  from pypdf import PdfReader
 
8
  GraphMaker, Ontology, Document, OpenAIClient
9
  )
10
 
11
+ # ── Page setup ──────────────────────────────────────────────────────────────────
12
  st.set_page_config(page_title="Knowledge Graph (OpenRouter)", layout="wide")
13
  st.title("Knowledge Graph from Text/PDF β€” OpenRouter")
14
+ st.caption("Builds a knowledge graph with knowledge-graph-maker via OpenRouter. Paste text or upload a PDF; choose a model.")
15
 
16
+ # ── Secrets / env ───────────────────────────────────────────────────────────────
17
  OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")
18
 
19
+ # Preset OpenRouter models (you can add more)
20
  OPENROUTER_MODELS = [
21
  "openai/gpt-oss-20b:free",
22
  "moonshotai/kimi-k2:free",
 
24
  "google/gemma-3-27b-it:free",
25
  ]
26
 
27
+ # ── Sidebar controls ───────────────────────────────────────────────────────────
28
  with st.sidebar:
29
  st.subheader("Model & Generation Settings")
30
  model_choice = st.selectbox("OpenRouter model", OPENROUTER_MODELS, index=0)
 
43
  value="Relation between any pair of Entities",
44
  )
45
 
46
+ # ── Helpers ────────────────────────────────────────────────────────────────────
47
+ def parse_labels(text: str):
48
  return [lbl.strip() for lbl in text.split(",") if lbl.strip()] or [
49
+ "Person", "Object", "Event", "Place", "Document", "Organisation", "Action", "Miscellanous"
50
  ]
51
 
52
  def pdf_to_text(file) -> str:
 
64
  for i in range(0, len(text), chars):
65
  chunk = text[i:i+chars].strip()
66
  if chunk:
67
+ docs.append(Document(text=chunk, metadata={"chunk_id": i // chars}))
68
  return docs
69
 
70
  def edges_to_pyvis(edges):
71
+ # IMPORTANT: cdn_resources="in_line" prevents PyVis from creating a ./lib folder
72
+ net = Network(
73
+ height="700px",
74
+ width="100%",
75
+ bgcolor="#ffffff",
76
+ font_color="#222222",
77
+ notebook=False,
78
+ directed=False,
79
+ cdn_resources="in_line",
80
+ )
81
  node_ids = {}
82
  for e in edges:
83
  n1 = f"{e.node_1.label}:{e.node_1.name}"
 
92
  net.toggle_physics(True)
93
  return net
94
 
95
+ # ── Input tabs ─────────────────────────────────────────────────────────────────
96
  tab_text, tab_pdf = st.tabs(["πŸ“ Paste Text", "πŸ“„ Upload PDF"])
97
  input_text = ""
98
  with tab_text:
 
102
  if pdf_file:
103
  input_text = pdf_to_text(pdf_file)
104
 
105
+ # ── Action ─────────────────────────────────────────────────────────────────────
106
  if st.button("Generate Knowledge Graph", type="primary"):
107
  if not input_text.strip():
108
  st.warning("Please provide text or a PDF.")
 
111
  st.error("OPENROUTER_API_KEY is not set in Space Secrets.")
112
  st.stop()
113
 
114
+ # Route OpenAI SDK traffic through OpenRouter (OpenAI-compatible)
115
  os.environ["OPENAI_API_KEY"] = OPENROUTER_API_KEY
116
  os.environ["OPENAI_BASE_URL"] = "https://openrouter.ai/api/v1"
117
+ # Optional attribution headers for OpenRouter analytics/ranking
 
118
  os.environ["OPENAI_DEFAULT_HEADERS"] = (
119
  '{"HTTP-Referer":"https://huggingface.co/spaces/blazingbunny/rahulnyk_knowledge_graph",'
120
  '"X-Title":"Knowledge Graph (OpenRouter)"}'
 
126
  ontology = Ontology(
127
  labels=parse_labels(labels_text),
128
  relationships=[r.strip() for r in relationships_text.split(",") if r.strip()] or
129
+ ["Relation between any pair of Entities"],
130
  )
131
 
132
  st.info("Chunking input and building graph…")
133
  docs = chunk_text(input_text)
134
 
135
+ # LLM client (OpenRouter via OpenAI client)
136
  llm = OpenAIClient(model=selected_model, temperature=temperature, top_p=top_p)
137
 
138
  gm = GraphMaker(ontology=ontology, llm_client=llm, verbose=False)
139
+ edges = gm.from_documents(docs, delay_s_between=0) # tweak delay for rate limits if needed
140
 
141
  st.success(f"Graph built with {len(edges)} edges.")
142
 
143
+ # Show edge table
144
  df = pd.DataFrame([{
145
  "node_1_label": e.node_1.label, "node_1": e.node_1.name,
146
  "node_2_label": e.node_2.label, "node_2": e.node_2.name,
 
148
  } for e in edges])
149
  st.dataframe(df, use_container_width=True)
150
 
151
+ # Render graph in-memory (no writes)
152
  net = edges_to_pyvis(edges)
153
+ html = net.generate_html() # <- avoids creating ./lib
154
+ st.components.v1.html(html, height=750, scrolling=True)
 
 
 
 
155
 
156
  st.markdown("---")
157
  st.caption("Powered by knowledge-graph-maker via OpenRouter.")