graphdatascience 1.11a3__tar.gz → 1.11a4__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 (141) hide show
  1. {graphdatascience-1.11a3/graphdatascience.egg-info → graphdatascience-1.11a4}/PKG-INFO +2 -4
  2. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/README.md +0 -2
  3. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/call_builder.py +1 -1
  4. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/endpoints.py +17 -2
  5. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_cypher_runner.py +10 -3
  6. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph_data_science.py +6 -1
  7. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/link_prediction_model.py +1 -1
  8. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model.py +62 -60
  9. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model_proc_runner.py +23 -15
  10. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/node_classification_model.py +2 -2
  11. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/node_regression_model.py +1 -1
  12. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/pipeline_model.py +3 -3
  13. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/arrow_query_runner.py +3 -0
  14. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/aura_db_query_runner.py +3 -0
  15. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/neo4j_query_runner.py +7 -0
  16. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/query_runner.py +4 -0
  17. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/aura_api.py +107 -89
  18. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/aura_api_responses.py +5 -1
  19. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/aura_graph_data_science.py +13 -4
  20. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/dedicated_sessions.py +15 -10
  21. graphdatascience-1.11a3/graphdatascience/utils/util_endpoints.py → graphdatascience-1.11a4/graphdatascience/utils/direct_util_endpoints.py +0 -5
  22. graphdatascience-1.11a4/graphdatascience/utils/util_node_property_func_runner.py +31 -0
  23. graphdatascience-1.11a4/graphdatascience/utils/util_proc_runner.py +43 -0
  24. graphdatascience-1.11a4/graphdatascience/utils/util_remote_proc_runner.py +48 -0
  25. graphdatascience-1.11a4/graphdatascience/version.py +1 -0
  26. {graphdatascience-1.11a3 → graphdatascience-1.11a4/graphdatascience.egg-info}/PKG-INFO +2 -4
  27. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience.egg-info/SOURCES.txt +3 -1
  28. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience.egg-info/requires.txt +1 -1
  29. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/requirements/base/base.txt +1 -1
  30. graphdatascience-1.11a3/graphdatascience/utils/util_proc_runner.py +0 -68
  31. graphdatascience-1.11a3/graphdatascience/version.py +0 -1
  32. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/LICENSE +0 -0
  33. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/MANIFEST.in +0 -0
  34. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/__init__.py +0 -0
  35. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/algo/__init__.py +0 -0
  36. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/algo/algo_endpoints.py +0 -0
  37. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/algo/algo_proc_runner.py +0 -0
  38. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/algo/single_mode_algo_endpoints.py +0 -0
  39. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/call_parameters.py +0 -0
  40. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/caller_base.py +0 -0
  41. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/__init__.py +0 -0
  42. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/client_only_endpoint.py +0 -0
  43. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/cypher_warning_handler.py +0 -0
  44. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/endpoint_suggester.py +0 -0
  45. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/gds_not_installed.py +0 -0
  46. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/illegal_attr_checker.py +0 -0
  47. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/unable_to_connect.py +0 -0
  48. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/error/uncallable_namespace.py +0 -0
  49. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/__init__.py +0 -0
  50. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/base_graph_proc_runner.py +0 -0
  51. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_alpha_proc_runner.py +0 -0
  52. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_beta_proc_runner.py +0 -0
  53. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_create_result.py +0 -0
  54. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_endpoints.py +0 -0
  55. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_entity_ops_runner.py +0 -0
  56. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_export_runner.py +0 -0
  57. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_object.py +0 -0
  58. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_proc_runner.py +0 -0
  59. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_project_runner.py +0 -0
  60. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_remote_proc_runner.py +0 -0
  61. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_remote_project_runner.py +0 -0
  62. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_sample_runner.py +0 -0
  63. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/graph_type_check.py +0 -0
  64. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/nx_loader.py +0 -0
  65. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/graph/ogb_loader.py +0 -0
  66. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/ignored_server_endpoints.py +0 -0
  67. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/__init__.py +0 -0
  68. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/graphsage_model.py +0 -0
  69. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model_alpha_proc_runner.py +0 -0
  70. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model_beta_proc_runner.py +0 -0
  71. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model_endpoints.py +0 -0
  72. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/model_resolver.py +0 -0
  73. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/model/simple_rel_embedding_model.py +0 -0
  74. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/__init__.py +0 -0
  75. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/classification_training_pipeline.py +0 -0
  76. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/lp_pipeline_create_runner.py +0 -0
  77. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/lp_training_pipeline.py +0 -0
  78. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/nc_pipeline_create_runner.py +0 -0
  79. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/nc_training_pipeline.py +0 -0
  80. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/nr_pipeline_create_runner.py +0 -0
  81. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/nr_training_pipeline.py +0 -0
  82. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/pipeline_alpha_proc_runner.py +0 -0
  83. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/pipeline_beta_proc_runner.py +0 -0
  84. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/pipeline_endpoints.py +0 -0
  85. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/pipeline_proc_runner.py +0 -0
  86. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/pipeline/training_pipeline.py +0 -0
  87. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/py.typed +0 -0
  88. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/__init__.py +0 -0
  89. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/arrow_endpoint_version.py +0 -0
  90. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/arrow_graph_constructor.py +0 -0
  91. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/cypher_graph_constructor.py +0 -0
  92. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/gds_arrow_client.py +0 -0
  93. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/query_runner/graph_constructor.py +0 -0
  94. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/__init__.py +0 -0
  95. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/cora/__init__.py +0 -0
  96. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/cora/cora_nodes.parquet.gzip +0 -0
  97. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/cora/cora_rels.parquet.gzip +0 -0
  98. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/cora/serialize_cora.py +0 -0
  99. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/__init__.py +0 -0
  100. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_acted_in.parquet.gzip +0 -0
  101. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_actors.parquet.gzip +0 -0
  102. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_directed_in.parquet.gzip +0 -0
  103. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_directors.parquet.gzip +0 -0
  104. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_movies_with_genre.parquet.gzip +0 -0
  105. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/imdb_movies_without_genre.parquet.gzip +0 -0
  106. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/imdb/serialize_imdb.py +0 -0
  107. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/karate/__init__.py +0 -0
  108. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/karate/karate_club.parquet.gzip +0 -0
  109. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/__init__.py +0 -0
  110. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/artist_nodes.parquet.gzip +0 -0
  111. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/serialize_lastfm.py +0 -0
  112. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/user_friend_df_directed.parquet.gzip +0 -0
  113. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/user_listen_artist_rels.parquet.gzip +0 -0
  114. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/user_nodes.parquet.gzip +0 -0
  115. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/resources/lastfm/user_tag_artist_rels.parquet.gzip +0 -0
  116. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/server_version/__init__.py +0 -0
  117. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/server_version/compatible_with.py +0 -0
  118. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/server_version/server_version.py +0 -0
  119. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/__init__.py +0 -0
  120. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/algorithm_category.py +0 -0
  121. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/aurads_sessions.py +0 -0
  122. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/dbms_connection_info.py +0 -0
  123. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/gds_sessions.py +0 -0
  124. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/region_suggester.py +0 -0
  125. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/session_info.py +0 -0
  126. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/session/session_sizes.py +0 -0
  127. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/system/__init__.py +0 -0
  128. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/system/config_endpoints.py +0 -0
  129. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/system/system_endpoints.py +0 -0
  130. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/topological_lp/__init__.py +0 -0
  131. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/topological_lp/topological_lp_alpha_runner.py +0 -0
  132. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/topological_lp/topological_lp_endpoints.py +0 -0
  133. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience/utils/__init__.py +0 -0
  134. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience.egg-info/dependency_links.txt +0 -0
  135. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience.egg-info/not-zip-safe +0 -0
  136. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/graphdatascience.egg-info/top_level.txt +0 -0
  137. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/pyproject.toml +0 -0
  138. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/requirements/base/networkx.txt +0 -0
  139. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/requirements/base/ogb.txt +0 -0
  140. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/setup.cfg +0 -0
  141. {graphdatascience-1.11a3 → graphdatascience-1.11a4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: graphdatascience
3
- Version: 1.11a3
3
+ Version: 1.11a4
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
@@ -29,7 +29,7 @@ Requires-Python: >=3.8
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
31
  Requires-Dist: multimethod<2.0,>=1.0
32
- Requires-Dist: neo4j<6.0,>=4.4.2
32
+ Requires-Dist: neo4j<6.0,>=4.4.12
33
33
  Requires-Dist: numpy<2.0
34
34
  Requires-Dist: pandas<3.0,>=1.0
35
35
  Requires-Dist: pyarrow<17.0,>=14.0.1
@@ -142,8 +142,6 @@ The manual is versioned to cover all GDS Python Client versions, so make sure to
142
142
  Operations known to not yet work with `graphdatascience`:
143
143
 
144
144
  * [Numeric utility functions](https://neo4j.com/docs/graph-data-science/current/management-ops/utility-functions/#utility-functions-numeric) (will never be supported)
145
- * [Cypher on GDS](https://neo4j.com/docs/graph-data-science/current/management-ops/create-cypher-db/) (might be supported in the future)
146
- * [Projecting graphs using Cypher Aggregation](https://neo4j.com/docs/graph-data-science/current/management-ops/projections/graph-project-cypher-aggregation/) (might be supported in the future)
147
145
 
148
146
 
149
147
  ## License
@@ -98,8 +98,6 @@ The manual is versioned to cover all GDS Python Client versions, so make sure to
98
98
  Operations known to not yet work with `graphdatascience`:
99
99
 
100
100
  * [Numeric utility functions](https://neo4j.com/docs/graph-data-science/current/management-ops/utility-functions/#utility-functions-numeric) (will never be supported)
101
- * [Cypher on GDS](https://neo4j.com/docs/graph-data-science/current/management-ops/create-cypher-db/) (might be supported in the future)
102
- * [Projecting graphs using Cypher Aggregation](https://neo4j.com/docs/graph-data-science/current/management-ops/projections/graph-project-cypher-aggregation/) (might be supported in the future)
103
101
 
104
102
 
105
103
  ## License
@@ -1,6 +1,6 @@
1
1
  from .algo.algo_endpoints import AlgoEndpoints
2
2
  from .error.uncallable_namespace import UncallableNamespace
3
- from .utils.util_endpoints import IndirectUtilAlphaEndpoints
3
+ from .utils.direct_util_endpoints import IndirectUtilAlphaEndpoints
4
4
 
5
5
 
6
6
  class IndirectCallBuilder(AlgoEndpoints, UncallableNamespace):
@@ -23,7 +23,7 @@ from .system.system_endpoints import (
23
23
  SystemBetaEndpoints,
24
24
  )
25
25
  from .topological_lp.topological_lp_endpoints import TopologicalLPAlphaEndpoints
26
- from .utils.util_endpoints import DirectUtilEndpoints
26
+ from .utils.direct_util_endpoints import DirectUtilEndpoints
27
27
 
28
28
  """
29
29
  This class should inherit endpoint classes that only contain endpoints that can be called directly from
@@ -44,7 +44,7 @@ class DirectEndpoints(
44
44
 
45
45
 
46
46
  """
47
- This class should inherit endpoint classes that only expose calls of the `gds.beta` namespace.
47
+ This class should inherit endpoint classes that only expose calls of the `gds.alpha` namespace.
48
48
  Example of such endpoints: "gds.alpha.listProgress".
49
49
  """
50
50
 
@@ -65,6 +65,21 @@ class AlphaEndpoints(
65
65
  return IndirectAlphaCallBuilder(self._query_runner, f"{self._namespace}.{attr}", self._server_version)
66
66
 
67
67
 
68
+ class AlphaRemoteEndpoints(
69
+ GraphAlphaEndpoints,
70
+ PipelineAlphaEndpoints,
71
+ ModelAlphaEndpoints,
72
+ SingleModeAlphaAlgoEndpoints,
73
+ SystemAlphaEndpoints,
74
+ AlphaConfigEndpoints,
75
+ ):
76
+ def __init__(self, query_runner: QueryRunner, namespace: str, server_version: ServerVersion):
77
+ super().__init__(query_runner, namespace, server_version)
78
+
79
+ def __getattr__(self, attr: str) -> IndirectAlphaCallBuilder:
80
+ return IndirectAlphaCallBuilder(self._query_runner, f"{self._namespace}.{attr}", self._server_version)
81
+
82
+
68
83
  """
69
84
  This class should inherit endpoint classes that only expose calls of the `gds.beta` namespace.
70
85
  Example of such endpoints: "gds.beta.listProgress".
@@ -1,6 +1,10 @@
1
+ from __future__ import annotations
2
+
1
3
  import re
2
4
  from itertools import chain, zip_longest
3
- from typing import Any, Optional
5
+ from typing import Any, Dict, Optional
6
+
7
+ from pandas import Series
4
8
 
5
9
  from ..caller_base import CallerBase
6
10
  from ..query_runner.query_runner import QueryRunner
@@ -41,7 +45,10 @@ class GraphCypherRunner(CallerBase):
41
45
 
42
46
  GraphCypherRunner._verify_query_ends_with_return_clause(self._namespace, query)
43
47
 
44
- result = self._query_runner.run_cypher(query, params, database, False).squeeze()
48
+ result: Optional[Dict[str, Any]] = self._query_runner.run_cypher(query, params, database, False).squeeze()
49
+
50
+ if not result:
51
+ raise ValueError("Projected graph cannot be empty.")
45
52
 
46
53
  try:
47
54
  graph_name = str(result["graphName"])
@@ -50,7 +57,7 @@ class GraphCypherRunner(CallerBase):
50
57
  f"Invalid query, the query must end with the `RETURN {self._namespace}(...)` call: {query}"
51
58
  )
52
59
 
53
- return GraphCreateResult(Graph(graph_name, self._query_runner, self._server_version), result)
60
+ return GraphCreateResult(Graph(graph_name, self._query_runner, self._server_version), Series(data=result))
54
61
 
55
62
  __separators = re.compile(r"[,(.]")
56
63
 
@@ -13,6 +13,7 @@ from .query_runner.neo4j_query_runner import Neo4jQueryRunner
13
13
  from .query_runner.query_runner import QueryRunner
14
14
  from .server_version.server_version import ServerVersion
15
15
  from graphdatascience.graph.graph_proc_runner import GraphProcRunner
16
+ from graphdatascience.utils.util_proc_runner import UtilProcRunner
16
17
 
17
18
 
18
19
  class GraphDataScience(DirectEndpoints, UncallableNamespace):
@@ -81,12 +82,16 @@ class GraphDataScience(DirectEndpoints, UncallableNamespace):
81
82
  None if arrow is True else arrow,
82
83
  )
83
84
 
84
- super().__init__(self._query_runner, "gds", self._server_version)
85
+ super().__init__(self._query_runner, namespace="gds", server_version=self._server_version)
85
86
 
86
87
  @property
87
88
  def graph(self) -> GraphProcRunner:
88
89
  return GraphProcRunner(self._query_runner, f"{self._namespace}.graph", self._server_version)
89
90
 
91
+ @property
92
+ def util(self) -> UtilProcRunner:
93
+ return UtilProcRunner(self._query_runner, f"{self._namespace}.util", self._server_version)
94
+
90
95
  @property
91
96
  def alpha(self) -> AlphaEndpoints:
92
97
  return AlphaEndpoints(self._query_runner, "gds.alpha", self._server_version)
@@ -41,5 +41,5 @@ class LPModel(PipelineModel):
41
41
  A list of LinkFeatures of the pipeline.
42
42
 
43
43
  """
44
- steps: List[Dict[str, Any]] = self._list_info()["modelInfo"][0]["pipeline"]["featureSteps"]
44
+ steps: List[Dict[str, Any]] = self._list_info()["modelInfo"]["pipeline"]["featureSteps"]
45
45
  return [LinkFeature(s["name"], s["config"]) for s in steps]
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from abc import ABC, abstractmethod
2
4
  from typing import Any, Dict
3
5
 
@@ -21,34 +23,32 @@ class Model(ABC):
21
23
  def _endpoint_prefix(self) -> str:
22
24
  pass
23
25
 
24
- def _list_info(self) -> DataFrame:
26
+ def _list_info(self) -> Series[Any]:
27
+ params = CallParameters(name=self.name())
28
+
29
+ result: Series[Any]
25
30
  if self._server_version < ServerVersion(2, 5, 0):
26
- query = "CALL gds.beta.model.list($name)"
31
+ result = self._query_runner.call_procedure(
32
+ "gds.beta.model.list", params=params, custom_error=False
33
+ ).squeeze()
27
34
  else:
28
- query = """
29
- CALL gds.model.list($name)
30
- YIELD
31
- modelName, modelType, modelInfo,
32
- creationTime, trainConfig, graphSchema,
33
- loaded, stored, published
34
- RETURN
35
- modelName, modelType,
36
- modelInfo {.*, modelName: modelName, modelType: modelType} AS modelInfo,
37
- creationTime, trainConfig, graphSchema,
38
- loaded, stored, published, published AS shared
39
- """
40
-
41
- params = {"name": self.name()}
42
-
43
- # FIXME use call procedure + do post processing on the client side
44
- info = self._query_runner.run_cypher(query, params, custom_error=False)
45
-
46
- if len(info) == 0:
35
+ result = self._query_runner.call_procedure("gds.model.list", params=params, custom_error=False).squeeze()
36
+
37
+ if not result.empty:
38
+ # 2.5 compat format
39
+ result["modelInfo"] = {
40
+ **result["modelInfo"],
41
+ "modelName": result["modelName"],
42
+ "modelType": result["modelType"],
43
+ }
44
+ result["shared"] = result["published"]
45
+
46
+ if result.empty:
47
47
  raise ValueError(f"There is no '{self.name()}' in the model catalog")
48
48
 
49
- return info
49
+ return result
50
50
 
51
- def _estimate_predict(self, predict_mode: str, graph_name: str, config: Dict[str, Any]) -> "Series[Any]":
51
+ def _estimate_predict(self, predict_mode: str, graph_name: str, config: Dict[str, Any]) -> Series[Any]:
52
52
  endpoint = f"{self._endpoint_prefix()}{predict_mode}.estimate"
53
53
  config["modelName"] = self.name()
54
54
  params = CallParameters(graph_name=graph_name, config=config)
@@ -76,9 +76,9 @@ class Model(ABC):
76
76
  The type of the model.
77
77
 
78
78
  """
79
- return self._list_info()["modelInfo"][0]["modelType"] # type: ignore
79
+ return self._list_info()["modelInfo"]["modelType"] # type: ignore
80
80
 
81
- def train_config(self) -> "Series[Any]":
81
+ def train_config(self) -> Series[Any]:
82
82
  """
83
83
  Get the train config of the model.
84
84
 
@@ -86,10 +86,10 @@ class Model(ABC):
86
86
  The train config of the model.
87
87
 
88
88
  """
89
- train_config: "Series[Any]" = Series(self._list_info()["trainConfig"][0])
89
+ train_config: Series[Any] = Series(self._list_info()["trainConfig"])
90
90
  return train_config
91
91
 
92
- def graph_schema(self) -> "Series[Any]":
92
+ def graph_schema(self) -> Series[Any]:
93
93
  """
94
94
  Get the graph schema of the model.
95
95
 
@@ -97,7 +97,7 @@ class Model(ABC):
97
97
  The graph schema of the model.
98
98
 
99
99
  """
100
- graph_schema: "Series[Any]" = Series(self._list_info()["graphSchema"][0])
100
+ graph_schema: Series[Any] = Series(self._list_info()["graphSchema"])
101
101
  return graph_schema
102
102
 
103
103
  def loaded(self) -> bool:
@@ -108,7 +108,7 @@ class Model(ABC):
108
108
  True if the model is loaded in memory, False otherwise.
109
109
 
110
110
  """
111
- return self._list_info()["loaded"].squeeze() # type: ignore
111
+ return self._list_info()["loaded"] # type: ignore
112
112
 
113
113
  def stored(self) -> bool:
114
114
  """
@@ -118,7 +118,7 @@ class Model(ABC):
118
118
  True if the model is stored on disk, False otherwise.
119
119
 
120
120
  """
121
- return self._list_info()["stored"].squeeze() # type: ignore
121
+ return self._list_info()["stored"] # type: ignore
122
122
 
123
123
  def creation_time(self) -> Any: # neo4j.time.DateTime not exported
124
124
  """
@@ -128,7 +128,7 @@ class Model(ABC):
128
128
  The creation time of the model.
129
129
 
130
130
  """
131
- return self._list_info()["creationTime"].squeeze()
131
+ return self._list_info()["creationTime"]
132
132
 
133
133
  def shared(self) -> bool:
134
134
  """
@@ -138,7 +138,7 @@ class Model(ABC):
138
138
  True if the model is shared, False otherwise.
139
139
 
140
140
  """
141
- return self._list_info()["shared"].squeeze() # type: ignore
141
+ return self._list_info()["shared"] # type: ignore
142
142
 
143
143
  @compatible_with("published", min_inclusive=ServerVersion(2, 5, 0))
144
144
  def published(self) -> bool:
@@ -149,9 +149,9 @@ class Model(ABC):
149
149
  True if the model is published, False otherwise.
150
150
 
151
151
  """
152
- return self._list_info()["published"].squeeze() # type: ignore
152
+ return self._list_info()["published"] # type: ignore
153
153
 
154
- def model_info(self) -> "Series[Any]":
154
+ def model_info(self) -> Dict[str, Any]:
155
155
  """
156
156
  Get the model info of the model.
157
157
 
@@ -159,7 +159,7 @@ class Model(ABC):
159
159
  The model info of the model.
160
160
 
161
161
  """
162
- return Series(self._list_info()["modelInfo"].squeeze())
162
+ return Series(self._list_info()["modelInfo"]) # type: ignore
163
163
 
164
164
  def exists(self) -> bool:
165
165
  """
@@ -179,7 +179,7 @@ class Model(ABC):
179
179
  endpoint=endpoint, params=params, yields=yields, custom_error=False
180
180
  ).squeeze()
181
181
 
182
- def drop(self, failIfMissing: bool = False) -> "Series[Any]":
182
+ def drop(self, failIfMissing: bool = False) -> Series[Any]:
183
183
  """
184
184
  Drop the model.
185
185
 
@@ -190,27 +190,29 @@ class Model(ABC):
190
190
  The result of the drop operation.
191
191
 
192
192
  """
193
+ params = CallParameters(model_name=self._name, fail_if_missing=failIfMissing)
193
194
  if self._server_version < ServerVersion(2, 5, 0):
194
- query = "CALL gds.beta.model.drop($model_name, $fail_if_missing)"
195
+ return self._query_runner.call_procedure( # type: ignore
196
+ "gds.beta.model.drop", params=params, custom_error=False
197
+ ).squeeze()
195
198
  else:
196
- query = """
197
- CALL gds.model.drop($model_name, $fail_if_missing)
198
- YIELD
199
- modelName, modelType, modelInfo,
200
- creationTime, trainConfig, graphSchema,
201
- loaded, stored, published
202
- RETURN
203
- modelName, modelType,
204
- modelInfo {.*, modelName: modelName, modelType: modelType} AS modelInfo,
205
- creationTime, trainConfig, graphSchema,
206
- loaded, stored, published, published AS shared
207
- """
208
-
209
- params = {"model_name": self._name, "fail_if_missing": failIfMissing}
210
- # FIXME use call procedure + do post processing on the client side
211
- return self._query_runner.run_cypher(query, params, custom_error=False).squeeze() # type: ignore
212
-
213
- def metrics(self) -> "Series[Any]":
199
+ result: Series[Any] = self._query_runner.call_procedure(
200
+ "gds.model.drop", params=params, custom_error=False
201
+ ).squeeze()
202
+
203
+ if result.empty:
204
+ return result
205
+
206
+ # modelInfo {.*, modelName: modelName, modelType: modelType} AS modelInfo
207
+ result["modelInfo"] = {
208
+ **result["modelInfo"],
209
+ "modelName": result["modelName"],
210
+ "modelType": result["modelType"],
211
+ }
212
+ result["shared"] = result["published"]
213
+ return result
214
+
215
+ def metrics(self) -> Series[Any]:
214
216
  """
215
217
  Get the metrics of the model.
216
218
 
@@ -218,8 +220,8 @@ class Model(ABC):
218
220
  The metrics of the model.
219
221
 
220
222
  """
221
- model_info = self._list_info()["modelInfo"][0]
222
- metrics: "Series[Any]" = Series(model_info["metrics"])
223
+ model_info = self._list_info()["modelInfo"]
224
+ metrics: Series[Any] = Series(model_info["metrics"])
223
225
  return metrics
224
226
 
225
227
  @graph_type_check
@@ -242,7 +244,7 @@ class Model(ABC):
242
244
  return self._query_runner.call_procedure(endpoint=endpoint, params=params, logging=True)
243
245
 
244
246
  @graph_type_check
245
- def predict_stream_estimate(self, G: Graph, **config: Any) -> "Series[Any]":
247
+ def predict_stream_estimate(self, G: Graph, **config: Any) -> Series[Any]:
246
248
  """
247
249
  Estimate the prediction on the given graph using the model and stream the results as DataFrame
248
250
 
@@ -257,7 +259,7 @@ class Model(ABC):
257
259
  return self._estimate_predict("stream", G.name(), config)
258
260
 
259
261
  @graph_type_check
260
- def predict_mutate(self, G: Graph, **config: Any) -> "Series[Any]":
262
+ def predict_mutate(self, G: Graph, **config: Any) -> Series[Any]:
261
263
  """
262
264
  Predict on the given graph using the model and mutate the graph with the results.
263
265
 
@@ -278,7 +280,7 @@ class Model(ABC):
278
280
  ).squeeze()
279
281
 
280
282
  @graph_type_check
281
- def predict_mutate_estimate(self, G: Graph, **config: Any) -> "Series[Any]":
283
+ def predict_mutate_estimate(self, G: Graph, **config: Any) -> Series[Any]:
282
284
  """
283
285
  Estimate the memory needed to predict on the given graph using the model.
284
286
 
@@ -1,4 +1,6 @@
1
- from typing import Any, Dict, List, Optional, Tuple
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional, Tuple, Union
2
4
 
3
5
  from pandas import DataFrame, Series
4
6
 
@@ -49,23 +51,29 @@ class TransECreator(UncallableNamespace, IllegalAttrChecker):
49
51
  class ModelProcRunner(ModelResolver):
50
52
  @client_only_endpoint("gds.model")
51
53
  def get(self, model_name: str) -> Model:
54
+ params = CallParameters(model_name=model_name)
52
55
  if self._server_version < ServerVersion(2, 5, 0):
53
- query = "CALL gds.beta.model.list($model_name) YIELD modelInfo RETURN modelInfo.modelType AS modelType"
56
+ endpoint = "gds.beta.model.list"
57
+ yields = ["modelInfo"]
58
+ result_25: Series[Any] = self._query_runner.call_procedure(
59
+ endpoint=endpoint, params=params, yields=yields, custom_error=False
60
+ ).squeeze()
61
+ model_type = str(result_25["modelInfo"]["modelType"]) if not result_25.empty else None
54
62
  else:
55
- query = "CALL gds.model.list($model_name) YIELD modelType"
56
-
57
- params = {"model_name": model_name}
58
- # FIXME use call procedure + do post processing on the client side
59
- result = self._query_runner.run_cypher(query, params, custom_error=False)
60
-
61
- if len(result) == 0:
63
+ endpoint = "gds.model.list"
64
+ yields = ["modelType"]
65
+ result: Union[str, Series[Any]] = self._query_runner.call_procedure(
66
+ endpoint=endpoint, params=params, yields=yields, custom_error=False
67
+ ).squeeze()
68
+ model_type = result if isinstance(result, str) else None
69
+
70
+ if model_type is None:
62
71
  raise ValueError(f"No loaded model named '{model_name}' exists")
63
72
 
64
- model_type = str(result["modelType"].squeeze())
65
73
  return self._resolve_model(model_type, model_name)
66
74
 
67
75
  @compatible_with("store", min_inclusive=ServerVersion(2, 5, 0))
68
- def store(self, model: Model, failIfUnsupportedType: bool = True) -> "Series[Any]":
76
+ def store(self, model: Model, failIfUnsupportedType: bool = True) -> Series[Any]:
69
77
  self._namespace += ".store"
70
78
  params = CallParameters(model_name=model.name(), fail_flag=failIfUnsupportedType)
71
79
 
@@ -88,7 +96,7 @@ class ModelProcRunner(ModelResolver):
88
96
  return self._resolve_model(model_type, model_name)
89
97
 
90
98
  @compatible_with("load", min_inclusive=ServerVersion(2, 5, 0))
91
- def load(self, model_name: str) -> Tuple[Model, "Series[Any]"]:
99
+ def load(self, model_name: str) -> Tuple[Model, Series[Any]]:
92
100
  self._namespace += ".load"
93
101
 
94
102
  params = CallParameters(model_name=model_name)
@@ -101,7 +109,7 @@ class ModelProcRunner(ModelResolver):
101
109
  return proc_runner.get(result["modelName"]), result
102
110
 
103
111
  @compatible_with("delete", min_inclusive=ServerVersion(2, 5, 0))
104
- def delete(self, model: Model) -> "Series[Any]":
112
+ def delete(self, model: Model) -> Series[Any]:
105
113
  self._namespace += ".delete"
106
114
  params = CallParameters(model_name=model.name())
107
115
  return self._query_runner.call_procedure(endpoint=self._namespace, params=params).squeeze() # type: ignore
@@ -117,7 +125,7 @@ class ModelProcRunner(ModelResolver):
117
125
  return self._query_runner.call_procedure(endpoint=self._namespace, params=params)
118
126
 
119
127
  @compatible_with("exists", min_inclusive=ServerVersion(2, 5, 0))
120
- def exists(self, model_name: str) -> "Series[Any]":
128
+ def exists(self, model_name: str) -> Series[Any]:
121
129
  self._namespace += ".exists"
122
130
 
123
131
  return self._query_runner.call_procedure( # type: ignore
@@ -125,7 +133,7 @@ class ModelProcRunner(ModelResolver):
125
133
  ).squeeze()
126
134
 
127
135
  @compatible_with("drop", min_inclusive=ServerVersion(2, 5, 0))
128
- def drop(self, model: Model) -> "Series[Any]":
136
+ def drop(self, model: Model) -> Series[Any]:
129
137
  self._namespace += ".drop"
130
138
 
131
139
  return self._query_runner.call_procedure( # type: ignore
@@ -62,7 +62,7 @@ class NCModel(PipelineModel):
62
62
  The classes of the model.
63
63
 
64
64
  """
65
- return self._list_info()["modelInfo"][0]["classes"] # type: ignore
65
+ return self._list_info()["modelInfo"]["classes"] # type: ignore
66
66
 
67
67
  def feature_properties(self) -> List[str]:
68
68
  """
@@ -72,5 +72,5 @@ class NCModel(PipelineModel):
72
72
  The feature properties of the model.
73
73
 
74
74
  """
75
- features: List[Dict[str, Any]] = self._list_info()["modelInfo"][0]["pipeline"]["featureProperties"]
75
+ features: List[Dict[str, Any]] = self._list_info()["modelInfo"]["pipeline"]["featureProperties"]
76
76
  return [f["feature"] for f in features]
@@ -21,5 +21,5 @@ class NRModel(PipelineModel):
21
21
  The feature properties of the model.
22
22
 
23
23
  """
24
- features: List[Dict[str, Any]] = self._list_info()["modelInfo"][0]["pipeline"]["featureProperties"]
24
+ features: List[Dict[str, Any]] = self._list_info()["modelInfo"]["pipeline"]["featureProperties"]
25
25
  return [f["feature"] for f in features]
@@ -75,7 +75,7 @@ class PipelineModel(Model, ABC):
75
75
  The best parameters for the pipeline model.
76
76
 
77
77
  """
78
- best_params: Dict[str, Any] = self._list_info()["modelInfo"][0]["bestParameters"]
78
+ best_params: Dict[str, Any] = self._list_info()["modelInfo"]["bestParameters"]
79
79
  return Series(best_params)
80
80
 
81
81
  def node_property_steps(self) -> List[NodePropertyStep]:
@@ -86,7 +86,7 @@ class PipelineModel(Model, ABC):
86
86
  The node property steps for the pipeline model.
87
87
 
88
88
  """
89
- steps: List[Dict[str, Any]] = self._list_info()["modelInfo"][0]["pipeline"]["nodePropertySteps"]
89
+ steps: List[Dict[str, Any]] = self._list_info()["modelInfo"]["pipeline"]["nodePropertySteps"]
90
90
  return [NodePropertyStep(s["name"], s["config"]) for s in steps]
91
91
 
92
92
  def metrics(self) -> "Series[Any]":
@@ -97,6 +97,6 @@ class PipelineModel(Model, ABC):
97
97
  The metrics for the pipeline model.
98
98
 
99
99
  """
100
- model_metrics: Dict[str, Any] = self._list_info()["modelInfo"][0]["metrics"]
100
+ model_metrics: Dict[str, Any] = self._list_info()["modelInfo"]["metrics"]
101
101
  metric_scores: Dict[str, MetricScores] = {k: MetricScores.create(v) for k, v in (model_metrics.items())}
102
102
  return Series(metric_scores)
@@ -64,6 +64,9 @@ class ArrowQueryRunner(QueryRunner):
64
64
  ) -> DataFrame:
65
65
  return self._fallback_query_runner.run_cypher(query, params, database, custom_error)
66
66
 
67
+ def call_function(self, endpoint: str, params: Optional[CallParameters] = None) -> Any:
68
+ return self._fallback_query_runner.call_function(endpoint, params)
69
+
67
70
  def call_procedure(
68
71
  self,
69
72
  endpoint: str,
@@ -35,6 +35,9 @@ class AuraDbQueryRunner(QueryRunner):
35
35
  ) -> DataFrame:
36
36
  return self._db_query_runner.run_cypher(query, params, database, custom_error)
37
37
 
38
+ def call_function(self, endpoint: str, params: Optional[CallParameters] = None) -> Any:
39
+ return self._gds_query_runner.call_function(endpoint, params)
40
+
38
41
  def call_procedure(
39
42
  self,
40
43
  endpoint: str,
@@ -131,6 +131,13 @@ class Neo4jQueryRunner(QueryRunner):
131
131
 
132
132
  return df
133
133
 
134
+ def call_function(self, endpoint: str, params: Optional[CallParameters] = None) -> Any:
135
+ if params is None:
136
+ params = CallParameters()
137
+ query = f"RETURN {endpoint}({params.placeholder_str()})"
138
+
139
+ return self.run_cypher(query, params).squeeze()
140
+
134
141
  def call_procedure(
135
142
  self,
136
143
  endpoint: str,
@@ -21,6 +21,10 @@ class QueryRunner(ABC):
21
21
  ) -> DataFrame:
22
22
  pass
23
23
 
24
+ @abstractmethod
25
+ def call_function(self, endpoint: str, params: Optional[CallParameters] = None) -> Any:
26
+ pass
27
+
24
28
  @abstractmethod
25
29
  def run_cypher(
26
30
  self,