dcicutils 8.14.0.1b3__py3-none-any.whl → 8.14.0.1b5__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.
@@ -236,6 +236,7 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
236
236
  _print(f"DEBUG: File ({file}) contains a dictionary of schema names.")
237
237
  for schema_name in data:
238
238
  if isinstance(schema_data := data[schema_name], list):
239
+ schema_data = _impose_special_ordering(schema_data, schema_name)
239
240
  if debug:
240
241
  _print(f"DEBUG: Processing {update_action_name}s for type: {schema_name}")
241
242
  for index, item in enumerate(schema_data):
@@ -250,6 +251,8 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
250
251
  elif isinstance(data, list):
251
252
  if debug:
252
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)
253
256
  for index, item in enumerate(data):
254
257
  update_function(portal, item, schema_name, file=file, index=index,
255
258
  patch_delete_fields=patch_delete_fields,
@@ -286,6 +289,12 @@ def _post_or_patch_or_upsert(portal: Portal, file_or_directory: str,
286
289
  _print(f"ERROR: Cannot find file or directory: {file_or_directory}")
287
290
 
288
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
+
289
298
  def post_data(portal: Portal, data: dict, schema_name: str,
290
299
  file: Optional[str] = None, index: int = 0,
291
300
  patch_delete_fields: Optional[str] = None,
@@ -66,7 +66,7 @@ from typing import Callable, List, Optional, TextIO, Tuple, Union
66
66
  import yaml
67
67
  from dcicutils.captured_output import captured_output, uncaptured_output
68
68
  from dcicutils.command_utils import yes_or_no
69
- from dcicutils.misc_utils import get_error_message, is_uuid, PRINT
69
+ from dcicutils.misc_utils import get_error_message, is_uuid, PRINT, to_snake_case
70
70
  from dcicutils.portal_utils import Portal
71
71
 
72
72
 
@@ -104,6 +104,8 @@ 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("--insert-files", action="store_true", required=False, default=False,
108
+ help="Output for to insert files.")
107
109
  parser.add_argument("--ignore", nargs="+", help="Ignore these fields for --inserts.")
108
110
  parser.add_argument("--tree", action="store_true", required=False, default=False, help="Tree output for schemas.")
109
111
  parser.add_argument("--database", action="store_true", required=False, default=False,
@@ -117,6 +119,7 @@ def main():
117
119
  parser.add_argument("--indent", required=False, default=False, help="Indent output.", type=int)
118
120
  parser.add_argument("--summary", action="store_true", required=False, default=False,
119
121
  help="Summary output (for schema only).")
122
+ parser.add_argument("--force", action="store_true", required=False, default=False, help="Debugging output.")
120
123
  parser.add_argument("--terse", action="store_true", required=False, default=False, help="Terse output.")
121
124
  parser.add_argument("--verbose", action="store_true", required=False, default=False, help="Verbose output.")
122
125
  parser.add_argument("--debug", action="store_true", required=False, default=False, help="Debugging output.")
@@ -129,6 +132,15 @@ def main():
129
132
  _print("UUID or schema or path required.")
130
133
  _exit(1)
131
134
 
135
+ if args.insert_files:
136
+ args.inserts = True
137
+ if args.output:
138
+ if not os.path.isdir(args.output):
139
+ _print(f"Specified output directory for insert files does not exist: {args.output}")
140
+ exit(1)
141
+ args.insert_files = args.output
142
+ args.output = None
143
+
132
144
  if args.output:
133
145
  if os.path.exists(args.output):
134
146
  if os.path.isdir(args.output):
@@ -136,7 +148,7 @@ def main():
136
148
  _exit(1)
137
149
  elif os.path.isfile(args.output):
138
150
  _print(f"Specified output file already exists: {args.output}")
139
- if not yes_or_no(f"Do you want to overwrite this file?"):
151
+ if (not args.force) and not yes_or_no(f"Do you want to overwrite this file?"):
140
152
  _exit(0)
141
153
  _output_file = io.open(args.output, "w")
142
154
 
@@ -191,8 +203,12 @@ def main():
191
203
  all=args.all, summary=args.summary, yaml=args.yaml)
192
204
  return
193
205
 
194
- data = _get_portal_object(portal=portal, uuid=args.uuid, raw=args.raw, inserts=args.inserts,
195
- ignore=args.ignore, database=args.database, check=args.bool, verbose=args.verbose)
206
+ data = _get_portal_object(portal=portal, uuid=args.uuid, raw=args.raw, database=args.database,
207
+ inserts=args.inserts, insert_files=args.insert_files,
208
+ ignore=args.ignore, check=args.bool, force=args.force, verbose=args.verbose)
209
+ if args.insert_files:
210
+ return
211
+
196
212
  if args.bool:
197
213
  if data:
198
214
  _print(f"{args.uuid}: found")
@@ -242,9 +258,10 @@ def _create_portal(ini: str, env: Optional[str] = None,
242
258
 
243
259
 
244
260
  def _get_portal_object(portal: Portal, uuid: str,
245
- raw: bool = False, inserts: bool = False, database: bool = False,
261
+ raw: bool = False, database: bool = False,
262
+ inserts: bool = False, insert_files: bool = False,
246
263
  ignore: Optional[List[str]] = None,
247
- check: bool = False, verbose: bool = False) -> dict:
264
+ check: bool = False, force: bool = False, verbose: bool = False) -> dict:
248
265
 
249
266
  def prune_data(data: dict) -> dict:
250
267
  nonlocal ignore
@@ -324,6 +341,28 @@ def _get_portal_object(portal: Portal, uuid: str,
324
341
  elif ((response_cooked := portal.get(path, database=database)) and
325
342
  (isinstance(response_type := response_cooked.json().get("@type"), list) and response_type)):
326
343
  response = {f"{response_type[0]}": [prune_data(response)]}
344
+ if insert_files:
345
+ output_directory = insert_files if isinstance(insert_files, str) else os.getcwd()
346
+ for schema_name in response:
347
+ schema_data = response[schema_name]
348
+ file_name = f"{to_snake_case(schema_name)}.json"
349
+ file_path = os.path.join(output_directory, file_name)
350
+ if os.path.exists(file_path):
351
+ if os.path.isdir(file_path):
352
+ _print(f"WARNING: Output file already exists as a directory. SKIPPING: {file_path}")
353
+ continue
354
+ if force:
355
+ if verbose:
356
+ _print(f"Overwriting extant file (per --force option): {file_path}")
357
+ else:
358
+ _print(f"Output file already exists: {file_path}")
359
+ if (not force) and not yes_or_no(f"Overwrite this file?"):
360
+ continue
361
+ if verbose:
362
+ _print(f"Writing {schema_name} (object{'s' if len(schema_data) != 1 else ''}:"
363
+ f" {len(schema_data)}) file: {file_path}")
364
+ with io.open(file_path, "w") as f:
365
+ json.dump(schema_data, f, indent=4)
327
366
  elif raw:
328
367
  response.pop("schema_version", None)
329
368
  return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 8.14.0.1b3
3
+ Version: 8.14.0.1b5
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=qo_TGji-naaK2UXa-VbCfTSMsvRSEduqbQDuVXX3y4g,22188
64
- dcicutils/scripts/view_portal_object.py,sha256=6day_AXtFf9y4oYNvZC_fGa-h9xQKbNwUBuoluVcuiI,33691
63
+ dcicutils/scripts/update_portal_object.py,sha256=bkadJlw3pJGLid8GXrNiZG0PWD9hvy4klGUNQhgjRhI,22610
64
+ dcicutils/scripts/view_portal_object.py,sha256=RgNlX-AObLlOQ8flc3MxFAxsaXqMsswkH_jLsGLUScE,35778
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.1b3.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
- dcicutils-8.14.0.1b3.dist-info/METADATA,sha256=iuq31-VVzXhHa2-CxoblCc7iu0CgVP7hT4hXWU75szQ,3439
80
- dcicutils-8.14.0.1b3.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
- dcicutils-8.14.0.1b3.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
- dcicutils-8.14.0.1b3.dist-info/RECORD,,
78
+ dcicutils-8.14.0.1b5.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
+ dcicutils-8.14.0.1b5.dist-info/METADATA,sha256=V2K3KDP_z_RIjiAwxfAfxg3t0X-htcbhpo-1EmJtH5I,3439
80
+ dcicutils-8.14.0.1b5.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
+ dcicutils-8.14.0.1b5.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
+ dcicutils-8.14.0.1b5.dist-info/RECORD,,