dcicutils 8.5.0.1b2__py3-none-any.whl → 8.5.0.1b4__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.
- dcicutils/portal_utils.py +23 -8
- dcicutils/structured_data.py +20 -8
- {dcicutils-8.5.0.1b2.dist-info → dcicutils-8.5.0.1b4.dist-info}/METADATA +1 -1
- {dcicutils-8.5.0.1b2.dist-info → dcicutils-8.5.0.1b4.dist-info}/RECORD +7 -7
- {dcicutils-8.5.0.1b2.dist-info → dcicutils-8.5.0.1b4.dist-info}/LICENSE.txt +0 -0
- {dcicutils-8.5.0.1b2.dist-info → dcicutils-8.5.0.1b4.dist-info}/WHEEL +0 -0
- {dcicutils-8.5.0.1b2.dist-info → dcicutils-8.5.0.1b4.dist-info}/entry_points.txt +0 -0
dcicutils/portal_utils.py
CHANGED
@@ -23,15 +23,14 @@ class Portal:
|
|
23
23
|
2. From a key dictionary, containing "key" and "secret" property values.
|
24
24
|
3. From a key tuple, containing (in order) a key and secret values.
|
25
25
|
4. From a keys file assumed to reside in ~/.{app}-keys.json where the given "app" value is either "smaht", "cgap",
|
26
|
-
or "fourfront";
|
27
|
-
|
28
|
-
an "app" value is not specified but the given "env" value begins with one of the app values then that value
|
29
|
-
will be used, i.e. e.g. if env is "smaht-
|
26
|
+
or "fourfront"; where is assumed to contain a dictionary with a key for the given "env" value, e.g. smaht-local;
|
27
|
+
and with a dictionary value containing "key" and "secret" property values, and an optional "server" property;
|
28
|
+
if an "app" value is not specified but the given "env" value begins with one of the app values then that value
|
29
|
+
will be used, i.e. e.g. if "env" is "smaht-local" and app is unspecified than it is assumed to be "smaht".
|
30
30
|
5. From a keys file as described above (#4) but rather than be identified by the given "env" value it
|
31
|
-
is looked up
|
31
|
+
is looked up via the given "server" name and the "server" key dictionary value in the key file.
|
32
32
|
6. From a given "vapp" value (which is assumed to be a TestApp or VirtualApp).
|
33
|
-
7. From another Portal object.
|
34
|
-
8. From a a pyramid Router object.
|
33
|
+
7. From another Portal object; or from a a pyramid Router object.
|
35
34
|
"""
|
36
35
|
def __init__(self,
|
37
36
|
arg: Optional[Union[VirtualApp, TestApp, Router, Portal, dict, tuple, str]] = None,
|
@@ -62,6 +61,7 @@ class Portal:
|
|
62
61
|
self._server = portal._server
|
63
62
|
self._key = portal._key
|
64
63
|
self._key_pair = portal._key_pair
|
64
|
+
self._key_id = portal._key_id
|
65
65
|
self._key_file = portal._key_file
|
66
66
|
return
|
67
67
|
self._vapp = None
|
@@ -70,6 +70,7 @@ class Portal:
|
|
70
70
|
self._server = server
|
71
71
|
self._key = None
|
72
72
|
self._key_pair = None
|
73
|
+
self._key_id = None
|
73
74
|
self._key_file = None
|
74
75
|
if isinstance(portal, (VirtualApp, TestApp)):
|
75
76
|
self._vapp = portal
|
@@ -95,6 +96,10 @@ class Portal:
|
|
95
96
|
self._key = key_manager.get_keydict_for_server(self._server)
|
96
97
|
self._key_pair = key_manager.keydict_to_keypair(self._key) if self._key else None
|
97
98
|
self._key_file = key_manager.keys_file
|
99
|
+
if self._key and (key_id := self._key.get("key")):
|
100
|
+
self._key_id = key_id
|
101
|
+
elif self._key_pair and (key_id := self._key_pair[1]):
|
102
|
+
self._key_id = key_id
|
98
103
|
|
99
104
|
@property
|
100
105
|
def env(self):
|
@@ -116,6 +121,10 @@ class Portal:
|
|
116
121
|
def key_pair(self):
|
117
122
|
return self._key_pair
|
118
123
|
|
124
|
+
@property
|
125
|
+
def key_id(self):
|
126
|
+
return self._key_id
|
127
|
+
|
119
128
|
@property
|
120
129
|
def key_file(self):
|
121
130
|
return self._key_file
|
@@ -206,13 +215,19 @@ class Portal:
|
|
206
215
|
super_type_map_flattened[super_type_name] = breadth_first(super_type_map, super_type_name)
|
207
216
|
return super_type_map_flattened
|
208
217
|
|
218
|
+
def ping(self) -> bool:
|
219
|
+
try:
|
220
|
+
return self.get("/health").status_code == 200
|
221
|
+
except Exception:
|
222
|
+
return False
|
223
|
+
|
209
224
|
def _uri(self, uri: str) -> str:
|
210
225
|
if not isinstance(uri, str) or not uri:
|
211
226
|
return "/"
|
212
227
|
if uri.lower().startswith("http://") or uri.lower().startswith("https://"):
|
213
228
|
return uri
|
214
229
|
uri = re.sub(r"/+", "/", uri)
|
215
|
-
return (self._server + ("/" if uri.startswith("/") else "") + uri) if self._server else uri
|
230
|
+
return (self._server + ("/" if not uri.startswith("/") else "") + uri) if self._server else uri
|
216
231
|
|
217
232
|
def _kwargs(self, **kwargs) -> dict:
|
218
233
|
result_kwargs = {"headers":
|
dcicutils/structured_data.py
CHANGED
@@ -42,8 +42,8 @@ StructuredDataSet = Type["StructuredDataSet"]
|
|
42
42
|
class StructuredDataSet:
|
43
43
|
|
44
44
|
def __init__(self, file: Optional[str] = None, portal: Optional[Union[VirtualApp, TestApp, Portal]] = None,
|
45
|
-
schemas: Optional[List[dict]] = None,
|
46
|
-
order: Optional[List[str]] = None, prune: bool = True) -> None:
|
45
|
+
schemas: Optional[List[dict]] = None, autoadd: Optional[dict] = None,
|
46
|
+
data: Optional[List[dict]] = None, order: Optional[List[str]] = None, prune: bool = True) -> None:
|
47
47
|
self.data = {} if not data else data # If portal is None then no schemas nor refs.
|
48
48
|
self._portal = Portal(portal, data=self.data, schemas=schemas) if portal else None
|
49
49
|
self._order = order
|
@@ -52,13 +52,14 @@ class StructuredDataSet:
|
|
52
52
|
self._errors = {}
|
53
53
|
self._resolved_refs = set()
|
54
54
|
self._validated = False
|
55
|
+
self._autoadd_properties = autoadd if isinstance(autoadd, dict) and autoadd else None
|
55
56
|
self._load_file(file) if file else None
|
56
57
|
|
57
58
|
@staticmethod
|
58
59
|
def load(file: str, portal: Optional[Union[VirtualApp, TestApp, Portal]] = None,
|
59
|
-
schemas: Optional[List[dict]] = None,
|
60
|
+
schemas: Optional[List[dict]] = None, autoadd: Optional[dict] = None,
|
60
61
|
order: Optional[List[str]] = None, prune: bool = True) -> StructuredDataSet:
|
61
|
-
return StructuredDataSet(file=file, portal=portal, schemas=schemas, order=order, prune=prune)
|
62
|
+
return StructuredDataSet(file=file, portal=portal, schemas=schemas, autoadd=autoadd, order=order, prune=prune)
|
62
63
|
|
63
64
|
def validate(self, force: bool = False) -> None:
|
64
65
|
if self._validated and not force:
|
@@ -163,6 +164,8 @@ class StructuredDataSet:
|
|
163
164
|
structured_row = structured_row_template.create_row()
|
164
165
|
for column_name, value in row.items():
|
165
166
|
structured_row_template.set_value(structured_row, column_name, value, reader.file, reader.row_number)
|
167
|
+
if self._autoadd_properties:
|
168
|
+
self._add_properties(structured_row, self._autoadd_properties, schema)
|
166
169
|
self._add(type_name, structured_row)
|
167
170
|
self._note_warning(reader.warnings, "reader")
|
168
171
|
if schema:
|
@@ -177,6 +180,11 @@ class StructuredDataSet:
|
|
177
180
|
else:
|
178
181
|
self.data[type_name] = [data] if isinstance(data, dict) else data
|
179
182
|
|
183
|
+
def _add_properties(self, structured_row: dict, properties: dict, schema: Optional[dict] = None) -> None:
|
184
|
+
for name in properties:
|
185
|
+
if name not in structured_row and (not schema or schema.data.get("properties", {}).get(name)):
|
186
|
+
structured_row[name] = properties[name]
|
187
|
+
|
180
188
|
def _note_warning(self, item: Optional[Union[dict, List[dict]]], group: str) -> None:
|
181
189
|
self._note_issue(self._warnings, item, group)
|
182
190
|
|
@@ -317,7 +325,8 @@ class Schema:
|
|
317
325
|
|
318
326
|
@staticmethod
|
319
327
|
def load_by_name(name: str, portal: Portal) -> Optional[dict]:
|
320
|
-
|
328
|
+
schema_json = portal.get_schema(Schema.type_name(name)) if portal else None
|
329
|
+
return Schema(schema_json, portal) if schema_json else None
|
321
330
|
|
322
331
|
def validate(self, data: dict) -> List[str]:
|
323
332
|
errors = []
|
@@ -565,7 +574,9 @@ class Portal(PortalBase):
|
|
565
574
|
|
566
575
|
@lru_cache(maxsize=256)
|
567
576
|
def get_schema(self, schema_name: str) -> Optional[dict]:
|
568
|
-
if (schemas := self.get_schemas())
|
577
|
+
if not (schemas := self.get_schemas()):
|
578
|
+
return None
|
579
|
+
if schema := schemas.get(schema_name := Schema.type_name(schema_name)):
|
569
580
|
return schema
|
570
581
|
if schema_name == schema_name.upper() and (schema := schemas.get(schema_name.lower().title())):
|
571
582
|
return schema
|
@@ -573,8 +584,9 @@ class Portal(PortalBase):
|
|
573
584
|
return schema
|
574
585
|
|
575
586
|
@lru_cache(maxsize=1)
|
576
|
-
def get_schemas(self) -> dict:
|
577
|
-
schemas
|
587
|
+
def get_schemas(self) -> Optional[dict]:
|
588
|
+
if not (schemas := super().get_schemas()) or (schemas.get("status") == "error"):
|
589
|
+
return None
|
578
590
|
if self._schemas:
|
579
591
|
schemas = copy.deepcopy(schemas)
|
580
592
|
for user_specified_schema in self._schemas:
|
@@ -43,7 +43,7 @@ dcicutils/log_utils.py,sha256=7pWMc6vyrorUZQf-V-M3YC6zrPgNhuV_fzm9xqTPph0,10883
|
|
43
43
|
dcicutils/misc_utils.py,sha256=nRjLEORY35YmJwTjO0fnauBPznaI_bkVasIW8PccDYM,100179
|
44
44
|
dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmjw,5963
|
45
45
|
dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
|
46
|
-
dcicutils/portal_utils.py,sha256=
|
46
|
+
dcicutils/portal_utils.py,sha256=Wh918ZKpUJFbt7w6Bn5G7v-0k6ImOUWMFmE9Oxt1ZN4,14560
|
47
47
|
dcicutils/project_utils.py,sha256=qPdCaFmWUVBJw4rw342iUytwdQC0P-XKpK4mhyIulMM,31250
|
48
48
|
dcicutils/qa_checkers.py,sha256=cdXjeL0jCDFDLT8VR8Px78aS10hwNISOO5G_Zv2TZ6M,20534
|
49
49
|
dcicutils/qa_utils.py,sha256=TT0SiJWiuxYvbsIyhK9VO4uV_suxhB6CpuC4qPacCzQ,160208
|
@@ -56,14 +56,14 @@ dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19
|
|
56
56
|
dcicutils/sheet_utils.py,sha256=VlmzteONW5VF_Q4vo0yA5vesz1ViUah1MZ_yA1rwZ0M,33629
|
57
57
|
dcicutils/snapshot_utils.py,sha256=ymP7PXH6-yEiXAt75w0ldQFciGNqWBClNxC5gfX2FnY,22961
|
58
58
|
dcicutils/ssl_certificate_utils.py,sha256=F0ifz_wnRRN9dfrfsz7aCp4UDLgHEY8LaK7PjnNvrAQ,9707
|
59
|
-
dcicutils/structured_data.py,sha256=
|
59
|
+
dcicutils/structured_data.py,sha256=tMKBhq6OuM2t6iDxIPBFcxV66MiwmOHTBeACxhvkbiQ,33307
|
60
60
|
dcicutils/task_utils.py,sha256=MF8ujmTD6-O2AC2gRGPHyGdUrVKgtr8epT5XU8WtNjk,8082
|
61
61
|
dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
|
62
62
|
dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
|
63
63
|
dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
|
64
64
|
dcicutils/zip_utils.py,sha256=0OXR0aLNwyLIZOzIFTM_5DOun7dxIv6TIZbFiithkO0,3276
|
65
|
-
dcicutils-8.5.0.
|
66
|
-
dcicutils-8.5.0.
|
67
|
-
dcicutils-8.5.0.
|
68
|
-
dcicutils-8.5.0.
|
69
|
-
dcicutils-8.5.0.
|
65
|
+
dcicutils-8.5.0.1b4.dist-info/LICENSE.txt,sha256=t0_-jIjqxNnymZoNJe-OltRIuuF8qfhN0ATlHyrUJPk,1102
|
66
|
+
dcicutils-8.5.0.1b4.dist-info/METADATA,sha256=Zpf8fTsgsuRfo8WDGkONHxtcf4SPWOFK_4iCNVAhB78,3314
|
67
|
+
dcicutils-8.5.0.1b4.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
68
|
+
dcicutils-8.5.0.1b4.dist-info/entry_points.txt,sha256=8wbw5csMIgBXhkwfgsgJeuFcoUc0WsucUxmOyml2aoA,209
|
69
|
+
dcicutils-8.5.0.1b4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|