dcicutils 8.14.0.1b16__py3-none-any.whl → 8.14.0.1b17__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/scripts/update_portal_object.py +56 -10
- {dcicutils-8.14.0.1b16.dist-info → dcicutils-8.14.0.1b17.dist-info}/METADATA +1 -1
- {dcicutils-8.14.0.1b16.dist-info → dcicutils-8.14.0.1b17.dist-info}/RECORD +6 -6
- {dcicutils-8.14.0.1b16.dist-info → dcicutils-8.14.0.1b17.dist-info}/LICENSE.txt +0 -0
- {dcicutils-8.14.0.1b16.dist-info → dcicutils-8.14.0.1b17.dist-info}/WHEEL +0 -0
- {dcicutils-8.14.0.1b16.dist-info → dcicutils-8.14.0.1b17.dist-info}/entry_points.txt +0 -0
@@ -21,7 +21,7 @@ from dcicutils.captured_output import captured_output
|
|
21
21
|
from dcicutils.command_utils import yes_or_no
|
22
22
|
from dcicutils.common import ORCHESTRATED_APPS, APP_CGAP, APP_FOURFRONT, APP_SMAHT
|
23
23
|
from dcicutils.ff_utils import delete_metadata, purge_metadata
|
24
|
-
from dcicutils.misc_utils import get_error_message, ignored, PRINT, to_camel_case, to_snake_case
|
24
|
+
from dcicutils.misc_utils import get_error_message, ignored, normalize_string, PRINT, to_camel_case, to_snake_case
|
25
25
|
from dcicutils.portal_utils import Portal as PortalFromUtils
|
26
26
|
from dcicutils.tmpfile_utils import temporary_directory
|
27
27
|
|
@@ -393,14 +393,20 @@ def _load_data(portal: Portal, load: str, ini_file: str, explicit_schema_name: O
|
|
393
393
|
verbose: bool = False, debug: bool = False, noprogress: bool = False,
|
394
394
|
_single_insert_file: Optional[str] = None) -> bool:
|
395
395
|
|
396
|
+
import snovault.loadxl
|
396
397
|
from snovault.loadxl import load_all_gen, LoadGenWrapper
|
397
398
|
from dcicutils.progress_bar import ProgressBar
|
398
399
|
|
399
400
|
loadxl_summary = {}
|
401
|
+
loadxl_unresolved = {}
|
402
|
+
loadxl_output = []
|
403
|
+
loadxl_total_item_count = 0
|
404
|
+
loadxl_total_error_count = 0
|
400
405
|
|
401
406
|
def loadxl(portal: Portal, inserts_directory: str, schema_names_to_load: dict):
|
402
407
|
|
403
408
|
nonlocal LoadGenWrapper, load_all_gen, loadxl_summary, verbose, debug
|
409
|
+
nonlocal loadxl_total_item_count, loadxl_total_error_count
|
404
410
|
progress_total = sum(schema_names_to_load.values()) * 2 # loadxl does two passes
|
405
411
|
progress_bar = ProgressBar(progress_total, interrupt_exit=True) if not noprogress else None
|
406
412
|
|
@@ -413,27 +419,54 @@ def _load_data(portal: Portal, load: str, ini_file: str, explicit_schema_name: O
|
|
413
419
|
return str_or_bytes.strip()
|
414
420
|
return ""
|
415
421
|
|
422
|
+
def loadxl_print(arg):
|
423
|
+
if arg:
|
424
|
+
loadxl_output.append(normalize_string(str(arg)))
|
425
|
+
|
426
|
+
snovault.loadxl.print = loadxl_print
|
427
|
+
|
416
428
|
LOADXL_RESPONSE_PATTERN = re.compile(r"^([A-Z]+):\s*([a-zA-Z\/\d_-]+)\s*(\S+)\s*(\S+)?\s*(.*)$")
|
417
429
|
LOADXL_ACTION_NAME = {"POST": "Create", "PATCH": "Update", "SKIP": "Check",
|
418
430
|
"CHECK": "Validate", "ERROR": "Error"}
|
419
431
|
current_item_type = None
|
420
432
|
current_item_count = 0
|
421
433
|
current_item_total = 0
|
422
|
-
|
434
|
+
|
423
435
|
for item in LoadGenWrapper(load_all_gen(testapp=portal.vapp, inserts=inserts_directory,
|
424
436
|
docsdir=None, overwrite=True, verbose=True)):
|
425
|
-
|
437
|
+
loadxl_total_item_count += 1
|
426
438
|
item = decode_bytes(item)
|
427
439
|
match = LOADXL_RESPONSE_PATTERN.match(item)
|
428
440
|
if not match or match.re.groups < 3:
|
429
441
|
continue
|
430
|
-
action
|
431
|
-
|
432
|
-
|
442
|
+
if (action := LOADXL_ACTION_NAME[match.group(1).upper()]) == "Error":
|
443
|
+
identifying_value = match.group(2)
|
444
|
+
# Example message for unresolved link:
|
445
|
+
# ERROR: /22813a02-906b-4b60-b2b2-4afaea24aa28 Bad response: 422 Unprocessable Entity
|
446
|
+
# (not 200 OK or 3xx redirect for http://localhost/file_set?skip_indexing=true)b\'{"@type":
|
447
|
+
# ["ValidationFailure", "Error"], "status": "error", "code": # 422, "title": "Unprocessable Entity",
|
448
|
+
# "description": "Failed validation", "errors": [{"location": "body", "name": # "Schema: ",
|
449
|
+
# "description": "Unable to resolve link: /Library/a4e8f79f-4d47-4e85-9707-c343c940a315"},
|
450
|
+
# {"location": "body", "name": "Schema: libraries.0",
|
451
|
+
# "description": "\\\'a4e8f79f-4d47-4e85-9707-c343c940a315\\\' not found"}]}\'
|
452
|
+
unresolved_link_error_message_prefix = "Unable to resolve link:"
|
453
|
+
if (i := item.find(unresolved_link_error_message_prefix)) > 0:
|
454
|
+
unresolved_link = item[i + len(unresolved_link_error_message_prefix):].strip()
|
455
|
+
if (i := unresolved_link.find("\"")) > 0:
|
456
|
+
if (unresolved_link := unresolved_link[0:i]):
|
457
|
+
if ((error_type := re.search(r"https?://.*/(.*)\?skip_indexing=.*", item)) and
|
458
|
+
(len(error_type.groups()) == 1)): # noqa
|
459
|
+
error_type = to_camel_case(error_type.group(1))
|
460
|
+
identifying_value = f"/{error_type}{identifying_value}"
|
461
|
+
if not loadxl_unresolved.get(identifying_value):
|
462
|
+
loadxl_unresolved[identifying_value] = []
|
463
|
+
loadxl_unresolved[identifying_value].append(unresolved_link)
|
464
|
+
loadxl_total_error_count += 1
|
465
|
+
continue
|
433
466
|
item_type = match.group(3)
|
434
467
|
if current_item_type != item_type:
|
435
468
|
if noprogress and debug and current_item_type is not None:
|
436
|
-
|
469
|
+
_print()
|
437
470
|
current_item_type = item_type
|
438
471
|
current_item_count = 0
|
439
472
|
current_item_total = schema_names_to_load[item_type]
|
@@ -444,12 +477,13 @@ def _load_data(portal: Portal, load: str, ini_file: str, explicit_schema_name: O
|
|
444
477
|
loadxl_summary[current_item_type] = 0
|
445
478
|
loadxl_summary[current_item_type] += 1
|
446
479
|
if progress_bar:
|
447
|
-
progress_bar.set_progress(
|
480
|
+
progress_bar.set_progress(loadxl_total_item_count)
|
448
481
|
elif debug:
|
449
|
-
|
482
|
+
_print(f"{current_item_type}: {current_item_count} or {current_item_total} ({action})")
|
450
483
|
if progress_bar:
|
451
484
|
progress_bar.set_description("▶ Load Complete")
|
452
|
-
|
485
|
+
if loadxl_total_item_count > loadxl_total_error_count:
|
486
|
+
_print()
|
453
487
|
|
454
488
|
if not portal.vapp:
|
455
489
|
_print("Must using INI based Portal object with --load (use --ini option to specify an INI file).")
|
@@ -573,8 +607,20 @@ def _load_data(portal: Portal, load: str, ini_file: str, explicit_schema_name: O
|
|
573
607
|
_print(f"Done loading data into Portal (via snovault.loadxl) from file: {_single_insert_file}")
|
574
608
|
else:
|
575
609
|
_print(f"Done loading data into Portal (via snovault.loadxl) from directory: {inserts_directory}")
|
610
|
+
_print(f"Total items loaded: {loadxl_total_item_count}"
|
611
|
+
f"{f' (errors: {loadxl_total_error_count})' if loadxl_total_error_count else ''}")
|
576
612
|
for item in sorted(loadxl_summary.keys()):
|
577
613
|
_print(f"▷ {to_camel_case(item)}: {loadxl_summary[item]}")
|
614
|
+
if loadxl_unresolved:
|
615
|
+
_print("✗ Unresolved references:")
|
616
|
+
for item in loadxl_unresolved:
|
617
|
+
_print(f" ▶ {item}: {len(loadxl_unresolved[item])}")
|
618
|
+
for subitem in loadxl_unresolved[item]:
|
619
|
+
_print(f" ▷ {subitem}")
|
620
|
+
if debug and loadxl_output:
|
621
|
+
_print("✗ Output from loadxl:")
|
622
|
+
for item in loadxl_output:
|
623
|
+
_print(f" ▶ {item}")
|
578
624
|
|
579
625
|
return True
|
580
626
|
|
@@ -60,7 +60,7 @@ dcicutils/s3_utils.py,sha256=h2B9ftOo-kxqfiKth5ZDC_cAUFy1Pbu7BrVanFnE5Iw,28839
|
|
60
60
|
dcicutils/schema_utils.py,sha256=GmRm-XqZKJ6qine16SQF1txcby9WougDav_sYmKNs9E,12400
|
61
61
|
dcicutils/scripts/publish_to_pypi.py,sha256=sMd4WASQGlxlh7uLrt2eGkFRXYgONVmvIg8mClMS5RQ,13903
|
62
62
|
dcicutils/scripts/run_license_checker.py,sha256=z2keYnRDZsHQbTeo1XORAXSXNJK5axVzL5LjiNqZ7jE,4184
|
63
|
-
dcicutils/scripts/update_portal_object.py,sha256=
|
63
|
+
dcicutils/scripts/update_portal_object.py,sha256=MsNpF6eHGVxr7dUg8QrwZo9XfIjPjAavOWqyI_RrfpA,38397
|
64
64
|
dcicutils/scripts/view_portal_object.py,sha256=lcgXWH9ooVf7tJDIRnoFGOgT0wYLGhiJlJW3a9w6A_c,36983
|
65
65
|
dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19745
|
66
66
|
dcicutils/sheet_utils.py,sha256=VlmzteONW5VF_Q4vo0yA5vesz1ViUah1MZ_yA1rwZ0M,33629
|
@@ -75,8 +75,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
|
|
75
75
|
dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
|
76
76
|
dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
|
77
77
|
dcicutils/zip_utils.py,sha256=_Y9EmL3D2dUZhxucxHvrtmmlbZmK4FpSsHEb7rGSJLU,3265
|
78
|
-
dcicutils-8.14.0.
|
79
|
-
dcicutils-8.14.0.
|
80
|
-
dcicutils-8.14.0.
|
81
|
-
dcicutils-8.14.0.
|
82
|
-
dcicutils-8.14.0.
|
78
|
+
dcicutils-8.14.0.1b17.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
|
79
|
+
dcicutils-8.14.0.1b17.dist-info/METADATA,sha256=WxgzreGqLqRZT1QRIzME9quTpxihdyduDQKkxX9kdS0,3440
|
80
|
+
dcicutils-8.14.0.1b17.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
81
|
+
dcicutils-8.14.0.1b17.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
|
82
|
+
dcicutils-8.14.0.1b17.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|