Phani-ISB/Knowledge_Graphs
0
1# -*- coding: utf-8 -*-2"""Learn with Knowledge Graphs.ipynb3 4Automatically generated by Colab.5 6Original file is located at7 https://colab.research.google.com/drive/16UX6wbUmaLG6YBJKzH5YouNYYnw2mL8H8"""9 10# app.py11import streamlit as st12import wikipediaapi13import requests, json14import networkx as nx15import matplotlib.pyplot as plt16from neo4j import GraphDatabase17 18# ---------------------------19# CONFIGURATION20# ---------------------------21# API Key for Perplexity22PPLX_API_KEY = "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"23 24# Optional Neo4j credentials (leave empty if not using Neo4j)25NEO4J_URI = "neo4j+s://1a780c1e.databases.neo4j.io"26NEO4J_USER = "neo4j"27NEO4J_PASSWORD = "Xaabk9z1r5J-DPK6JPOH5QuOHL_MrTeFytx2c4sxjN4"28 29driver = None30if NEO4J_URI and NEO4J_USER and NEO4J_PASSWORD:31 driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))32 33 34# ---------------------------35# FUNCTIONS36# ---------------------------37def perplexity_chat(prompt, model="sonar-medium-online"):38 url = "https://api.perplexity.ai/chat/completions"39 headers = {40 "Authorization": f"Bearer {PPLX_API_KEY}",41 "Content-Type": "application/json",42 }43 data = {44 "model": model,45 "messages": [{"role": "user", "content": prompt}],46 "temperature": 0,47 }48 resp = requests.post(url, headers=headers, data=json.dumps(data))49 if resp.status_code != 200:50 return f"โ Error {resp.status_code}: {resp.text}"51 return resp.json()["choices"][0]["message"]["content"]52 53 54def extract_triples_from_chunk(text, max_triples=5):55 prompt = f"""Extract up to {max_triples} subject-predicate-object triples56from the text below. Return only triples in the format (subject, predicate, object).57 58Text: {text}"""59 60 content = perplexity_chat(prompt)61 triples = []62 for line in content.splitlines():63 line = line.strip(" ()[]{}")64 if not line:65 continue66 parts = [p.strip() for p in line.split(",")]67 if len(parts) == 3:68 triples.append(tuple(parts))69 return triples70 71 72def build_kg_from_wiki_title(title, lang="en", chunk_chars=800, max_triples_per_chunk=5):73 wiki = wikipediaapi.Wikipedia(lang, user_agent = "MyKGApp/1.0 (contact: your_email@example.com)")74 page = wiki.page(title)75 if not page.exists():76 return []77 78 text = page.text79 chunks = [text[i:i+chunk_chars] for i in range(0, len(text), chunk_chars)]80 81 triples = []82 for chunk in chunks:83 chunk_triples = extract_triples_from_chunk(chunk, max_triples=max_triples_per_chunk)84 triples.extend(chunk_triples)85 86 return triples87 88 89def insert_triple(tx, subject, predicate, obj):90 tx.run(91 """92 MERGE (s:Entity {name: $subject})93 MERGE (o:Entity {name: $object})94 MERGE (s)-[:RELATION {type: $predicate}]->(o)95 """,96 subject=subject, predicate=predicate, object=obj97 )98 99def insert_triples(triples):100 if not driver:101 return102 with driver.session() as session:103 for s, p, o in triples:104 session.execute_write(insert_triple, s, p, o)105 106 107def answer_with_kg(question, triples, top_k=10, model="sonar-medium-online"):108 context_triples = triples[:top_k]109 context_str = "\n".join([f"({s}, {p}, {o})" for s, p, o in context_triples])110 111 prompt = f"""112 You are a QA assistant.113 Use the following knowledge graph triples as context to answer the question.114 115 Knowledge Graph Triples:116 {context_str}117 118 Question: {question}119 120 Answer in a clear, concise way. If you don't find enough info in triples,121 say 'Not found in knowledge graph'.122 """123 return perplexity_chat(prompt, model=model)124 125 126# ---------------------------127# STREAMLIT APP128# ---------------------------129st.title("๐ Knowledge Graph Chatbot (Wikipedia + Perplexity)")130 131# Input for Wikipedia Title132title = st.text_input("Enter a Wikipedia Title (e.g., Harry Potter):")133 134if title:135 st.write(f"๐ Building Knowledge Graph for: **{title}** ...")136 triples = build_kg_from_wiki_title(title)137 138 if triples:139 st.success(f"Extracted {len(triples)} triples โ
")140 141 # Save in Neo4j if configured142 if driver:143 insert_triples(triples)144 st.info("๐ก Triples also stored in Neo4j.")145 146 # Show sample triples147 st.subheader("Sample Triples")148 st.json(triples[:10])149 150 # Visualization inside Streamlit151 st.subheader("Graph Visualization")152 G = nx.DiGraph()153 for s, p, o in triples[:30]:154 G.add_edge(s, o, label=p)155 156 plt.figure(figsize=(12, 8))157 pos = nx.spring_layout(G, k=0.5)158 nx.draw(G, pos, with_labels=True, node_size=2500, node_color="lightblue",159 font_size=10, font_weight="bold", arrows=True)160 edge_labels = nx.get_edge_attributes(G, 'label')161 nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)162 st.pyplot(plt)163 164 # Chat interface165 st.subheader("๐ฌ Ask Questions")166 user_question = st.text_input("Your question:")167 if user_question:168 answer = answer_with_kg(user_question, triples)169 st.write("๐ค", answer)170 else:171 st.error("Page not found or no triples extracted.")172 173 