Skip to main content

IPython/Jupyter magic commands for Neo4j Cypher queries (%cypher / %%cypher)

Project description

ipython-neo4j

IPython / Jupyter magic commands for Neo4j Cypher queries. A modern replacement for icypher built on the neo4j-rust-ext Bolt driver with first-class graph visualization via neo4j-viz.

%load_ext ipython_neo4j

%neo4j bolt://localhost:7687 -u neo4j -p secret

%cypher MATCH (m:Movie) RETURN m.title AS title, m.released AS year LIMIT 10

Installation

pip install ipython-neo4j

Or with uv:

uv add ipython-neo4j

To use .env file support via %neo4j --env-file, install the optional extra:

pip install "ipython-neo4j[dotenv]"

Requirements: Python ≥ 3.10, Neo4j 6.x.


Quick start

# 1. Load the extension
%load_ext ipython_neo4j

# 2. Connect
%neo4j bolt://localhost:7687 -u neo4j -p secret

# 3. Run a read query — renders as an HTML table
%cypher MATCH (m:Movie) RETURN m.title AS title LIMIT 5

# 4. Multi-line query in a cell
%%cypher
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name AS actor, count(m) AS films
ORDER BY films DESC
LIMIT 10

# 5. Get a pandas DataFrame
%%cypher --df -o df
MATCH (m:Movie) RETURN m.title AS title, m.released AS year

df.describe()

# 6. Visualize a subgraph
%%cypher --viz
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
RETURN p, r, m
LIMIT 30

Magic commands

%neo4j — connect / status / disconnect

%neo4j [URI] [-u USERNAME] [-p PASSWORD] [-d DATABASE]
       [--env-file FILE]
       [--status] [--close]
Flag Description
URI Bolt URI, e.g. bolt://localhost:7687 or neo4j+s://host
-u / --username Neo4j username
-p / --password Neo4j password
-d / --database Target database (default: neo4j)
--env-file FILE Load connection settings from a .env file
--status Show current connection status
--close Close the active connection

%cypher / %%cypher — read queries

%cypher [flags] QUERY
%%cypher [flags]
<query body>

%wcypher / %%wcypher — write queries

Identical to %cypher / %%cypher but write and schema operations are explicitly allowed. Use this to make write intent visible in notebooks.

Common flags for %cypher / %%cypher / %wcypher / %%wcypher

Flag Description
--write / -w Allow write / schema queries (alternative to %%wcypher)
--no-preflight Skip the EXPLAIN query-type pre-flight check
-o VAR Store the CypherResult in the notebook variable VAR
--df Return / store a pandas DataFrame instead of a CypherResult
--viz Render an interactive graph visualization (requires neo4j-viz)
-P EXPR Query parameters — a Python expression evaluated in the notebook namespace
-u / --uri Override connection URI for this query only
--username Override username for this query only
-p / --password Override password for this query only
-d / --database Override database for this query only

Configuring the connection

Connection settings are resolved in this priority order (highest wins):

explicit flag on %neo4j  >  --env-file values  >  shell env vars  >  built-in defaults

Option 1 — Direct flags (most explicit)

%neo4j bolt://localhost:7687 -u neo4j -p secret -d mydb

Option 2 — .env file

Create a .env file (and add it to .gitignore):

NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=secret
NEO4J_DATABASE=mydb

Then in your notebook:

%neo4j --env-file .env
%neo4j --env-file secrets.env -d override_db   # file + per-flag override

Requires python-dotenv:

pip install python-dotenv

Option 3 — IPython %env magic (no file needed)

%env NEO4J_URI=bolt://localhost:7687
%env NEO4J_USERNAME=neo4j
%env NEO4J_PASSWORD=secret
%env NEO4J_DATABASE=mydb
%neo4j   # picks up the vars automatically

Option 4 — Shell environment variables

Set variables before launching Jupyter, then call %neo4j with no arguments:

export NEO4J_URI=bolt://localhost:7687
export NEO4J_USERNAME=neo4j
export NEO4J_PASSWORD=secret
export NEO4J_DATABASE=mydb
jupyter lab
%neo4j   # auto-connects from env

Option 5 — python-dotenv directly in a cell

from dotenv import load_dotenv
load_dotenv(".env")   # populates os.environ
%neo4j                # reads from env

Option 6 — Per-query connection override

Override the global connection for a single query without changing it:

%%cypher -u bolt://other-host:7687 --username analyst -p readonly -d reporting
MATCH (n:Report) RETURN n LIMIT 5

Read / write safety

%cypher (and %%cypher) block write and schema queries by default. Before executing, an EXPLAIN pre-flight call is made to detect the query type:

Neo4j type Meaning Default behaviour
r Read ✅ Allowed
w Write ❌ Blocked
rw Read + write ❌ Blocked
s Schema (DDL) ❌ Blocked

To allow writes, use --write or the dedicated %%wcypher magic:

# Either of these works:
%%cypher --write
CREATE (n:Person {name: 'Alice'}) RETURN n

%%wcypher
CREATE INDEX person_name IF NOT EXISTS FOR (n:Person) ON (n.name)

Skip the pre-flight check when you know the query is safe (e.g. on slow connections):

%%cypher --no-preflight
MATCH (n) RETURN n LIMIT 100

Multi-statement cells

Statements can be separated by a semicolon at the end of a line — the same convention used in Cypher Shell and Neo4j Browser:

%%wcypher
CREATE INDEX person_name IF NOT EXISTS FOR (n:Person) ON (n.name);
CREATE CONSTRAINT person_id IF NOT EXISTS FOR (n:Person) REQUIRE n.id IS UNIQUE

Each statement is EXPLAIN'd individually. If any statement is a write or schema operation the entire cell is blocked unless --write / %%wcypher is used.

Note: Mid-line semicolons — e.g. inside string literals like WHERE name = 'O;Brien' — are not treated as statement separators.

When multiple statements are present, each result is displayed with a numbered header and the last result is stored when -o VAR is used.


Working with results

%%cypher -o result
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name AS name, m.title AS title
LIMIT 20
# CypherResult renders as an HTML table in Jupyter automatically

result           # display HTML table
result.df        # pandas DataFrame shorthand
result.to_dataframe()   # same

len(result)      # number of rows
result.keys      # column names
result.counters  # write counters (nodes_created, etc.)
result.summary   # full Neo4j ResultSummary

result.visualize()               # render neo4j-viz graph
result.visualize(color_by="caption")   # with custom coloring
result.to_graph()                # VisualizationGraph object

Query parameters

Pass a Python expression (evaluated in the notebook namespace) with -P:

params = {"year": 2000, "name": "Tom Hanks"}

%%cypher -P params -o movies
MATCH (p:Person {name: $name})-[:ACTED_IN]->(m:Movie)
WHERE m.released >= $year
RETURN m.title AS title, m.released AS year

Graph visualization

Return Node and Relationship objects and render them with --viz:

%%cypher --viz
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
RETURN p, r, m
LIMIT 40

Or call .visualize() programmatically on any CypherResult:

%%cypher -o g
MATCH (p:Person)-[r:DIRECTED]->(m:Movie) RETURN p, r, m LIMIT 20

g.visualize(color_by="caption")

Visualization is powered by neo4j-viz and is installed automatically as a dependency.


Error rendering

Neo4j errors (syntax errors, type errors, auth failures, connectivity issues) are rendered as styled HTML in the cell output rather than raw Python tracebacks:

%cypher MATCH (n) RETURN @@bad@@
# → Cypher Syntax Error: rendered with error code and query context

Reloading after code changes

When developing ipython-neo4j itself, reload the extension without restarting the kernel:

%reload_ext ipython_neo4j

Development

git clone https://github.com/neo4j-labs/ipython-neo4j
cd ipython-neo4j
uv sync --all-groups

# unit tests (no Neo4j required)
uv run pytest tests/test_connection.py tests/test_result.py tests/test_magic.py -v

# integration tests (requires Neo4j)
# credentials in integration.env
uv run pytest tests/test_integration.py -v

# run the demo notebook
uv run jupyter lab notebooks/demo.ipynb

Integration tests use:

  • Read-only demo (integration.env default): neo4j+s://demo.neo4jlabs.com — user/db: movies
  • Local write tests: bolt://localhost:7687 — user: neo4j, password: password

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ipython_neo4j-0.1.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ipython_neo4j-0.1.0-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file ipython_neo4j-0.1.0.tar.gz.

File metadata

  • Download URL: ipython_neo4j-0.1.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ipython_neo4j-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5d18d1620e96f8c4c4bb8c264badd217a06577ffb90c9bd5c24a957d6bafc031
MD5 648ee7659f043a253ebcafc75158096e
BLAKE2b-256 34fbfe0aa2b7edecca54bf4b62aeafdd3cdcffc45d3d5b5baeac47ac3ab397dc

See more details on using hashes here.

File details

Details for the file ipython_neo4j-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ipython_neo4j-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ipython_neo4j-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 039ba2a0ebd4a3af7b0699cb72812ce444fcf899615d438584efe99d1fd2a6b0
MD5 81c51ef768a83042ea5c9607fe690319
BLAKE2b-256 fba137e8bb5b0694cc56e7e820e7e4915d8a8906f282089576ee5f288ec74ec2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page