Skip to content

Commit 2c702a6

Browse files
4.0 config refactoring (#374)
* moved WorkSpaceConfig into conf.py * moved SessionConfig into conf.py * moved defined variables into api.py * updated config to use the defined variable WRITE_ACCESS * added documentation naming comments for config * config naming fix max_connection_pool_size * config naming fix max_connection_lifetime * config naming fix connection_timeout * config naming fix connection_acquisition_timeout * updated naming for IOPool config to pool_config * improved naming for session config * config propagation update * config values explained * added database name to api defined variables * testing conf.py * moved parse_routing_context into api.py * transaction configuration update * fetch_size and dabase moved into WorkspaceConfig * removed redundant import * default config values are not overwritten by other default fix
1 parent 683b78c commit 2c702a6

22 files changed

+512
-225
lines changed

docs/source/driver.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ The maximum time for which a connection can exist before being closed on release
122122

123123
The maximum number of connections managed by the connection pool
124124

125-
``acquire_timeout``
125+
``connection_acquisition_timeout``
126126
----------------------------------
127127

128128
The maximum time to wait for a connection to be acquired from the pool.

docs/source/usage_patterns.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Session Initialization Work Pattern
9898
"database": "default",
9999
"bookmarks": ["bookmark-1",],
100100
"access_mode": ACCESS_WRITE,
101-
"acquire_timeout": 60.0,
101+
"connection_acquisition_timeout": 60.0,
102102
"max_retry_time": 30.0,
103103
"initial_retry_delay": 1.0,
104104
"retry_delay_multiplier": 2.0,

neo4j/__init__.py

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,15 @@
3030
]
3131

3232
from logging import getLogger
33-
from urllib.parse import (
34-
urlparse,
35-
parse_qs,
36-
)
33+
3734

3835
from neo4j.addressing import (
3936
Address,
4037
IPv4Address,
4138
IPv6Address,
4239
)
4340
from neo4j.api import (
44-
Auth,
41+
Auth, # TODO: Validate naming for Auth compared to other drivers.
4542
AuthToken,
4643
basic_auth,
4744
kerberos_auth,
@@ -51,12 +48,16 @@
5148
Version,
5249
READ_ACCESS,
5350
WRITE_ACCESS,
51+
SYSTEM_DATABASE,
52+
DEFAULT_DATABASE,
53+
TRUST_ALL_CERTIFICATES,
54+
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES,
5455
)
5556
from neo4j.conf import (
5657
Config,
5758
PoolConfig,
58-
TRUST_ALL_CERTIFICATES,
59-
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES,
59+
WorkspaceConfig,
60+
SessionConfig,
6061
)
6162
from neo4j.meta import (
6263
experimental,
@@ -72,7 +73,6 @@
7273
ResultSummary,
7374
Query,
7475
Session,
75-
SessionConfig,
7676
unit_of_work,
7777
)
7878

@@ -85,7 +85,7 @@ class GraphDatabase:
8585
"""
8686

8787
@classmethod
88-
def driver(cls, uri, *, auth=None, acquire_timeout=None, **config):
88+
def driver(cls, uri, *, auth=None, **config):
8989
""" Create a Neo4j driver that uses socket I/O and thread-based
9090
concurrency.
9191
@@ -116,12 +116,12 @@ def driver(cls, uri, *, auth=None, acquire_timeout=None, **config):
116116
**Settings:** Neo4jDriver with encryption (accepts only certificates signed by an certificate authority), full certificate checks.
117117
118118
:param auth:
119-
:param acquire_timeout: seconds
120119
:param config: connection configuration settings
121120
"""
122121

123122
from neo4j.api import (
124123
parse_neo4j_uri,
124+
parse_routing_context,
125125
DRIVER_BOLT,
126126
DRIVER_NEO4j,
127127
SECURITY_TYPE_NOT_SECURE,
@@ -173,60 +173,37 @@ def driver(cls, uri, *, auth=None, acquire_timeout=None, **config):
173173
config["trust"] = TRUST_ALL_CERTIFICATES
174174

175175
if driver_type == DRIVER_BOLT:
176-
return cls.bolt_driver(parsed.netloc, auth=auth, acquire_timeout=acquire_timeout, **config)
176+
return cls.bolt_driver(parsed.netloc, auth=auth, **config)
177177
elif driver_type == DRIVER_NEO4j:
178-
rc = cls._parse_routing_context(parsed.query)
179-
return cls.neo4j_driver(parsed.netloc, auth=auth, routing_context=rc, acquire_timeout=acquire_timeout, **config)
178+
routing_context = parse_routing_context(parsed.query)
179+
return cls.neo4j_driver(parsed.netloc, auth=auth, routing_context=routing_context, **config)
180180

181181
@classmethod
182-
def bolt_driver(cls, target, *, auth=None, acquire_timeout=None, **config):
182+
def bolt_driver(cls, target, *, auth=None, **config):
183183
""" Create a driver for direct Bolt server access that uses
184184
socket I/O and thread-based concurrency.
185185
"""
186186
from neo4j._exceptions import BoltHandshakeError, BoltSecurityError
187187

188188
try:
189-
return BoltDriver.open(target, auth=auth, acquire_timeout=acquire_timeout, **config)
189+
return BoltDriver.open(target, auth=auth, **config)
190190
except (BoltHandshakeError, BoltSecurityError) as error:
191191
from neo4j.exceptions import ServiceUnavailable
192192
raise ServiceUnavailable(str(error)) from error
193193

194194
@classmethod
195-
def neo4j_driver(cls, *targets, auth=None, routing_context=None, acquire_timeout=None,
196-
**config):
195+
def neo4j_driver(cls, *targets, auth=None, routing_context=None, **config):
197196
""" Create a driver for routing-capable Neo4j service access
198197
that uses socket I/O and thread-based concurrency.
199198
"""
200199
from neo4j._exceptions import BoltHandshakeError, BoltSecurityError
201200

202201
try:
203-
return Neo4jDriver.open(*targets, auth=auth, routing_context=routing_context, acquire_timeout=acquire_timeout, **config)
202+
return Neo4jDriver.open(*targets, auth=auth, routing_context=routing_context, **config)
204203
except (BoltHandshakeError, BoltSecurityError) as error:
205204
from neo4j.exceptions import ServiceUnavailable
206205
raise ServiceUnavailable(str(error)) from error
207206

208-
@classmethod
209-
def _parse_routing_context(cls, query):
210-
""" Parse the query portion of a URI to generate a routing
211-
context dictionary.
212-
"""
213-
if not query:
214-
return {}
215-
216-
context = {}
217-
parameters = parse_qs(query, True)
218-
for key in parameters:
219-
value_list = parameters[key]
220-
if len(value_list) != 1:
221-
raise ValueError("Duplicated query parameters with key '%s', "
222-
"value '%s' found in query string '%s'" % (key, value_list, query))
223-
value = value_list[0]
224-
if not value:
225-
raise ValueError("Invalid parameters:'%s=%s' in query string "
226-
"'%s'." % (key, value, query))
227-
context[key] = value
228-
return context
229-
230207

231208
class Direct:
232209

@@ -303,7 +280,7 @@ def __exit__(self, exc_type, exc_value, traceback):
303280

304281
@property
305282
def encrypted(self):
306-
return bool(self._pool.config.encrypted)
283+
return bool(self._pool.pool_config.encrypted)
307284

308285
def session(self, **config):
309286
""" Create a simple session.
@@ -350,7 +327,6 @@ class BoltDriver(Direct, Driver):
350327
@classmethod
351328
def open(cls, target, *, auth=None, **config):
352329
from neo4j.io import BoltPool
353-
from neo4j.work import WorkspaceConfig
354330
address = cls.parse_target(target)
355331
pool_config, default_workspace_config = Config.consume_chain(config, PoolConfig, WorkspaceConfig)
356332
pool = BoltPool.open(address, auth=auth, **pool_config)
@@ -362,15 +338,15 @@ def __init__(self, pool, default_workspace_config):
362338
self._default_workspace_config = default_workspace_config
363339

364340
def session(self, **config):
365-
from neo4j.work.simple import Session, SessionConfig
366-
session_config = SessionConfig(self._default_workspace_config,
367-
SessionConfig.consume(config))
341+
from neo4j.work.simple import Session
342+
session_config = SessionConfig(self._default_workspace_config, config)
343+
SessionConfig.consume(config) # Consume the config
368344
return Session(self._pool, session_config)
369345

370346
def pipeline(self, **config):
371347
from neo4j.work.pipelining import Pipeline, PipelineConfig
372-
pipeline_config = PipelineConfig(self._default_workspace_config,
373-
PipelineConfig.consume(config))
348+
pipeline_config = PipelineConfig(self._default_workspace_config, config)
349+
PipelineConfig.consume(config) # Consume the config
374350
return Pipeline(self._pool, pipeline_config)
375351

376352
def verify_connectivity(self, **config):
@@ -394,7 +370,6 @@ class Neo4jDriver(Routing, Driver):
394370
@classmethod
395371
def open(cls, *targets, auth=None, routing_context=None, **config):
396372
from neo4j.io import Neo4jPool
397-
from neo4j.work import WorkspaceConfig
398373
addresses = cls.parse_targets(*targets)
399374
pool_config, default_workspace_config = Config.consume_chain(config, PoolConfig, WorkspaceConfig)
400375
pool = Neo4jPool.open(*addresses, auth=auth, routing_context=routing_context, **pool_config)
@@ -406,15 +381,15 @@ def __init__(self, pool, default_workspace_config):
406381
self._default_workspace_config = default_workspace_config
407382

408383
def session(self, **config):
409-
from neo4j.work.simple import Session, SessionConfig
410-
session_config = SessionConfig(self._default_workspace_config,
411-
SessionConfig.consume(config))
384+
from neo4j.work.simple import Session
385+
session_config = SessionConfig(self._default_workspace_config, config)
386+
SessionConfig.consume(config) # Consume the config
412387
return Session(self._pool, session_config)
413388

414389
def pipeline(self, **config):
415390
from neo4j.work.pipelining import Pipeline, PipelineConfig
416-
pipeline_config = PipelineConfig(self._default_workspace_config,
417-
PipelineConfig.consume(config))
391+
pipeline_config = PipelineConfig(self._default_workspace_config, config)
392+
PipelineConfig.consume(config) # Consume the config
418393
return Pipeline(self._pool, pipeline_config)
419394

420395
def get_routing_table(self):

neo4j/api.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from urllib.parse import (
2222
urlparse,
23+
parse_qs,
2324
)
2425
from.exceptions import (
2526
ConfigurationError,
@@ -48,6 +49,12 @@
4849

4950
URI_SCHEME_BOLT_ROUTING = "bolt+routing"
5051

52+
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES = "TRUST_SYSTEM_CA_SIGNED_CERTIFICATES" # Default
53+
TRUST_ALL_CERTIFICATES = "TRUST_ALL_CERTIFICATES"
54+
55+
SYSTEM_DATABASE = "system"
56+
DEFAULT_DATABASE = None
57+
5158

5259
class Auth:
5360
""" Container for auth details.
@@ -230,3 +237,33 @@ def parse_neo4j_uri(uri):
230237
))
231238

232239
return driver_type, security_type, parsed
240+
241+
242+
def check_access_mode(access_mode):
243+
if access_mode is None:
244+
return WRITE_ACCESS
245+
if access_mode not in (READ_ACCESS, WRITE_ACCESS):
246+
msg = "Unsupported access mode {}".format(access_mode)
247+
raise ConfigurationError(msg)
248+
249+
return access_mode
250+
251+
252+
def parse_routing_context(query):
253+
""" Parse the query portion of a URI to generate a routing context dictionary.
254+
"""
255+
if not query:
256+
return {}
257+
258+
context = {}
259+
parameters = parse_qs(query, True)
260+
for key in parameters:
261+
value_list = parameters[key]
262+
if len(value_list) != 1:
263+
raise ConfigurationError("Duplicated query parameters with key '%s', value '%s' found in query string '%s'" % (key, value_list, query))
264+
value = value_list[0]
265+
if not value:
266+
raise ConfigurationError("Invalid parameters:'%s=%s' in query string '%s'." % (key, value, query))
267+
context[key] = value
268+
269+
return context

0 commit comments

Comments
 (0)