Get started

This section gives an overview of the official Neo4j Python Driver and how to connect to a Neo4j database with a "Hello World" example.

1. About the official Python driver

Neo4j provides official drivers for a number of popular programming languages. These drivers are supported by Neo4j.

Community drivers also exist for many languages, but vary greatly in terms of feature sets, maturity, and support. To find more about community drivers, visit https://neo4j.com/developer/language-guides/.

The following languages and frameworks are officially supported by Neo4j:

Table 1. Supported languages and frameworks for the 4.x driver series
Language/framework Versions supported

.NET

Go

Go 1.10

Java

Java 8+ (latest patch releases).

JavaScript

All LTS versions of Node.JS, specifically the 4.x and 6.x series runtimes (https://github.com/nodejs/LTS).

Python

Python 3.5 and above.

The driver API is intended to be topologically agnostic. This means that the underlying database topology — single instance, Causal Cluster, etc. — can be altered without requiring a corresponding alteration to application code.

In the general case, only the connection URI needs to be modified when changes are made to the topology.

The official drivers do not support HTTP communication. If you need an HTTP driver, choose one of the community drivers.

See also the HTTP API documentation.

2. Driver versions and installation

Starting with Neo4j 4.0, the versioning scheme for the database, driver and protocol have all been aligned. This simplifies general compatibility concerns.

Cross-version compatibility is still available, and minimum support for current and previous versions between both server and driver is guaranteed. More specifically, this means that Neo4j 4.0 is guaranteed to be compatible with both 4.0 Drivers and 1.7 Drivers, and the 4.0 Drivers are guaranteed to be compatible with both Neo4j 4.0 and Neo4j 3.5. In cases where at least one peer is below version 4.0, communication will occur in fallback mode, limiting functionality to that available in the lowest-versioned component.

Drivers 1.7 do not support multiple databases and Neo4j Fabric, features introduced in Neo4j 4.0. To be able to run multiple databases online concurrently and to do distributed queries over them, you must upgrade Drivers from 1.7 to 4.0. For information, see 4.0 Migration Guide → Chapter 6. Upgrade Neo4j drivers.

Wherever possible, it is recommended to use the latest stable driver release available. This will provide the greatest degree of stability and will ensure that the full set of server functionality is available. The drivers, when used with Neo4j Enterprise Edition, come with full cluster routing support. The drivers make no explicit distinction between Enterprise Edition and Community Edition however, and simply operate with the functionality made available by Neo4j itself.

Example 1. Acquire the driver

To find the latest stable version of the Python Driver, visit https://pypi.org/project/neo4j/

To find a list of all available releases, visit https://pypi.org/simple/neo4j/

To install the latest stable version of the Python Driver:

pip install neo4j

It is also an option to install a certain version of the driver.

Example 2. Installation with Python

The following is the syntax for installing a certain version of the Python Driver:

pip install neo4j==$PYTHON_DRIVER_VERSION

In the following example we are installing Python Driver version 4.4.0.

pip install neo4j==4.4.0
Example 3. Installation with Python, get Python Driver prerelease

In the following example we get the latest prerelease version:

pip install neo4 --pre

The release notes for the Python Driver are available here

3. A "Hello World" example

The example below shows the minimal configuration necessary to interact with Neo4j through the Python driver:

Example 4. Hello World
import logging
import sys

from neo4j import GraphDatabase
from neo4j.exceptions import ServiceUnavailable
class App:

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

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

    @staticmethod
    def enable_log(level, output_stream):
        handler = logging.StreamHandler(output_stream)
        handler.setLevel(level)
        logging.getLogger("neo4j").addHandler(handler)
        logging.getLogger("neo4j").setLevel(level)

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

    @staticmethod
    def _create_and_return_friendship(tx, person1_name, person2_name, knows_from):
        # To learn more about the Cypher syntax, see https://neo4j.com/docs/cypher-manual/current/
        # The Reference Card is also a good resource for keywords https://neo4j.com/docs/cypher-refcard/current/
        query = (
            "CREATE (p1:Person { name: $person1_name }) "
            "CREATE (p2:Person { name: $person2_name }) "
            "CREATE (p1)-[k:KNOWS { from: $knows_from }]->(p2) "
            "RETURN p1, p2, k"
        )
        result = tx.run(query, person1_name=person1_name,
                        person2_name=person2_name, knows_from=knows_from)
        try:
            return [{
                        "p1": row["p1"]["name"],
                        "p2": row["p2"]["name"],
                        "knows_from": row["k"]["from"]
                    }
                    for row in result]
        # Capture any errors along with the query and data for traceability
        except ServiceUnavailable as exception:
            logging.error("{query} raised an error: \n {exception}".format(
                query=query, exception=exception))
            raise

    def find_person(self, person_name):
        with self.driver.session() as session:
            result = session.read_transaction(self._find_and_return_person, person_name)
            for row in result:
                print("Found person: {row}".format(row=row))

    @staticmethod
    def _find_and_return_person(tx, person_name):
        query = (
            "MATCH (p:Person) "
            "WHERE p.name = $person_name "
            "RETURN p.name AS name"
        )
        result = tx.run(query, person_name=person_name)
        return [row["name"] for row in result]


if __name__ == "__main__":
    bolt_url = "%%BOLT_URL_PLACEHOLDER%%"
    user = "<Username for database>"
    password = "<Password for database>"
    App.enable_log(logging.INFO, sys.stdout)
    app = App(bolt_url, user, password)
    app.create_friendship("Alice", "David", "School")
    app.find_person("Alice")
    app.close()

4. Driver API docs

For a comprehensive listing of all driver functionality, refer to the API documentation: https://neo4j.com/docs/api/python-driver/4.4/