Skip to content

Commit a8a2b04

Browse files
robsdedudefbiville
andauthored
Updated examples and docs (#929)
* Remove 3.5->4.x migration notes * Update examples to use `driver.execute_query` where appropriate * Updated links to external resources * Add GraphAcademy to further reading links --------- Signed-off-by: Rouven Bauer <rouven.bauer@neo4j.com> Co-authored-by: Florent Biville <florent.biville@neo4j.com>
1 parent c3884e5 commit a8a2b04

File tree

7 files changed

+166
-197
lines changed

7 files changed

+166
-197
lines changed

README.rst

Lines changed: 36 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -47,99 +47,56 @@ Quick Example
4747

4848
.. code-block:: python
4949
50-
from neo4j import GraphDatabase
50+
from neo4j import GraphDatabase, RoutingControl
5151
52-
driver = GraphDatabase.driver("neo4j://localhost:7687",
53-
auth=("neo4j", "password"))
5452
55-
def add_friend(tx, name, friend_name):
56-
tx.run("MERGE (a:Person {name: $name}) "
57-
"MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})",
58-
name=name, friend_name=friend_name)
53+
URI = "neo4j://localhost:7687"
54+
AUTH = ("neo4j", "password")
5955
60-
def print_friends(tx, name):
61-
query = ("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
62-
"RETURN friend.name ORDER BY friend.name")
63-
for record in tx.run(query, name=name):
64-
print(record["friend.name"])
65-
66-
with driver.session(database="neo4j") as session:
67-
session.execute_write(add_friend, "Arthur", "Guinevere")
68-
session.execute_write(add_friend, "Arthur", "Lancelot")
69-
session.execute_write(add_friend, "Arthur", "Merlin")
70-
session.execute_read(print_friends, "Arthur")
71-
72-
driver.close()
73-
74-
75-
Connection Settings Breaking Change (4.x)
76-
=========================================
77-
78-
+ The driver’s default configuration for encrypted is now false
79-
(meaning that driver will only attempt plain text connections by default).
80-
81-
+ Connections to encrypted services (such as Neo4j Aura) should now explicitly
82-
be set to encrypted.
83-
84-
+ When encryption is explicitly enabled, the default trust mode is to trust the
85-
CAs that are trusted by operating system and use hostname verification.
86-
87-
+ This means that encrypted connections to servers holding self-signed
88-
certificates will now fail on certificate verification by default.
89-
90-
+ Using the new ``neo4j+ssc`` scheme will allow to connect to servers holding self-signed certificates and not use hostname verification.
91-
92-
+ The ``neo4j://`` scheme replaces ``bolt+routing://`` and can be used for both clustered and single-instance configurations with Neo4j 4.0.
93-
94-
95-
96-
See, https://neo4j.com/docs/migration-guide/4.0/upgrade-driver/#upgrade-driver-breakingchanges
9756
57+
def add_friend(driver, name, friend_name):
58+
driver.execute_query(
59+
"MERGE (a:Person {name: $name}) "
60+
"MERGE (friend:Person {name: $friend_name}) "
61+
"MERGE (a)-[:KNOWS]->(friend)",
62+
name=name, friend_name=friend_name, database_="neo4j",
63+
)
9864
99-
See, https://neo4j.com/docs/driver-manual/current/client-applications/#driver-connection-uris for changes in default security settings between 3.x and 4.x
10065
66+
def print_friends(driver, name):
67+
records, _, _ = driver.execute_query(
68+
"MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
69+
"RETURN friend.name ORDER BY friend.name",
70+
name=name, database_="neo4j", routing_=RoutingControl.READ,
71+
)
72+
for record in records:
73+
print(record["friend.name"])
10174
102-
Connecting with Python Driver 4.x to Neo4j 3.5 (EOL)
103-
----------------------------------------------------
104-
105-
Using the Python Driver 4.x and connecting to Neo4j 3.5 with default connection settings for Neo4j 3.5.
106-
107-
.. code-block:: python
108-
109-
# the preferred form
110-
111-
driver = GraphDatabase.driver("neo4j+ssc://localhost:7687", auth=("neo4j", "password"))
112-
113-
# is equivalent to
114-
115-
driver = GraphDatabase.driver("neo4j://localhost:7687", auth=("neo4j", "password"), encrypted=True, trust=False)
116-
117-
118-
Connecting with Python Driver 1.7 (EOL) to Neo4j 4.x
119-
----------------------------------------------------
120-
121-
Using the Python Driver 1.7 and connecting to Neo4j 4.x with default connection settings for Neo4j 4.x.
122-
123-
.. code-block:: python
12475
125-
driver = GraphDatabase.driver("neo4j://localhost:7687", auth=("neo4j", "password"), encrypted=False)
76+
with GraphDatabase.driver(URI, auth=AUTH) as driver:
77+
add_friend(driver, "Arthur", "Guinevere")
78+
add_friend(driver, "Arthur", "Lancelot")
79+
add_friend(driver, "Arthur", "Merlin")
80+
print_friends(driver, "Arthur")
12681
12782
128-
Other Information
129-
=================
83+
Further Information
84+
===================
13085

131-
* `The Neo4j Operations Manual`_
132-
* `The Neo4j Drivers Manual`_
133-
* `Python Driver API Documentation`_
134-
* `Neo4j Cypher Refcard`_
135-
* `Example Project`_
86+
* `The Neo4j Operations Manual`_ (docs on how to run a Neo4j server)
87+
* `The Neo4j Python Driver Manual`_ (good introduction to this driver)
88+
* `Python Driver API Documentation`_ (full API documentation for this driver)
89+
* `Neo4j Cypher Cheat Sheet`_ (summary of Cypher syntax - Neo4j's graph query language)
90+
* `Example Project`_ (small web application using this driver)
91+
* `GraphAcademy`_ (interactive, free online trainings for Neo4j)
13692
* `Driver Wiki`_ (includes change logs)
137-
* `Neo4j 4.0 Migration Guide`_
93+
* `Neo4j Migration Guide`_
13894

13995
.. _`The Neo4j Operations Manual`: https://neo4j.com/docs/operations-manual/current/
140-
.. _`The Neo4j Drivers Manual`: https://neo4j.com/docs/driver-manual/current/
96+
.. _`The Neo4j Python Driver Manual`: https://neo4j.com/docs/python-manual/current/
14197
.. _`Python Driver API Documentation`: https://neo4j.com/docs/api/python-driver/current/
142-
.. _`Neo4j Cypher Refcard`: https://neo4j.com/docs/cypher-refcard/current/
98+
.. _`Neo4j Cypher Cheat Sheet`: https://neo4j.com/docs/cypher-cheat-sheet/
14399
.. _`Example Project`: https://github.com/neo4j-examples/movies-python-bolt
100+
.. _`GraphAcademy`: https://graphacademy.neo4j.com/categories/python/
144101
.. _`Driver Wiki`: https://github.com/neo4j/neo4j-python-driver/wiki
145-
.. _`Neo4j 4.0 Migration Guide`: https://neo4j.com/docs/migration-guide/4.0/
102+
.. _`Neo4j Migration Guide`: https://neo4j.com/docs/migration-guide/current/

docs/source/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ See :class:`.BookmarkManager` for more information.
10351035
``auth``
10361036
--------
10371037
Optional :class:`neo4j.Auth` or ``(user, password)``-tuple. Use this overwrite the
1038-
authentication information for the session.
1038+
authentication information for the session (user-switching).
10391039
This requires the server to support re-authentication on the protocol level. You can
10401040
check this by calling :meth:`.Driver.supports_session_auth` / :meth:`.AsyncDriver.supports_session_auth`.
10411041

docs/source/index.rst

Lines changed: 85 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ To install the latest pre-release, use:
6161
python -m pip install --pre neo4j
6262
6363
64+
.. TODO: 7.0 - remove this note
65+
66+
.. note::
67+
68+
``neo4j-driver`` is the old name for this package. It is now deprecated and
69+
and will receive no further updates starting with 6.0.0. Make sure to
70+
install ``neo4j`` as shown above.
71+
6472
.. note::
6573

6674
It is always recommended to install python packages for user space in a virtual environment.
@@ -92,60 +100,40 @@ To deactivate the current active virtual environment, use:
92100
Quick Example
93101
*************
94102

95-
Creating nodes and relationships.
96-
97103
.. code-block:: python
98104
99-
from neo4j import GraphDatabase
105+
from neo4j import GraphDatabase, RoutingControl
100106
101107
102108
URI = "neo4j://localhost:7687"
103109
AUTH = ("neo4j", "password")
104110
105111
106-
def create_person(tx, name):
107-
tx.run("CREATE (a:Person {name: $name})", name=name)
112+
def add_friend(driver, name, friend_name):
113+
driver.execute_query(
114+
"MERGE (a:Person {name: $name}) "
115+
"MERGE (friend:Person {name: $friend_name}) "
116+
"MERGE (a)-[:KNOWS]->(friend)",
117+
name=name, friend_name=friend_name, database_="neo4j",
118+
)
108119
109120
110-
def create_friend_of(tx, name, friend):
111-
tx.run("MATCH (a:Person) WHERE a.name = $name "
112-
"CREATE (a)-[:KNOWS]->(:Person {name: $friend})",
113-
name=name, friend=friend)
121+
def print_friends(driver, name):
122+
records, _, _ = driver.execute_query(
123+
"MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
124+
"RETURN friend.name ORDER BY friend.name",
125+
name=name, database_="neo4j", routing_=RoutingControl.READ,
126+
)
127+
for record in records:
128+
print(record["friend.name"])
114129
115130
116131
with GraphDatabase.driver(URI, auth=AUTH) as driver:
117-
with driver.session() as session:
118-
session.execute_write(create_person, "Alice")
119-
session.execute_write(create_friend_of, "Alice", "Bob")
120-
session.execute_write(create_friend_of, "Alice", "Carl")
121-
132+
add_friend(driver, "Arthur", "Guinevere")
133+
add_friend(driver, "Arthur", "Lancelot")
134+
add_friend(driver, "Arthur", "Merlin")
135+
print_friends(driver, "Arthur")
122136
123-
Finding nodes.
124-
125-
.. code-block:: python
126-
127-
from neo4j import GraphDatabase
128-
129-
130-
URI = "neo4j://localhost:7687"
131-
AUTH = ("neo4j", "password")
132-
133-
134-
def get_friends_of(tx, name):
135-
friends = []
136-
result = tx.run("MATCH (a:Person)-[:KNOWS]->(f) "
137-
"WHERE a.name = $name "
138-
"RETURN f.name AS friend", name=name)
139-
for record in result:
140-
friends.append(record["friend"])
141-
return friends
142-
143-
144-
with GraphDatabase.driver(URI, auth=AUTH) as driver:
145-
with driver.session() as session:
146-
friends = session.execute_read(get_friends_of, "Alice")
147-
for friend in friends:
148-
print(friend)
149137
150138
151139
*******************
@@ -155,99 +143,112 @@ Example Application
155143
.. code-block:: python
156144
157145
import logging
158-
from neo4j import GraphDatabase
159-
from neo4j.exceptions import ServiceUnavailable
146+
147+
from neo4j import GraphDatabase, RoutingControl
148+
from neo4j.exceptions import DriverError, Neo4jError
160149
161150
162151
class App:
163152
164-
def __init__(self, uri, user, password):
153+
def __init__(self, uri, user, password, database=None):
165154
self.driver = GraphDatabase.driver(uri, auth=(user, password))
155+
self.database = database
166156
167157
def close(self):
168-
# Don't forget to close the driver connection when you are finished with it
158+
# Don't forget to close the driver connection when you are finished
159+
# with it
169160
self.driver.close()
170161
171162
def create_friendship(self, person1_name, person2_name):
172163
with self.driver.session() as session:
173-
# Write transactions allow the driver to handle retries and transient errors
174-
result = session.execute_write(
175-
self._create_and_return_friendship, person1_name, person2_name)
176-
for record in result:
177-
print("Created friendship between: {p1}, {p2}".format(
178-
p1=record['p1'], p2=record['p2']))
164+
# Write transactions allow the driver to handle retries and
165+
# transient errors
166+
result = self._create_and_return_friendship(
167+
person1_name, person2_name
168+
)
169+
print("Created friendship between: "
170+
f"{result['p1']}, {result['p2']}")
179171
180-
@staticmethod
181-
def _create_and_return_friendship(tx, person1_name, person2_name):
172+
def _create_and_return_friendship(self, person1_name, person2_name):
182173
183174
# To learn more about the Cypher syntax,
184175
# see https://neo4j.com/docs/cypher-manual/current/
185176
186-
# The Reference Card is also a good resource for keywords,
187-
# see https://neo4j.com/docs/cypher-refcard/current/
177+
# The Cheat Sheet is also a good resource for keywords,
178+
# see https://neo4j.com/docs/cypher-cheat-sheet/
188179
189180
query = (
190181
"CREATE (p1:Person { name: $person1_name }) "
191182
"CREATE (p2:Person { name: $person2_name }) "
192183
"CREATE (p1)-[:KNOWS]->(p2) "
193-
"RETURN p1, p2"
184+
"RETURN p1.name, p2.name"
194185
)
195-
result = tx.run(query, person1_name=person1_name, person2_name=person2_name)
196186
try:
197-
return [{"p1": record["p1"]["name"], "p2": record["p2"]["name"]}
198-
for record in result]
187+
record = self.driver.execute_query(
188+
query, person1_name=person1_name, person2_name=person2_name,
189+
database_=self.database,
190+
result_transformer_=lambda r: r.single(strict=True)
191+
)
192+
return {"p1": record["p1.name"], "p2": record["p2.name"]}
199193
# Capture any errors along with the query and data for traceability
200-
except ServiceUnavailable as exception:
201-
logging.error("{query} raised an error: \n {exception}".format(
202-
query=query, exception=exception))
194+
except (DriverError, Neo4jError) as exception:
195+
logging.error("%s raised an error: \n%s", query, exception)
203196
raise
204197
205198
def find_person(self, person_name):
206-
with self.driver.session() as session:
207-
result = session.execute_read(self._find_and_return_person, person_name)
208-
for record in result:
209-
print("Found person: {record}".format(record=record))
199+
names = self._find_and_return_person(person_name)
200+
for name in names:
201+
print(f"Found person: {name}")
210202
211-
@staticmethod
212-
def _find_and_return_person(tx, person_name):
203+
def _find_and_return_person(self, person_name):
213204
query = (
214205
"MATCH (p:Person) "
215206
"WHERE p.name = $person_name "
216207
"RETURN p.name AS name"
217208
)
218-
result = tx.run(query, person_name=person_name)
219-
return [record["name"] for record in result]
209+
names = self.driver.execute_query(
210+
query, person_name=person_name,
211+
database_=self.database, routing_=RoutingControl.READ,
212+
result_transformer_=lambda r: r.value("name")
213+
)
214+
return names
220215
221216
if __name__ == "__main__":
222-
# See https://neo4j.com/developer/aura-connect-driver/ for Aura specific connection URL.
217+
# For Aura specific connection URI,
218+
# see https://neo4j.com/developer/aura-connect-driver/ .
223219
scheme = "neo4j" # Connecting to Aura, use the "neo4j+s" URI scheme
224220
host_name = "example.com"
225221
port = 7687
226-
url = f"{scheme}://{host_name}:{port}"
222+
uri = f"{scheme}://{host_name}:{port}"
227223
user = "<Username for Neo4j database>"
228224
password = "<Password for Neo4j database>"
229-
app = App(url, user, password)
225+
database = "neo4j"
226+
app = App(uri, user, password, database)
230227
try:
231228
app.create_friendship("Alice", "David")
232229
app.find_person("Alice")
233230
finally:
234231
app.close()
235232
236233
237-
*****************
238-
Other Information
239-
*****************
234+
*******************
235+
Further Information
236+
*******************
240237

241-
* `Neo4j Documentation`_
242-
* `The Neo4j Drivers Manual`_
243-
* `Cypher Cheat Sheet`_
244-
* `Example Project`_
238+
* `The Neo4j Operations Manual`_ (docs on how to run a Neo4j server)
239+
* `The Neo4j Python Driver Manual`_ (good introduction to this driver)
240+
* `Python Driver API Documentation`_ (full API documentation for this driver)
241+
* `Neo4j Cypher Cheat Sheet`_ (summary of Cypher syntax - Neo4j's graph query language)
242+
* `Example Project`_ (small web application using this driver)
243+
* `GraphAcademy`_ (interactive, free online trainings for Neo4j)
245244
* `Driver Wiki`_ (includes change logs)
246-
* `Neo4j Aura`_
245+
* `Neo4j Migration Guide`_
247246

248-
.. _`Neo4j Documentation`: https://neo4j.com/docs/
249-
.. _`The Neo4j Drivers Manual`: https://neo4j.com/docs/driver-manual/current/
250-
.. _`Cypher Cheat Sheet`: https://neo4j.com/docs/cypher-cheat-sheet/current/
247+
.. _`The Neo4j Operations Manual`: https://neo4j.com/docs/operations-manual/current/
248+
.. _`The Neo4j Python Driver Manual`: https://neo4j.com/docs/python-manual/current/
249+
.. _`Python Driver API Documentation`: https://neo4j.com/docs/api/python-driver/current/
250+
.. _`Neo4j Cypher Cheat Sheet`: https://neo4j.com/docs/cypher-cheat-sheet/
251251
.. _`Example Project`: https://github.com/neo4j-examples/movies-python-bolt
252+
.. _`GraphAcademy`: https://graphacademy.neo4j.com/categories/python/
252253
.. _`Driver Wiki`: https://github.com/neo4j/neo4j-python-driver/wiki
253-
.. _`Neo4j Aura`: https://neo4j.com/neo4j-aura/
254+
.. _`Neo4j Migration Guide`: https://neo4j.com/docs/migration-guide/current/

0 commit comments

Comments
 (0)