Spaces:
Sleeping
Sleeping
File size: 2,519 Bytes
df3294b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# genesis/graphdb.py
from __future__ import annotations
import os
from typing import Dict, List
from neo4j import GraphDatabase
NEO4J_URI = os.getenv("NEO4J_URI")
NEO4J_USER = os.getenv("NEO4J_USER")
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
def _require_config():
if not (NEO4J_URI and NEO4J_USER and NEO4J_PASSWORD):
raise RuntimeError(
"Neo4j not configured. Set NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD in Space Secrets."
)
async def write_topic_and_papers(topic: str, citations: List[Dict[str, str]]) -> Dict[str, int]:
"""
Create/merge a Topic node and Paper nodes, and connect them with MENTIONS edges.
Schema:
(t:Topic {id})-[:MENTIONS]->(p:Paper {url}) with p.title set/updated.
Returns: {"nodes": <int>, "rels": <int>}
"""
_require_config()
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
nodes = 0
rels = 0
try:
with driver.session() as sess:
# Topic
sess.run(
"MERGE (t:Topic {id:$id}) SET t.title=$title",
id=(topic or "Topic")[:200],
title=(topic or "Topic")[:500],
)
nodes += 1
# Papers + edges
for c in citations or []:
title = (c.get("title") or "citation")[:500]
url = (c.get("url") or "")[:1000]
if not url and not title:
continue
sess.run(
"""
MERGE (p:Paper {url:$url})
ON CREATE SET p.title=$title
ON MATCH SET p.title = coalesce(p.title, $title)
WITH p
MATCH (t:Topic {id:$topic})
MERGE (t)-[:MENTIONS]->(p)
""",
url=url,
title=title,
topic=(topic or "Topic")[:200],
)
nodes += 1
rels += 1
return {"nodes": nodes, "rels": rels}
finally:
driver.close()
# Optional helper for debugging connectivity in a notebook/Space shell
def verify_connection() -> str:
_require_config()
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
try:
with driver.session() as sess:
res = sess.run("RETURN 1 AS ok").single()
assert res and res["ok"] == 1
return "Neo4j connection OK."
finally:
driver.close()
|