How To Connect To Neo4j Using The Python Driver

by John Singer November 8, 2020 at 11:42 am

This post describes how to use the Neo4j Python driver to connect to a Neo4j server. We will use Python 3.8 and the V4 release of the Neo4j Python driver. This is one of many posts that make up a complete tutorial on using python to access Neo4j. I hope you find this one useful and check out the entire series.

Take a look at the environment used for this tutorial. You can recreate this environment and follow along or use whatever python development environment you like.

Example code is shown using python’s Idle editor or as simple scripts you can run using Idle.

This post uses the native Neo4j Python Driver V4. If you are wondering if you should use the native driver or the Py2Neo community driver see this.

Neo4j Python Driver Compatibility

The older Python driver V1.7 won’t work with Neo4j V4.x databases so you have to upgrade to the newer driver. The V4 driver will work with both Neo4j V4 and V3.5 with the caveat that server functionality new to V4 (such as connecting to different databases) won’t work with V3.x servers.

The older Python driver V1.7 won’t work with Neo4j V4.x databases so you have to upgrade to the newer driver. The V4 driver will work with both Neo4j V4 and V3.5 with the caveat that server functionality new to V4 (such as connecting to different databases) won’t work with V3.x servers. You need to upgrade to Python 3 as Python 2.7 is no longer supported.

Neo4j Python Driver Example

So let’s get started! We will show an example of how to connect to Neo4j using the native Python driver. First we need to import the GraphDatabase class. This class provides the ability to connect to Neo4j servers.

from neo4j import GraphDatabase

Like any database driver, the first task is to create a connection to the Neo4j database server. The connection requires a URI and authentication. We will be using simple auth so a userid and password is needed to make the connection. To do this you create a driver object.

# create the uri for the connection
uri = "neo4j://localhost:7687"
# create a driver object
driver = GraphDatabase.driver(uri, auth=("neo4j", "nachodog"))

Neo4j Python Driver URI

The uri above is an example of connecting to a Neo4j Desktop server running on your laptop which has the host name of “localhost”. The standard Bolt port is shown in this example. The URI “schemes” have changed a bit with the “bolt+routing” scheme being replaced with “neo4j” as shown in the example above.

Here are all the schemes and their uses:

URI SchemeDriver Object and Setting
boltBoltDriver with no encryption.
bolt+sscBoltDriver with encryption (accepts self signed certificates).
bolt+sBoltDriver with encryption (accepts only certificates signed by a certificate authority), full certificate checks.
neo4jNeo4jDriver with no encryption.
neo4j+sscNeo4jDriver with encryption (accepts self signed certificates).
neo4j+sNeo4jDriver with encryption (accepts only certificates signed by a certificate authority), full certificate checks.

For a deeper discussion of Neo4j standard ports see this.

The Driver Object

The driver object is the main object used to create connections to the Neo4j Server. It is created by calling the “driver” class method of the GraphDatabase class – see the example above. The driver object maintains the URI, the authentication information, and other detailed parameters (covered in another post). The driver object also maintains a connection pool that session objects use to access the server. In general, an application will create one driver object that can last the lifetime of the application. This assumes you don’t want to access a different URI or the authentication information hasn’t changed. In either of these cases you would need to close the driver and create a new one.

The following illustrates the output from the dir(driver) python command:

['__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_default_workspace_config', '_initial_addresses', '_pool', '_verify_routing_connectivity', 'close', 'default_host', 'default_port', 'default_targets', 'encrypted', 'initial_addresses', 'open', 'parse_targets', 'pipeline', 'session', 'supports_multi_db', 'verify_connectivity']

The verify_connectivity function describes the server you’re connecting to.

# get info about the driver
print("connected: {}".format(driver.verify_connectivity()))

Here’s the output from the print statement above:

connected: {IPv4Address(('localhost', 7687)): [{'ttl': 300, 'servers': [{'addresses': ['localhost:7687'], 'role': 'WRITE'}, {'addresses': ['localhost:7687'], 'role': 'READ'}, {'addresses': ['localhost:7687'], 'role': 'ROUTE'}]}]}

The driver can tell you if it supports multiple databases (i.e. it is V4 or greater) by looking at the driver.supports_multi_db() method with will return either True or False. The following print statement illustrates how to use this method.

print("multi_db: {}".format(driver.supports_multi_db()))

The driver will verify it’s host and port as well as tell you if it is using encryption. The following print statement illustrates the driver properties that supply this information.

print("Host: {}".format(driver.default_host))
print("Port: {}".format(driver.default_port))
print("Encrypted: {}".format(driver.encrypted))

Finally, the driver provides a “close” method that should be used when the application is finished accessing Neo4j. The close method will close all connections in the shared connection pool managed by the driver.

What happens when the driver object simply goes out of scope?

# close the driver
driver.close()

Summary

Here’s the entire script we’ve built up in this post you can copy this into a text file and run it using Idle or whatever python IDE you like.

from neo4j import GraphDatabase
print("tutorialconnect.py - starting")
# create the uri for the connection
uri = "neo4j://localhost:7687"

# create a driver object
driver = GraphDatabase.driver(uri, auth=("neo4j", "nachodog"))
print("tutorialconnect.py - driver created")

# get info about the driver
print("connected: {}".format(driver.verify_connectivity()))

print("multi_db: {}".format(driver.supports_multi_db()))

print("Host: {}".format(driver.default_host))
print("Port: {}".format(driver.default_port))
print("Encrypted: {}".format(driver.encrypted))

# close the driver
driver.close()

print("tutorialconnect.py - driver closed")

The following is the output from running the script in idle.

Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
====== RESTART: C:\Users\Jsing\PythonEnvV4Test\Source\tutorialconnect1.py ======
tutorialconnect.py - starting
tutorialconnect.py - driver created

Warning (from warnings module):
  File "C:\Users\Jsing\PythonEnvV4Test\Source\tutorialconnect1.py", line 11
    print("connected: {}".format(driver.verify_connectivity()))
ExperimentalWarning: The configuration may change in the future.
connected: {IPv4Address(('localhost', 7687)): [{'ttl': 300, 'servers': [{'addresses': ['localhost:7687'], 'role': 'WRITE'}, {'addresses': ['localhost:7687'], 'role': 'READ'}, {'addresses': ['localhost:7687'], 'role': 'ROUTE'}]}]}

Warning (from warnings module):
  File "C:\Users\Jsing\PythonEnvV4Test\Source\tutorialconnect1.py", line 13
    print("multi_db: {}".format(driver.supports_multi_db()))
ExperimentalWarning: Feature support query, based on Bolt Protocol Version and Neo4j Server Version will change in the future.
multi_db: True
Host: localhost
Port: 7687
Encrypted: False
tutorialconnect.py - driver closed
>>> 

Note the “Warning (from warnings module):” sections of the output. Neo4j is actually warning us that some functionality may be subject to change in the future (imagine that). This will be covered in more detail in a post on error handling.

You might be wondering how do I specify which database I want to use if your Neo4j 4.x server as been configured with multiple databases. That is specified as a part of creating the Session object and is covered in another post.

That’s it for connecting to a Neo4j server using the Python driver.

Be sure to check out the additional posts on how to use Python to access Neo4j.