Neo4j Python Driver 5.20

The Official Neo4j Driver for Python.

Neo4j versions supported:

  • Neo4j 5.0 - 5.20

  • Neo4j 4.4

Python versions supported:

  • Python 3.12 (added in driver version 5.14.0)

  • Python 3.11 (added in driver version 5.3.0)

  • Python 3.10

  • Python 3.9

  • Python 3.8

  • Python 3.7



To install the latest stable release, use:

python -m pip install neo4j

To install the latest pre-release, use:

python -m pip install --pre neo4j


neo4j-driver is the old name for this package. It is now deprecated and and will receive no further updates starting with 6.0.0. Make sure to install neo4j as shown above.


It is always recommended to install python packages for user space in a virtual environment.

Virtual Environment

To create a virtual environment named sandbox, use:

python -m venv sandbox

To activate the virtual environment named sandbox, use:

source sandbox/bin/activate

To deactivate the current active virtual environment, use:


Development Environment

For development, we recommend to run Python in development mode (python -X dev ...). Specifically for this driver, this will:

  • enable ResourceWarning, which the driver emits if resources (e.g., Sessions) aren’t properly closed.

  • enable DeprecationWarning, which the driver emits if deprecated APIs are used.

  • enable the driver’s debug mode (this can also be achieved by setting the environment variable PYTHONNEO4JDEBUG):

    • This is experimental. It might be changed or removed any time even without prior notice.

    • the driver will raise an exception if non-concurrency-safe methods are used concurrently.

      Added in version 5.15.

Quick Example

from neo4j import GraphDatabase, RoutingControl

URI = "neo4j://localhost:7687"
AUTH = ("neo4j", "password")

def add_friend(driver, name, friend_name):
        "MERGE (a:Person {name: $name}) "
        "MERGE (friend:Person {name: $friend_name}) "
        "MERGE (a)-[:KNOWS]->(friend)",
        name=name, friend_name=friend_name, database_="neo4j",

def print_friends(driver, name):
    records, _, _ = driver.execute_query(
        "MATCH (a:Person)-[:KNOWS]->(friend) WHERE = $name "
        "RETURN ORDER BY",
        name=name, database_="neo4j", routing_=RoutingControl.READ,
    for record in records:

with GraphDatabase.driver(URI, auth=AUTH) as driver:
    add_friend(driver, "Arthur", "Guinevere")
    add_friend(driver, "Arthur", "Lancelot")
    add_friend(driver, "Arthur", "Merlin")
    print_friends(driver, "Arthur")

Example Application

import logging

from neo4j import GraphDatabase, RoutingControl
from neo4j.exceptions import DriverError, Neo4jError

class App:

    def __init__(self, uri, user, password, database=None):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))
        self.database = database

    def close(self):
        # Don't forget to close the driver connection when you are finished
        # with it

    def create_friendship(self, person1_name, person2_name):
        with self.driver.session() as session:
            # Write transactions allow the driver to handle retries and
            # transient errors
            result = self._create_and_return_friendship(
                person1_name, person2_name
            print("Created friendship between: "
                  f"{result['p1']}, {result['p2']}")

    def _create_and_return_friendship(self, person1_name, person2_name):

        # To learn more about the Cypher syntax,
        # see

        # The Cheat Sheet is also a good resource for keywords,
        # see

        query = (
            "CREATE (p1:Person { name: $person1_name }) "
            "CREATE (p2:Person { name: $person2_name }) "
            "CREATE (p1)-[:KNOWS]->(p2) "
            record = self.driver.execute_query(
                query, person1_name=person1_name, person2_name=person2_name,
                result_transformer_=lambda r: r.single(strict=True)
            return {"p1": record[""], "p2": record[""]}
        # Capture any errors along with the query and data for traceability
        except (DriverError, Neo4jError) as exception:
            logging.error("%s raised an error: \n%s", query, exception)

    def find_person(self, person_name):
        names = self._find_and_return_person(person_name)
        for name in names:
            print(f"Found person: {name}")

    def _find_and_return_person(self, person_name):
        query = (
            "MATCH (p:Person) "
            "WHERE = $person_name "
            "RETURN AS name"
        names = self.driver.execute_query(
            query, person_name=person_name,
            database_=self.database, routing_=RoutingControl.READ,
            result_transformer_=lambda r: r.value("name")
        return names

if __name__ == "__main__":
    # For Aura specific connection URI,
    # see .
    scheme = "neo4j"  # Connecting to Aura, use the "neo4j+s" URI scheme
    host_name = ""
    port = 7687
    uri = f"{scheme}://{host_name}:{port}"
    user = "<Username for Neo4j database>"
    password = "<Password for Neo4j database>"
    database = "neo4j"
    app = App(uri, user, password, database)
        app.create_friendship("Alice", "David")

Further Information