@@ -228,7 +228,7 @@ def list_blobs(
228228 if limit is not None :
229229 df = df .head (limit )
230230
231- logging .info (f"Found { len (df ):,} blobs " )
231+ logging .info (f"Found { len (df ):,} blob(s) " )
232232 # List the blobs in the logger
233233 for _ , row in df .iterrows ():
234234 logging .info (f"Blob ID: { row ['id' ]} , Description: { row .get ('description' )} " )
@@ -240,77 +240,6 @@ def get_media_type(file_path: str) -> str:
240240 return mime_type or "application/octet-stream"
241241
242242
243- def main (
244- directive : str ,
245- input_file : str ,
246- blob_id : str ,
247- description : Optional [str ],
248- media_type : Optional [str ],
249- office : str ,
250- api_root : str ,
251- api_key : str ,
252- overwrite : Optional [bool ] = True ,
253- dry_run : Optional [bool ] = False ,
254- ):
255- """
256- Upload, Download, Delete, or Update blob data in CWMS.
257-
258- DIRECTIVE is the action to perform (upload, download, delete, update).
259- INPUT_FILE is the path to the file on disk.
260- BLOB_ID is the blob ID to store under.
261- """
262-
263- cwms .api .init_session (api_root = api_root , api_key = api_key )
264- file_data = None
265- if directive in ["upload" , "update" ]:
266- if not input_file or not os .path .isfile (input_file ):
267- logging .warning (
268- "Valid input_file required for upload/update. Use --input-file to specify."
269- )
270- sys .exit (0 )
271- try :
272- file_size = os .path .getsize (input_file )
273- with open (input_file , "rb" ) as f :
274- file_data = f .read ()
275- logging .info (f"Read file: { input_file } ({ file_size } bytes)" )
276- except Exception as e :
277- logging .error (f"Failed to read file: { e } " )
278- sys .exit (1 )
279-
280- # Determine what should be done based on directive
281- if directive == "upload" :
282- store_blob (
283- office = office ,
284- api_root = api_root ,
285- input_file = input_file ,
286- blob_id = blob_id ,
287- description = description ,
288- media_type = media_type ,
289- file_data = file_data ,
290- overwrite = overwrite ,
291- dry_run = dry_run ,
292- )
293- elif directive == "list" :
294- list_blobs (office = office , blob_id_like = blob_id , sort_by = "blob_id" )
295- elif directive == "download" :
296- retrieve_blob (
297- office = office ,
298- blob_id = blob_id ,
299- )
300- elif directive == "delete" :
301- # TODO: Delete endpoint does not exist in cwms-python yet
302- logging .warning (
303- "[NOT IMPLEMENTED] Delete Blob is not supported yet!\n \t https://github.com/HydrologicEngineeringCenter/cwms-python/issues/192"
304- )
305- pass
306- elif directive == "update" :
307- # TODO: Patch endpoint does not exist in cwms-python yet
308- logging .warning (
309- "[NOT IMPLEMENTED] Update Blob is not supported yet! Consider overwriting instead if a rename is not needed.\n \t https://github.com/HydrologicEngineeringCenter/cwms-python/issues/192"
310- )
311- pass
312-
313-
314243def upload_cmd (
315244 input_file : str ,
316245 blob_id : str ,
@@ -322,7 +251,7 @@ def upload_cmd(
322251 api_root : str ,
323252 api_key : str ,
324253):
325- cwms .api . init_session (api_root = api_root , api_key = get_api_key (api_key , "" ))
254+ cwms .init_session (api_root = api_root , api_key = get_api_key (api_key , "" ))
326255 try :
327256 file_size = os .path .getsize (input_file )
328257 with open (input_file , "rb" ) as f :
@@ -350,7 +279,7 @@ def upload_cmd(
350279 params = {"fail-if-exists" : not overwrite }
351280
352281 if dry_run :
353- logging .info (f"--dry-run : would POST { api_root } blobs with params={ params } " )
282+ logging .info (f"DRY RUN : would POST { api_root } blobs with params={ params } " )
354283 logging .info (
355284 json .dumps (
356285 {
@@ -376,8 +305,15 @@ def upload_cmd(
376305 sys .exit (1 )
377306
378307
379- def download_cmd (blob_id : str , dest : str , office : str , api_root : str , api_key : str ):
380- cwms .api .init_session (api_root = api_root , api_key = get_api_key (api_key , "" ))
308+ def download_cmd (
309+ blob_id : str , dest : str , office : str , api_root : str , api_key : str , dry_run : bool
310+ ):
311+ if dry_run :
312+ logging .info (
313+ f"DRY RUN: would GET { api_root } blob with blob-id={ blob_id } office={ office } ."
314+ )
315+ return
316+ cwms .init_session (api_root = api_root , api_key = get_api_key (api_key , "" ))
381317 bid = blob_id .upper ()
382318 logging .debug (f"Office={ office } BlobID={ bid } " )
383319
@@ -395,18 +331,62 @@ def download_cmd(blob_id: str, dest: str, office: str, api_root: str, api_key: s
395331 sys .exit (1 )
396332
397333
398- def delete_cmd (blob_id : str , office : str , api_root : str , api_key : str ):
399- logging .warning (
400- "[NOT IMPLEMENTED] Delete Blob is not supported yet.\n "
401- "See: https://github.com/HydrologicEngineeringCenter/cwms-python/issues/192"
402- )
334+ def delete_cmd (blob_id : str , office : str , api_root : str , api_key : str , dry_run : bool ):
403335
336+ if dry_run :
337+ logging .info (
338+ f"DRY RUN: would DELETE { api_root } blob with blob-id={ blob_id } office={ office } "
339+ )
340+ return
341+ cwms .init_session (api_root = api_root , api_key = api_key )
342+ cwms .delete_blob (office_id = office , blob_id = blob_id )
343+ logging .info (f"Deleted blob: { blob_id } for office: { office } " )
404344
405- def update_cmd (blob_id : str , input_file : str , office : str , api_root : str , api_key : str ):
406- logging .warning (
407- "[NOT IMPLEMENTED] Update Blob is not supported yet. Consider --overwrite with upload.\n "
408- "See: https://github.com/HydrologicEngineeringCenter/cwms-python/issues/192"
409- )
345+
346+ def update_cmd (
347+ input_file : str ,
348+ blob_id : str ,
349+ description : str ,
350+ media_type : str ,
351+ overwrite : bool ,
352+ dry_run : bool ,
353+ office : str ,
354+ api_root : str ,
355+ api_key : str ,
356+ ):
357+ if dry_run :
358+ logging .info (
359+ f"DRY RUN: would PATCH { api_root } blob with blob-id={ blob_id } office={ office } "
360+ )
361+ return
362+ file_data = None
363+ if input_file :
364+ try :
365+ file_size = os .path .getsize (input_file )
366+ with open (input_file , "rb" ) as f :
367+ file_data = f .read ()
368+ logging .info (f"Read file: { input_file } ({ file_size } bytes)" )
369+ except Exception as e :
370+ logging .error (f"Failed to read file: { e } " )
371+ sys .exit (1 )
372+ # Setup minimum required payload
373+ blob = {"office-id" : office , "id" : blob_id .upper ()}
374+ if description :
375+ blob ["description" ] = description
376+ if media_type :
377+ blob ["media-type-id" ] = media_type
378+ else :
379+ logging .info ("Media type not specified; Retrieving existing media type..." )
380+ blob_metadata = cwms .get_blobs (office_id = office , blob_id_like = blob_id )
381+ blob ["media-type-id" ] = blob_metadata .df .get (
382+ "media-type-id" , "application/octet-stream"
383+ )[0 ]
384+ logging .info (f"Using existing media type: { blob ['media-type-id' ]} " )
385+
386+ if file_data :
387+ blob ["value" ] = base64 .b64encode (file_data ).decode ("utf-8" )
388+ cwms .init_session (api_root = api_root , api_key = api_key )
389+ cwms .update_blob (blob , fail_if_not_exists = not overwrite )
410390
411391
412392def list_cmd (
@@ -420,7 +400,7 @@ def list_cmd(
420400 api_root : str ,
421401 api_key : str ,
422402):
423- cwms .api . init_session (api_root = api_root , api_key = get_api_key (api_key , None ))
403+ cwms .init_session (api_root = api_root , api_key = get_api_key (api_key , None ))
424404 df = list_blobs (
425405 office = office ,
426406 blob_id_like = blob_id_like ,
0 commit comments