How to fix: ModuleNotFoundError: No module named 'neo4j.io._bolt4 when using old JupyterLab

This is weird. The follow works within python 3, but when running in Jupyter Lab, I get an odd Python error.

When I upgraded to the latest Jupyter Lab, the problem went away!

pip install neo4j

from neo4j import GraphDatabase
import neo4j
print(neo4j.__version__)
4.2.1
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "MYPASSWORD"))

And I got

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-11-5fb897f84ca1> in <module>
----> 1 driver = GraphDatabase.driver("neo4j://localhost:7473", auth=("neo4j", "clem"))

~/3.7/lib/python3.8/site-packages/neo4j/__init__.py in driver(cls, uri, auth, **config)
    184         elif driver_type == DRIVER_NEO4j:
    185             routing_context = parse_routing_context(parsed.query)
--> 186             return cls.neo4j_driver(parsed.netloc, auth=auth, routing_context=routing_context, **config)
    187 
    188     @classmethod

~/3.7/lib/python3.8/site-packages/neo4j/__init__.py in neo4j_driver(cls, auth, routing_context, *targets, **config)
    207 
    208         try:
--> 209             return Neo4jDriver.open(*targets, auth=auth, routing_context=routing_context, **config)
    210         except (BoltHandshakeError, BoltSecurityError) as error:
    211             from neo4j.exceptions import ServiceUnavailable

~/3.7/lib/python3.8/site-packages/neo4j/__init__.py in open(cls, auth, routing_context, *targets, **config)
    408         addresses = cls.parse_targets(*targets)
    409         pool_config, default_workspace_config = Config.consume_chain(config, PoolConfig, WorkspaceConfig)
--> 410         pool = Neo4jPool.open(*addresses, auth=auth, routing_context=routing_context, pool_config=pool_config, workspace_config=default_workspace_config)
    411         return cls(pool, default_workspace_config)
    412 

~/3.7/lib/python3.8/site-packages/neo4j/io/__init__.py in open(cls, auth, pool_config, workspace_config, routing_context, *addresses)
    579             pool.close()
    580             raise
--> 581         else:
    582             return pool
    583 

~/3.7/lib/python3.8/site-packages/neo4j/io/__init__.py in update_routing_table(self, database)
    788                 # Why is only the first initial routing address used?
    789                 return
--> 790 
    791         if self.update_routing_table_from(*existing_routers, database=database):
    792             return

~/3.7/lib/python3.8/site-packages/neo4j/io/__init__.py in update_routing_table_from(self, database, *routers)
    766             if new_routing_table is not None:
    767                 self.routing_tables[database].update(new_routing_table)
--> 768                 log.debug("[#0000]  C: <UPDATE ROUTING TABLE> address={!r} ({!r})".format(router, self.routing_tables[database]))
    769                 return True
    770         return False

~/3.7/lib/python3.8/site-packages/neo4j/io/__init__.py in fetch_routing_table(self, address, timeout, database)
    729         if new_routing_info is None:
    730             return None
--> 731         elif not new_routing_info:
    732             raise BoltRoutingError("Invalid routing table", address)
    733         else:

~/3.7/lib/python3.8/site-packages/neo4j/io/__init__.py in fetch_routing_info(self, address, timeout, database)
    678 
    679         from neo4j.api import (
--> 680             SYSTEM_DATABASE,
    681             DEFAULT_DATABASE,
    682             READ_ACCESS,

ModuleNotFoundError: No module named 'neo4j.io._bolt4'
  • Python: '3.8.2 (default, Dec 21 2020, 15:06:04) \n[Clang 12.0.0 (clang-1200.0.32.29)]'
  • Neo4j 4.2.2
  • Mac OS 10.15.7
  • jupyter --version
jupyter core     : 4.7.1
jupyter-notebook : 6.2.0
qtconsole        : 5.0.2
ipython          : 7.20.0
ipykernel        : 5.4.3
jupyter client   : 6.1.11
jupyter lab      : 3.0.7
nbconvert        : 6.0.7
ipywidgets       : 7.6.3
nbformat         : 5.1.2
traitlets        : 5.0.5

Jupyter Server 1.2.2

But after I upgraded:

pip install jupyter -U

which did a bunch of upgrades and the problem went away:

Successfully installed deprecation-2.1.0 jupyter-packaging-0.10.1 jupyter-server-1.6.4 jupyterlab-3.0.14 jupyterlab-server-2.5.0 tomlkit-0.7.0

Oddly,

print(neo4j.__version__)

results in:

4.1.1

(I guess heavy duty magic is happening somewhere...)