15
15
16
16
from neo4j import Driver , GraphDatabase
17
17
18
+ from testcontainers .core .config import TIMEOUT
18
19
from testcontainers .core .generic import DbContainer
19
20
from testcontainers .core .waiting_utils import wait_container_is_ready , wait_for_logs
21
+ from typing import Optional
20
22
21
23
22
24
class Neo4jContainer (DbContainer ):
@@ -35,26 +37,17 @@ class Neo4jContainer(DbContainer):
35
37
... result = session.run("MATCH (n) RETURN n LIMIT 1")
36
38
... record = result.single()
37
39
"""
38
-
39
- # The official image requires a change of password on startup.
40
- NEO4J_ADMIN_PASSWORD = os .environ .get ("NEO4J_ADMIN_PASSWORD" , "password" )
41
- # Default port for the binary Bolt protocol.
42
- DEFAULT_BOLT_PORT = 7687
43
- AUTH_FORMAT = "neo4j/{password}"
44
- NEO4J_STARTUP_TIMEOUT_SECONDS = 10
45
- NEO4J_USER = "neo4j"
46
-
47
- def __init__ (self , image : str = "neo4j:latest" , ** kwargs ) -> None :
40
+ def __init__ (self , image : str = "neo4j:latest" , * , bolt_port : int = 7687 ,
41
+ password : Optional [str ] = None , username : Optional [str ] = None , ** kwargs ) -> None :
48
42
super (Neo4jContainer , self ).__init__ (image , ** kwargs )
49
- self .bolt_port = Neo4jContainer .DEFAULT_BOLT_PORT
43
+ self .username = username or os .environ .get ("NEO4J_USER" , "password" )
44
+ self .password = password or os .environ .get ("NEO4J_PASSWORD" , "password" )
45
+ self .bolt_port = bolt_port
50
46
self .with_exposed_ports (self .bolt_port )
51
47
self ._driver = None
52
48
53
49
def _configure (self ) -> None :
54
- self .with_env (
55
- "NEO4J_AUTH" ,
56
- Neo4jContainer .AUTH_FORMAT .format (password = Neo4jContainer .NEO4J_ADMIN_PASSWORD )
57
- )
50
+ self .with_env ("NEO4J_AUTH" , f"neo4j/{ self .password } " )
58
51
59
52
def get_connection_url (self ) -> str :
60
53
return "{dialect}://{host}:{port}" .format (
@@ -65,12 +58,7 @@ def get_connection_url(self) -> str:
65
58
66
59
@wait_container_is_ready ()
67
60
def _connect (self ) -> None :
68
- # First we wait for Neo4j to say it's listening
69
- wait_for_logs (
70
- self ,
71
- "Remote interface available at" ,
72
- Neo4jContainer .NEO4J_STARTUP_TIMEOUT_SECONDS ,
73
- )
61
+ wait_for_logs (self , "Remote interface available at" , TIMEOUT )
74
62
75
63
# Then we actually check that the container really is listening
76
64
with self .get_driver () as driver :
@@ -81,6 +69,6 @@ def _connect(self) -> None:
81
69
def get_driver (self , ** kwargs ) -> Driver :
82
70
return GraphDatabase .driver (
83
71
self .get_connection_url (),
84
- auth = (Neo4jContainer . NEO4J_USER , Neo4jContainer . NEO4J_ADMIN_PASSWORD ),
72
+ auth = (self . username , self . password ),
85
73
** kwargs
86
74
)
0 commit comments