dcicutils 8.7.0.1b35__py3-none-any.whl → 8.7.0.1b37__py3-none-any.whl

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.
@@ -1,8 +1,6 @@
1
1
  from functools import lru_cache
2
- import re
3
- from typing import Any, Callable, List, Optional, Tuple, Type, Union
2
+ from typing import List, Optional, Tuple, Type, Union
4
3
  from dcicutils.portal_utils import Portal
5
- from dcicutils.schema_utils import Schema
6
4
 
7
5
  PortalObject = Type["PortalObject"] # Forward type reference for type hints.
8
6
 
@@ -73,6 +71,7 @@ class PortalObject:
73
71
  for identifying_property in identifying_properties:
74
72
  if (identifying_value := self._data.get(identifying_property)):
75
73
  if identifying_property == "uuid":
74
+ identifying_paths.append(f"/{self.type}/{identifying_value}")
76
75
  identifying_paths.append(f"/{identifying_value}")
77
76
  # For now at least we include the path both with and without the schema type component,
78
77
  # as for some identifying values, it works (only) with, and some, it works (only) without.
@@ -111,55 +110,3 @@ class PortalObject:
111
110
  except Exception:
112
111
  pass
113
112
  return None, self.identifying_path
114
-
115
- def compare(self, value: Union[dict, PortalObject], consider_link_to: bool = False) -> dict:
116
- """
117
- Compares this Portal object against the given Portal object value; noting differences values of properites
118
- which they have in common; and properties which are in this Portal object and not in the given Portal object;
119
- we do NOT check the converse, i.e. properties in the given Portal object which are not in this Portal object.
120
- Returns a dictionary with a description of the differences.
121
- """
122
- def are_properties_equal(property_path: str, property_value_a: Any, property_value_b: Any) -> bool:
123
- if property_value_a == property_value_b:
124
- return True
125
- nonlocal self
126
- if (schema := self.schema) and (property_type := Schema.get_property_by_path(schema, property_path)):
127
- if link_to := property_type.get("linkTo"):
128
- if a := self._portal.get(f"/{link_to}/{property_value_a}", raw=True):
129
- if (a.status_code == 200) and (a := a.json()):
130
- if b := self._portal.get(f"/{link_to}/{property_value_b}", raw=True):
131
- if (b.status_code == 200) and (b := b.json()):
132
- return a == b
133
- return False
134
- return PortalObject._compare(self._data, value.data if isinstance(value, PortalObject) else value,
135
- compare=are_properties_equal if consider_link_to else None)
136
-
137
- _ARRAY_KEY_REGULAR_EXPRESSION = re.compile(rf"^({Schema._ARRAY_NAME_SUFFIX_CHAR}\d+)$")
138
-
139
- @staticmethod
140
- def _compare(a: dict, b: dict, compare: Optional[Callable] = None, _path: Optional[str] = None) -> dict:
141
- def key_to_path(key: str) -> Optional[str]: # noqa
142
- nonlocal _path
143
- if match := PortalObject._ARRAY_KEY_REGULAR_EXPRESSION.search(key):
144
- return f"{_path}{match.group(1)}" if _path else match.group(1)
145
- return f"{_path}.{key}" if _path else key
146
- def list_to_dictionary(value: list) -> dict: # noqa
147
- result = {}
148
- for index, item in enumerate(sorted(value)): # ignore array order
149
- result[f"#{index}"] = item
150
- return result
151
- diffs = {}
152
- for key in a:
153
- path = key_to_path(key)
154
- if key not in b:
155
- diffs[path] = {"value": a[key], "missing_value": True}
156
- else:
157
- if isinstance(a[key], dict) and isinstance(b[key], dict):
158
- diffs.update(PortalObject._compare(a[key], b[key], compare=compare, _path=path))
159
- elif isinstance(a[key], list) and isinstance(b[key], list):
160
- diffs.update(PortalObject._compare(list_to_dictionary(a[key]),
161
- list_to_dictionary(b[key]), compare=compare, _path=path))
162
- elif a[key] != b[key]:
163
- if not callable(compare) or not compare(path, a[key], b[key]):
164
- diffs[path] = {"value": a[key], "differing_value": b[key]}
165
- return diffs
dcicutils/schema_utils.py CHANGED
@@ -1,6 +1,4 @@
1
- import os
2
- from typing import Any, Dict, List, Optional, Tuple
3
- from dcicutils.misc_utils import to_camel_case
1
+ from typing import Any, Dict, List
4
2
 
5
3
 
6
4
  class JsonSchemaConstants:
@@ -185,79 +183,3 @@ def get_one_of_formats(schema: Dict[str, Any]) -> List[str]:
185
183
  for one_of_schema in get_one_of(schema)
186
184
  if get_format(one_of_schema)
187
185
  ]
188
-
189
-
190
- class Schema:
191
-
192
- def __init__(self, schema: dict, schema_type: Optional[str] = None) -> None:
193
- self._data = schema if isinstance(schema, dict) else (schema.data if isinstance(schema, Schema) else {})
194
- self._type = (isinstance(schema_type, str) and schema_type) or Schema.type_name(self._data.get("title", ""))
195
-
196
- @property
197
- def data(self) -> dict:
198
- return self._data
199
-
200
- @property
201
- def type(self) -> str:
202
- return self._type
203
-
204
- @staticmethod
205
- def type_name(value: str) -> Optional[str]: # File or other name.
206
- if isinstance(value, str) and (value := os.path.basename(value.replace(" ", ""))):
207
- return to_camel_case(value[0:dot] if (dot := value.rfind(".")) >= 0 else value)
208
-
209
- def property_by_path(self, property_path: str) -> Optional[dict]:
210
- """
211
- TODO
212
- """
213
- return Schema.get_property_by_path(self._data, property_path)
214
-
215
- _ARRAY_NAME_SUFFIX_CHAR = "#"
216
- _DOTTED_NAME_DELIMITER_CHAR = "."
217
-
218
- @staticmethod
219
- def get_property_by_path(schema: dict, property_path: str) -> Optional[dict]:
220
- if not isinstance(schema, dict) or not isinstance(property_path, str):
221
- return None
222
- elif not (schema_properties := schema.get("properties")):
223
- return None
224
- property_paths = property_path.split(Schema._DOTTED_NAME_DELIMITER_CHAR)
225
- for property_index, property_name in enumerate(property_paths):
226
- property_name, array_specifiers = Schema._unarrayize_property_name(property_name)
227
- if not (property_value := schema_properties.get(property_name)):
228
- return None
229
- elif (property_type := property_value.get("type")) == "object":
230
- property_paths_tail = Schema._DOTTED_NAME_DELIMITER_CHAR.join(property_paths[property_index + 1:])
231
- return Schema.get_property_by_path(property_value, property_paths_tail)
232
- elif (property_type := property_value.get("type")) == "array":
233
- if not array_specifiers:
234
- if property_index == len(property_paths) - 1:
235
- return property_value
236
- return None
237
- for array_index in range(len(array_specifiers)):
238
- if property_type != "array":
239
- return None
240
- elif not (array_items := property_value.get("items")):
241
- return None
242
- property_type = (property_value := array_items).get("type")
243
- if property_type == "object":
244
- if property_index == len(property_paths) - 1:
245
- return property_value
246
- property_paths_tail = Schema._DOTTED_NAME_DELIMITER_CHAR.join(property_paths[property_index + 1:])
247
- return Schema.get_property_by_path(property_value, property_paths_tail)
248
- return property_value
249
-
250
- @staticmethod
251
- def _unarrayize_property_name(property_name: str) -> Tuple[str, Optional[List[int]]]:
252
- if len(components := (property_name := property_name.strip()).split(Schema._ARRAY_NAME_SUFFIX_CHAR)) < 2:
253
- return property_name, None
254
- unarrayized_property_name = components[0].strip()
255
- array_specifiers = []
256
- for component in components[1:]:
257
- if component.isdigit():
258
- array_specifiers.append(int(component))
259
- elif component == "":
260
- array_specifiers.append(0)
261
- else:
262
- return property_name, None
263
- return unarrayized_property_name, array_specifiers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 8.7.0.1b35
3
+ Version: 8.7.0.1b37
4
4
  Summary: Utility package for interacting with the 4DN Data Portal and other 4DN resources
5
5
  Home-page: https://github.com/4dn-dcic/utils
6
6
  License: MIT
@@ -44,7 +44,7 @@ dcicutils/log_utils.py,sha256=7pWMc6vyrorUZQf-V-M3YC6zrPgNhuV_fzm9xqTPph0,10883
44
44
  dcicutils/misc_utils.py,sha256=bMRWWxdbhuF3PKdCZEH-H4U1ecgT3Nag3EL92D9XGoY,100973
45
45
  dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmjw,5963
46
46
  dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
47
- dcicutils/portal_object_utils.py,sha256=udjT_-IYWInTc-oXoh0Ie_xVYp28YEg3BRIlS88eUwQ,8352
47
+ dcicutils/portal_object_utils.py,sha256=P8KW0ASWhac8u0Ddzt-uuQ2LFKAEwCrb7ORMsQNJ8HI,5199
48
48
  dcicutils/portal_utils.py,sha256=jKYgZUYVdkg6VOs1hsiX4bSULLguOIBJFFRpvvZEklU,26704
49
49
  dcicutils/project_utils.py,sha256=qPdCaFmWUVBJw4rw342iUytwdQC0P-XKpK4mhyIulMM,31250
50
50
  dcicutils/qa_checkers.py,sha256=cdXjeL0jCDFDLT8VR8Px78aS10hwNISOO5G_Zv2TZ6M,20534
@@ -52,7 +52,7 @@ dcicutils/qa_utils.py,sha256=TT0SiJWiuxYvbsIyhK9VO4uV_suxhB6CpuC4qPacCzQ,160208
52
52
  dcicutils/redis_tools.py,sha256=qkcSNMtvqkpvts-Cm9gWhneK523Q_oHwhNUud1be1qk,7055
53
53
  dcicutils/redis_utils.py,sha256=VJ-7g8pOZqR1ZCtdcjKz3-6as2DMUcs1b1zG6wSprH4,6462
54
54
  dcicutils/s3_utils.py,sha256=LauLFQGvZLfpBJ81tYMikjLd3SJRz2R_FrL1n4xSlyI,28868
55
- dcicutils/schema_utils.py,sha256=h3VlIiBxE8EmxnfcXHF5KZhNeIZIA71LvqeIM-04gKY,9169
55
+ dcicutils/schema_utils.py,sha256=3Gd9QboOjQ3FHFawerylvYYU8Lor1Ma2pFv4JmezCdg,5501
56
56
  dcicutils/scripts/publish_to_pypi.py,sha256=LFzNHIQK2EXFr88YcfctyA_WKEBFc1ElnSjWrCXedPM,13889
57
57
  dcicutils/scripts/run_license_checker.py,sha256=z2keYnRDZsHQbTeo1XORAXSXNJK5axVzL5LjiNqZ7jE,4184
58
58
  dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19745
@@ -66,8 +66,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
66
66
  dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
67
67
  dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
68
68
  dcicutils/zip_utils.py,sha256=rnjNv_k6L9jT2SjDSgVXp4BEJYLtz9XN6Cl2Fy-tqnM,2027
69
- dcicutils-8.7.0.1b35.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
70
- dcicutils-8.7.0.1b35.dist-info/METADATA,sha256=v9eG3K-Qg11ZBSXujKZI_CGs6AYp8YCAp1OAe6Eywgo,3315
71
- dcicutils-8.7.0.1b35.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
72
- dcicutils-8.7.0.1b35.dist-info/entry_points.txt,sha256=8wbw5csMIgBXhkwfgsgJeuFcoUc0WsucUxmOyml2aoA,209
73
- dcicutils-8.7.0.1b35.dist-info/RECORD,,
69
+ dcicutils-8.7.0.1b37.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
70
+ dcicutils-8.7.0.1b37.dist-info/METADATA,sha256=p_b5H768OpaJuXp9IfbDntuVg2MIjyAnjvaZB5T7Vv4,3315
71
+ dcicutils-8.7.0.1b37.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
72
+ dcicutils-8.7.0.1b37.dist-info/entry_points.txt,sha256=8wbw5csMIgBXhkwfgsgJeuFcoUc0WsucUxmOyml2aoA,209
73
+ dcicutils-8.7.0.1b37.dist-info/RECORD,,