Karate Club dataset

This notebook shows the classic Zachary Karate Club network loaded into both NetworkXGraph and Neo4jGraph using the shared loader in drm.exemples.

Dataset notes:

  • 34 members

  • classic community-detection benchmark

  • club attribute is used to build club nodes

[ ]:
import importlib.util

# Comprovació de presència del paquet
package_to_check = 'drm'
spec = importlib.util.find_spec(package_to_check)

if spec is None:
    print(f'⚠️ {package_to_check} no està instal·lat. Iniciant instal·lació...')
    %pip install -q --upgrade drm-tools
    print("✅ Instal·lació completada. L'estat del kernel PODRIA requerir un reinici.")
else:
    print(f'✅ {package_to_check} ja està present al sistema. Saltant instal·lació.')

[7]:
import os

from drm import Neo4jGraph, NetworkXGraph
from drm.exemples import load_karate_club


def neo4j_config(default_target="DEV"):
    target = os.environ.get("NEO4J_TARGET", default_target).upper()
    prefix = f"NEO4J_{target}_"
    return {
        "target": target,
        "url": os.environ.get(f"{prefix}URL", os.environ.get("NEO4J_URL", "bolt://localhost:7687")),
        "user": os.environ.get(f"{prefix}USER", os.environ.get("NEO4J_USER", "neo4j")),
        "password": os.environ.get(f"{prefix}PASSWORD", os.environ.get("NEO4J_PASSWORD", "secret")),
        "database": os.environ.get(f"{prefix}DATABASE", os.environ.get("NEO4J_DATABASE", "neo4j")),
    }

NetworkXGraph

[8]:
nx_graph = NetworkXGraph()
nx_stats = load_karate_club(nx_graph)
print("NetworkX stats:", nx_stats)
print("NetworkX nodes:", len(nx_graph.get_nodes()))
print("NetworkX edges:", len(nx_graph.get_edges()))
nx_graph.close()
NetworkX stats: {'members': 34, 'clubs': 2, 'interacts': 78, 'member_of': 34}
NetworkX nodes: 36
NetworkX edges: 112

Neo4jGraph

[9]:
cfg = neo4j_config()
print("Using Neo4j target:", cfg["target"])
neo4j_graph = Neo4jGraph(
    url=cfg["url"],
    user=cfg["user"],
    password=cfg["password"],
    database=cfg["database"],
)
try:
    neo4j_stats = load_karate_club(neo4j_graph)
    print("Neo4j stats:", neo4j_stats)
finally:
    neo4j_graph.close()

Using Neo4j target: DEV
---------------------------------------------------------------------------
AuthError                                 Traceback (most recent call last)
Cell In[9], line 3
      1 cfg = neo4j_config()
      2 print("Using Neo4j target:", cfg["target"])
----> 3 neo4j_graph = Neo4jGraph(
      4     url=cfg["url"],
      5     user=cfg["user"],
      6     password=cfg["password"],

File ~/Desenvolupament/drm-tools/drm/neo4j_graph.py:55, in Neo4jGraph.__init__(self, url, user, password, database)
     51     self._session = self._driver.session(database=database)
     52 # self._version = list(list(self._session._pool.connections.values())[0])[
     53 #    0
     54 # ].PROTOCOL_VERSION[0]
---> 55 self._version = self._driver.get_server_info().protocol_version[0]
     56 # FK index: neo4j_id → set of (other_id, rel_type, direction)
     57 # direction: "out" = edge starts here, "in" = edge ends here
     58 self._fk_index: Dict[int, Set[Tuple[int, str, str]]] = {}

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/driver.py:1142, in Driver.get_server_info(self, **config)
   1137     preview_warn(
   1138         "Passing key-word arguments to get_server_info() is a "
   1139         "preview feature."
   1140     )
   1141 session_config = self._read_session_config(config)
-> 1142 return self._get_server_info(session_config)

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/driver.py:1293, in Driver._get_server_info(self, session_config)
   1291 def _get_server_info(self, session_config) -> ServerInfo:
   1292     with self._session(session_config) as session:
-> 1293         return session._get_server_info()

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/work/session.py:175, in Session._get_server_info(self)
    173 def _get_server_info(self):
    174     assert not self._connection
--> 175     self._connect(
    176         READ_ACCESS, liveness_check_timeout=0, unprepared=True
    177     )
    178     server_info = self._connection.server_info
    179     self._disconnect()

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/work/session.py:128, in Session._connect(self, access_mode, **acquire_kwargs)
    126     access_mode = self._config.default_access_mode
    127 try:
--> 128     super()._connect(
    129         access_mode, auth=self._config.auth, **acquire_kwargs
    130     )
    131 except asyncio.CancelledError:
    132     self._handle_cancellation(message="_connect")

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/work/workspace.py:181, in Workspace._connect(self, access_mode, auth, **acquire_kwargs)
    171 acquire_kwargs_ = {
    172     "access_mode": access_mode,
    173     "timeout": acquisition_deadline,
   (...)    178     "database_callback": self._make_db_resolution_callback(),
    179 }
    180 acquire_kwargs_.update(acquire_kwargs)
--> 181 self._connection = self._pool.acquire(**acquire_kwargs_)
    182 if (
    183     target_db.guessed
    184     and not self._pinned_database
   (...)    188     # support SSR.
    189     # => we need to fall back to explicit home database resolution
    190     log.debug(
    191         "[#0000]  _: <WORKSPACE> detected ssr support race; "
    192         "falling back to explicit home database resolution",
    193     )

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_pool.py:678, in BoltPool.acquire(self, access_mode, timeout, database, bookmarks, auth, liveness_check_timeout, unprepared, database_callback)
    671 deadline = acquisition_timeout_to_deadline(timeout)
    672 log.debug(
    673     "[#0000]  _: <POOL> acquire direct connection, "
    674     "access_mode=%r, database=%r",
    675     access_mode,
    676     database,
    677 )
--> 678 return self._acquire(
    679     self.address, auth, deadline, liveness_check_timeout, unprepared
    680 )

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_pool.py:418, in IOPool._acquire(self, address, auth, deadline, liveness_check_timeout, unprepared)
    413             raise ConnectionAcquisitionTimeoutError(
    414                 "failed to obtain a connection from the pool within "
    415                 f"{deadline.original_timeout!r}s (timeout)"
    416             )
    417 log.debug("[#0000]  _: <POOL> trying to hand out new connection")
--> 418 return connection_creator()

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_pool.py:231, in IOPool._acquire_new_later.<locals>.connection_creator()
    229 try:
    230     try:
--> 231         connection = self.opener(
    232             address, auth or self.pool_config.auth, deadline
    233         )
    234     except ServiceUnavailable:
    235         self.deactivate(address)

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_pool.py:638, in BoltPool.open.<locals>.opener(addr, auth_manager, deadline)
    637 def opener(addr, auth_manager, deadline):
--> 638     return Bolt.open(
    639         addr,
    640         auth_manager=auth_manager,
    641         deadline=deadline,
    642         routing_context=None,
    643         pool_config=pool_config,
    644     )

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_bolt.py:426, in Bolt.open(address, auth_manager, deadline, routing_context, pool_config)
    424 connection.socket.set_write_deadline(deadline)
    425 try:
--> 426     connection.hello()
    427 finally:
    428     connection.socket.set_read_deadline(None)

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_bolt4.py:658, in Bolt4x3.hello(self, dehydration_hooks, hydration_hooks)
    649 self._append(
    650     b"\x01",
    651     (headers,),
   (...)    655     dehydration_hooks=dehydration_hooks,
    656 )
    657 self.send_all()
--> 658 self.fetch_all()

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_bolt.py:883, in Bolt.fetch_all(self)
    881 response = self.responses[0]
    882 while not response.complete:
--> 883     detail_delta, summary_delta = self.fetch_message()
    884     detail_count += detail_delta
    885     summary_count += summary_delta

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_bolt.py:868, in Bolt.fetch_message(self)
    864 # Receive exactly one message
    865 tag, fields = self.inbox.pop(
    866     hydration_hooks=self.responses[0].hydration_hooks
    867 )
--> 868 res = self._process_message(tag, fields)
    869 self.idle_since = monotonic()
    870 return res

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_bolt4.py:497, in Bolt4x0._process_message(self, tag, fields)
    495 self._server_state_manager.state = BoltStates.FAILED
    496 try:
--> 497     response.on_failure(summary_metadata or {})
    498 except (ServiceUnavailable, DatabaseUnavailable):
    499     if self.pool:

File ~/opt/anaconda3/envs/drm-env/lib/python3.11/site-packages/neo4j/_sync/io/_common.py:292, in InitResponse.on_failure(self, metadata)
    287 Util.callback(handler)
    288 metadata["message"] = metadata.get(
    289     "message",
    290     "Connection initialisation failed due to an unknown error",
    291 )
--> 292 raise self._hydrate_error(metadata)

AuthError: {neo4j_code: Neo.ClientError.Security.Unauthorized} {message: The client is unauthorized due to authentication failure.} {gql_status: 50N42} {gql_status_description: error: general processing exception - unexpected error. The client is unauthorized due to authentication failure.}
[ ]: