diff --git a/ChangeLog.md b/ChangeLog.md index c23ac96b..042c2a72 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -7,7 +7,8 @@ Starting with v1.31.6, this file will contain a record of major features and upd - Allow `%%neptune_ml` to accept JSON blob as parameter input for most phases ([Link to PR](https://github.com/aws/graph-notebook/pull/202)) - Added `--silent` option for suppressing query output ([PR #1](https://github.com/aws/graph-notebook/pull/201)) ([PR #2](https://github.com/aws/graph-notebook/pull/203)) - Added all `parserConfiguration` options to `%load` ([Link to PR](https://github.com/aws/graph-notebook/pull/205)) -- Pinned `ipython` and `ipykernel` dependency versions ([Link to PR](https://github.com/aws/graph-notebook/pull/207)) +- Upgraded to Gremlin-Python 3.5 and Jupyter Notebook 6.x ([Link to PR](https://github.com/aws/graph-notebook/pull/209)) +- Resolved smart indent bug in openCypher magic cells ([Link to PR](https://github.com/aws/graph-notebook/pull/209)) ## Release 3.0.6 (September 20, 2021) - Added a new `%stream_viewer` magic that allows interactive exploration of the Neptune CDC stream (if enabled). ([Link to PR](https://github.com/aws/graph-notebook/pull/191)) diff --git a/README.md b/README.md index 4cca69e6..7ff75a12 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,7 @@ It is recommended to check the [ChangeLog.md](ChangeLog.md) file periodically to You will need: -* [Python](https://www.python.org/downloads/) 3.6.1-3.6.12 -* [Jupyter Notebook](https://jupyter.org/install) 5.7.13 -* [Tornado](https://pypi.org/project/tornado/) 4.5.3 +* [Python](https://www.python.org/downloads/) 3.6.13-3.9.7 * [RDFLib](https://pypi.org/project/rdflib/) 5.0.0 * A graph database that provides one or more of: * A SPARQL 1.1 endpoint @@ -102,10 +100,6 @@ You will need: ``` # pin specific versions of required dependencies -pip install tornado==4.5.3 -pip install ipykernel==5.3.4 -pip install "ipython>=7.16.1,<=7.19.0" -pip install notebook==5.7.13 pip install rdflib==5.0.0 # install the package @@ -123,7 +117,7 @@ python -m graph_notebook.nbextensions.install python -m graph_notebook.notebooks.install --destination ~/notebook/destination/dir # start jupyter -jupyter notebook ~/notebook/destination/dir +python -m graph_notebook.start_notebook --notebooks-dir ~/notebook/destination/dir ``` ## Connecting to a graph database diff --git a/requirements.txt b/requirements.txt index 680c57d3..e12584c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,20 @@ -tornado==4.5.3 SPARQLWrapper==1.8.4 networkx==2.4 Jinja2==2.11.3 jupyter -notebook==5.7.13 +notebook>=6.1.5 ipywidgets==7.5.1 jupyter-contrib-nbextensions widgetsnbextension -gremlinpython<=3.4.* +gremlinpython>=3.5.1 requests==2.24.0 -ipython>=7.16.1,<=7.19.0 +ipython>=7.16.1 ipykernel==5.3.4 neo4j==4.2.1 rdflib~=5.0.0 traitlets~=4.3.3 setuptools~=40.6.2 +nbconvert<6 # requirements for testing botocore~=1.18.18 diff --git a/setup.py b/setup.py index f7d99abb..500a34d6 100644 --- a/setup.py +++ b/setup.py @@ -66,14 +66,13 @@ def get_version(): package_dir={'': 'src'}, include_package_data=True, install_requires=[ - 'gremlinpython<3.5.*', + 'gremlinpython>=3.5.1', 'SPARQLWrapper==1.8.4', - 'tornado==4.5.3', 'requests', 'ipywidgets', 'networkx==2.4', 'Jinja2==2.11.3', - 'notebook', + 'notebook>=6.1.5', 'jupyter-contrib-nbextensions', 'widgetsnbextension', 'jupyter>=1.0.0', @@ -83,7 +82,8 @@ def get_version(): 'ipython>=7.16.1,<=7.19.0', 'neo4j==4.3.2', 'rdflib==5.0.0', - 'ipykernel==5.3.4' + 'ipykernel==5.3.4', + 'nbconvert==5.6.1' ], package_data={ 'graph_notebook': ['graph_notebook/widgets/nbextensions/static/*.js', diff --git a/src/graph_notebook/neptune/client.py b/src/graph_notebook/neptune/client.py index 677daf78..98e65282 100644 --- a/src/graph_notebook/neptune/client.py +++ b/src/graph_notebook/neptune/client.py @@ -14,9 +14,11 @@ from botocore.awsrequest import AWSRequest from gremlin_python.driver import client from neo4j import GraphDatabase -from tornado import httpclient +import nest_asyncio -import graph_notebook.neptune.gremlin.graphsonV3d0_MapType_objectify_patch # noqa F401 +# This patch is no longer needed when graph_notebook is using the a Gremlin Python +# client >= 3.5.0 as the HashableDict is now part of that client driver. +# import graph_notebook.neptune.gremlin.graphsonV3d0_MapType_objectify_patch # noqa F401 DEFAULT_SPARQL_CONTENT_TYPE = 'application/x-www-form-urlencoded' DEFAULT_PORT = 8182 @@ -158,12 +160,13 @@ def sparql_cancel(self, query_id: str, silent: bool = False): return self._query_status('sparql', query_id=query_id, silent=silent, cancelQuery=True) def get_gremlin_connection(self) -> client.Client: + nest_asyncio.apply() + uri = f'{self._http_protocol}://{self.host}:{self.port}/gremlin' request = self._prepare_request('GET', uri) ws_url = f'{self._ws_protocol}://{self.host}:{self.port}/gremlin' - ws_request = httpclient.HTTPRequest(ws_url, headers=dict(request.headers)) - return client.Client(ws_request, 'g') + return client.Client(ws_url, 'g', headers=dict(request.headers)) def gremlin_query(self, query, bindings=None): c = self.get_gremlin_connection() diff --git a/src/graph_notebook/start_notebook.py b/src/graph_notebook/start_notebook.py new file mode 100644 index 00000000..2d03a1c5 --- /dev/null +++ b/src/graph_notebook/start_notebook.py @@ -0,0 +1,48 @@ +""" +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +""" + +import os +import argparse +import json + +HOME_PATH = os.path.expanduser("~") +NOTEBOOK_CFG_PATH = HOME_PATH + '/.jupyter/nbconfig/notebook.json' + + +def patch_cm_cypher_config(): + cypher_cfg = { + "cm_config": { + "smartIndent": False, + "mode": "cypher" + } + } + + try: + with open(NOTEBOOK_CFG_PATH, 'r') as file: + notebook_cfg = json.load(file) + except (json.decoder.JSONDecodeError, FileNotFoundError) as e: + notebook_cfg = {} + + notebook_cfg["CodeCell"] = cypher_cfg + + with open(NOTEBOOK_CFG_PATH, 'w') as file: + json.dump(notebook_cfg, file) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--notebooks-dir', default='', type=str, help='The directory to start Jupyter from.') + + args = parser.parse_args() + + patch_cm_cypher_config() + + kernel_manager_option = "--NotebookApp.kernel_manager_class=notebook.services.kernels.kernelmanager.AsyncMappingKernelManager" + notebooks_dir = '~/notebook/destination/dir' if args.notebooks_dir == '' else args.notebooks_dir + os.system(f'''jupyter notebook {kernel_manager_option} {notebooks_dir}''') + + +if __name__ == '__main__': + main()