Skip to content

Commit b60326a

Browse files
committed
fix(notebooks): add nest_asyncio to langchain/langgraph notebooks; fix find_related Cypher
- 02_langchain and 03_langgraph were missing nest_asyncio install+apply, causing "Cannot run the event loop while another loop is running" in Jupyter (CoordinodeClient sync wrapper calls asyncio.run() internally) - 03_langgraph: remove path variable p= from find_related Cypher — CoordiNode does not support MATCH p=(...) path binding; rewrite to MATCH (...)-[*1..N]->(...) RETURN DISTINCT m.name
1 parent cb53d45 commit b60326a

2 files changed

Lines changed: 79 additions & 5 deletions

File tree

demo/notebooks/02_langchain_graph_chain.ipynb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,15 @@
102102
" \"git+https://github.com/structured-world/coordinode-python.git@4efc7b287211f4cfcf203ce92c83773d7d72ff61#subdirectory=langchain-coordinode\",\n",
103103
" \"langchain-community\",\n",
104104
" \"langchain-openai\",\n",
105+
" \"nest_asyncio\",\n",
105106
" ],\n",
106107
" check=True,\n",
107108
" timeout=300,\n",
108109
")\n",
109110
"\n",
111+
"import nest_asyncio\n",
112+
"nest_asyncio.apply()\n",
113+
"\n",
110114
"print(\"SDK installed\")"
111115
]
112116
},

demo/notebooks/03_langgraph_agent.ipynb

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,78 @@
3737
"id": "d4e5f6a7-0003-0000-0000-000000000003",
3838
"metadata": {},
3939
"outputs": [],
40-
"source": "import os, sys, subprocess\n\nIN_COLAB = \"google.colab\" in sys.modules\n\n# Install coordinode-embedded in Colab only (requires Rust build).\nif IN_COLAB and not os.environ.get(\"COORDINODE_ADDR\"):\n # Install Rust toolchain via rustup (https://rustup.rs).\n # Colab's apt packages ship rustc ≤1.75, which cannot build coordinode-embedded\n # (requires Rust ≥1.80 for maturin/pyo3). apt-get is not a viable alternative here.\n # Download the installer to a temp file and execute it explicitly — this avoids\n # piping remote content directly into a shell while maintaining HTTPS/TLS security\n # through Python's default ssl context (cert-verified, TLS 1.2+).\n # SHA256 pinning of rustup-init is intentionally omitted: rustup.rs does not\n # publish a stable per-release checksum for sh.rustup.rs itself (only for\n # platform-specific rustup-init binaries), and pinning a hash here would break\n # silently on every rustup release. The HTTPS/TLS verification + temp-file\n # execution (not piped to shell) is the rustup team's recommended trust model.\n # Skip embedded build if COORDINODE_ADDR is set — user has a gRPC server,\n # no need to spend 5+ minutes building coordinode-embedded from source.\n # The `IN_COLAB` check already guards against local/server environments.\n import ssl as _ssl, tempfile as _tmp, urllib.request as _ur\n\n _ctx = _ssl.create_default_context()\n with _tmp.NamedTemporaryFile(mode=\"wb\", suffix=\".sh\", delete=False) as _f:\n with _ur.urlopen(\"https://sh.rustup.rs\", context=_ctx, timeout=30) as _r:\n _f.write(_r.read())\n _rustup_path = _f.name\n try:\n subprocess.run([\"/bin/sh\", _rustup_path, \"-s\", \"--\", \"-y\", \"-q\"], check=True, timeout=300)\n finally:\n os.unlink(_rustup_path)\n # Add cargo to PATH so maturin/pip can find it.\n _cargo_bin = os.path.expanduser(\"~/.cargo/bin\")\n os.environ[\"PATH\"] = f\"{_cargo_bin}{os.pathsep}{os.environ.get('PATH', '')}\"\n subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"maturin\"], check=True, timeout=300)\n subprocess.run(\n [\n sys.executable,\n \"-m\",\n \"pip\",\n \"install\",\n \"-q\",\n \"git+https://github.com/structured-world/coordinode-python.git@4efc7b287211f4cfcf203ce92c83773d7d72ff61#subdirectory=coordinode-embedded\",\n ],\n check=True,\n timeout=600,\n )\n\nsubprocess.run(\n [\n sys.executable,\n \"-m\",\n \"pip\",\n \"install\",\n \"-q\",\n \"coordinode\",\n \"langchain-coordinode\",\n \"langchain-community\",\n \"langchain-openai\",\n \"langgraph\",\n ],\n check=True,\n timeout=300,\n)\n\nprint(\"SDK installed\")"
40+
"source": [
41+
"import os, sys, subprocess\n",
42+
"\n",
43+
"IN_COLAB = \"google.colab\" in sys.modules\n",
44+
"\n",
45+
"# Install coordinode-embedded in Colab only (requires Rust build).\n",
46+
"if IN_COLAB and not os.environ.get(\"COORDINODE_ADDR\"):\n",
47+
" # Install Rust toolchain via rustup (https://rustup.rs).\n",
48+
" # Colab's apt packages ship rustc ≤1.75, which cannot build coordinode-embedded\n",
49+
" # (requires Rust ≥1.80 for maturin/pyo3). apt-get is not a viable alternative here.\n",
50+
" # Download the installer to a temp file and execute it explicitly — this avoids\n",
51+
" # piping remote content directly into a shell while maintaining HTTPS/TLS security\n",
52+
" # through Python's default ssl context (cert-verified, TLS 1.2+).\n",
53+
" # SHA256 pinning of rustup-init is intentionally omitted: rustup.rs does not\n",
54+
" # publish a stable per-release checksum for sh.rustup.rs itself (only for\n",
55+
" # platform-specific rustup-init binaries), and pinning a hash here would break\n",
56+
" # silently on every rustup release. The HTTPS/TLS verification + temp-file\n",
57+
" # execution (not piped to shell) is the rustup team's recommended trust model.\n",
58+
" # Skip embedded build if COORDINODE_ADDR is set — user has a gRPC server,\n",
59+
" # no need to spend 5+ minutes building coordinode-embedded from source.\n",
60+
" # The `IN_COLAB` check already guards against local/server environments.\n",
61+
" import ssl as _ssl, tempfile as _tmp, urllib.request as _ur\n",
62+
"\n",
63+
" _ctx = _ssl.create_default_context()\n",
64+
" with _tmp.NamedTemporaryFile(mode=\"wb\", suffix=\".sh\", delete=False) as _f:\n",
65+
" with _ur.urlopen(\"https://sh.rustup.rs\", context=_ctx, timeout=30) as _r:\n",
66+
" _f.write(_r.read())\n",
67+
" _rustup_path = _f.name\n",
68+
" try:\n",
69+
" subprocess.run([\"/bin/sh\", _rustup_path, \"-s\", \"--\", \"-y\", \"-q\"], check=True, timeout=300)\n",
70+
" finally:\n",
71+
" os.unlink(_rustup_path)\n",
72+
" # Add cargo to PATH so maturin/pip can find it.\n",
73+
" _cargo_bin = os.path.expanduser(\"~/.cargo/bin\")\n",
74+
" os.environ[\"PATH\"] = f\"{_cargo_bin}{os.pathsep}{os.environ.get('PATH', '')}\"\n",
75+
" subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"maturin\"], check=True, timeout=300)\n",
76+
" subprocess.run(\n",
77+
" [\n",
78+
" sys.executable,\n",
79+
" \"-m\",\n",
80+
" \"pip\",\n",
81+
" \"install\",\n",
82+
" \"-q\",\n",
83+
" \"git+https://github.com/structured-world/coordinode-python.git@4efc7b287211f4cfcf203ce92c83773d7d72ff61#subdirectory=coordinode-embedded\",\n",
84+
" ],\n",
85+
" check=True,\n",
86+
" timeout=600,\n",
87+
" )\n",
88+
"\n",
89+
"subprocess.run(\n",
90+
" [\n",
91+
" sys.executable,\n",
92+
" \"-m\",\n",
93+
" \"pip\",\n",
94+
" \"install\",\n",
95+
" \"-q\",\n",
96+
" \"coordinode\",\n",
97+
" \"langchain-coordinode\",\n",
98+
" \"langchain-community\",\n",
99+
" \"langchain-openai\",\n",
100+
" \"langgraph\",\n",
101+
" \"nest_asyncio\",\n",
102+
" ],\n",
103+
" check=True,\n",
104+
" timeout=300,\n",
105+
")\n",
106+
"\n",
107+
"import nest_asyncio\n",
108+
"nest_asyncio.apply()\n",
109+
"\n",
110+
"print(\"SDK installed\")"
111+
]
41112
},
42113
{
43114
"cell_type": "markdown",
@@ -199,14 +270,13 @@
199270
" \"\"\"Find all entities reachable from entity_name within the given number of hops (max 3).\"\"\"\n",
200271
" safe_depth = max(1, min(int(depth), 3))\n",
201272
" rows = client.cypher(\n",
202-
" f\"MATCH p=(n:Entity {{name: $name, session: $sess}})-[*1..{safe_depth}]->(m:Entity {{session: $sess}}) \"\n",
203-
" \"WHERE ALL(x IN nodes(p) WHERE x.session = $sess) \"\n",
204-
" \"RETURN m.name AS related, type(last(relationships(p))) AS via LIMIT 20\",\n",
273+
" f\"MATCH (n:Entity {{name: $name, session: $sess}})-[*1..{safe_depth}]->(m:Entity {{session: $sess}}) \"\n",
274+
" \"RETURN DISTINCT m.name AS related LIMIT 20\",\n",
205275
" params={\"name\": entity_name, \"sess\": SESSION},\n",
206276
" )\n",
207277
" if not rows:\n",
208278
" return f\"No related entities found for {entity_name}\"\n",
209-
" return \"\\n\".join(f\"{r['via']} -> {r['related']}\" for r in rows)\n",
279+
" return \"\\n\".join(r['related'] for r in rows)\n",
210280
"\n",
211281
"\n",
212282
"@tool\n",

0 commit comments

Comments
 (0)