dcicutils 8.8.4.1b36__tar.gz → 8.8.4.1b39__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/PKG-INFO +1 -1
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/scripts/view_portal_object.py +87 -5
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/structured_data.py +12 -1
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/pyproject.toml +1 -1
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/LICENSE.txt +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/README.rst +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/__init__.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/base.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/beanstalk_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/bundle_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/captured_output.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/cloudformation_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/codebuild_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/command_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/common.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/contribution_scripts.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/contribution_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/creds_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/data_readers.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/data_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/datetime_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/deployment_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/diff_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/docker_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ecr_scripts.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ecr_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ecs_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/env_base.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/env_manager.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/env_scripts.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/env_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/env_utils_legacy.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/es_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/exceptions.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ff_mocks.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ff_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/file_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/function_cache_decorator.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/glacier_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/http_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/jh_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/kibana/dashboards.json +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/kibana/readme.md +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/lang_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/c4-infrastructure.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/c4-python-infrastructure.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-common-server.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-common.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-gpl-pipeline.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-pipeline.jsonc +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/log_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/misc_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/obfuscation_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/opensearch_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/portal_object_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/portal_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/progress_bar.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/project_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/qa_checkers.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/qa_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/redis_tools.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/redis_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/s3_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/schema_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/scripts/publish_to_pypi.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/scripts/run_license_checker.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/secrets_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/sheet_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/snapshot_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/ssl_certificate_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/submitr/progress_constants.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/submitr/ref_lookup_strategy.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/task_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/tmpfile_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/trace_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/validation_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/variant_utils.py +0 -0
- {dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/zip_utils.py +0 -0
@@ -57,6 +57,7 @@
|
|
57
57
|
|
58
58
|
import argparse
|
59
59
|
from functools import lru_cache
|
60
|
+
import io
|
60
61
|
import json
|
61
62
|
import pyperclip
|
62
63
|
import os
|
@@ -97,11 +98,18 @@ def main():
|
|
97
98
|
help="Include all properties for schema usage.")
|
98
99
|
parser.add_argument("--raw", action="store_true", required=False, default=False, help="Raw output.")
|
99
100
|
parser.add_argument("--tree", action="store_true", required=False, default=False, help="Tree output for schemas.")
|
101
|
+
parser.add_argument("--post", type=str, required=False, default=None,
|
102
|
+
help="POST data of the main arg type with data from file specified with this option.")
|
103
|
+
parser.add_argument("--patch", type=str, required=False, default=None,
|
104
|
+
help="PATCH data of the main arg type with data from file specified with this option.")
|
100
105
|
parser.add_argument("--database", action="store_true", required=False, default=False,
|
101
106
|
help="Read from database output.")
|
107
|
+
parser.add_argument("--bool", action="store_true", required=False,
|
108
|
+
default=False, help="Only return whether found or not.")
|
102
109
|
parser.add_argument("--yaml", action="store_true", required=False, default=False, help="YAML output.")
|
103
110
|
parser.add_argument("--copy", "-c", action="store_true", required=False, default=False,
|
104
111
|
help="Copy object data to clipboard.")
|
112
|
+
parser.add_argument("--indent", required=False, default=False, help="Indent output.", type=int)
|
105
113
|
parser.add_argument("--details", action="store_true", required=False, default=False, help="Detailed output.")
|
106
114
|
parser.add_argument("--more-details", action="store_true", required=False, default=False,
|
107
115
|
help="More detailed output.")
|
@@ -151,6 +159,18 @@ def main():
|
|
151
159
|
args.schema = True
|
152
160
|
|
153
161
|
if args.schema:
|
162
|
+
if args.post:
|
163
|
+
if post_data := _read_json_from_file(args.post):
|
164
|
+
if args.verbose:
|
165
|
+
_print(f"POSTing data from file ({args.post}) as type: {args.uuid}")
|
166
|
+
if isinstance(post_data, dict):
|
167
|
+
post_data = [post_data]
|
168
|
+
elif not isinstance(post_data, list):
|
169
|
+
_print(f"POST data neither list nor dictionary: {args.post}")
|
170
|
+
for item in post_data:
|
171
|
+
portal.post_metadata(args.uuid, item)
|
172
|
+
if args.verbose:
|
173
|
+
_print(f"Done POSTing data from file ({args.post}) as type: {args.uuid}")
|
154
174
|
schema, schema_name = _get_schema(portal, args.uuid)
|
155
175
|
if schema:
|
156
176
|
if args.copy:
|
@@ -166,14 +186,50 @@ def main():
|
|
166
186
|
_print_schema(schema, details=args.details, more_details=args.details,
|
167
187
|
all=args.all, raw=args.raw, raw_yaml=args.yaml)
|
168
188
|
return
|
169
|
-
|
170
|
-
|
189
|
+
elif args.patch:
|
190
|
+
if patch_data := _read_json_from_file(args.patch):
|
191
|
+
if args.verbose:
|
192
|
+
_print(f"PATCHing data from file ({args.patch}) for object: {args.uuid}")
|
193
|
+
if isinstance(patch_data, dict):
|
194
|
+
patch_data = [patch_data]
|
195
|
+
elif not isinstance(patch_data, list):
|
196
|
+
_print(f"PATCH data neither list nor dictionary: {args.patch}")
|
197
|
+
for item in patch_data:
|
198
|
+
portal.patch_metadata(args.uuid, item)
|
199
|
+
if args.verbose:
|
200
|
+
_print(f"Done PATCHing data from file ({args.patch}) as type: {args.uuid}")
|
201
|
+
return
|
202
|
+
else:
|
203
|
+
_print(f"No PATCH data found in file: {args.patch}")
|
204
|
+
exit(1)
|
205
|
+
|
206
|
+
data = _get_portal_object(portal=portal, uuid=args.uuid, raw=args.raw,
|
207
|
+
database=args.database, check=args.bool, verbose=args.verbose)
|
208
|
+
if args.bool:
|
209
|
+
if data:
|
210
|
+
_print(f"{args.uuid}: found")
|
211
|
+
exit(0)
|
212
|
+
else:
|
213
|
+
_print(f"{args.uuid}: not found")
|
214
|
+
exit(1)
|
171
215
|
if args.copy:
|
172
216
|
pyperclip.copy(json.dumps(data, indent=4))
|
173
217
|
if args.yaml:
|
174
218
|
_print(yaml.dump(data))
|
175
219
|
else:
|
176
|
-
|
220
|
+
if args.indent > 0:
|
221
|
+
_print(_format_json_with_indent(data, indent=args.indent))
|
222
|
+
else:
|
223
|
+
_print(json.dumps(data, default=str, indent=4))
|
224
|
+
|
225
|
+
|
226
|
+
def _format_json_with_indent(value: dict, indent: int = 0) -> Optional[str]:
|
227
|
+
if isinstance(value, dict):
|
228
|
+
result = json.dumps(value, indent=4)
|
229
|
+
if indent > 0:
|
230
|
+
result = f"{indent * ' '}{result}"
|
231
|
+
result = result.replace("\n", f"\n{indent * ' '}")
|
232
|
+
return result
|
177
233
|
|
178
234
|
|
179
235
|
def _create_portal(ini: str, env: Optional[str] = None,
|
@@ -198,7 +254,8 @@ def _create_portal(ini: str, env: Optional[str] = None,
|
|
198
254
|
|
199
255
|
|
200
256
|
def _get_portal_object(portal: Portal, uuid: str,
|
201
|
-
raw: bool = False, database: bool = False,
|
257
|
+
raw: bool = False, database: bool = False,
|
258
|
+
check: bool = False, verbose: bool = False) -> dict:
|
202
259
|
response = None
|
203
260
|
try:
|
204
261
|
if not uuid.startswith("/"):
|
@@ -212,13 +269,18 @@ def _get_portal_object(portal: Portal, uuid: str,
|
|
212
269
|
_exit()
|
213
270
|
_exit(f"Exception getting Portal object from {portal.server}: {uuid}\n{get_error_message(e)}")
|
214
271
|
if not response:
|
272
|
+
if check:
|
273
|
+
return None
|
215
274
|
_exit(f"Null response getting Portal object from {portal.server}: {uuid}")
|
216
275
|
if response.status_code not in [200, 307]:
|
217
276
|
# TODO: Understand why the /me endpoint returns HTTP status code 307, which is only why we mention it above.
|
218
277
|
_exit(f"Invalid status code ({response.status_code}) getting Portal object from {portal.server}: {uuid}")
|
219
278
|
if not response.json:
|
220
279
|
_exit(f"Invalid JSON getting Portal object: {uuid}")
|
221
|
-
|
280
|
+
response = response.json()
|
281
|
+
if raw:
|
282
|
+
response.pop("schema_version", None)
|
283
|
+
return response
|
222
284
|
|
223
285
|
|
224
286
|
@lru_cache(maxsize=1)
|
@@ -257,6 +319,7 @@ def _print_schema_info(schema: dict, level: int = 0,
|
|
257
319
|
required: Optional[List[str]] = None) -> None:
|
258
320
|
if not schema or not isinstance(schema, dict):
|
259
321
|
return
|
322
|
+
identifying_properties = schema.get("identifyingProperties")
|
260
323
|
if level == 0:
|
261
324
|
if required_properties := schema.get("required"):
|
262
325
|
_print("- required properties:")
|
@@ -383,6 +446,8 @@ def _print_schema_info(schema: dict, level: int = 0,
|
|
383
446
|
suffix += f" | enum"
|
384
447
|
if property_required:
|
385
448
|
suffix += f" | required"
|
449
|
+
if property_name in (identifying_properties or []):
|
450
|
+
suffix += f" | identifying"
|
386
451
|
if property.get("uniqueKey"):
|
387
452
|
suffix += f" | unique"
|
388
453
|
if pattern := property.get("pattern"):
|
@@ -529,6 +594,23 @@ def _print_tree(root_name: Optional[str],
|
|
529
594
|
print(line)
|
530
595
|
|
531
596
|
|
597
|
+
def _read_json_from_file(file: str) -> Optional[dict]:
|
598
|
+
if not os.path.exists(file):
|
599
|
+
_print(f"Cannot find file: {file}")
|
600
|
+
exit(1)
|
601
|
+
try:
|
602
|
+
with io.open(file, "r") as f:
|
603
|
+
try:
|
604
|
+
return json.load(f)
|
605
|
+
except Exception:
|
606
|
+
_print(f"Cannot parse JSON in file: {file}")
|
607
|
+
exit(1)
|
608
|
+
except Exception as e:
|
609
|
+
print(e)
|
610
|
+
_print(f"Cannot open file: {file}")
|
611
|
+
exit(1)
|
612
|
+
|
613
|
+
|
532
614
|
def _print(*args, **kwargs):
|
533
615
|
with uncaptured_output():
|
534
616
|
PRINT(*args, **kwargs)
|
@@ -350,7 +350,18 @@ class StructuredDataSet:
|
|
350
350
|
|
351
351
|
def _load_json_file(self, file: str) -> None:
|
352
352
|
with open(file) as f:
|
353
|
-
|
353
|
+
file_json = json.load(f)
|
354
|
+
schema_inferred_from_file_name = Schema.type_name(file)
|
355
|
+
if self._portal.get_schema(schema_inferred_from_file_name) is not None:
|
356
|
+
# If the JSON file name looks like a schema name then assume it
|
357
|
+
# contains an object or an array of object of that schema type.
|
358
|
+
self._add(Schema.type_name(file), file_json)
|
359
|
+
elif isinstance(file_json, dict):
|
360
|
+
# Otherwise if the JSON file name does not look like a schema name then
|
361
|
+
# assume it a dictionary where each property is the name of a schema, and
|
362
|
+
# which (each property) contains a list of object of that schema type.
|
363
|
+
for schema_name in file_json:
|
364
|
+
self._add(schema_name, file_json[schema_name])
|
354
365
|
|
355
366
|
def _load_reader(self, reader: RowReader, type_name: str) -> None:
|
356
367
|
schema = None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "dcicutils"
|
3
|
-
version = "8.8.4.
|
3
|
+
version = "8.8.4.1b39" # TODO: To become 8.8.5
|
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
|
File without changes
|
File without changes
|
File without changes
|
{dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/c4-infrastructure.jsonc
RENAMED
File without changes
|
File without changes
|
File without changes
|
{dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-common.jsonc
RENAMED
File without changes
|
{dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/dcicutils/license_policies/park-lab-gpl-pipeline.jsonc
RENAMED
File without changes
|
{dcicutils-8.8.4.1b36 → dcicutils-8.8.4.1b39}/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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|