graphdatascience 1.13__tar.gz → 1.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. {graphdatascience-1.13/graphdatascience.egg-info → graphdatascience-1.14}/PKG-INFO +18 -5
  2. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/algo/algo_proc_runner.py +1 -0
  3. graphdatascience-1.14/graphdatascience/call_parameters.py +40 -0
  4. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/base_graph_proc_runner.py +14 -6
  5. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_entity_ops_runner.py +4 -1
  6. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_remote_project_runner.py +2 -0
  7. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_type_check.py +1 -15
  8. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/ogb_loader.py +6 -6
  9. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/arrow_endpoint_version.py +1 -8
  10. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/cypher_graph_constructor.py +3 -2
  11. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/gds_arrow_client.py +22 -21
  12. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/neo4j_query_runner.py +9 -25
  13. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/progress/progress_provider.py +2 -0
  14. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/progress/query_progress_logger.py +62 -17
  15. graphdatascience-1.14/graphdatascience/query_runner/progress/query_progress_provider.py +53 -0
  16. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/progress/static_progress_provider.py +1 -1
  17. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/protocol/project_protocols.py +15 -1
  18. graphdatascience-1.14/graphdatascience/query_runner/protocol/retry_utils.py +19 -0
  19. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/protocol/write_protocols.py +35 -5
  20. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/session_query_runner.py +31 -12
  21. graphdatascience-1.14/graphdatascience/query_runner/termination_flag.py +69 -0
  22. graphdatascience-1.14/graphdatascience/semantic_version/semantic_version.py +44 -0
  23. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/aura_api.py +8 -2
  24. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/aura_api_responses.py +2 -2
  25. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/dedicated_sessions.py +22 -5
  26. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/gds_sessions.py +10 -3
  27. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/session_info.py +1 -1
  28. graphdatascience-1.14/graphdatascience/utils/__init__.py +0 -0
  29. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/version.py +1 -1
  30. {graphdatascience-1.13 → graphdatascience-1.14/graphdatascience.egg-info}/PKG-INFO +18 -5
  31. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience.egg-info/SOURCES.txt +4 -0
  32. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience.egg-info/requires.txt +3 -3
  33. {graphdatascience-1.13 → graphdatascience-1.14}/requirements/base/base.txt +3 -3
  34. {graphdatascience-1.13 → graphdatascience-1.14}/setup.py +1 -0
  35. graphdatascience-1.13/graphdatascience/call_parameters.py +0 -9
  36. graphdatascience-1.13/graphdatascience/query_runner/progress/query_progress_provider.py +0 -36
  37. {graphdatascience-1.13 → graphdatascience-1.14}/LICENSE +0 -0
  38. {graphdatascience-1.13 → graphdatascience-1.14}/MANIFEST.in +0 -0
  39. {graphdatascience-1.13 → graphdatascience-1.14}/README.md +0 -0
  40. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/__init__.py +0 -0
  41. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/algo/__init__.py +0 -0
  42. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/algo/algo_endpoints.py +0 -0
  43. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/algo/single_mode_algo_endpoints.py +0 -0
  44. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/call_builder.py +0 -0
  45. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/caller_base.py +0 -0
  46. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/endpoints.py +0 -0
  47. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/__init__.py +0 -0
  48. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/client_only_endpoint.py +0 -0
  49. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/cypher_warning_handler.py +0 -0
  50. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/endpoint_suggester.py +0 -0
  51. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/gds_not_installed.py +0 -0
  52. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/illegal_attr_checker.py +0 -0
  53. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/unable_to_connect.py +0 -0
  54. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/error/uncallable_namespace.py +0 -0
  55. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/__init__.py +0 -0
  56. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_alpha_proc_runner.py +0 -0
  57. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_beta_proc_runner.py +0 -0
  58. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_create_result.py +0 -0
  59. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_cypher_runner.py +0 -0
  60. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_endpoints.py +0 -0
  61. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_export_runner.py +0 -0
  62. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_object.py +0 -0
  63. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_proc_runner.py +0 -0
  64. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_project_runner.py +0 -0
  65. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_remote_proc_runner.py +0 -0
  66. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/graph_sample_runner.py +0 -0
  67. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph/nx_loader.py +0 -0
  68. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/graph_data_science.py +0 -0
  69. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/ignored_server_endpoints.py +0 -0
  70. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/__init__.py +0 -0
  71. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/graphsage_model.py +0 -0
  72. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/link_prediction_model.py +0 -0
  73. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model.py +0 -0
  74. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model_alpha_proc_runner.py +0 -0
  75. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model_beta_proc_runner.py +0 -0
  76. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model_endpoints.py +0 -0
  77. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model_proc_runner.py +0 -0
  78. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/model_resolver.py +0 -0
  79. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/node_classification_model.py +0 -0
  80. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/node_regression_model.py +0 -0
  81. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/pipeline_model.py +0 -0
  82. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/model/simple_rel_embedding_model.py +0 -0
  83. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/__init__.py +0 -0
  84. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/classification_training_pipeline.py +0 -0
  85. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/lp_pipeline_create_runner.py +0 -0
  86. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/lp_training_pipeline.py +0 -0
  87. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/nc_pipeline_create_runner.py +0 -0
  88. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/nc_training_pipeline.py +0 -0
  89. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/nr_pipeline_create_runner.py +0 -0
  90. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/nr_training_pipeline.py +0 -0
  91. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/pipeline_alpha_proc_runner.py +0 -0
  92. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/pipeline_beta_proc_runner.py +0 -0
  93. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/pipeline_endpoints.py +0 -0
  94. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/pipeline_proc_runner.py +0 -0
  95. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/pipeline/training_pipeline.py +0 -0
  96. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/py.typed +0 -0
  97. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/__init__.py +0 -0
  98. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/arrow_graph_constructor.py +0 -0
  99. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/arrow_info.py +0 -0
  100. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/arrow_query_runner.py +0 -0
  101. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/graph_constructor.py +0 -0
  102. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/progress/__init__.py +0 -0
  103. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/protocol/__init__.py +0 -0
  104. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/protocol/status.py +0 -0
  105. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/query_runner/query_runner.py +0 -0
  106. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/__init__.py +0 -0
  107. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/cora/__init__.py +0 -0
  108. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/cora/cora_nodes.parquet.gzip +0 -0
  109. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/cora/cora_rels.parquet.gzip +0 -0
  110. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/cora/serialize_cora.py +0 -0
  111. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/__init__.py +0 -0
  112. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_acted_in.parquet.gzip +0 -0
  113. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_actors.parquet.gzip +0 -0
  114. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_directed_in.parquet.gzip +0 -0
  115. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_directors.parquet.gzip +0 -0
  116. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_movies_with_genre.parquet.gzip +0 -0
  117. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/imdb_movies_without_genre.parquet.gzip +0 -0
  118. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/imdb/serialize_imdb.py +0 -0
  119. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/karate/__init__.py +0 -0
  120. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/karate/karate_club.parquet.gzip +0 -0
  121. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/__init__.py +0 -0
  122. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/artist_nodes.parquet.gzip +0 -0
  123. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/serialize_lastfm.py +0 -0
  124. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/user_friend_df_directed.parquet.gzip +0 -0
  125. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/user_listen_artist_rels.parquet.gzip +0 -0
  126. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/user_nodes.parquet.gzip +0 -0
  127. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/resources/lastfm/user_tag_artist_rels.parquet.gzip +0 -0
  128. {graphdatascience-1.13/graphdatascience/server_version → graphdatascience-1.14/graphdatascience/semantic_version}/__init__.py +0 -0
  129. {graphdatascience-1.13/graphdatascience/session/dbms → graphdatascience-1.14/graphdatascience/server_version}/__init__.py +0 -0
  130. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/server_version/compatible_with.py +0 -0
  131. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/server_version/server_version.py +0 -0
  132. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/__init__.py +0 -0
  133. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/algorithm_category.py +0 -0
  134. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/aura_graph_data_science.py +0 -0
  135. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/aurads_sessions.py +0 -0
  136. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/cloud_location.py +0 -0
  137. {graphdatascience-1.13/graphdatascience/system → graphdatascience-1.14/graphdatascience/session/dbms}/__init__.py +0 -0
  138. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/dbms/protocol_resolver.py +0 -0
  139. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/dbms/protocol_version.py +0 -0
  140. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/dbms_connection_info.py +0 -0
  141. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/region_suggester.py +0 -0
  142. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/session/session_sizes.py +0 -0
  143. {graphdatascience-1.13/graphdatascience/topological_lp → graphdatascience-1.14/graphdatascience/system}/__init__.py +0 -0
  144. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/system/config_endpoints.py +0 -0
  145. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/system/system_endpoints.py +0 -0
  146. {graphdatascience-1.13/graphdatascience/utils → graphdatascience-1.14/graphdatascience/topological_lp}/__init__.py +0 -0
  147. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/topological_lp/topological_lp_alpha_runner.py +0 -0
  148. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/topological_lp/topological_lp_endpoints.py +0 -0
  149. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/utils/direct_util_endpoints.py +0 -0
  150. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/utils/util_node_property_func_runner.py +0 -0
  151. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/utils/util_proc_runner.py +0 -0
  152. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience/utils/util_remote_proc_runner.py +0 -0
  153. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience.egg-info/dependency_links.txt +0 -0
  154. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience.egg-info/not-zip-safe +0 -0
  155. {graphdatascience-1.13 → graphdatascience-1.14}/graphdatascience.egg-info/top_level.txt +0 -0
  156. {graphdatascience-1.13 → graphdatascience-1.14}/pyproject.toml +0 -0
  157. {graphdatascience-1.13 → graphdatascience-1.14}/requirements/base/networkx.txt +0 -0
  158. {graphdatascience-1.13 → graphdatascience-1.14}/requirements/base/ogb.txt +0 -0
  159. {graphdatascience-1.13 → graphdatascience-1.14}/requirements/base/rust-ext.txt +0 -0
  160. {graphdatascience-1.13 → graphdatascience-1.14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: graphdatascience
3
- Version: 1.13
3
+ Version: 1.14
4
4
  Summary: A Python client for the Neo4j Graph Data Science (GDS) library
5
5
  Home-page: https://neo4j.com/product/graph-data-science/
6
6
  Author: Neo4j
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.9
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
23
24
  Classifier: Topic :: Database
24
25
  Classifier: Topic :: Scientific/Engineering
25
26
  Classifier: Topic :: Software Development
@@ -27,11 +28,11 @@ Classifier: Typing :: Typed
27
28
  Requires-Python: >=3.9
28
29
  Description-Content-Type: text/markdown
29
30
  License-File: LICENSE
30
- Requires-Dist: multimethod<2.0,>=1.0
31
+ Requires-Dist: multimethod<3.0,>=1.0
31
32
  Requires-Dist: neo4j<6.0,>=4.4.12
32
- Requires-Dist: numpy<2.0
33
+ Requires-Dist: numpy<2.3
33
34
  Requires-Dist: pandas<3.0,>=1.0
34
- Requires-Dist: pyarrow<19.0,>=15.0.2
35
+ Requires-Dist: pyarrow<20.0,>=16.0
35
36
  Requires-Dist: textdistance<5.0,>=4.0
36
37
  Requires-Dist: tqdm<5.0,>=4.0
37
38
  Requires-Dist: typing-extensions<5.0,>=4.0
@@ -43,6 +44,18 @@ Provides-Extra: networkx
43
44
  Requires-Dist: networkx<4.0,>=2.0; extra == "networkx"
44
45
  Provides-Extra: rust-ext
45
46
  Requires-Dist: neo4j-rust-ext<6.0,>=4.4.12; extra == "rust-ext"
47
+ Dynamic: author
48
+ Dynamic: author-email
49
+ Dynamic: classifier
50
+ Dynamic: description
51
+ Dynamic: description-content-type
52
+ Dynamic: home-page
53
+ Dynamic: license
54
+ Dynamic: project-url
55
+ Dynamic: provides-extra
56
+ Dynamic: requires-dist
57
+ Dynamic: requires-python
58
+ Dynamic: summary
46
59
 
47
60
  # Neo4j Graph Data Science Client
48
61
 
@@ -14,6 +14,7 @@ class AlgoProcRunner(IllegalAttrChecker, ABC):
14
14
  @graph_type_check
15
15
  def _run_procedure(self, G: Graph, config: dict[str, Any], with_logging: bool = True) -> DataFrame:
16
16
  params = CallParameters(graph_name=G.name(), config=config)
17
+ params.ensure_job_id_in_config()
17
18
 
18
19
  return self._query_runner.call_procedure(endpoint=self._namespace, params=params, logging=with_logging)
19
20
 
@@ -0,0 +1,40 @@
1
+ from collections import OrderedDict
2
+ from typing import Any, Optional
3
+ from uuid import uuid4
4
+
5
+
6
+ class CallParameters(OrderedDict[str, Any]):
7
+ # since Python 3.6 also initializing through CallParameters(**kwargs) is order preserving
8
+
9
+ def placeholder_str(self) -> str:
10
+ return ", ".join([f"${k}" for k in self.keys()])
11
+
12
+ def get_job_id(self) -> Optional[str]:
13
+ config = self["config"] if "config" in self else {}
14
+
15
+ job_id = None
16
+ if "jobId" in config:
17
+ job_id = config["jobId"]
18
+
19
+ if "job_id" in config:
20
+ job_id = config["job_id"]
21
+
22
+ if job_id is None:
23
+ return None
24
+
25
+ return str(job_id)
26
+
27
+ def ensure_job_id_in_config(self) -> str:
28
+ """
29
+ Ensure that a job id is present in the `config` parameter. If not, generate a new one.
30
+ This enables the client to check on the progress later on.
31
+ """
32
+ config = self.get("config")
33
+
34
+ assert config is not None, "config is not set in the parameters. This method should not be called."
35
+
36
+ job_id = self.get_job_id()
37
+ if job_id is None:
38
+ job_id = str(uuid4())
39
+ config["jobId"] = job_id
40
+ return job_id
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  import pathlib
3
5
  import warnings
@@ -31,7 +33,6 @@ from .graph_sample_runner import GraphSampleRunner
31
33
  from .graph_type_check import (
32
34
  from_graph_type_check,
33
35
  graph_type_check,
34
- graph_type_check_optional,
35
36
  )
36
37
  from .ogb_loader import OGBLLoader, OGBNLoader
37
38
 
@@ -237,6 +238,7 @@ class BaseGraphProcRunner(UncallableNamespace, IllegalAttrChecker):
237
238
  params = CallParameters(
238
239
  graph_name=graph_name, node_count=node_count, average_degree=average_degree, config=config
239
240
  )
241
+ params.ensure_job_id_in_config()
240
242
 
241
243
  result = self._query_runner.call_procedure(
242
244
  endpoint=self._namespace,
@@ -263,6 +265,8 @@ class BaseGraphProcRunner(UncallableNamespace, IllegalAttrChecker):
263
265
  relationship_filter=relationship_filter,
264
266
  config=config,
265
267
  )
268
+ params.ensure_job_id_in_config()
269
+
266
270
  result = self._query_runner.call_procedure(
267
271
  endpoint=self._namespace,
268
272
  logging=True,
@@ -292,7 +296,7 @@ class BaseGraphProcRunner(UncallableNamespace, IllegalAttrChecker):
292
296
  failIfMissing: bool = False,
293
297
  dbName: str = "",
294
298
  username: Optional[str] = None,
295
- ) -> Optional["Series[Any]"]:
299
+ ) -> Optional[Series[Any]]:
296
300
  self._namespace += ".drop"
297
301
 
298
302
  if isinstance(graph, Graph):
@@ -315,7 +319,7 @@ class BaseGraphProcRunner(UncallableNamespace, IllegalAttrChecker):
315
319
 
316
320
  return None
317
321
 
318
- def exists(self, graph_name: str) -> "Series[Any]":
322
+ def exists(self, graph_name: str) -> Series[Any]:
319
323
  self._namespace += ".exists"
320
324
  result = self._query_runner.call_procedure(
321
325
  endpoint=self._namespace,
@@ -324,13 +328,17 @@ class BaseGraphProcRunner(UncallableNamespace, IllegalAttrChecker):
324
328
 
325
329
  return result.squeeze() # type: ignore
326
330
 
327
- @graph_type_check_optional
328
- def list(self, G: Optional[Graph] = None) -> DataFrame:
331
+ def list(self, G: Optional[Union[Graph, str]] = None) -> DataFrame:
329
332
  self._namespace += ".list"
330
333
 
334
+ if isinstance(G, Graph):
335
+ graph_name = G.name()
336
+ elif isinstance(G, str):
337
+ graph_name = G
338
+
331
339
  params = CallParameters()
332
340
  if G:
333
- params["graph_name"] = G.name()
341
+ params["graph_name"] = graph_name
334
342
 
335
343
  return self._query_runner.call_procedure(
336
344
  endpoint=self._namespace,
@@ -101,7 +101,7 @@ class GraphNodePropertiesRunner(GraphEntityOpsBaseRunner):
101
101
  def stream(
102
102
  self,
103
103
  G: Graph,
104
- node_properties: list[str],
104
+ node_properties: Union[str, list[str]],
105
105
  node_labels: Strings = ["*"],
106
106
  separate_property_columns: bool = False,
107
107
  db_node_properties: list[str] = [],
@@ -109,6 +109,9 @@ class GraphNodePropertiesRunner(GraphEntityOpsBaseRunner):
109
109
  ) -> DataFrame:
110
110
  self._namespace += ".stream"
111
111
 
112
+ if isinstance(node_properties, str):
113
+ node_properties = [node_properties]
114
+
112
115
  # find if list contain duplicates
113
116
  if len(set(node_properties)) != len(node_properties):
114
117
  raise ValueError(f"The provided node_properties contain duplicate property names: `{node_properties}`.")
@@ -22,6 +22,7 @@ class GraphProjectRemoteRunner(IllegalAttrChecker):
22
22
  undirected_relationship_types: Optional[list[str]] = None,
23
23
  inverse_indexed_relationship_types: Optional[list[str]] = None,
24
24
  batch_size: Optional[int] = None,
25
+ logging: bool = True,
25
26
  ) -> GraphCreateResult:
26
27
  if inverse_indexed_relationship_types is None:
27
28
  inverse_indexed_relationship_types = []
@@ -45,5 +46,6 @@ class GraphProjectRemoteRunner(IllegalAttrChecker):
45
46
  result = self._query_runner.call_procedure(
46
47
  endpoint=SessionQueryRunner.GDS_REMOTE_PROJECTION_PROC_NAME,
47
48
  params=params,
49
+ logging=True,
48
50
  ).squeeze()
49
51
  return GraphCreateResult(Graph(graph_name, self._query_runner), result)
@@ -1,5 +1,5 @@
1
1
  from functools import wraps
2
- from typing import Any, Callable, Optional, TypeVar, cast
2
+ from typing import Any, Callable, TypeVar, cast
3
3
 
4
4
  from .graph_object import Graph
5
5
 
@@ -20,20 +20,6 @@ def graph_type_check(func: F) -> F:
20
20
  return cast(F, wrapper)
21
21
 
22
22
 
23
- def graph_type_check_optional(func: F) -> F:
24
- @wraps(func)
25
- def wrapper(self: Any, G: Optional[Graph] = None, *args: Any, **kwargs: Any) -> Any:
26
- if isinstance(G, str):
27
- raise TypeError(
28
- f"The parameter 'G' takes a `Graph` object, but received string '{G}'. "
29
- "To resolve a graph name string into a `Graph` object, please use `gds.graph.get`"
30
- )
31
-
32
- return func(self, G, *args, **kwargs)
33
-
34
- return cast(F, wrapper)
35
-
36
-
37
23
  def from_graph_type_check(func: F) -> F:
38
24
  @wraps(func)
39
25
  def wrapper(self: Any, graph_name: str, from_G: Graph, *args: Any, **kwargs: Any) -> Any:
@@ -108,12 +108,12 @@ class OGBNLoader(OGBLoader):
108
108
  "nodeId": list(range(node_count)),
109
109
  }
110
110
  if "node_feat" in graph and graph["node_feat"] is not None:
111
- node_dict["features"] = graph["node_feat"].tolist()
111
+ node_dict["features"] = graph["node_feat"].tolist() # type: ignore
112
112
 
113
113
  if len(dataset.labels[0]) == 1:
114
114
  node_dict["classLabel"] = [cl[0] for cl in dataset.labels]
115
115
  else:
116
- node_dict["classLabel"] = dataset.labels.tolist()
116
+ node_dict["classLabel"] = dataset.labels.tolist() # type: ignore
117
117
 
118
118
  split = dataset.get_idx_split()
119
119
  node_labels = ["Train" for _ in range(node_count)]
@@ -170,13 +170,13 @@ class OGBNLoader(OGBLoader):
170
170
  }
171
171
 
172
172
  if node_label in node_features:
173
- node_dict["features"] = node_features[node_label].tolist()
173
+ node_dict["features"] = node_features[node_label].tolist() # type: ignore
174
174
 
175
175
  if node_label in class_labels:
176
176
  if len(class_labels[node_label]) == 1:
177
177
  node_dict["classLabel"] = [cl[0] for cl in class_labels[node_label]]
178
178
  else:
179
- node_dict["classLabel"] = class_labels[node_label].tolist()
179
+ node_dict["classLabel"] = class_labels[node_label].tolist() # type: ignore
180
180
 
181
181
  node_id_offsets[node_label] = current_offset
182
182
  current_offset += node_count
@@ -243,7 +243,7 @@ class OGBLLoader(OGBLoader):
243
243
  "labels": "N",
244
244
  }
245
245
  if "node_feat" in graph and graph["node_feat"] is not None:
246
- node_dict["features"] = graph["node_feat"].tolist()
246
+ node_dict["features"] = graph["node_feat"].tolist() # type: ignore
247
247
  nodes = pd.DataFrame(node_dict)
248
248
 
249
249
  self._logger.info("Preparing relationship data for transfer to server...")
@@ -283,7 +283,7 @@ class OGBLLoader(OGBLoader):
283
283
  }
284
284
 
285
285
  if node_label in node_features:
286
- node_dict["features"] = node_features[node_label].tolist()
286
+ node_dict["features"] = node_features[node_label].tolist() # type: ignore
287
287
 
288
288
  node_id_offsets[node_label] = current_offset
289
289
  current_offset += node_count
@@ -4,8 +4,8 @@ from enum import Enum
4
4
 
5
5
 
6
6
  class ArrowEndpointVersion(Enum):
7
- ALPHA = ""
8
7
  V1 = "v1/"
8
+ V2 = "v2/"
9
9
 
10
10
  def version(self) -> str:
11
11
  return self._name_.lower()
@@ -15,17 +15,10 @@ class ArrowEndpointVersion(Enum):
15
15
 
16
16
  @staticmethod
17
17
  def from_arrow_info(supported_arrow_versions: list[str]) -> ArrowEndpointVersion:
18
- # Fallback for pre 2.6.0 servers that do not support versions
19
- if len(supported_arrow_versions) == 0:
20
- return ArrowEndpointVersion.ALPHA
21
-
22
18
  # If the server supports versioned endpoints, we try v1 first
23
19
  if ArrowEndpointVersion.V1.version() in supported_arrow_versions:
24
20
  return ArrowEndpointVersion.V1
25
21
 
26
- if ArrowEndpointVersion.ALPHA.version() in supported_arrow_versions:
27
- return ArrowEndpointVersion.ALPHA
28
-
29
22
  raise UnsupportedArrowEndpointVersion(supported_arrow_versions)
30
23
 
31
24
 
@@ -386,7 +386,8 @@ class CypherGraphConstructor(GraphConstructor):
386
386
  )
387
387
 
388
388
  def _node_query(self, node_df: DataFrame) -> tuple[str, list[list[Any]]]:
389
- node_list = node_df.values.tolist()
389
+ # ignore type as tolist return depends on number of dimensions)
390
+ node_list: list[list[Any]] = node_df.values.tolist() # type: ignore
390
391
  node_columns = list(node_df.columns)
391
392
  node_id_index = node_columns.index("nodeId")
392
393
 
@@ -411,7 +412,7 @@ class CypherGraphConstructor(GraphConstructor):
411
412
  return f"UNWIND $nodes as node RETURN node[{node_id_index}] as id{label_query}{property_query}", node_list
412
413
 
413
414
  def _relationship_query(self, rel_df: DataFrame) -> tuple[str, list[list[Any]]]:
414
- rel_list = rel_df.values.tolist()
415
+ rel_list: list[list[Any]] = rel_df.values.tolist() # type: ignore
415
416
  rel_columns = list(rel_df.columns)
416
417
  source_id_index = rel_columns.index("sourceNodeId")
417
418
  target_id_index = rel_columns.index("targetNodeId")
@@ -9,15 +9,16 @@ from dataclasses import dataclass
9
9
  from types import TracebackType
10
10
  from typing import Any, Callable, Dict, Iterable, Optional, Type, Union
11
11
 
12
+ import pandas
12
13
  import pyarrow
13
14
  from neo4j.exceptions import ClientError
14
- from pandas import DataFrame
15
15
  from pyarrow import Array, ChunkedArray, DictionaryArray, RecordBatch, Table, chunked_array, flight
16
16
  from pyarrow import __version__ as arrow_version
17
17
  from pyarrow.flight import ClientMiddleware, ClientMiddlewareFactory
18
18
  from pyarrow.types import is_dictionary
19
19
  from tenacity import retry, retry_if_exception_type, stop_after_attempt, stop_after_delay, wait_exponential
20
20
 
21
+ from ..semantic_version.semantic_version import SemanticVersion
21
22
  from ..version import __version__
22
23
  from .arrow_endpoint_version import ArrowEndpointVersion
23
24
  from .arrow_info import ArrowInfo
@@ -154,7 +155,7 @@ class GdsArrowClient:
154
155
  node_labels: Optional[list[str]] = None,
155
156
  list_node_labels: bool = False,
156
157
  concurrency: Optional[int] = None,
157
- ) -> DataFrame:
158
+ ) -> pandas.DataFrame:
158
159
  """
159
160
  Get node properties from the graph.
160
161
 
@@ -194,7 +195,7 @@ class GdsArrowClient:
194
195
 
195
196
  return self._do_get(database, graph_name, proc, concurrency, config)
196
197
 
197
- def get_node_labels(self, graph_name: str, database: str, concurrency: Optional[int] = None) -> DataFrame:
198
+ def get_node_labels(self, graph_name: str, database: str, concurrency: Optional[int] = None) -> pandas.DataFrame:
198
199
  """
199
200
  Get all nodes and their labels from the graph.
200
201
 
@@ -216,7 +217,7 @@ class GdsArrowClient:
216
217
 
217
218
  def get_relationships(
218
219
  self, graph_name: str, database: str, relationship_types: list[str], concurrency: Optional[int] = None
219
- ) -> DataFrame:
220
+ ) -> pandas.DataFrame:
220
221
  """
221
222
  Get relationships from the graph.
222
223
 
@@ -251,7 +252,7 @@ class GdsArrowClient:
251
252
  relationship_properties: Union[str, list[str]],
252
253
  relationship_types: list[str],
253
254
  concurrency: Optional[int] = None,
254
- ) -> DataFrame:
255
+ ) -> pandas.DataFrame:
255
256
  """
256
257
  Get relationships and their properties from the graph.
257
258
 
@@ -488,7 +489,7 @@ class GdsArrowClient:
488
489
  def upload_nodes(
489
490
  self,
490
491
  graph_name: str,
491
- node_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], DataFrame],
492
+ node_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], pandas.DataFrame],
492
493
  batch_size: int = 10_000,
493
494
  progress_callback: Callable[[int], None] = lambda x: None,
494
495
  ) -> None:
@@ -511,7 +512,7 @@ class GdsArrowClient:
511
512
  def upload_relationships(
512
513
  self,
513
514
  graph_name: str,
514
- relationship_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], DataFrame],
515
+ relationship_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], pandas.DataFrame],
515
516
  batch_size: int = 10_000,
516
517
  progress_callback: Callable[[int], None] = lambda x: None,
517
518
  ) -> None:
@@ -534,7 +535,7 @@ class GdsArrowClient:
534
535
  def upload_triplets(
535
536
  self,
536
537
  graph_name: str,
537
- triplet_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], DataFrame],
538
+ triplet_data: Union[pyarrow.Table, Iterable[pyarrow.RecordBatch], pandas.DataFrame],
538
539
  batch_size: int = 10_000,
539
540
  progress_callback: Callable[[int], None] = lambda x: None,
540
541
  ) -> None:
@@ -590,13 +591,13 @@ class GdsArrowClient:
590
591
  self,
591
592
  graph_name: str,
592
593
  entity_type: str,
593
- data: Union[pyarrow.Table, list[pyarrow.RecordBatch], DataFrame],
594
+ data: Union[pyarrow.Table, list[pyarrow.RecordBatch], pandas.DataFrame],
594
595
  batch_size: int,
595
596
  progress_callback: Callable[[int], None],
596
597
  ) -> None:
597
598
  if isinstance(data, pyarrow.Table):
598
599
  batches = data.to_batches(batch_size)
599
- elif isinstance(data, DataFrame):
600
+ elif isinstance(data, pandas.DataFrame):
600
601
  batches = pyarrow.Table.from_pandas(data).to_batches(batch_size)
601
602
  else:
602
603
  batches = data
@@ -635,7 +636,7 @@ class GdsArrowClient:
635
636
  procedure_name: str,
636
637
  concurrency: Optional[int],
637
638
  configuration: dict[str, Any],
638
- ) -> DataFrame:
639
+ ) -> pandas.DataFrame:
639
640
  payload: dict[str, Any] = {
640
641
  "database_name": database,
641
642
  "graph_name": graph_name,
@@ -674,7 +675,11 @@ class GdsArrowClient:
674
675
  message=r"Passing a BlockManager to DataFrame is deprecated",
675
676
  )
676
677
 
677
- return self._sanitize_arrow_table(arrow_table).to_pandas() # type: ignore
678
+ if SemanticVersion.from_string(pandas.__version__) >= SemanticVersion(2, 0, 0):
679
+ return arrow_table.to_pandas(types_mapper=pandas.ArrowDtype) # type: ignore
680
+ else:
681
+ arrow_table = self._sanitize_arrow_table(arrow_table)
682
+ return arrow_table.to_pandas() # type: ignore
678
683
 
679
684
  def __enter__(self) -> GdsArrowClient:
680
685
  return self
@@ -695,15 +700,11 @@ class GdsArrowClient:
695
700
  return self._arrow_endpoint_version.prefix() + action_type
696
701
 
697
702
  def _versioned_flight_descriptor(self, flight_descriptor: dict[str, Any]) -> dict[str, Any]:
698
- return (
699
- flight_descriptor
700
- if self._arrow_endpoint_version == ArrowEndpointVersion.ALPHA
701
- else {
702
- "name": "PUT_MESSAGE",
703
- "version": ArrowEndpointVersion.V1.version(),
704
- "body": flight_descriptor,
705
- }
706
- )
703
+ return {
704
+ "name": "PUT_COMMAND",
705
+ "version": ArrowEndpointVersion.V1.version(),
706
+ "body": flight_descriptor,
707
+ }
707
708
 
708
709
  @staticmethod
709
710
  def _sanitize_arrow_table(arrow_table: Table) -> Table:
@@ -5,7 +5,6 @@ import re
5
5
  import time
6
6
  import warnings
7
7
  from typing import Any, NamedTuple, Optional, Union
8
- from uuid import uuid4
9
8
 
10
9
  import neo4j
11
10
  from pandas import DataFrame
@@ -14,6 +13,7 @@ from ..call_parameters import CallParameters
14
13
  from ..error.endpoint_suggester import generate_suggestive_error_message
15
14
  from ..error.gds_not_installed import GdsNotFound
16
15
  from ..error.unable_to_connect import UnableToConnectError
16
+ from ..semantic_version.semantic_version import SemanticVersion
17
17
  from ..server_version.server_version import ServerVersion
18
18
  from ..version import __version__
19
19
  from .cypher_graph_constructor import CypherGraphConstructor
@@ -25,7 +25,7 @@ from .query_runner import QueryRunner
25
25
  class Neo4jQueryRunner(QueryRunner):
26
26
  _AURA_DS_PROTOCOL = "neo4j+s"
27
27
  _LOG_POLLING_INTERVAL = 0.5
28
- _NEO4J_DRIVER_VERSION = ServerVersion.from_string(neo4j.__version__)
28
+ _NEO4J_DRIVER_VERSION = SemanticVersion.from_string(neo4j.__version__)
29
29
 
30
30
  @staticmethod
31
31
  def create_for_db(
@@ -61,7 +61,7 @@ class Neo4jQueryRunner(QueryRunner):
61
61
  else:
62
62
  raise ValueError(f"Invalid endpoint type: {type(endpoint)}")
63
63
 
64
- if Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= ServerVersion(5, 21, 0):
64
+ if Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= SemanticVersion(5, 21, 0):
65
65
  notifications_logger = logging.getLogger("neo4j.notifications")
66
66
  # the client does not expose YIELD fields so we just skip these warnings for now
67
67
  notifications_logger.addFilter(
@@ -94,7 +94,7 @@ class Neo4jQueryRunner(QueryRunner):
94
94
  instance_description="GDS Session",
95
95
  )
96
96
 
97
- if Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= ServerVersion(5, 21, 0):
97
+ if Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= SemanticVersion(5, 21, 0):
98
98
  notifications_logger = logging.getLogger("neo4j.notifications")
99
99
  # the client does not expose YIELD fields so we just skip these warnings for now
100
100
  notifications_logger.addFilter(
@@ -176,13 +176,13 @@ class Neo4jQueryRunner(QueryRunner):
176
176
 
177
177
  df = result.to_df()
178
178
 
179
- if self._NEO4J_DRIVER_VERSION < ServerVersion(5, 0, 0):
179
+ if self._NEO4J_DRIVER_VERSION < SemanticVersion(5, 0, 0):
180
180
  self._last_bookmarks = [session.last_bookmark()]
181
181
  else:
182
182
  self._last_bookmarks = session.last_bookmarks()
183
183
 
184
184
  if (
185
- Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= ServerVersion(5, 21, 0)
185
+ Neo4jQueryRunner._NEO4J_DRIVER_VERSION >= SemanticVersion(5, 21, 0)
186
186
  and result._warn_notification_severity == "WARNING"
187
187
  ):
188
188
  # the client does not expose YIELD fields so we just skip these warnings for now
@@ -222,8 +222,8 @@ class Neo4jQueryRunner(QueryRunner):
222
222
  def run_cypher_query() -> DataFrame:
223
223
  return self.run_cypher(query, params, database, custom_error)
224
224
 
225
- if self._resolve_show_progress(logging):
226
- job_id = self._extract_or_create_job_id(params)
225
+ job_id = None if not params else params.get_job_id()
226
+ if self._resolve_show_progress(logging) and job_id:
227
227
  return self._progress_logger.run_with_progress_logging(run_cypher_query, job_id, database)
228
228
  else:
229
229
  return run_cypher_query()
@@ -310,22 +310,6 @@ class Neo4jQueryRunner(QueryRunner):
310
310
  def set_show_progress(self, show_progress: bool) -> None:
311
311
  self._show_progress = show_progress
312
312
 
313
- @staticmethod
314
- def _extract_or_create_job_id(params: CallParameters) -> str:
315
- config = params["config"] if "config" in params else {}
316
-
317
- job_id = None
318
- if "jobId" in config:
319
- job_id = config["jobId"]
320
-
321
- if "job_id" in config:
322
- job_id = config["job_id"]
323
-
324
- if not job_id:
325
- return str(uuid4())
326
-
327
- return str(job_id)
328
-
329
313
  @staticmethod
330
314
  def handle_driver_exception(session: neo4j.Session, e: Exception) -> None:
331
315
  reg_gds_hit = re.search(
@@ -359,7 +343,7 @@ class Neo4jQueryRunner(QueryRunner):
359
343
  retrys = 0
360
344
  while retrys < retry_config.max_retries:
361
345
  try:
362
- if self._NEO4J_DRIVER_VERSION < ServerVersion(5, 0, 0):
346
+ if self._NEO4J_DRIVER_VERSION < SemanticVersion(5, 0, 0):
363
347
  warnings.filterwarnings(
364
348
  "ignore",
365
349
  category=neo4j.ExperimentalWarning,
@@ -7,6 +7,8 @@ from typing import Optional
7
7
  class TaskWithProgress:
8
8
  task_name: str
9
9
  progress_percent: str
10
+ status: str
11
+ sub_tasks_description: Optional[str] = None
10
12
 
11
13
 
12
14
  class ProgressProvider(ABC):