66import logging
77import asyncio
88import aiohttp
9- from medimgkit .dicom_utils import anonymize_dicom , to_bytesio , is_dicom , is_dicom_report
9+ from medimgkit .dicom_utils import anonymize_dicom , to_bytesio , is_dicom , is_dicom_report , GeneratorWithLength
1010from medimgkit import dicom_utils , standardize_mimetype
1111from medimgkit .io_utils import is_io_object , peek
1212from medimgkit .format_detection import guess_typez , guess_extension , DEFAULT_MIME_TYPE
@@ -185,9 +185,7 @@ async def _upload_single_resource_async(self,
185185 resp_data = await self ._run_request_async (request_params , session )
186186 if 'error' in resp_data :
187187 raise DatamintException (resp_data ['error' ])
188- _LOGGER .info (f"Response on uploading { name } : { resp_data } " )
189-
190- _USER_LOGGER .info (f'"{ name } " uploaded' )
188+ _LOGGER .debug (f"Response on uploading { name } : { resp_data } " )
191189 return resp_data ['id' ]
192190 except Exception as e :
193191 if 'name' in locals ():
@@ -212,6 +210,7 @@ async def _upload_resources_async(self,
212210 segmentation_files : Optional [list [dict ]] = None ,
213211 transpose_segmentation : bool = False ,
214212 metadata_files : Optional [list [str | dict | None ]] = None ,
213+ progress_bar : tqdm | None = None ,
215214 ) -> list [str ]:
216215 if on_error not in ['raise' , 'skip' ]:
217216 raise ValueError ("on_error must be either 'raise' or 'skip'" )
@@ -225,6 +224,8 @@ async def _upload_resources_async(self,
225224 async with aiohttp .ClientSession () as session :
226225 async def __upload_single_resource (file_path , segfiles : dict [str , list | dict ],
227226 metadata_file : str | dict | None ):
227+ name = file_path .name if is_io_object (file_path ) else file_path
228+ name = os .path .basename (name )
228229 rid = await self ._upload_single_resource_async (
229230 file_path = file_path ,
230231 mimetype = mimetype ,
@@ -238,6 +239,12 @@ async def __upload_single_resource(file_path, segfiles: dict[str, list | dict],
238239 publish = publish ,
239240 metadata_file = metadata_file ,
240241 )
242+ if progress_bar :
243+ progress_bar .update (1 )
244+ progress_bar .set_postfix (file = name )
245+ else :
246+ _USER_LOGGER .info (f'"{ name } " uploaded' )
247+
241248 if segfiles is not None :
242249 fpaths = segfiles ['files' ]
243250 names = segfiles .get ('names' , _infinite_gen (None ))
@@ -295,7 +302,9 @@ def _assemble_dicoms(self, files_path: Sequence[str | IO]
295302 if new_len != orig_len :
296303 _LOGGER .info (f"Assembled { new_len } dicom files out of { orig_len } files." )
297304 mapping_idx = [None ] * len (files_path )
298- files_path = itertools .chain (dicoms_files_path , other_files_path )
305+
306+ files_path = GeneratorWithLength (itertools .chain (dicoms_files_path , other_files_path ),
307+ length = new_len + len (other_files_path ))
299308 assembled = True
300309 for orig_idx , value in zip (dicom_original_idxs , dicoms_files_path .inverse_mapping_idx ):
301310 mapping_idx [orig_idx ] = value
@@ -391,7 +400,8 @@ def upload_resource(self,
391400 transpose_segmentation = transpose_segmentation ,
392401 modality = modality ,
393402 assemble_dicoms = assemble_dicoms ,
394- metadata = metadata
403+ metadata = metadata ,
404+ progress_bar = False
395405 )
396406
397407 return result [0 ]
@@ -412,7 +422,8 @@ def upload_resources(self,
412422 modality : Optional [str ] = None ,
413423 assemble_dicoms : bool = True ,
414424 metadata : list [str | dict | None ] | dict | str | None = None ,
415- discard_dicom_reports : bool = True
425+ discard_dicom_reports : bool = True ,
426+ progress_bar : bool = False
416427 ) -> list [str | Exception ] | str | Exception :
417428 """
418429 Upload resources.
@@ -485,6 +496,11 @@ def upload_resources(self,
485496 assemble_dicoms = assembled
486497 else :
487498 mapping_idx = [i for i in range (len (files_path ))]
499+ n_files = len (files_path )
500+
501+ if n_files <= 1 :
502+ # Disable progress bar for single file uploads
503+ progress_bar = False
488504
489505 if segmentation_files is not None :
490506 if assemble_dicoms :
@@ -513,22 +529,32 @@ def upload_resources(self,
513529 "segmentation_files['names'] must have the same length as segmentation_files['files']." )
514530
515531 loop = asyncio .get_event_loop ()
516- task = self ._upload_resources_async (files_path = files_path ,
517- mimetype = mimetype ,
518- anonymize = anonymize ,
519- anonymize_retain_codes = anonymize_retain_codes ,
520- on_error = on_error ,
521- tags = tags ,
522- mung_filename = mung_filename ,
523- channel = channel ,
524- publish = publish ,
525- segmentation_files = segmentation_files ,
526- transpose_segmentation = transpose_segmentation ,
527- modality = modality ,
528- metadata_files = metadata ,
529- )
530-
531- resource_ids = loop .run_until_complete (task )
532+ pbar = None
533+ try :
534+ if progress_bar :
535+ pbar = tqdm (total = n_files , desc = "Uploading resources" , unit = "file" )
536+
537+ task = self ._upload_resources_async (files_path = files_path ,
538+ mimetype = mimetype ,
539+ anonymize = anonymize ,
540+ anonymize_retain_codes = anonymize_retain_codes ,
541+ on_error = on_error ,
542+ tags = tags ,
543+ mung_filename = mung_filename ,
544+ channel = channel ,
545+ publish = publish ,
546+ segmentation_files = segmentation_files ,
547+ transpose_segmentation = transpose_segmentation ,
548+ modality = modality ,
549+ metadata_files = metadata ,
550+ progress_bar = pbar
551+ )
552+
553+ resource_ids = loop .run_until_complete (task )
554+ finally :
555+ if pbar :
556+ pbar .close ()
557+
532558 _LOGGER .info (f"Resources uploaded: { resource_ids } " )
533559
534560 if publish_to is not None :
0 commit comments