polly-python 4.2.0__tar.gz → 4.4.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.
- {polly_python-4.2.0/polly_python.egg-info → polly_python-4.4.0}/PKG-INFO +30 -19
- polly_python-4.4.0/polly/__init__.py +1 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/analyze.py +6 -6
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/helpers.py +2 -2
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/omixatlas.py +4 -4
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/polly_kg.py +146 -12
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/s3_utils.py +1 -1
- {polly_python-4.2.0 → polly_python-4.4.0/polly_python.egg-info}/PKG-INFO +30 -19
- polly_python-4.4.0/polly_python.egg-info/requires.txt +53 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/dataset.py +3 -3
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/files/files_hlpr.py +10 -18
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/schema/schema.py +2 -5
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/schema/validate_schema_hlpr.py +28 -13
- polly_python-4.4.0/setup.cfg +78 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_kg.py +121 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_omixatlas.py +14 -27
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_s3_utils.py +2 -2
- polly_python-4.2.0/polly/__init__.py +0 -1
- polly_python-4.2.0/polly_python.egg-info/requires.txt +0 -26
- polly_python-4.2.0/setup.cfg +0 -65
- {polly_python-4.2.0 → polly_python-4.4.0}/LICENSE.md +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/MANIFEST.in +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/README.md +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/application_error_info.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/atlas.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/auth.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/constants.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/curation.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/data_management.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/errors.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/help.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/http_response_codes.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/index_schema_level_conversion_const.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/jobs.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/omixatlas_hlpr.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/pipelines.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/session.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/threading_utils.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/tracking.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/validation.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/validation_hlpr.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly/workspaces.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_interfaces/IFiles.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_interfaces/IReporting.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_interfaces/ISchema.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_interfaces/__init__.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_python.egg-info/SOURCES.txt +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_python.egg-info/dependency_links.txt +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_python.egg-info/top_level.txt +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/__init__.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/files/__init__.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/files/files.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/polly_services_hlpr.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/reporting/__init__.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/reporting/reporting.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/reporting/reporting_hlpr.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/schema/__init__.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/schema/schema_const.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/polly_services/schema/schema_hlpr.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/pyproject.toml +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/setup.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_atlas.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_constants.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_curation.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_data_management.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_help.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_helpers.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_jobs.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_pipelines.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_schema_ux.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_threading_utils.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_validation.py +0 -0
- {polly_python-4.2.0 → polly_python-4.4.0}/tests/test_workspaces.py +0 -0
|
@@ -1,36 +1,47 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: polly_python
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.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
|
|
7
7
|
Project-URL: Tutorial Notebooks, https://github.com/ElucidataInc/polly-python
|
|
8
|
-
Requires-Python: <3.
|
|
8
|
+
Requires-Python: <3.15,>=3.9
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.md
|
|
11
|
-
Requires-Dist: cmapPy
|
|
12
|
-
Requires-Dist: cloudpathlib
|
|
11
|
+
Requires-Dist: cmapPy==4.0.1
|
|
12
|
+
Requires-Dist: cloudpathlib<1.0.0,>=0.19.0
|
|
13
13
|
Requires-Dist: retrying==1.3.4
|
|
14
14
|
Requires-Dist: rst2txt==1.1.0
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
15
|
+
Requires-Dist: mixpanel<5.0.0,>=4.10.0
|
|
16
|
+
Requires-Dist: Deprecated<2.0.0,>=1.2.12
|
|
17
|
+
Requires-Dist: pydantic<3.0.0,>=2.8.2
|
|
18
|
+
Requires-Dist: requests<=2.32.3,>=2.31.0
|
|
19
|
+
Requires-Dist: boto3<2.0.0,>=1.34.0
|
|
20
|
+
Requires-Dist: joblib==1.4.2
|
|
21
|
+
Requires-Dist: rich<14.0.0,>=13.0.0
|
|
22
|
+
Requires-Dist: tqdm==4.66.4
|
|
23
|
+
Requires-Dist: plotly==6.3.1
|
|
24
|
+
Requires-Dist: cryptography<=38.0.0; python_full_version >= "3.9.0" and python_full_version <= "3.9.1"
|
|
25
|
+
Requires-Dist: cryptography==46.0.2; python_full_version >= "3.9.2"
|
|
26
|
+
Requires-Dist: setuptools>=65.0.0; python_version >= "3.12"
|
|
27
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.9"
|
|
28
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.10"
|
|
29
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.11"
|
|
30
|
+
Requires-Dist: pandas<=2.2.3,>=2.1.0; python_version == "3.12"
|
|
31
|
+
Requires-Dist: pandas<=2.2.3,>=2.2.2; python_version == "3.13"
|
|
32
|
+
Requires-Dist: pandas<=2.2.3,>=2.2.2; python_version == "3.14"
|
|
33
|
+
Requires-Dist: numpy<=1.25.2,>=1.23.0; python_version == "3.9"
|
|
34
|
+
Requires-Dist: numpy<=2.2.2,>=1.23.0; python_version == "3.10"
|
|
35
|
+
Requires-Dist: numpy<=2.2.2,>=1.24.0; python_version == "3.11"
|
|
36
|
+
Requires-Dist: numpy<=2.2.2,>=1.26.0; python_version == "3.12"
|
|
37
|
+
Requires-Dist: numpy<=2.2.2,>=2.2.0; python_version == "3.13"
|
|
38
|
+
Requires-Dist: numpy<=2.2.2,>=2.2.0; python_version == "3.14"
|
|
30
39
|
Provides-Extra: testing
|
|
31
40
|
Requires-Dist: black; extra == "testing"
|
|
32
41
|
Requires-Dist: flake8; extra == "testing"
|
|
33
42
|
Requires-Dist: pytest; extra == "testing"
|
|
43
|
+
Requires-Dist: pytest-mock; extra == "testing"
|
|
44
|
+
Requires-Dist: moto; extra == "testing"
|
|
34
45
|
Dynamic: license-file
|
|
35
46
|
|
|
36
47
|
[](https://www.python.org/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.4.0"
|
|
@@ -272,12 +272,12 @@ class Analyze:
|
|
|
272
272
|
)
|
|
273
273
|
|
|
274
274
|
cohort_df["kw_condition"] = "NA"
|
|
275
|
-
cohort_df.loc[
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
cohort_df.loc[
|
|
279
|
-
|
|
280
|
-
|
|
275
|
+
cohort_df.loc[cohort_df["sample_id"].isin(control_ids), "kw_condition"] = (
|
|
276
|
+
"control"
|
|
277
|
+
)
|
|
278
|
+
cohort_df.loc[cohort_df["sample_id"].isin(perturbation_ids), "kw_condition"] = (
|
|
279
|
+
"perturbation"
|
|
280
|
+
)
|
|
281
281
|
|
|
282
282
|
return cohort_df
|
|
283
283
|
|
|
@@ -196,7 +196,7 @@ def upload_to_S3(cloud_path: str, local_path: str, credentials: dict) -> None:
|
|
|
196
196
|
and path_split[len(path_split) - 1][0] in punctuation_chars
|
|
197
197
|
):
|
|
198
198
|
raise InvalidParameterException(
|
|
199
|
-
f"path can't start with {path_split[len(path_split)-1][0]}"
|
|
199
|
+
f"path can't start with {path_split[len(path_split) - 1][0]}"
|
|
200
200
|
)
|
|
201
201
|
new_source_path = client.CloudPath(cloud_path)
|
|
202
202
|
if new_source_path.exists():
|
|
@@ -245,7 +245,7 @@ def download_from_S3(
|
|
|
245
245
|
# If copy_workspace_path is True, append workspace_path to destination_path to copy the directory structure.
|
|
246
246
|
# ex- make_path('/home/user/project/', 'folder1/folder2') = '/home/user/project/folder1/folder2'
|
|
247
247
|
if copy_workspace_path is True:
|
|
248
|
-
destination_path = f"{make_path(destination_path,workspace_path)}"
|
|
248
|
+
destination_path = f"{make_path(destination_path, workspace_path)}"
|
|
249
249
|
|
|
250
250
|
source_path.copytree(destination_path, force_overwrite_to_cloud=True)
|
|
251
251
|
except ClientError as e:
|
|
@@ -1060,10 +1060,10 @@ class OmixAtlas:
|
|
|
1060
1060
|
)
|
|
1061
1061
|
|
|
1062
1062
|
frontendinfo_curr_data = repo_curr_data["data"]["attributes"]["frontend_info"]
|
|
1063
|
-
repo_curr_data["data"]["attributes"][
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1063
|
+
repo_curr_data["data"]["attributes"]["frontend_info"] = (
|
|
1064
|
+
omix_hlpr.update_frontendinfo_value(
|
|
1065
|
+
frontendinfo_curr_data, image_url, description, display_name, controls
|
|
1066
|
+
)
|
|
1067
1067
|
)
|
|
1068
1068
|
|
|
1069
1069
|
repository_url = f"{self.resource_url}/{repo_key}"
|
|
@@ -277,13 +277,30 @@ class PollyKG:
|
|
|
277
277
|
result_json = requests.get(result_s3_signed_url)
|
|
278
278
|
return result_json.json()
|
|
279
279
|
elif status == "FAILED":
|
|
280
|
-
|
|
280
|
+
metadata = (
|
|
281
281
|
status_response.json()
|
|
282
282
|
.get("data", {})
|
|
283
283
|
.get("attributes", {})
|
|
284
284
|
.get("metadata", {})
|
|
285
|
-
.get("error")
|
|
286
285
|
)
|
|
286
|
+
# Try new format first: metadata.results.error and metadata.results.details
|
|
287
|
+
results = metadata.get("results", {})
|
|
288
|
+
if results and ("error" in results or "details" in results):
|
|
289
|
+
error_type = results.get("error", "Unknown error")
|
|
290
|
+
error_details = results.get("details", "")
|
|
291
|
+
error_message = (
|
|
292
|
+
f"{error_type}: {error_details}"
|
|
293
|
+
if error_details
|
|
294
|
+
else error_type
|
|
295
|
+
)
|
|
296
|
+
else:
|
|
297
|
+
# Fallback to old format: metadata.error
|
|
298
|
+
error_message = metadata.get(
|
|
299
|
+
"error", "Query failed without a specific error message."
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
print(f"Query failed. Query ID: {query_id}. Error: {error_message}")
|
|
303
|
+
raise QueryFailedException(error_message)
|
|
287
304
|
except Exception as e:
|
|
288
305
|
print(e)
|
|
289
306
|
raise e
|
|
@@ -386,11 +403,25 @@ class PollyKG:
|
|
|
386
403
|
|
|
387
404
|
status = data.get("attributes", {}).get("status")
|
|
388
405
|
if status == "FAILED":
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
406
|
+
metadata = data.get("attributes", {}).get("metadata", {})
|
|
407
|
+
# Try new format first: metadata.results.error and metadata.results.details
|
|
408
|
+
results = metadata.get("results", {})
|
|
409
|
+
if results and ("error" in results or "details" in results):
|
|
410
|
+
error_type = results.get("error", "Unknown error")
|
|
411
|
+
error_details = results.get("details", "")
|
|
412
|
+
error_message = (
|
|
413
|
+
f"{error_type}: {error_details}"
|
|
414
|
+
if error_details
|
|
415
|
+
else error_type
|
|
416
|
+
)
|
|
417
|
+
else:
|
|
418
|
+
# Fallback to old format: metadata.error
|
|
419
|
+
error_message = metadata.get(
|
|
420
|
+
"error", "Query failed without a specific error message."
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
print(f"Query failed. Query ID: {query_id}. Error: {error_message}")
|
|
424
|
+
raise QueryFailedException(error_message)
|
|
394
425
|
result_s3_signed_url = (
|
|
395
426
|
data.get("attributes", {})
|
|
396
427
|
.get("metadata", {})
|
|
@@ -436,11 +467,25 @@ class PollyKG:
|
|
|
436
467
|
|
|
437
468
|
status = data.get("attributes", {}).get("status")
|
|
438
469
|
if status == "FAILED":
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
470
|
+
metadata = data.get("attributes", {}).get("metadata", {})
|
|
471
|
+
# Try new format first: metadata.results.error and metadata.results.details
|
|
472
|
+
results = metadata.get("results", {})
|
|
473
|
+
if results and ("error" in results or "details" in results):
|
|
474
|
+
error_type = results.get("error", "Unknown error")
|
|
475
|
+
error_details = results.get("details", "")
|
|
476
|
+
error_message = (
|
|
477
|
+
f"{error_type}: {error_details}"
|
|
478
|
+
if error_details
|
|
479
|
+
else error_type
|
|
480
|
+
)
|
|
481
|
+
else:
|
|
482
|
+
# Fallback to old format: metadata.error
|
|
483
|
+
error_message = metadata.get(
|
|
484
|
+
"error", "Query failed without a specific error message."
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
print(f"Query failed. Query ID: {query_id}. Error: {error_message}")
|
|
488
|
+
raise QueryFailedException(error_message)
|
|
444
489
|
result_s3_signed_url = (
|
|
445
490
|
data.get("attributes", {})
|
|
446
491
|
.get("metadata", {})
|
|
@@ -503,3 +548,92 @@ class PollyKG:
|
|
|
503
548
|
return handle_success_and_error_response(response)
|
|
504
549
|
except Exception as e:
|
|
505
550
|
print(e)
|
|
551
|
+
|
|
552
|
+
@Track.track_decorator
|
|
553
|
+
def get_all_kgs(
|
|
554
|
+
self,
|
|
555
|
+
include_unpublished: bool = False,
|
|
556
|
+
include_instances: bool = False,
|
|
557
|
+
include_terminated: bool = False,
|
|
558
|
+
) -> list:
|
|
559
|
+
"""Retrieve all available Knowledge Graphs.
|
|
560
|
+
|
|
561
|
+
This function fetches a list of all available Knowledge Graphs (KGs)
|
|
562
|
+
that the user has access to, including their metadata such as kg_id,
|
|
563
|
+
kg_name, kg_description, version_id, created_at timestamp, and
|
|
564
|
+
published status.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
include_unpublished (bool, optional): Include unpublished knowledge graphs.
|
|
568
|
+
Defaults to False.
|
|
569
|
+
include_instances (bool, optional): Include instance information for each KG.
|
|
570
|
+
When True, each KG will include an 'instances' array with details about
|
|
571
|
+
available instances (instance_id, instance_type, CPU/RAM, etc.).
|
|
572
|
+
Defaults to False.
|
|
573
|
+
include_terminated (bool, optional): Include terminated instances in the response.
|
|
574
|
+
Only applies when include_instances is True. Defaults to False.
|
|
575
|
+
|
|
576
|
+
Returns:
|
|
577
|
+
list: A list of dictionaries, where each dictionary contains:
|
|
578
|
+
- kg_id (str): Unique identifier for the knowledge graph
|
|
579
|
+
- kg_name (str): Name of the knowledge graph
|
|
580
|
+
- kg_description (str): Description of the knowledge graph
|
|
581
|
+
- version_id (int): Current version ID
|
|
582
|
+
- created_at (int): Creation timestamp (Unix epoch in milliseconds)
|
|
583
|
+
- published (bool): Whether the KG is published
|
|
584
|
+
- instances (list, optional): Available when include_instances=True.
|
|
585
|
+
Each instance contains:
|
|
586
|
+
- instance_id (str): Unique identifier for the instance
|
|
587
|
+
- instance_type (str): Type/size of instance (e.g., "t3.medium")
|
|
588
|
+
- is_terminated (bool): Whether the instance is terminated
|
|
589
|
+
- default_instance (bool): Whether this is the default instance
|
|
590
|
+
- org_id (int): Organization ID
|
|
591
|
+
- created_at (int): Instance creation timestamp
|
|
592
|
+
|
|
593
|
+
Raises:
|
|
594
|
+
ResourceNotFoundError: Raised when no knowledge graphs are found.
|
|
595
|
+
AccessDeniedError: Raised when the user does not have permission to access the KGs.
|
|
596
|
+
RequestFailureException: Raised when the request fails due to an unexpected error.
|
|
597
|
+
|
|
598
|
+
Example:
|
|
599
|
+
>>> kg = PollyKG()
|
|
600
|
+
>>> # Get only published KGs
|
|
601
|
+
>>> kgs = kg.get_all_kgs()
|
|
602
|
+
>>> for kg_info in kgs:
|
|
603
|
+
... print(f"{kg_info['kg_name']} (ID: {kg_info['kg_id']})")
|
|
604
|
+
base kg v3 (ID: 14_base_kg_v3)
|
|
605
|
+
|
|
606
|
+
>>> # Get all KGs including unpublished ones with instance details
|
|
607
|
+
>>> kgs_with_instances = kg.get_all_kgs(
|
|
608
|
+
... include_unpublished=True,
|
|
609
|
+
... include_instances=True,
|
|
610
|
+
... include_terminated=True
|
|
611
|
+
... )
|
|
612
|
+
>>> for kg_info in kgs_with_instances:
|
|
613
|
+
... print(f"{kg_info['kg_name']} - {len(kg_info.get('instances', []))} instances")
|
|
614
|
+
"""
|
|
615
|
+
try:
|
|
616
|
+
kg_url = f"{self.polly_kg_neo4j_endpoint}/kg"
|
|
617
|
+
|
|
618
|
+
# Build query parameters
|
|
619
|
+
params = {}
|
|
620
|
+
if include_unpublished:
|
|
621
|
+
params["include_unpublished"] = "true"
|
|
622
|
+
if include_instances:
|
|
623
|
+
params["include_instances"] = "true"
|
|
624
|
+
if include_terminated:
|
|
625
|
+
params["include_terminated"] = "true"
|
|
626
|
+
|
|
627
|
+
response = self.session.get(kg_url, params=params)
|
|
628
|
+
handle_success_and_error_response(response)
|
|
629
|
+
|
|
630
|
+
data = response.json().get("data", [])
|
|
631
|
+
|
|
632
|
+
if not data:
|
|
633
|
+
raise ResourceNotFoundError(detail="No knowledge graphs found.")
|
|
634
|
+
|
|
635
|
+
return data
|
|
636
|
+
|
|
637
|
+
except Exception as e:
|
|
638
|
+
print(e)
|
|
639
|
+
raise
|
|
@@ -596,7 +596,7 @@ def _copy_remote_file(
|
|
|
596
596
|
part_id = i + 1
|
|
597
597
|
part = ctx.s3_client.upload_part_copy(
|
|
598
598
|
CopySource=src_params,
|
|
599
|
-
CopySourceRange=f"bytes={start}-{end-1}",
|
|
599
|
+
CopySourceRange=f"bytes={start}-{end - 1}",
|
|
600
600
|
Bucket=dest_bucket,
|
|
601
601
|
Key=dest_key,
|
|
602
602
|
UploadId=upload_id,
|
|
@@ -1,36 +1,47 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: polly_python
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.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
|
|
7
7
|
Project-URL: Tutorial Notebooks, https://github.com/ElucidataInc/polly-python
|
|
8
|
-
Requires-Python: <3.
|
|
8
|
+
Requires-Python: <3.15,>=3.9
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.md
|
|
11
|
-
Requires-Dist: cmapPy
|
|
12
|
-
Requires-Dist: cloudpathlib
|
|
11
|
+
Requires-Dist: cmapPy==4.0.1
|
|
12
|
+
Requires-Dist: cloudpathlib<1.0.0,>=0.19.0
|
|
13
13
|
Requires-Dist: retrying==1.3.4
|
|
14
14
|
Requires-Dist: rst2txt==1.1.0
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
15
|
+
Requires-Dist: mixpanel<5.0.0,>=4.10.0
|
|
16
|
+
Requires-Dist: Deprecated<2.0.0,>=1.2.12
|
|
17
|
+
Requires-Dist: pydantic<3.0.0,>=2.8.2
|
|
18
|
+
Requires-Dist: requests<=2.32.3,>=2.31.0
|
|
19
|
+
Requires-Dist: boto3<2.0.0,>=1.34.0
|
|
20
|
+
Requires-Dist: joblib==1.4.2
|
|
21
|
+
Requires-Dist: rich<14.0.0,>=13.0.0
|
|
22
|
+
Requires-Dist: tqdm==4.66.4
|
|
23
|
+
Requires-Dist: plotly==6.3.1
|
|
24
|
+
Requires-Dist: cryptography<=38.0.0; python_full_version >= "3.9.0" and python_full_version <= "3.9.1"
|
|
25
|
+
Requires-Dist: cryptography==46.0.2; python_full_version >= "3.9.2"
|
|
26
|
+
Requires-Dist: setuptools>=65.0.0; python_version >= "3.12"
|
|
27
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.9"
|
|
28
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.10"
|
|
29
|
+
Requires-Dist: pandas<=2.2.3,>=1.5.3; python_version == "3.11"
|
|
30
|
+
Requires-Dist: pandas<=2.2.3,>=2.1.0; python_version == "3.12"
|
|
31
|
+
Requires-Dist: pandas<=2.2.3,>=2.2.2; python_version == "3.13"
|
|
32
|
+
Requires-Dist: pandas<=2.2.3,>=2.2.2; python_version == "3.14"
|
|
33
|
+
Requires-Dist: numpy<=1.25.2,>=1.23.0; python_version == "3.9"
|
|
34
|
+
Requires-Dist: numpy<=2.2.2,>=1.23.0; python_version == "3.10"
|
|
35
|
+
Requires-Dist: numpy<=2.2.2,>=1.24.0; python_version == "3.11"
|
|
36
|
+
Requires-Dist: numpy<=2.2.2,>=1.26.0; python_version == "3.12"
|
|
37
|
+
Requires-Dist: numpy<=2.2.2,>=2.2.0; python_version == "3.13"
|
|
38
|
+
Requires-Dist: numpy<=2.2.2,>=2.2.0; python_version == "3.14"
|
|
30
39
|
Provides-Extra: testing
|
|
31
40
|
Requires-Dist: black; extra == "testing"
|
|
32
41
|
Requires-Dist: flake8; extra == "testing"
|
|
33
42
|
Requires-Dist: pytest; extra == "testing"
|
|
43
|
+
Requires-Dist: pytest-mock; extra == "testing"
|
|
44
|
+
Requires-Dist: moto; extra == "testing"
|
|
34
45
|
Dynamic: license-file
|
|
35
46
|
|
|
36
47
|
[](https://www.python.org/)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
cmapPy==4.0.1
|
|
2
|
+
cloudpathlib<1.0.0,>=0.19.0
|
|
3
|
+
retrying==1.3.4
|
|
4
|
+
rst2txt==1.1.0
|
|
5
|
+
mixpanel<5.0.0,>=4.10.0
|
|
6
|
+
Deprecated<2.0.0,>=1.2.12
|
|
7
|
+
pydantic<3.0.0,>=2.8.2
|
|
8
|
+
requests<=2.32.3,>=2.31.0
|
|
9
|
+
boto3<2.0.0,>=1.34.0
|
|
10
|
+
joblib==1.4.2
|
|
11
|
+
rich<14.0.0,>=13.0.0
|
|
12
|
+
tqdm==4.66.4
|
|
13
|
+
plotly==6.3.1
|
|
14
|
+
|
|
15
|
+
[:python_full_version >= "3.9.0" and python_full_version <= "3.9.1"]
|
|
16
|
+
cryptography<=38.0.0
|
|
17
|
+
|
|
18
|
+
[:python_full_version >= "3.9.2"]
|
|
19
|
+
cryptography==46.0.2
|
|
20
|
+
|
|
21
|
+
[:python_version == "3.10"]
|
|
22
|
+
pandas<=2.2.3,>=1.5.3
|
|
23
|
+
numpy<=2.2.2,>=1.23.0
|
|
24
|
+
|
|
25
|
+
[:python_version == "3.11"]
|
|
26
|
+
pandas<=2.2.3,>=1.5.3
|
|
27
|
+
numpy<=2.2.2,>=1.24.0
|
|
28
|
+
|
|
29
|
+
[:python_version == "3.12"]
|
|
30
|
+
pandas<=2.2.3,>=2.1.0
|
|
31
|
+
numpy<=2.2.2,>=1.26.0
|
|
32
|
+
|
|
33
|
+
[:python_version == "3.13"]
|
|
34
|
+
pandas<=2.2.3,>=2.2.2
|
|
35
|
+
numpy<=2.2.2,>=2.2.0
|
|
36
|
+
|
|
37
|
+
[:python_version == "3.14"]
|
|
38
|
+
pandas<=2.2.3,>=2.2.2
|
|
39
|
+
numpy<=2.2.2,>=2.2.0
|
|
40
|
+
|
|
41
|
+
[:python_version == "3.9"]
|
|
42
|
+
pandas<=2.2.3,>=1.5.3
|
|
43
|
+
numpy<=1.25.2,>=1.23.0
|
|
44
|
+
|
|
45
|
+
[:python_version >= "3.12"]
|
|
46
|
+
setuptools>=65.0.0
|
|
47
|
+
|
|
48
|
+
[testing]
|
|
49
|
+
black
|
|
50
|
+
flake8
|
|
51
|
+
pytest
|
|
52
|
+
pytest-mock
|
|
53
|
+
moto
|
|
@@ -120,9 +120,9 @@ class S3ClientManager:
|
|
|
120
120
|
def _init_client(self) -> S3SessionDetails:
|
|
121
121
|
if (self.omixatlas_id, self.copy_dest_omixatlas_id) not in self._cache:
|
|
122
122
|
session_details = self._get_autorefresh_session()
|
|
123
|
-
self._cache[
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
self._cache[(self.omixatlas_id, self.copy_dest_omixatlas_id)] = (
|
|
124
|
+
session_details
|
|
125
|
+
)
|
|
126
126
|
|
|
127
127
|
return self._cache[(self.omixatlas_id, self.copy_dest_omixatlas_id)]
|
|
128
128
|
|
|
@@ -3,7 +3,6 @@ from polly import helpers
|
|
|
3
3
|
from polly_services import polly_services_hlpr
|
|
4
4
|
import json
|
|
5
5
|
from polly import constants as const
|
|
6
|
-
from tabulate import tabulate
|
|
7
6
|
from functools import lru_cache
|
|
8
7
|
import pandas as pd
|
|
9
8
|
import copy
|
|
@@ -1217,9 +1216,9 @@ def upload_metadata_to_s3(
|
|
|
1217
1216
|
combined_metadata_file_path,
|
|
1218
1217
|
metadata_upload_details["metadata_directory"],
|
|
1219
1218
|
)
|
|
1220
|
-
file_status_dict[
|
|
1221
|
-
const.
|
|
1222
|
-
|
|
1219
|
+
file_status_dict[const.COMBINED_METADATA_FILE_NAME] = (
|
|
1220
|
+
const.UPLOAD_URL_CREATED
|
|
1221
|
+
)
|
|
1223
1222
|
except Exception as err:
|
|
1224
1223
|
if isinstance(err, S3UploadFailedError) and const.EXPIRED_TOKEN in str(err):
|
|
1225
1224
|
(
|
|
@@ -1241,13 +1240,13 @@ def upload_metadata_to_s3(
|
|
|
1241
1240
|
combined_metadata_file_path,
|
|
1242
1241
|
metadata_upload_details["metadata_directory"],
|
|
1243
1242
|
)
|
|
1244
|
-
file_status_dict[
|
|
1245
|
-
const.
|
|
1246
|
-
|
|
1243
|
+
file_status_dict[const.COMBINED_METADATA_FILE_NAME] = (
|
|
1244
|
+
const.UPLOAD_URL_CREATED
|
|
1245
|
+
)
|
|
1247
1246
|
else:
|
|
1248
|
-
file_status_dict[
|
|
1249
|
-
const.
|
|
1250
|
-
|
|
1247
|
+
file_status_dict[const.COMBINED_METADATA_FILE_NAME] = (
|
|
1248
|
+
const.UPLOAD_ERROR_CODE
|
|
1249
|
+
)
|
|
1251
1250
|
raise err
|
|
1252
1251
|
return file_status_dict
|
|
1253
1252
|
|
|
@@ -2673,11 +2672,4 @@ def convert_delete_datasets_res_dict_to_df(result_dict: dict):
|
|
|
2673
2672
|
df_list.append(df_1)
|
|
2674
2673
|
|
|
2675
2674
|
data_delete_df = pd.concat(df_list, axis=0, ignore_index=True)
|
|
2676
|
-
print(
|
|
2677
|
-
tabulate(
|
|
2678
|
-
data_delete_df,
|
|
2679
|
-
headers="keys",
|
|
2680
|
-
tablefmt="fancy_grid",
|
|
2681
|
-
maxcolwidths=[None, 10, None],
|
|
2682
|
-
)
|
|
2683
|
-
)
|
|
2675
|
+
print(data_delete_df.to_string(index=False, max_colwidth=10))
|
|
@@ -2,7 +2,6 @@ from polly_interfaces.ISchema import ISchema
|
|
|
2
2
|
from polly.errors import error_handler
|
|
3
3
|
from polly import constants as const
|
|
4
4
|
import json
|
|
5
|
-
from tabulate import tabulate
|
|
6
5
|
from polly import helpers
|
|
7
6
|
from polly_services import polly_services_hlpr
|
|
8
7
|
from polly_services.schema import schema_hlpr
|
|
@@ -148,13 +147,11 @@ class Schema(ISchema):
|
|
|
148
147
|
print("Schema has no errors")
|
|
149
148
|
else:
|
|
150
149
|
print(
|
|
151
|
-
"Schema insert/update/replace/validate didn
|
|
150
|
+
"Schema insert/update/replace/validate didn't go through because there are errors in "
|
|
152
151
|
+ "the schema. Those errors is summarised in the table below: "
|
|
153
152
|
)
|
|
154
153
|
print("\n")
|
|
155
|
-
print(
|
|
156
|
-
tabulate(error_res_combined, headers="keys", tablefmt="fancy_grid")
|
|
157
|
-
)
|
|
154
|
+
print(error_res_combined.to_string(index=False))
|
|
158
155
|
return error_res_combined
|
|
159
156
|
|
|
160
157
|
except Exception as err:
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
from pydantic import
|
|
1
|
+
from pydantic import (
|
|
2
|
+
BaseModel,
|
|
3
|
+
constr,
|
|
4
|
+
create_model,
|
|
5
|
+
field_validator,
|
|
6
|
+
ValidationError,
|
|
7
|
+
conint,
|
|
8
|
+
ValidationInfo,
|
|
9
|
+
)
|
|
2
10
|
from typing import Optional
|
|
3
11
|
import pandas as pd
|
|
4
12
|
import copy
|
|
@@ -21,19 +29,21 @@ class FieldType(str, Enum):
|
|
|
21
29
|
class AttributeModel(BaseModel):
|
|
22
30
|
original_name: constr(strict=True, min_length=1, max_length=50)
|
|
23
31
|
type: FieldType
|
|
24
|
-
is_keyword: Optional[bool]
|
|
25
|
-
is_array: Optional[bool]
|
|
26
|
-
is_column: Optional[bool]
|
|
27
|
-
is_curated: Optional[bool]
|
|
28
|
-
is_searchable: Optional[bool]
|
|
32
|
+
is_keyword: Optional[bool] = None
|
|
33
|
+
is_array: Optional[bool] = None
|
|
34
|
+
is_column: Optional[bool] = None
|
|
35
|
+
is_curated: Optional[bool] = None
|
|
36
|
+
is_searchable: Optional[bool] = None
|
|
29
37
|
filter_size: conint(ge=1, le=3000) = 500
|
|
30
38
|
display_name: constr(strict=True, min_length=1, max_length=50)
|
|
31
39
|
description: constr(strict=True, min_length=1, max_length=300)
|
|
32
|
-
is_ontology: Optional[bool]
|
|
33
|
-
is_filter: Optional[bool]
|
|
40
|
+
is_ontology: Optional[bool] = None
|
|
41
|
+
is_filter: Optional[bool] = None
|
|
34
42
|
|
|
35
|
-
@
|
|
36
|
-
|
|
43
|
+
@field_validator("is_filter")
|
|
44
|
+
@classmethod
|
|
45
|
+
def is_filter_check(cls, is_filter, info: ValidationInfo):
|
|
46
|
+
values = info.data
|
|
37
47
|
if is_filter:
|
|
38
48
|
if not values.get("is_keyword"):
|
|
39
49
|
raise ValueError(
|
|
@@ -110,10 +120,15 @@ def _validate_schema_values(field_dict: dict):
|
|
|
110
120
|
Create pydantic model to validate schema values
|
|
111
121
|
"""
|
|
112
122
|
field_name = field_dict["field_name"]
|
|
123
|
+
|
|
124
|
+
# Create a field_validator for the field_name in V2 style
|
|
125
|
+
def check_field_name_wrapper(cls, value):
|
|
126
|
+
return _check_field_name(cls, value)
|
|
127
|
+
|
|
113
128
|
validators = {
|
|
114
|
-
"check_field_name":
|
|
115
|
-
|
|
116
|
-
)
|
|
129
|
+
"check_field_name": field_validator("field_name")(
|
|
130
|
+
classmethod(check_field_name_wrapper)
|
|
131
|
+
)
|
|
117
132
|
}
|
|
118
133
|
schema_model = _build_schema_validation_model(field_name, validators)
|
|
119
134
|
try:
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
description_file = README.md
|
|
3
|
+
name = polly_python
|
|
4
|
+
version = attr: polly.__version__
|
|
5
|
+
description = Polly SDK
|
|
6
|
+
url = https://github.com/ElucidataInc/polly-python
|
|
7
|
+
long_description = file: README.md
|
|
8
|
+
long_description_content_type = text/markdown
|
|
9
|
+
project_urls =
|
|
10
|
+
Documentation = https://docs.elucidata.io
|
|
11
|
+
Tutorial Notebooks = https://github.com/ElucidataInc/polly-python
|
|
12
|
+
|
|
13
|
+
[options]
|
|
14
|
+
packages = find:
|
|
15
|
+
setup_requires = wheel
|
|
16
|
+
python_requires = >=3.9, <3.15
|
|
17
|
+
install_requires =
|
|
18
|
+
cmapPy == 4.0.1
|
|
19
|
+
cloudpathlib >= 0.19.0, < 1.0.0
|
|
20
|
+
retrying == 1.3.4
|
|
21
|
+
rst2txt == 1.1.0
|
|
22
|
+
mixpanel >= 4.10.0, < 5.0.0
|
|
23
|
+
Deprecated >= 1.2.12, < 2.0.0
|
|
24
|
+
pydantic >= 2.8.2, < 3.0.0
|
|
25
|
+
requests >= 2.31.0, <= 2.32.3
|
|
26
|
+
boto3 >= 1.34.0, < 2.0.0
|
|
27
|
+
joblib == 1.4.2
|
|
28
|
+
rich >= 13.0.0, < 14.0.0
|
|
29
|
+
tqdm == 4.66.4
|
|
30
|
+
plotly == 6.3.1
|
|
31
|
+
cryptography <= 38.0.0 ; python_full_version >= '3.9.0' and python_full_version <= '3.9.1'
|
|
32
|
+
cryptography == 46.0.2 ; python_full_version >= '3.9.2'
|
|
33
|
+
setuptools >= 65.0.0 ; python_version >= '3.12'
|
|
34
|
+
|
|
35
|
+
pandas >= 1.5.3, <= 2.2.3 ; python_version == '3.9'
|
|
36
|
+
pandas >= 1.5.3, <= 2.2.3 ; python_version == '3.10'
|
|
37
|
+
pandas >= 1.5.3, <= 2.2.3 ; python_version == '3.11'
|
|
38
|
+
pandas >= 2.1.0, <= 2.2.3 ; python_version == '3.12'
|
|
39
|
+
pandas >= 2.2.2, <= 2.2.3 ; python_version == '3.13'
|
|
40
|
+
pandas >= 2.2.2, <= 2.2.3 ; python_version == '3.14'
|
|
41
|
+
|
|
42
|
+
numpy >= 1.23.0, <= 1.25.2 ; python_version == '3.9'
|
|
43
|
+
numpy >= 1.23.0, <= 2.2.2 ; python_version == '3.10'
|
|
44
|
+
numpy >= 1.24.0, <= 2.2.2 ; python_version == '3.11'
|
|
45
|
+
numpy >= 1.26.0, <= 2.2.2 ; python_version == '3.12'
|
|
46
|
+
numpy >= 2.2.0, <= 2.2.2 ; python_version == '3.13'
|
|
47
|
+
numpy >= 2.2.0, <= 2.2.2 ; python_version == '3.14'
|
|
48
|
+
include_package_data = True
|
|
49
|
+
|
|
50
|
+
[options.packages.find]
|
|
51
|
+
exclude =
|
|
52
|
+
tests*
|
|
53
|
+
build*
|
|
54
|
+
dist*
|
|
55
|
+
docs*
|
|
56
|
+
consumption_pipelines*
|
|
57
|
+
|
|
58
|
+
[options.extras_require]
|
|
59
|
+
testing =
|
|
60
|
+
black
|
|
61
|
+
flake8
|
|
62
|
+
pytest
|
|
63
|
+
pytest-mock
|
|
64
|
+
moto
|
|
65
|
+
|
|
66
|
+
[flake8]
|
|
67
|
+
exclude = build,.git, docs, dist, consumption_pipelines
|
|
68
|
+
extend-ignore = E731,W503
|
|
69
|
+
max-line-length = 127
|
|
70
|
+
max-complexity = 10
|
|
71
|
+
|
|
72
|
+
[black]
|
|
73
|
+
exclude = build,.git, docs, dist, consumption_pipelines
|
|
74
|
+
|
|
75
|
+
[egg_info]
|
|
76
|
+
tag_build =
|
|
77
|
+
tag_date = 0
|
|
78
|
+
|
|
@@ -222,3 +222,124 @@ def test_get_schema_success(mocker):
|
|
|
222
222
|
result = obj.get_schema()
|
|
223
223
|
|
|
224
224
|
assert "Disease" in result["schema"]["labels"]
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def test_get_all_kgs_success(mocker):
|
|
228
|
+
mocker.patch("polly.polly_kg._get_default_kg", return_value=("kg1", "v1"))
|
|
229
|
+
|
|
230
|
+
obj = PollyKG(token=token)
|
|
231
|
+
mock_response = mocker.Mock()
|
|
232
|
+
mock_response.status_code = 200
|
|
233
|
+
mock_response.json.return_value = {
|
|
234
|
+
"data": [
|
|
235
|
+
{
|
|
236
|
+
"kg_id": "14_base_kg_v3",
|
|
237
|
+
"kg_name": "base kg v3",
|
|
238
|
+
"kg_description": "Base KG v",
|
|
239
|
+
"version_id": 1,
|
|
240
|
+
"created_at": 1756115807076,
|
|
241
|
+
"published": True,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"kg_id": "15_test_kg",
|
|
245
|
+
"kg_name": "test kg",
|
|
246
|
+
"kg_description": "Test KG",
|
|
247
|
+
"version_id": 2,
|
|
248
|
+
"created_at": 1756115900000,
|
|
249
|
+
"published": False,
|
|
250
|
+
},
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
mocker.patch.object(obj.session, "get", return_value=mock_response)
|
|
255
|
+
result = obj.get_all_kgs()
|
|
256
|
+
|
|
257
|
+
assert isinstance(result, list)
|
|
258
|
+
assert len(result) == 2
|
|
259
|
+
assert result[0]["kg_id"] == "14_base_kg_v3"
|
|
260
|
+
assert result[0]["kg_name"] == "base kg v3"
|
|
261
|
+
assert result[0]["version_id"] == 1
|
|
262
|
+
assert result[0]["published"] is True
|
|
263
|
+
assert result[1]["kg_id"] == "15_test_kg"
|
|
264
|
+
assert result[1]["published"] is False
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def test_get_all_kgs_with_parameters(mocker):
|
|
268
|
+
mocker.patch("polly.polly_kg._get_default_kg", return_value=("kg1", "v1"))
|
|
269
|
+
|
|
270
|
+
obj = PollyKG(token=token)
|
|
271
|
+
mock_response = mocker.Mock()
|
|
272
|
+
mock_response.status_code = 200
|
|
273
|
+
mock_response.json.return_value = {
|
|
274
|
+
"data": [
|
|
275
|
+
{
|
|
276
|
+
"kg_id": "14_base_kg_v3",
|
|
277
|
+
"kg_name": "base kg v3",
|
|
278
|
+
"kg_description": "Base KG v",
|
|
279
|
+
"version_id": 1,
|
|
280
|
+
"created_at": 1756115807076,
|
|
281
|
+
"published": True,
|
|
282
|
+
"instances": [
|
|
283
|
+
{
|
|
284
|
+
"instance_id": "inst_123",
|
|
285
|
+
"instance_type": "t3.medium",
|
|
286
|
+
"is_terminated": False,
|
|
287
|
+
"default_instance": True,
|
|
288
|
+
"org_id": 1,
|
|
289
|
+
"created_at": 1756115807076,
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"kg_id": "15_test_kg",
|
|
295
|
+
"kg_name": "test kg",
|
|
296
|
+
"kg_description": "Test KG",
|
|
297
|
+
"version_id": 2,
|
|
298
|
+
"created_at": 1756115900000,
|
|
299
|
+
"published": False,
|
|
300
|
+
"instances": [
|
|
301
|
+
{
|
|
302
|
+
"instance_id": "inst_456",
|
|
303
|
+
"instance_type": "t3.large",
|
|
304
|
+
"is_terminated": True,
|
|
305
|
+
"default_instance": False,
|
|
306
|
+
"org_id": 1,
|
|
307
|
+
"created_at": 1756115900000,
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
mock_get = mocker.patch.object(obj.session, "get", return_value=mock_response)
|
|
315
|
+
result = obj.get_all_kgs(
|
|
316
|
+
include_unpublished=True, include_instances=True, include_terminated=True
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# Verify the API was called with correct parameters
|
|
320
|
+
mock_get.assert_called_once()
|
|
321
|
+
call_kwargs = mock_get.call_args.kwargs
|
|
322
|
+
assert "params" in call_kwargs
|
|
323
|
+
assert call_kwargs["params"] == {
|
|
324
|
+
"include_unpublished": "true",
|
|
325
|
+
"include_instances": "true",
|
|
326
|
+
"include_terminated": "true",
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
# Verify the response structure
|
|
330
|
+
assert isinstance(result, list)
|
|
331
|
+
assert len(result) == 2
|
|
332
|
+
assert result[0]["kg_id"] == "14_base_kg_v3"
|
|
333
|
+
assert result[0]["published"] is True
|
|
334
|
+
assert "instances" in result[0]
|
|
335
|
+
assert len(result[0]["instances"]) == 1
|
|
336
|
+
assert result[0]["instances"][0]["instance_id"] == "inst_123"
|
|
337
|
+
assert result[0]["instances"][0]["instance_type"] == "t3.medium"
|
|
338
|
+
assert result[0]["instances"][0]["is_terminated"] is False
|
|
339
|
+
|
|
340
|
+
assert result[1]["kg_id"] == "15_test_kg"
|
|
341
|
+
assert result[1]["published"] is False
|
|
342
|
+
assert "instances" in result[1]
|
|
343
|
+
assert len(result[1]["instances"]) == 1
|
|
344
|
+
assert result[1]["instances"][0]["instance_id"] == "inst_456"
|
|
345
|
+
assert result[1]["instances"][0]["is_terminated"] is True
|
|
@@ -1018,7 +1018,7 @@ def test_validate_schema_function_field_name_having_original_name_empty(
|
|
|
1018
1018
|
msg_val = res_df.iloc[0]["message"]
|
|
1019
1019
|
|
|
1020
1020
|
assert isinstance(res_df, pd.DataFrame)
|
|
1021
|
-
assert "
|
|
1021
|
+
assert "String should have at least 1 character" in msg_val
|
|
1022
1022
|
|
|
1023
1023
|
|
|
1024
1024
|
def test_validate_schema_function_field_name_having_original_name_greater_than_50_chars(
|
|
@@ -1039,7 +1039,7 @@ def test_validate_schema_function_field_name_having_original_name_greater_than_5
|
|
|
1039
1039
|
msg_val = res_df.iloc[0]["message"]
|
|
1040
1040
|
|
|
1041
1041
|
assert isinstance(res_df, pd.DataFrame)
|
|
1042
|
-
assert "
|
|
1042
|
+
assert "String should have at most 50 characters" in msg_val
|
|
1043
1043
|
|
|
1044
1044
|
|
|
1045
1045
|
def test_validate_schema_function_field_name_having_type_is_not_supported(
|
|
@@ -1061,8 +1061,7 @@ def test_validate_schema_function_field_name_having_type_is_not_supported(
|
|
|
1061
1061
|
|
|
1062
1062
|
assert isinstance(res_df, pd.DataFrame)
|
|
1063
1063
|
assert (
|
|
1064
|
-
"
|
|
1065
|
-
in msg_val
|
|
1064
|
+
"Input should be 'boolean', 'integer', 'float', 'text' or 'object'" in msg_val
|
|
1066
1065
|
)
|
|
1067
1066
|
|
|
1068
1067
|
|
|
@@ -1084,7 +1083,7 @@ def test_validate_schema_function_field_name_having_is_array_string(
|
|
|
1084
1083
|
msg_val = res_df.iloc[0]["message"]
|
|
1085
1084
|
|
|
1086
1085
|
assert isinstance(res_df, pd.DataFrame)
|
|
1087
|
-
assert "
|
|
1086
|
+
assert "Input should be a valid boolean" in msg_val
|
|
1088
1087
|
|
|
1089
1088
|
|
|
1090
1089
|
def test_validate_schema_function_field_name_having_is_keyword_string(
|
|
@@ -1104,7 +1103,7 @@ def test_validate_schema_function_field_name_having_is_keyword_string(
|
|
|
1104
1103
|
res_df = omix_obj.validate_schema(test_data)
|
|
1105
1104
|
msg_val = res_df.iloc[0]["message"]
|
|
1106
1105
|
assert isinstance(res_df, pd.DataFrame)
|
|
1107
|
-
assert "
|
|
1106
|
+
assert "Input should be a valid boolean" in msg_val
|
|
1108
1107
|
|
|
1109
1108
|
|
|
1110
1109
|
def test_validate_schema_function_field_name_having_filter_size_less(
|
|
@@ -1125,7 +1124,7 @@ def test_validate_schema_function_field_name_having_filter_size_less(
|
|
|
1125
1124
|
res_df = omix_obj.validate_schema(test_data)
|
|
1126
1125
|
msg_val = res_df.iloc[0]["message"]
|
|
1127
1126
|
assert isinstance(res_df, pd.DataFrame)
|
|
1128
|
-
assert "
|
|
1127
|
+
assert "Input should be greater than or equal to 1" in msg_val
|
|
1129
1128
|
|
|
1130
1129
|
|
|
1131
1130
|
def test_validate_schema_function_field_name_having_filter_size_greater(
|
|
@@ -1145,7 +1144,7 @@ def test_validate_schema_function_field_name_having_filter_size_greater(
|
|
|
1145
1144
|
res_df = omix_obj.validate_schema(test_data)
|
|
1146
1145
|
msg_val = res_df.iloc[0]["message"]
|
|
1147
1146
|
assert isinstance(res_df, pd.DataFrame)
|
|
1148
|
-
assert "
|
|
1147
|
+
assert "Input should be less than or equal to 3000" in msg_val
|
|
1149
1148
|
|
|
1150
1149
|
|
|
1151
1150
|
def test_validate_schema_function_field_name_having_display_name_empty(
|
|
@@ -1167,7 +1166,7 @@ def test_validate_schema_function_field_name_having_display_name_empty(
|
|
|
1167
1166
|
msg_val = res_df.iloc[0]["message"]
|
|
1168
1167
|
assert isinstance(res_df, pd.DataFrame)
|
|
1169
1168
|
assert "display_name" in loc
|
|
1170
|
-
assert "
|
|
1169
|
+
assert "String should have at least 1 character" in msg_val
|
|
1171
1170
|
|
|
1172
1171
|
|
|
1173
1172
|
def test_validate_schema_function_field_name_having_display_name_greater(
|
|
@@ -1190,7 +1189,7 @@ def test_validate_schema_function_field_name_having_display_name_greater(
|
|
|
1190
1189
|
msg_val = res_df.iloc[0]["message"]
|
|
1191
1190
|
assert isinstance(res_df, pd.DataFrame)
|
|
1192
1191
|
assert "display_name" in loc
|
|
1193
|
-
assert "
|
|
1192
|
+
assert "String should have at most 50 characters" in msg_val
|
|
1194
1193
|
|
|
1195
1194
|
|
|
1196
1195
|
def test_validate_schema_function_field_name_having_is_filter_is_keyword(
|
|
@@ -1272,7 +1271,7 @@ def test_validate_schema_function_having_original_name_int(
|
|
|
1272
1271
|
attribute_val = res_df.iloc[0]["attribute"]
|
|
1273
1272
|
assert isinstance(res_df, pd.DataFrame)
|
|
1274
1273
|
assert attribute_val == "original_name"
|
|
1275
|
-
assert "
|
|
1274
|
+
assert "Input should be a valid string" in msg_val
|
|
1276
1275
|
|
|
1277
1276
|
|
|
1278
1277
|
def test_validate_schema_function_having_field_size_str(
|
|
@@ -1294,7 +1293,7 @@ def test_validate_schema_function_having_field_size_str(
|
|
|
1294
1293
|
attribute_val = res_df.iloc[0]["attribute"]
|
|
1295
1294
|
assert isinstance(res_df, pd.DataFrame)
|
|
1296
1295
|
assert attribute_val == "filter_size"
|
|
1297
|
-
assert "
|
|
1296
|
+
assert "Input should be a valid integer" in msg_val
|
|
1298
1297
|
|
|
1299
1298
|
|
|
1300
1299
|
# def test_download_metadata():
|
|
@@ -2545,21 +2544,9 @@ def validate_schema_mock_fixture(
|
|
|
2545
2544
|
get_omixatlas_mock_fixture_polly_services,
|
|
2546
2545
|
get_ingestion_test_1_schema_fixture,
|
|
2547
2546
|
):
|
|
2548
|
-
#
|
|
2549
|
-
#
|
|
2550
|
-
|
|
2551
|
-
# )
|
|
2552
|
-
|
|
2553
|
-
mocker.patch(
|
|
2554
|
-
polly_services.polly_services_hlpr.__name__ + ".get_omixatlas",
|
|
2555
|
-
return_value=get_omixatlas_mock_fixture_polly_services,
|
|
2556
|
-
)
|
|
2557
|
-
|
|
2558
|
-
Polly.auth(testpolly_token, env="testpolly")
|
|
2559
|
-
omix_obj = omixatlas.OmixAtlas()
|
|
2560
|
-
|
|
2561
|
-
body = get_ingestion_test_1_schema_fixture
|
|
2562
|
-
error_df = omix_obj.validate_schema(body)
|
|
2547
|
+
# Return an empty DataFrame (no validation errors) for positive test cases
|
|
2548
|
+
# This fixture is used to mock validate_schema to skip actual validation
|
|
2549
|
+
error_df = pd.DataFrame()
|
|
2563
2550
|
return error_df
|
|
2564
2551
|
|
|
2565
2552
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
import boto3
|
|
3
|
-
from moto import
|
|
3
|
+
from moto import mock_aws
|
|
4
4
|
from polly.s3_utils import copy_file
|
|
5
5
|
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ def aws_credentials():
|
|
|
16
16
|
|
|
17
17
|
@pytest.fixture
|
|
18
18
|
def s3_client(aws_credentials):
|
|
19
|
-
with
|
|
19
|
+
with mock_aws():
|
|
20
20
|
conn = boto3.client("s3", region_name="us-east-1")
|
|
21
21
|
yield conn
|
|
22
22
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "4.2.0"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
cmapPy<=4.0.1
|
|
2
|
-
cloudpathlib>=0.15.0
|
|
3
|
-
retrying==1.3.4
|
|
4
|
-
rst2txt==1.1.0
|
|
5
|
-
python-jose==3.3.0
|
|
6
|
-
mixpanel==4.10.0
|
|
7
|
-
Deprecated>=1.2.12
|
|
8
|
-
pytest>=6.2.5
|
|
9
|
-
cryptography<=38.0.0,>=37.0.1
|
|
10
|
-
numpy<=1.26.4
|
|
11
|
-
requests==2.28.1
|
|
12
|
-
tabulate==0.9.0
|
|
13
|
-
|
|
14
|
-
[:python_version >= "3.7"]
|
|
15
|
-
plotly>=5.0.0
|
|
16
|
-
pandas<=2.2.2,>=1.3.5
|
|
17
|
-
pydantic==1.10.12
|
|
18
|
-
boto3<2.0,>=1.24.0
|
|
19
|
-
botocore<2.0,>=1.27.0
|
|
20
|
-
joblib>=1.2.0
|
|
21
|
-
tqdm==4.65.0
|
|
22
|
-
|
|
23
|
-
[testing]
|
|
24
|
-
black
|
|
25
|
-
flake8
|
|
26
|
-
pytest
|
polly_python-4.2.0/setup.cfg
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
[metadata]
|
|
2
|
-
description_file = README.md
|
|
3
|
-
name = polly_python
|
|
4
|
-
version = attr: polly.__version__
|
|
5
|
-
description = Polly SDK
|
|
6
|
-
url = https://github.com/ElucidataInc/polly-python
|
|
7
|
-
long_description = file: README.md
|
|
8
|
-
long_description_content_type = text/markdown
|
|
9
|
-
project_urls =
|
|
10
|
-
Documentation = https://docs.elucidata.io
|
|
11
|
-
Tutorial Notebooks = https://github.com/ElucidataInc/polly-python
|
|
12
|
-
|
|
13
|
-
[options]
|
|
14
|
-
packages = find:
|
|
15
|
-
setup_requires = wheel
|
|
16
|
-
python_requires = >=3.9, <3.12
|
|
17
|
-
install_requires =
|
|
18
|
-
cmapPy <= 4.0.1
|
|
19
|
-
cloudpathlib >= 0.15.0
|
|
20
|
-
retrying == 1.3.4
|
|
21
|
-
rst2txt == 1.1.0
|
|
22
|
-
python-jose == 3.3.0
|
|
23
|
-
mixpanel == 4.10.0
|
|
24
|
-
Deprecated >= 1.2.12
|
|
25
|
-
pytest >= 6.2.5
|
|
26
|
-
cryptography >= 37.0.1, <= 38.0.0
|
|
27
|
-
plotly >= 5.0.0 ; python_version >= '3.7'
|
|
28
|
-
pandas >= 1.3.5, <= 2.2.2 ; python_version >= '3.7'
|
|
29
|
-
numpy <= 1.26.4
|
|
30
|
-
pydantic == 1.10.12 ; python_version >= '3.7'
|
|
31
|
-
requests == 2.28.1
|
|
32
|
-
boto3 >= 1.24.0, <2.0; python_version >= '3.7'
|
|
33
|
-
botocore >= 1.27.0, <2.0; python_version >= '3.7'
|
|
34
|
-
joblib >= 1.2.0 ; python_version >= '3.7'
|
|
35
|
-
tabulate == 0.9.0
|
|
36
|
-
tqdm == 4.65.0 ; python_version >= '3.7'
|
|
37
|
-
include_package_data = True
|
|
38
|
-
|
|
39
|
-
[options.packages.find]
|
|
40
|
-
exclude =
|
|
41
|
-
tests*
|
|
42
|
-
build*
|
|
43
|
-
dist*
|
|
44
|
-
docs*
|
|
45
|
-
consumption_pipelines*
|
|
46
|
-
|
|
47
|
-
[options.extras_require]
|
|
48
|
-
testing =
|
|
49
|
-
black
|
|
50
|
-
flake8
|
|
51
|
-
pytest
|
|
52
|
-
|
|
53
|
-
[flake8]
|
|
54
|
-
exclude = build,.git, docs, dist, consumption_pipelines
|
|
55
|
-
extend-ignore = E731,W503
|
|
56
|
-
max-line-length = 127
|
|
57
|
-
max-complexity = 10
|
|
58
|
-
|
|
59
|
-
[black]
|
|
60
|
-
exclude = build,.git, docs, dist, consumption_pipelines
|
|
61
|
-
|
|
62
|
-
[egg_info]
|
|
63
|
-
tag_build =
|
|
64
|
-
tag_date = 0
|
|
65
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|