{"id":1580,"library":"neo4j","title":"Neo4j Python Driver","description":"The Neo4j Python Driver is the official client library for interacting with Neo4j graph databases from Python applications. It uses the Bolt protocol for efficient communication. The library maintains multiple major versions, including LTS releases, and typically sees minor and patch updates every few weeks, with new major versions released periodically to introduce significant features or breaking changes. The current stable version is 6.1.0.","status":"active","version":"6.1.0","language":"en","source_language":"en","source_url":"https://github.com/neo4j/neo4j-python-driver","tags":["database","graph","neo4j","driver"],"install":[{"cmd":"pip install neo4j","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"GraphDatabase","correct":"from neo4j import GraphDatabase"},{"note":"AuthTokens module for authentication was introduced in 5.x, replacing direct usage of tuples or basic_auth function from older versions.","wrong":"from neo4j import basic_auth","symbol":"AuthTokens","correct":"from neo4j import AuthTokens"}],"quickstart":{"code":"import os\nfrom neo4j import GraphDatabase, AuthTokens\n\n# Configure connection details using environment variables\nNEO4J_URI = os.environ.get(\"NEO4J_URI\", \"bolt://localhost:7687\")\nNEO4J_USERNAME = os.environ.get(\"NEO4J_USERNAME\", \"neo4j\")\nNEO4J_PASSWORD = os.environ.get(\"NEO4J_PASSWORD\", \"password\") # Use a strong password in production\n\nclass Neo4jApp:\n    def __init__(self, uri, username, password):\n        self.driver = GraphDatabase.driver(uri, auth=AuthTokens.basic(username, password))\n\n    def close(self):\n        self.driver.close()\n\n    def create_person(self, name):\n        with self.driver.session() as session:\n            greeting = session.execute_write(self._create_and_return_person, name)\n            print(f\"Created person: {greeting}\")\n\n    @staticmethod\n    def _create_and_return_person(tx, name):\n        query = (\n            \"CREATE (p:Person {name: $name}) \"\n            \"RETURN p.name AS name\"\n        )\n        result = tx.run(query, name=name)\n        return result.single()[\"name\"]\n\n    def find_person(self, name):\n        with self.driver.session() as session:\n            person_name = session.execute_read(self._find_and_return_person, name)\n            print(f\"Found person: {person_name}\")\n\n    @staticmethod\n    def _find_and_return_person(tx, name):\n        query = (\n            \"MATCH (p:Person {name: $name}) \"\n            \"RETURN p.name AS name\"\n        )\n        result = tx.run(query, name=name)\n        record = result.single()\n        return record[\"name\"] if record else None\n\nif __name__ == \"__main__\":\n    # Example usage (ensure Neo4j is running and accessible)\n    # To run this, you'd typically set NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD\n    # in your environment or update the defaults.\n    app = Neo4jApp(NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD)\n    try:\n        app.create_person(\"Alice\")\n        app.find_person(\"Alice\")\n        app.create_person(\"Bob\")\n        app.find_person(\"Bob\")\n    finally:\n        app.close()\n","lang":"python","description":"This quickstart demonstrates how to connect to a Neo4j database using environment variables, create and manage a driver, use `AuthTokens` for authentication, and execute Cypher queries within read/write transactions. It showcases creating and finding nodes, emphasizing proper session and driver resource management."},"warnings":[{"fix":"Adopt the new `Result` object API. Use `result.single()` for expected single records, `result.data()` for list of dictionaries, or iterate explicitly: `[record for record in result]`.","message":"The way to access records and iterate through `Result` objects significantly changed when migrating from version 4.x to 5.x. Direct iteration over `Result` might behave differently or raise errors. Methods like `single()`, `data()`, and explicit iteration are now the standard.","severity":"breaking","affected_versions":"4.x to 5.x, 5.x and later"},{"fix":"Update transaction callbacks to accept a `tx` object (e.g., `def my_tx_func(tx, param): tx.run(...)`). For manual transactions, use `session.begin_transaction()`, then `tx.run()`, `tx.commit()`, and `tx.rollback()`.","message":"The transaction API was revamped in 5.x. Functions like `session.read_transaction()` and `session.write_transaction()` now pass a `Transaction` object (`tx`) to the user-defined callback, rather than the `Session` object directly. Direct `session.run()` without an explicit transaction context often auto-commits.","severity":"breaking","affected_versions":"4.x to 5.x, 5.x and later"},{"fix":"Always use `with driver.session() as session:` for session management. Call `driver.close()` when your application is shutting down or the driver is no longer needed.","message":"It is crucial to properly close `Driver` and `Session` objects to prevent connection leaks and ensure resource release. Drivers are designed to be long-lived, while sessions should be short-lived.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use `auth=AuthTokens.basic(\"username\", \"password\")` when creating a `GraphDatabase.driver()` instance.","message":"Authentication token handling changed in 5.x. The `AuthTokens` module (e.g., `AuthTokens.basic`) is the recommended way to provide credentials, replacing simpler tuple-based authentication methods from older versions.","severity":"gotcha","affected_versions":"5.x and later"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}