polly-python 4.5.0__tar.gz → 4.7.0__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 (71) hide show
  1. {polly_python-4.5.0/polly_python.egg-info → polly_python-4.7.0}/PKG-INFO +1 -1
  2. polly_python-4.7.0/polly/__init__.py +1 -0
  3. {polly_python-4.5.0 → polly_python-4.7.0}/polly/atlas.py +6 -0
  4. {polly_python-4.5.0 → polly_python-4.7.0}/polly/help.py +5 -2
  5. {polly_python-4.5.0 → polly_python-4.7.0}/polly/polly_kg.py +131 -42
  6. {polly_python-4.5.0 → polly_python-4.7.0/polly_python.egg-info}/PKG-INFO +1 -1
  7. polly_python-4.5.0/polly/__init__.py +0 -1
  8. {polly_python-4.5.0 → polly_python-4.7.0}/LICENSE.md +0 -0
  9. {polly_python-4.5.0 → polly_python-4.7.0}/MANIFEST.in +0 -0
  10. {polly_python-4.5.0 → polly_python-4.7.0}/README.md +0 -0
  11. {polly_python-4.5.0 → polly_python-4.7.0}/polly/analyze.py +0 -0
  12. {polly_python-4.5.0 → polly_python-4.7.0}/polly/application_error_info.py +0 -0
  13. {polly_python-4.5.0 → polly_python-4.7.0}/polly/auth.py +0 -0
  14. {polly_python-4.5.0 → polly_python-4.7.0}/polly/constants.py +0 -0
  15. {polly_python-4.5.0 → polly_python-4.7.0}/polly/curation.py +0 -0
  16. {polly_python-4.5.0 → polly_python-4.7.0}/polly/data_management.py +0 -0
  17. {polly_python-4.5.0 → polly_python-4.7.0}/polly/errors.py +0 -0
  18. {polly_python-4.5.0 → polly_python-4.7.0}/polly/helpers.py +0 -0
  19. {polly_python-4.5.0 → polly_python-4.7.0}/polly/http_response_codes.py +0 -0
  20. {polly_python-4.5.0 → polly_python-4.7.0}/polly/index_schema_level_conversion_const.py +0 -0
  21. {polly_python-4.5.0 → polly_python-4.7.0}/polly/jobs.py +0 -0
  22. {polly_python-4.5.0 → polly_python-4.7.0}/polly/omixatlas.py +0 -0
  23. {polly_python-4.5.0 → polly_python-4.7.0}/polly/omixatlas_hlpr.py +0 -0
  24. {polly_python-4.5.0 → polly_python-4.7.0}/polly/pipelines.py +0 -0
  25. {polly_python-4.5.0 → polly_python-4.7.0}/polly/s3_utils.py +0 -0
  26. {polly_python-4.5.0 → polly_python-4.7.0}/polly/session.py +0 -0
  27. {polly_python-4.5.0 → polly_python-4.7.0}/polly/threading_utils.py +0 -0
  28. {polly_python-4.5.0 → polly_python-4.7.0}/polly/tracking.py +0 -0
  29. {polly_python-4.5.0 → polly_python-4.7.0}/polly/validation.py +0 -0
  30. {polly_python-4.5.0 → polly_python-4.7.0}/polly/validation_hlpr.py +0 -0
  31. {polly_python-4.5.0 → polly_python-4.7.0}/polly/workspaces.py +0 -0
  32. {polly_python-4.5.0 → polly_python-4.7.0}/polly_interfaces/IFiles.py +0 -0
  33. {polly_python-4.5.0 → polly_python-4.7.0}/polly_interfaces/IReporting.py +0 -0
  34. {polly_python-4.5.0 → polly_python-4.7.0}/polly_interfaces/ISchema.py +0 -0
  35. {polly_python-4.5.0 → polly_python-4.7.0}/polly_interfaces/__init__.py +0 -0
  36. {polly_python-4.5.0 → polly_python-4.7.0}/polly_python.egg-info/SOURCES.txt +0 -0
  37. {polly_python-4.5.0 → polly_python-4.7.0}/polly_python.egg-info/dependency_links.txt +0 -0
  38. {polly_python-4.5.0 → polly_python-4.7.0}/polly_python.egg-info/requires.txt +0 -0
  39. {polly_python-4.5.0 → polly_python-4.7.0}/polly_python.egg-info/top_level.txt +0 -0
  40. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/__init__.py +0 -0
  41. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/dataset.py +0 -0
  42. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/files/__init__.py +0 -0
  43. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/files/files.py +0 -0
  44. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/files/files_hlpr.py +0 -0
  45. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/polly_services_hlpr.py +0 -0
  46. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/reporting/__init__.py +0 -0
  47. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/reporting/reporting.py +0 -0
  48. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/reporting/reporting_hlpr.py +0 -0
  49. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/schema/__init__.py +0 -0
  50. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/schema/schema.py +0 -0
  51. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/schema/schema_const.py +0 -0
  52. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/schema/schema_hlpr.py +0 -0
  53. {polly_python-4.5.0 → polly_python-4.7.0}/polly_services/schema/validate_schema_hlpr.py +0 -0
  54. {polly_python-4.5.0 → polly_python-4.7.0}/pyproject.toml +0 -0
  55. {polly_python-4.5.0 → polly_python-4.7.0}/setup.cfg +0 -0
  56. {polly_python-4.5.0 → polly_python-4.7.0}/setup.py +0 -0
  57. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_atlas.py +0 -0
  58. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_constants.py +0 -0
  59. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_curation.py +0 -0
  60. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_data_management.py +0 -0
  61. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_help.py +0 -0
  62. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_helpers.py +0 -0
  63. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_jobs.py +0 -0
  64. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_kg.py +0 -0
  65. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_omixatlas.py +0 -0
  66. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_pipelines.py +0 -0
  67. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_s3_utils.py +0 -0
  68. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_schema_ux.py +0 -0
  69. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_threading_utils.py +0 -0
  70. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_validation.py +0 -0
  71. {polly_python-4.5.0 → polly_python-4.7.0}/tests/test_workspaces.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polly_python
3
- Version: 4.5.0
3
+ Version: 4.7.0
4
4
  Summary: Polly SDK
5
5
  Home-page: https://github.com/ElucidataInc/polly-python
6
6
  Project-URL: Documentation, https://docs.elucidata.io
@@ -0,0 +1 @@
1
+ __version__ = "4.7.0"
@@ -84,6 +84,12 @@ class Column:
84
84
  ### Boolean & JSON Data Types
85
85
  - `boolean`: Stores `true`, `false` values
86
86
  - `json`: Stores structured JSON data
87
+
88
+ ### Array Data Types
89
+ - `bigint_array`: Stores `bigint` values as arrays. For example: `[1234567894, 9876543216]`
90
+ - `double_precision_array`: Stores `double precision` values as arrays. For example: `[12.34, 56.78, 90.12]`
91
+ - `text_array`: Stores `text` values as arrays. For example: `["sample1", "sample2", "sample3"]`
92
+ - `integer_array`: Stores `integer` values as arrays. For example: `[100, 200, 300]`
87
93
  """
88
94
 
89
95
  def __init__(
@@ -273,8 +273,11 @@ def get_txt(
273
273
  and (not function_name or function_name == fun.split(".")[-1])
274
274
  and should_show_fun
275
275
  ):
276
- import rst2txt
277
- from docutils.core import publish_string
276
+ try:
277
+ import rst2txt
278
+ from docutils.core import publish_string
279
+ except ImportError:
280
+ return None
278
281
 
279
282
  # converting rst to txt
280
283
  txt = publish_string(
@@ -222,17 +222,14 @@ class PollyKG:
222
222
  if not query or query == "":
223
223
  raise InvalidParameterException("query")
224
224
  query_url = f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/queries/"
225
- is_async = True
226
- if query_type == "NLQ":
227
- is_async = False # NLQ queries are always synchronous
225
+ if query_type != "CYPHER":
226
+ raise InvalidParameterException(
227
+ f"Invalid query_type: '{query_type}'. Only 'CYPHER' query type is supported."
228
+ )
228
229
  payload = {
229
230
  "data": {
230
231
  "type": "kg_query",
231
- "attributes": {
232
- "query_string": query,
233
- "query_type": query_type,
234
- "is_async": is_async,
235
- },
232
+ "attributes": {"query_string": query, "query_type": query_type},
236
233
  }
237
234
  }
238
235
  try:
@@ -326,15 +323,17 @@ class PollyKG:
326
323
  if not query or query == "":
327
324
  raise InvalidParameterException("query")
328
325
  query_url = f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/queries/"
326
+ if query_type != "CYPHER":
327
+ raise InvalidParameterException(
328
+ f"Invalid query_type: '{query_type}'. Only 'CYPHER' query type is supported."
329
+ )
329
330
  is_async = True
330
- if query_type == "NLQ":
331
- is_async = False # NLQ queries are always synchronous
332
331
  payload = {
333
332
  "data": {
334
333
  "type": "kg_query",
335
334
  "attributes": {
336
335
  "query_string": query,
337
- "query_type": query_type,
336
+ "query_type": "CYPHER",
338
337
  "is_async": is_async,
339
338
  },
340
339
  }
@@ -509,9 +508,10 @@ class PollyKG:
509
508
  print(e)
510
509
  raise
511
510
 
512
- def get_summary(self) -> dict:
511
+ def get_summary(self, stats: bool = False) -> dict:
513
512
  """Retrieve a summary of the Polly Knowledge Graph.
514
-
513
+ Params:
514
+ stats: A boolean flag to retrieve the detailed counts edges.
515
515
  Returns:
516
516
  dict: A dictionary containing summary information about the graph,
517
517
  such as node counts, edge counts, and other metadata.
@@ -522,9 +522,14 @@ class PollyKG:
522
522
  RequestFailureException: Raised when the request fails due to an unexpected error.
523
523
  """
524
524
  try:
525
- response = self.session.get(
526
- f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/summary"
527
- )
525
+ if stats:
526
+ response = self.session.get(
527
+ f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/summary?stats=true"
528
+ )
529
+ else:
530
+ response = self.session.get(
531
+ f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/summary"
532
+ )
528
533
  return handle_success_and_error_response(response)
529
534
  except Exception as e:
530
535
  print(e)
@@ -564,6 +569,101 @@ class PollyKG:
564
569
  print(e)
565
570
  raise
566
571
 
572
+ @Track.track_decorator
573
+ def get_all_queries(
574
+ self,
575
+ status: str = "IN_PROGRESS",
576
+ page_size: int = 100,
577
+ next_token: str = None,
578
+ instance_id: str = None,
579
+ ) -> dict:
580
+ """Retrieve a list of queries for the specified KG version.
581
+
582
+ This function fetches queries based on their status, allowing you to filter
583
+ and paginate through query results. It supports filtering by status and
584
+ optionally by instance_id.
585
+
586
+ Args:
587
+ status (str, optional): Filter queries by status. Accepts "IN_PROGRESS",
588
+ "COMPLETED", "FAILED", "QUEUED", or "CANCELLED". Defaults to "IN_PROGRESS".
589
+ page_size (int, optional): Number of queries to return per page.
590
+ Maximum 100. Defaults to 100.
591
+ next_token (str, optional): Pagination token for retrieving the next page
592
+ of results. Obtained from the 'meta' section of the previous response.
593
+ Defaults to None.
594
+ instance_id (str, optional): Filter queries by specific instance ID.
595
+ Defaults to None.
596
+
597
+ Returns:
598
+ dict: A dictionary containing query data and pagination metadata:
599
+ - data (list): List of query objects with attributes including query_id,
600
+ query_string, status, created_at, and metadata.
601
+ - meta (dict): Pagination metadata including next_token if more results exist.
602
+ If no queries are found, returns a message string.
603
+
604
+ Raises:
605
+ BadRequestError: If invalid parameters are provided.
606
+ UnauthorizedException: If authentication fails.
607
+ RequestFailureException: If the request fails due to an unexpected error.
608
+ """
609
+ queries_url = f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/queries/"
610
+ params = {"status": status, "page_size": page_size}
611
+
612
+ if next_token:
613
+ params["next_token"] = next_token
614
+ if instance_id:
615
+ params["instance_id"] = instance_id
616
+
617
+ response = self.session.get(queries_url, params=params)
618
+ handle_success_and_error_response(response)
619
+ response_json = response.json()
620
+ meta = response_json.get("meta", {})
621
+
622
+ if "data" in response_json:
623
+ count = len(response_json["data"])
624
+ if count == 0:
625
+ return f"No {status} queries found"
626
+ return {"data": response_json["data"], "meta": meta}
627
+ return {
628
+ "message": response_json.get("message", "No information available"),
629
+ "meta": meta,
630
+ }
631
+
632
+ @Track.track_decorator
633
+ def cancel_query(self, query_id: str) -> dict:
634
+ """Cancel a running or queued query.
635
+
636
+ This function attempts to cancel a query that is currently in "IN_PROGRESS"
637
+ or "QUEUED" status. Once cancelled, the query status will be updated to
638
+ "CANCELLED" and it will stop execution.
639
+
640
+ Args:
641
+ query_id (str): The unique ID of the query to cancel. Must be a non-empty string.
642
+
643
+ Returns:
644
+ dict: A dictionary containing the cancellation response with updated query status.
645
+
646
+ Raises:
647
+ InvalidParameterException: If query_id is None, empty, or not a valid string.
648
+ ResourceNotFoundError: If the specified query_id does not exist.
649
+ BadRequestError: If the query cannot be cancelled (e.g., already completed or failed).
650
+ UnauthorizedException: If authentication fails.
651
+ RequestFailureException: If the request fails due to an unexpected error.
652
+ """
653
+ if not query_id or not isinstance(query_id, str) or query_id.strip() == "":
654
+ raise InvalidParameterException("query_id")
655
+
656
+ queries_url = f"{self.polly_kg_neo4j_endpoint}/kg/{self.kg_id}/versions/{self.version_id}/queries/{query_id}/status"
657
+ payload = {"data": {"type": "kg_query", "attributes": {"status": "CANCELLED"}}}
658
+
659
+ try:
660
+ response = self.session.patch(queries_url, data=json.dumps(payload))
661
+ handle_success_and_error_response(response)
662
+ return response.json()
663
+ except Exception as e:
664
+ print(e)
665
+ raise e
666
+
567
667
  def _transform_schema_to_legacy_format(
568
668
  self, new_schema: dict, kg_id: str, version_id: str
569
669
  ) -> dict:
@@ -580,6 +680,7 @@ class PollyKG:
580
680
  data = new_schema.get("data", {})
581
681
  attributes = data.get("attributes", {})
582
682
  schema = attributes.get("schema", {})
683
+ custom_attributes = attributes.get("custom_attributes", {})
583
684
 
584
685
  # Extract basic information
585
686
  node_types = schema.get("node_types", [])
@@ -658,19 +759,24 @@ class PollyKG:
658
759
  # Build legacy format response
659
760
  from datetime import datetime
660
761
 
762
+ # Build metadata with standard fields
763
+ metadata = {
764
+ "name": "schema",
765
+ "kg_id": str(kg_id),
766
+ "kg_version": str(version_id),
767
+ "last_updated": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
768
+ "computed_at": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
769
+ }
770
+
771
+ data_source = custom_attributes.get("data_source")
772
+ if data_source is not None:
773
+ metadata["data_source"] = data_source
774
+
661
775
  legacy_format = {
662
776
  "data": {
663
777
  "type": "kg_schema",
664
778
  "attributes": {
665
- "metadata": {
666
- "name": "schema",
667
- "kg_id": str(kg_id),
668
- "kg_version": str(version_id),
669
- "last_updated": datetime.utcnow().strftime(
670
- "%Y-%m-%dT%H:%M:%SZ"
671
- ),
672
- "computed_at": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
673
- },
779
+ "metadata": metadata,
674
780
  "node_types": node_types,
675
781
  "edge_types": edge_types,
676
782
  "nodes": transformed_nodes,
@@ -726,23 +832,6 @@ class PollyKG:
726
832
  ResourceNotFoundError: Raised when no knowledge graphs are found.
727
833
  AccessDeniedError: Raised when the user does not have permission to access the KGs.
728
834
  RequestFailureException: Raised when the request fails due to an unexpected error.
729
-
730
- Example:
731
- >>> kg = PollyKG()
732
- >>> # Get only published KGs
733
- >>> kgs = kg.get_all_kgs()
734
- >>> for kg_info in kgs:
735
- ... print(f"{kg_info['kg_name']} (ID: {kg_info['kg_id']})")
736
- base kg v3 (ID: 14_base_kg_v3)
737
-
738
- >>> # Get all KGs including unpublished ones with instance details
739
- >>> kgs_with_instances = kg.get_all_kgs(
740
- ... include_unpublished=True,
741
- ... include_instances=True,
742
- ... include_terminated=True
743
- ... )
744
- >>> for kg_info in kgs_with_instances:
745
- ... print(f"{kg_info['kg_name']} - {len(kg_info.get('instances', []))} instances")
746
835
  """
747
836
  try:
748
837
  kg_url = f"{self.polly_kg_neo4j_endpoint}/kg"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polly_python
3
- Version: 4.5.0
3
+ Version: 4.7.0
4
4
  Summary: Polly SDK
5
5
  Home-page: https://github.com/ElucidataInc/polly-python
6
6
  Project-URL: Documentation, https://docs.elucidata.io
@@ -1 +0,0 @@
1
- __version__ = "4.5.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes