dcicutils 8.7.1.1b9__tar.gz → 8.7.1.1b12__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/PKG-INFO +1 -1
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/portal_object_utils.py +32 -27
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/portal_utils.py +1 -1
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/schema_utils.py +2 -2
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/structured_data.py +12 -10
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/pyproject.toml +1 -1
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/LICENSE.txt +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/README.rst +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/__init__.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/base.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/beanstalk_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/bundle_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/cloudformation_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/codebuild_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/command_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/common.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/contribution_scripts.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/contribution_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/creds_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/data_readers.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/data_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/deployment_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/diff_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/docker_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ecr_scripts.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ecr_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ecs_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/env_base.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/env_manager.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/env_scripts.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/env_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/env_utils_legacy.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/es_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/exceptions.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ff_mocks.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ff_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/file_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/function_cache_decorator.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/glacier_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/jh_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/kibana/dashboards.json +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/kibana/readme.md +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/lang_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/c4-infrastructure.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/c4-python-infrastructure.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-common-server.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-common.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-gpl-pipeline.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-pipeline.jsonc +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/log_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/misc_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/obfuscation_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/opensearch_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/project_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/qa_checkers.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/qa_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/redis_tools.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/redis_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/s3_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/scripts/publish_to_pypi.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/scripts/run_license_checker.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/secrets_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/sheet_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/snapshot_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/ssl_certificate_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/task_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/tmpfile_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/trace_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/validation_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/variant_utils.py +0 -0
- {dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/zip_utils.py +0 -0
@@ -1,6 +1,5 @@
|
|
1
1
|
from copy import deepcopy
|
2
2
|
from functools import lru_cache
|
3
|
-
import re
|
4
3
|
from typing import Any, List, Optional, Tuple, Type, Union
|
5
4
|
from dcicutils.data_readers import RowReader
|
6
5
|
from dcicutils.misc_utils import create_readonly_object
|
@@ -14,28 +13,28 @@ class PortalObject:
|
|
14
13
|
|
15
14
|
_PROPERTY_DELETION_SENTINEL = RowReader.CELL_DELETION_SENTINEL
|
16
15
|
|
17
|
-
def __init__(self,
|
18
|
-
self._portal = portal
|
16
|
+
def __init__(self, portal_object: dict, portal: Portal = None, type: Optional[str] = None) -> None:
|
19
17
|
self._data = portal_object
|
20
|
-
self.
|
18
|
+
self._portal = portal
|
19
|
+
self._type = type if isinstance(type, str) and type else None
|
21
20
|
|
22
21
|
@property
|
23
|
-
def data(self):
|
22
|
+
def data(self) -> dict:
|
24
23
|
return self._data
|
25
24
|
|
26
25
|
@property
|
27
|
-
def portal(self):
|
26
|
+
def portal(self) -> Optional[Portal]:
|
28
27
|
return self._portal
|
29
28
|
|
30
29
|
@property
|
31
30
|
@lru_cache(maxsize=1)
|
32
|
-
def type(self):
|
31
|
+
def type(self) -> Optional[str]:
|
33
32
|
return self._type or Portal.get_schema_type(self._data)
|
34
33
|
|
35
34
|
@property
|
36
35
|
@lru_cache(maxsize=1)
|
37
|
-
def types(self):
|
38
|
-
return self._type
|
36
|
+
def types(self) -> Optional[List[str]]:
|
37
|
+
return [self._type] if self._type else Portal.get_schema_types(self._data)
|
39
38
|
|
40
39
|
@property
|
41
40
|
@lru_cache(maxsize=1)
|
@@ -44,22 +43,22 @@ class PortalObject:
|
|
44
43
|
|
45
44
|
@property
|
46
45
|
@lru_cache(maxsize=1)
|
47
|
-
def schema(self):
|
48
|
-
return self._portal.get_schema(self.type)
|
46
|
+
def schema(self) -> Optional[dict]:
|
47
|
+
return self._portal.get_schema(self.type) if self._portal else None
|
49
48
|
|
50
49
|
def copy(self) -> PortalObject:
|
51
|
-
return PortalObject(
|
50
|
+
return PortalObject(deepcopy(self.data), portal=self.portal, type=self.type)
|
52
51
|
|
53
52
|
@property
|
54
53
|
@lru_cache(maxsize=1)
|
55
|
-
def identifying_properties(self) -> List[str]:
|
54
|
+
def identifying_properties(self) -> Optional[List[str]]:
|
56
55
|
"""
|
57
56
|
Returns the list of all identifying property names of this Portal object which actually have values.
|
58
57
|
Implicitly include "uuid" and "identifier" properties as identifying properties if they are actually
|
59
58
|
properties in the object schema, and favor these (first); defavor "aliases"; no other ordering defined.
|
60
59
|
"""
|
61
60
|
if not (schema := self.schema) or not (schema_identifying_properties := schema.get("identifyingProperties")):
|
62
|
-
return
|
61
|
+
return None
|
63
62
|
identifying_properties = []
|
64
63
|
for identifying_property in schema_identifying_properties:
|
65
64
|
if identifying_property not in ["uuid", "identifier", "aliases"]:
|
@@ -71,17 +70,21 @@ class PortalObject:
|
|
71
70
|
identifying_properties.insert(0, "uuid")
|
72
71
|
if "aliases" in schema_identifying_properties and self._data.get("aliases"):
|
73
72
|
identifying_properties.append("aliases")
|
74
|
-
return identifying_properties
|
73
|
+
return identifying_properties or None
|
75
74
|
|
76
75
|
@property
|
77
76
|
@lru_cache(maxsize=1)
|
78
|
-
def identifying_paths(self) -> List[str]:
|
77
|
+
def identifying_paths(self) -> Optional[List[str]]:
|
79
78
|
"""
|
80
79
|
Returns a list of the possible Portal URL paths identifying this Portal object.
|
81
80
|
"""
|
82
|
-
if not (identifying_properties := self.identifying_properties):
|
83
|
-
return []
|
84
81
|
identifying_paths = []
|
82
|
+
if not (identifying_properties := self.identifying_properties):
|
83
|
+
if self.uuid:
|
84
|
+
if self.type:
|
85
|
+
identifying_paths.append(f"/{self.type}/{self.uuid}")
|
86
|
+
identifying_paths.append(f"/{self.uuid}")
|
87
|
+
return identifying_paths
|
85
88
|
for identifying_property in identifying_properties:
|
86
89
|
if (identifying_value := self._data.get(identifying_property)):
|
87
90
|
if identifying_property == "uuid":
|
@@ -96,12 +99,14 @@ class PortalObject:
|
|
96
99
|
# not work but /FileSet/UW_FILE-SET_COLO-829BL_HI-C_1 does work.
|
97
100
|
elif isinstance(identifying_value, list):
|
98
101
|
for identifying_value_item in identifying_value:
|
99
|
-
|
102
|
+
if self.type:
|
103
|
+
identifying_paths.append(f"/{self.type}/{identifying_value_item}")
|
100
104
|
identifying_paths.append(f"/{identifying_value_item}")
|
101
105
|
else:
|
102
|
-
|
106
|
+
if self.type:
|
107
|
+
identifying_paths.append(f"/{self.type}/{identifying_value}")
|
103
108
|
identifying_paths.append(f"/{identifying_value}")
|
104
|
-
return identifying_paths
|
109
|
+
return identifying_paths or None
|
105
110
|
|
106
111
|
@property
|
107
112
|
@lru_cache(maxsize=1)
|
@@ -118,9 +123,11 @@ class PortalObject:
|
|
118
123
|
|
119
124
|
def _lookup(self, raw: bool = False) -> Tuple[Optional[PortalObject], Optional[str]]:
|
120
125
|
try:
|
121
|
-
|
122
|
-
|
123
|
-
|
126
|
+
if identifying_paths := self.identifying_paths:
|
127
|
+
for identifying_path in identifying_paths:
|
128
|
+
if (value := self._portal.get(identifying_path, raw=raw)) and (value.status_code == 200):
|
129
|
+
return PortalObject(value.json(),
|
130
|
+
portal=self._portal, type=self.type if raw else None), identifying_path
|
124
131
|
except Exception:
|
125
132
|
pass
|
126
133
|
return None, self.identifying_path
|
@@ -139,8 +146,6 @@ class PortalObject:
|
|
139
146
|
return {}
|
140
147
|
return PortalObject._compare(this_data, comparing_data)
|
141
148
|
|
142
|
-
_ARRAY_KEY_REGULAR_EXPRESSION = re.compile(rf"^({Schema._ARRAY_NAME_SUFFIX_CHAR}\d+)$")
|
143
|
-
|
144
149
|
@staticmethod
|
145
150
|
def _compare(a: Any, b: Any, _path: Optional[str] = None) -> dict:
|
146
151
|
def diff_creating(value: Any) -> object: # noqa
|
@@ -175,7 +180,7 @@ class PortalObject:
|
|
175
180
|
else:
|
176
181
|
if index < len(b):
|
177
182
|
diffs[path] = diff_deleting(b[index])
|
178
|
-
elif len(b)
|
183
|
+
elif index < len(b):
|
179
184
|
diffs.update(PortalObject._compare(a[index], b[index], _path=path))
|
180
185
|
else:
|
181
186
|
diffs[path] = diff_creating(a[index])
|
@@ -28,7 +28,7 @@ class Portal:
|
|
28
28
|
"""
|
29
29
|
This is meant to be an Über wrapper for Portal access. It can be created in a variety of ways:
|
30
30
|
1. From a (Portal) .ini file (e.g. development.ini).
|
31
|
-
2. From a key dictionary, containing "key" and "secret" property values.
|
31
|
+
2. From a key dictionary, containing "key" and "secret" and (optional) "server" property values.
|
32
32
|
3. From a key pair tuple, containing (in order) a key and secret values.
|
33
33
|
4. From a keys .json file residing in ~/.{app}-keys.json where the given "app" value is either "smaht", "cgap",
|
34
34
|
or "fourfront"; where is assumed to contain a dictionary with a key for the given "env" value, e.g. smaht-local;
|
@@ -189,9 +189,9 @@ def get_one_of_formats(schema: Dict[str, Any]) -> List[str]:
|
|
189
189
|
|
190
190
|
class Schema:
|
191
191
|
|
192
|
-
def __init__(self, schema: dict,
|
192
|
+
def __init__(self, schema: dict, type: Optional[str] = None) -> None:
|
193
193
|
self._data = schema if isinstance(schema, dict) else (schema.data if isinstance(schema, Schema) else {})
|
194
|
-
self._type = (isinstance(
|
194
|
+
self._type = (type if isinstance(type, str) else "") or Schema.type_name(self._data.get("title", ""))
|
195
195
|
|
196
196
|
@property
|
197
197
|
def data(self) -> dict:
|
@@ -16,6 +16,7 @@ from dcicutils.misc_utils import (create_dict, create_readonly_object, load_json
|
|
16
16
|
split_string, to_boolean, to_enum, to_float, to_integer, VirtualApp)
|
17
17
|
from dcicutils.portal_object_utils import PortalObject
|
18
18
|
from dcicutils.portal_utils import Portal as PortalBase
|
19
|
+
from dcicutils.schema_utils import Schema as SchemaBase
|
19
20
|
from dcicutils.zip_utils import unpack_gz_file_to_temporary_file, unpack_files
|
20
21
|
|
21
22
|
|
@@ -154,7 +155,7 @@ class StructuredDataSet:
|
|
154
155
|
if not diffs.get(object_type):
|
155
156
|
diffs[object_type] = []
|
156
157
|
for portal_object in self.data[object_type]:
|
157
|
-
portal_object = PortalObject(self.portal,
|
158
|
+
portal_object = PortalObject(portal_object, portal=self.portal, type=object_type)
|
158
159
|
existing_object, identifying_path = portal_object.lookup(include_identifying_path=True, raw=True)
|
159
160
|
if existing_object:
|
160
161
|
object_diffs = portal_object.compare(existing_object, consider_refs=True, resolved_refs=refs)
|
@@ -363,11 +364,12 @@ class _StructuredRowTemplate:
|
|
363
364
|
return structured_row_template
|
364
365
|
|
365
366
|
|
366
|
-
class Schema:
|
367
|
+
class Schema(SchemaBase):
|
367
368
|
|
368
369
|
def __init__(self, schema_json: dict, portal: Optional[Portal] = None) -> None:
|
369
|
-
|
370
|
-
|
370
|
+
super().__init__(schema_json)
|
371
|
+
# self._data = schema_json if isinstance(schema_json, dict) else {}
|
372
|
+
# self._type = Schema.type_name(schema_json.get("title", ""))
|
371
373
|
self._portal = portal # Needed only to resolve linkTo references.
|
372
374
|
self._map_value_functions = {
|
373
375
|
"boolean": self._map_function_boolean,
|
@@ -380,13 +382,13 @@ class Schema:
|
|
380
382
|
self._unresolved_refs = []
|
381
383
|
self._typeinfo = self._create_typeinfo(schema_json)
|
382
384
|
|
383
|
-
|
384
|
-
|
385
|
-
|
385
|
+
# @property
|
386
|
+
# def data(self) -> dict:
|
387
|
+
# return self._data
|
386
388
|
|
387
|
-
|
388
|
-
|
389
|
-
|
389
|
+
# @property
|
390
|
+
# def type(self) -> str:
|
391
|
+
# return self._type
|
390
392
|
|
391
393
|
@staticmethod
|
392
394
|
def load_by_name(name: str, portal: Portal) -> Optional[dict]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "dcicutils"
|
3
|
-
version = "8.7.1.
|
3
|
+
version = "8.7.1.1b12" # TODO: To become 8.7.2
|
4
4
|
description = "Utility package for interacting with the 4DN Data Portal and other 4DN resources"
|
5
5
|
authors = ["4DN-DCIC Team <support@4dnucleome.org>"]
|
6
6
|
license = "MIT"
|
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
|
{dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/c4-infrastructure.jsonc
RENAMED
File without changes
|
File without changes
|
{dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-common-server.jsonc
RENAMED
File without changes
|
{dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-common.jsonc
RENAMED
File without changes
|
{dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-gpl-pipeline.jsonc
RENAMED
File without changes
|
{dcicutils-8.7.1.1b9 → dcicutils-8.7.1.1b12}/dcicutils/license_policies/park-lab-pipeline.jsonc
RENAMED
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
|