dcicutils 8.14.0.1b2__py3-none-any.whl → 8.14.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.
@@ -123,7 +123,8 @@ def main():
123
123
  parser.add_argument("--delete", type=str, required=False, default=None, help="Delete data.")
124
124
  parser.add_argument("--purge", type=str, required=False, default=None, help="Purge data.")
125
125
  parser.add_argument("--noignore", action="store_true", required=False, default=False,
126
- help="Do not ignore standard fields on insert.")
126
+ help="Do not ignore standard fields on update(s).")
127
+ parser.add_argument("--ignore", nargs="+", help="Ignore these additional fields.")
127
128
  parser.add_argument("--confirm", action="store_true", required=False, default=False, help="Confirm before action.")
128
129
  parser.add_argument("--verbose", action="store_true", required=False, default=False, help="Verbose output.")
129
130
  parser.add_argument("--quiet", action="store_true", required=False, default=False, help="Quiet output.")
@@ -158,7 +159,7 @@ def main():
158
159
  explicit_schema_name=explicit_schema_name,
159
160
  update_function=post_data,
160
161
  update_action_name="POST",
161
- noignore=args.noignore,
162
+ noignore=args.noignore, ignore=args.ignore,
162
163
  confirm=args.confirm, verbose=args.verbose, quiet=args.quiet, debug=args.debug)
163
164
  if args.patch:
164
165
  _post_or_patch_or_upsert(portal=portal,
@@ -167,7 +168,7 @@ def main():
167
168
  update_function=patch_data,
168
169
  update_action_name="PATCH",
169
170
  patch_delete_fields=args.delete,
170
- noignore=args.noignore,
171
+ noignore=args.noignore, ignore=args.ignore,
171
172
  confirm=args.confirm, verbose=args.verbose, quiet=args.quiet, debug=args.debug)
172
173
  args.delete = None
173
174
  if args.upsert:
@@ -177,7 +178,7 @@ def main():
177
178
  update_function=upsert_data,
178
179
  update_action_name="UPSERT",
179
180
  patch_delete_fields=args.delete,
180
- noignore=args.noignore,
181
+ noignore=args.noignore, ignore=args.ignore,
181
182
  confirm=args.confirm, verbose=args.verbose, quiet=args.quiet, debug=args.debug)
182
183
  args.delete = None
183
184
 
@@ -201,7 +202,7 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
201
202
  explicit_schema_name: str,
202
203
  update_function: Callable, update_action_name: str,
203
204
  patch_delete_fields: Optional[str] = None,
204
- noignore: bool = False,
205
+ noignore: bool = False, ignore: Optional[List[str]] = None,
205
206
  confirm: bool = False, verbose: bool = False,
206
207
  quiet: bool = False, debug: bool = False) -> None:
207
208
 
@@ -227,18 +228,21 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
227
228
  if debug:
228
229
  _print(f"DEBUG: File ({file}) contains an object of type: {schema_name}")
229
230
  update_function(portal, data, schema_name, file=file,
230
- patch_delete_fields=patch_delete_fields, noignore=noignore,
231
+ patch_delete_fields=patch_delete_fields,
232
+ noignore=noignore, ignore=ignore,
231
233
  confirm=confirm, verbose=verbose, debug=debug)
232
234
  elif is_schema_name_list(portal, list(data.keys())):
233
235
  if debug:
234
236
  _print(f"DEBUG: File ({file}) contains a dictionary of schema names.")
235
237
  for schema_name in data:
236
238
  if isinstance(schema_data := data[schema_name], list):
239
+ schema_data = _impose_special_ordering(schema_data, schema_name)
237
240
  if debug:
238
241
  _print(f"DEBUG: Processing {update_action_name}s for type: {schema_name}")
239
242
  for index, item in enumerate(schema_data):
240
243
  update_function(portal, item, schema_name, file=file, index=index,
241
- patch_delete_fields=patch_delete_fields, noignore=noignore,
244
+ patch_delete_fields=patch_delete_fields,
245
+ noignore=noignore, ignore=ignore,
242
246
  confirm=confirm, verbose=verbose, debug=debug)
243
247
  else:
244
248
  _print(f"WARNING: File ({file}) contains schema item which is not a list: {schema_name}")
@@ -247,9 +251,12 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
247
251
  elif isinstance(data, list):
248
252
  if debug:
249
253
  _print(f"DEBUG: File ({file}) contains a list of objects of type: {schema_name}")
254
+ import pdb ; pdb.set_trace() # noqa
255
+ data = _impose_special_ordering(data, schema_name)
250
256
  for index, item in enumerate(data):
251
257
  update_function(portal, item, schema_name, file=file, index=index,
252
- patch_delete_fields=patch_delete_fields, noignore=noignore,
258
+ patch_delete_fields=patch_delete_fields,
259
+ noignore=noignore, ignore=ignore,
253
260
  confirm=confirm, verbose=verbose, debug=debug)
254
261
  if debug:
255
262
  _print(f"DEBUG: Processing {update_action_name} file done: {file}")
@@ -282,9 +289,16 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
282
289
  _print(f"ERROR: Cannot find file or directory: {file_or_directory}")
283
290
 
284
291
 
292
+ def _impose_special_ordering(data: List[dict], schema_name: str) -> List[dict]:
293
+ if schema_name == "FileFormat":
294
+ return sorted(data, key=lambda item: "extra_file_formats" in item)
295
+ return data
296
+
297
+
285
298
  def post_data(portal: Portal, data: dict, schema_name: str,
286
299
  file: Optional[str] = None, index: int = 0,
287
- patch_delete_fields: Optional[str] = None, noignore: bool = False,
300
+ patch_delete_fields: Optional[str] = None,
301
+ noignore: bool = False, ignore: Optional[List[str]] = None,
288
302
  confirm: bool = False, verbose: bool = False, debug: bool = False) -> None:
289
303
  ignored(patch_delete_fields)
290
304
  if not (identifying_path := portal.get_identifying_path(data, portal_type=schema_name)):
@@ -301,7 +315,7 @@ def post_data(portal: Portal, data: dict, schema_name: str,
301
315
  if verbose:
302
316
  _print(f"POST {schema_name} item: {identifying_path}")
303
317
  try:
304
- data = _prune_data_for_update(data, noignore=noignore)
318
+ data = _prune_data_for_update(data, noignore=noignore, ignore=ignore)
305
319
  portal.post_metadata(schema_name, data)
306
320
  if debug:
307
321
  _print(f"DEBUG: POST {schema_name} item done: {identifying_path}")
@@ -313,7 +327,8 @@ def post_data(portal: Portal, data: dict, schema_name: str,
313
327
 
314
328
  def patch_data(portal: Portal, data: dict, schema_name: str,
315
329
  file: Optional[str] = None, index: int = 0,
316
- patch_delete_fields: Optional[str] = None, noignore: bool = False,
330
+ patch_delete_fields: Optional[str] = None,
331
+ noignore: bool = False, ignore: Optional[List[str]] = None,
317
332
  confirm: bool = False, verbose: bool = False, debug: bool = False) -> None:
318
333
  if not (identifying_path := portal.get_identifying_path(data, portal_type=schema_name)):
319
334
  if isinstance(file, str) and isinstance(index, int):
@@ -331,7 +346,7 @@ def patch_data(portal: Portal, data: dict, schema_name: str,
331
346
  try:
332
347
  if delete_fields := _parse_delete_fields(patch_delete_fields):
333
348
  identifying_path += f"?delete_fields={delete_fields}"
334
- data = _prune_data_for_update(data, noignore=noignore)
349
+ data = _prune_data_for_update(data, noignore=noignore, ignore=ignore)
335
350
  portal.patch_metadata(identifying_path, data)
336
351
  if debug:
337
352
  _print(f"DEBUG: PATCH {schema_name} item OK: {identifying_path}")
@@ -343,7 +358,8 @@ def patch_data(portal: Portal, data: dict, schema_name: str,
343
358
 
344
359
  def upsert_data(portal: Portal, data: dict, schema_name: str,
345
360
  file: Optional[str] = None, index: int = 0,
346
- patch_delete_fields: Optional[str] = None, noignore: bool = False,
361
+ patch_delete_fields: Optional[str] = None,
362
+ noignore: bool = False, ignore: Optional[List[str]] = None,
347
363
  confirm: bool = False, verbose: bool = False, debug: bool = False) -> None:
348
364
  if not (identifying_path := portal.get_identifying_path(data, portal_type=schema_name)):
349
365
  if isinstance(file, str) and isinstance(index, int):
@@ -358,12 +374,12 @@ def upsert_data(portal: Portal, data: dict, schema_name: str,
358
374
  _print(f"{'PATCH' if exists else 'POST'} {schema_name} item: {identifying_path}")
359
375
  try:
360
376
  if not exists:
361
- data = _prune_data_for_update(data, noignore=noignore)
377
+ data = _prune_data_for_update(data, noignore=noignore, ignore=ignore)
362
378
  portal.post_metadata(schema_name, data)
363
379
  else:
364
380
  if delete_fields := _parse_delete_fields(patch_delete_fields):
365
381
  identifying_path += f"?delete_fields={delete_fields}"
366
- data = _prune_data_for_update(data, noignore=noignore)
382
+ data = _prune_data_for_update(data, noignore=noignore, ignore=ignore)
367
383
  portal.patch_metadata(identifying_path, data)
368
384
  if debug:
369
385
  _print(f"DEBUG: UPSERT {schema_name} item OK: {identifying_path}")
@@ -373,10 +389,13 @@ def upsert_data(portal: Portal, data: dict, schema_name: str,
373
389
  return
374
390
 
375
391
 
376
- def _prune_data_for_update(data: dict, noignore: bool = False) -> dict:
377
- if noignore is True:
392
+ def _prune_data_for_update(data: dict, noignore: bool = False, ignore: Optional[List[str]] = None) -> dict:
393
+ ignore_these_properties = [] if noignore is True else _IGNORE_PROPERTIES_ON_UPDATE
394
+ if isinstance(ignore, list):
395
+ ignore_these_properties = ignore_these_properties + ignore
396
+ if not ignore_these_properties:
378
397
  return data
379
- return {key: value for key, value in data.items() if key not in _IGNORE_PROPERTIES_ON_UPDATE}
398
+ return {key: value for key, value in data.items() if key not in ignore_these_properties}
380
399
 
381
400
 
382
401
  def _create_portal(env: Optional[str] = None, app: Optional[str] = None,
@@ -104,6 +104,7 @@ def main():
104
104
  parser.add_argument("--raw", action="store_true", required=False, default=False, help="Raw output.")
105
105
  parser.add_argument("--inserts", action="store_true", required=False, default=False,
106
106
  help="Format output for subsequent inserts.")
107
+ parser.add_argument("--ignore", nargs="+", help="Ignore these fields for --inserts.")
107
108
  parser.add_argument("--tree", action="store_true", required=False, default=False, help="Tree output for schemas.")
108
109
  parser.add_argument("--database", action="store_true", required=False, default=False,
109
110
  help="Read from database output.")
@@ -191,7 +192,7 @@ def main():
191
192
  return
192
193
 
193
194
  data = _get_portal_object(portal=portal, uuid=args.uuid, raw=args.raw, inserts=args.inserts,
194
- database=args.database, check=args.bool, verbose=args.verbose)
195
+ ignore=args.ignore, database=args.database, check=args.bool, verbose=args.verbose)
195
196
  if args.bool:
196
197
  if data:
197
198
  _print(f"{args.uuid}: found")
@@ -242,7 +243,15 @@ def _create_portal(ini: str, env: Optional[str] = None,
242
243
 
243
244
  def _get_portal_object(portal: Portal, uuid: str,
244
245
  raw: bool = False, inserts: bool = False, database: bool = False,
246
+ ignore: Optional[List[str]] = None,
245
247
  check: bool = False, verbose: bool = False) -> dict:
248
+
249
+ def prune_data(data: dict) -> dict:
250
+ nonlocal ignore
251
+ if not isinstance(ignore, list) or not ignore:
252
+ return data
253
+ return {key: value for key, value in data.items() if key not in ignore}
254
+
246
255
  response = None
247
256
  try:
248
257
  if not uuid.startswith("/"):
@@ -300,6 +309,7 @@ def _get_portal_object(portal: Portal, uuid: str,
300
309
  for result in results:
301
310
  results_index += 1
302
311
  result.pop("schema_version", None)
312
+ result = prune_data(result)
303
313
  if (subtypes and
304
314
  (result_uuid := result.get("uuid")) and
305
315
  (individual_result_type := get_metadata_for_individual_result_type(result_uuid))): # noqa
@@ -313,7 +323,7 @@ def _get_portal_object(portal: Portal, uuid: str,
313
323
  # Get the result as non-raw so we can get its type.
314
324
  elif ((response_cooked := portal.get(path, database=database)) and
315
325
  (isinstance(response_type := response_cooked.json().get("@type"), list) and response_type)):
316
- response = {f"{response_type[0]}": [response]}
326
+ response = {f"{response_type[0]}": [prune_data(response)]}
317
327
  elif raw:
318
328
  response.pop("schema_version", None)
319
329
  return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 8.14.0.1b2
3
+ Version: 8.14.0.1b4
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
@@ -60,8 +60,8 @@ 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=gIO0fz6_SrfttYrdhfX7BVAYdtC4VZDXomycPrNWdbI,21395
64
- dcicutils/scripts/view_portal_object.py,sha256=yQAGxFWBZ7UU8vrD8xbeI_oS4oU2mXZBaQPCraLbdCU,33241
63
+ dcicutils/scripts/update_portal_object.py,sha256=bkadJlw3pJGLid8GXrNiZG0PWD9hvy4klGUNQhgjRhI,22610
64
+ dcicutils/scripts/view_portal_object.py,sha256=6day_AXtFf9y4oYNvZC_fGa-h9xQKbNwUBuoluVcuiI,33691
65
65
  dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19745
66
66
  dcicutils/sheet_utils.py,sha256=VlmzteONW5VF_Q4vo0yA5vesz1ViUah1MZ_yA1rwZ0M,33629
67
67
  dcicutils/snapshot_utils.py,sha256=YDeI3vD-MhAtHwKDzfEm2q-n3l-da2yRpRR3xp0Ah1M,23021
@@ -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.1b2.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
- dcicutils-8.14.0.1b2.dist-info/METADATA,sha256=uiJoLtk6VKcjRjvIlCDmF_8ADNo31t_Kuf1fxtv5OBM,3439
80
- dcicutils-8.14.0.1b2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
- dcicutils-8.14.0.1b2.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
- dcicutils-8.14.0.1b2.dist-info/RECORD,,
78
+ dcicutils-8.14.0.1b4.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
+ dcicutils-8.14.0.1b4.dist-info/METADATA,sha256=oCoIibABt6sbGex5upf6kouWpbqPgHubKlzmzPrmGKQ,3439
80
+ dcicutils-8.14.0.1b4.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
+ dcicutils-8.14.0.1b4.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
+ dcicutils-8.14.0.1b4.dist-info/RECORD,,