def test_get_labels_with_right_params(self, mock_response): id = uuid.uuid4() project_id = uuid.uuid4() response = mock_response.return_value response.status_code = 200 response.json.return_value = { 'data': { 'labels': { 'count': 100, 'edges': [{ 'id': id, 'projectId': project_id }] } } } manager = LabelManager() count, labels = manager.get_labels(project_id, page=0, page_size=10) self.assertEqual(count, 100) self.assertEqual(len(labels), 1) label = labels[0] self.assertEqual(label.id, id) self.assertEqual(label.project_id, project_id)
def update_data(self): manager = LabelManager() build_params = self._label_build_params if self._data.workapp == WorkappType.IMAGE_SIESTA.value else None self._data = manager.update_label(label=self._data, info_build_params=build_params) if build_params is not None: self._init_label_build_info()
def test_get_labels_count(self, mock_response): response = mock_response.return_value response.status_code = 200 response.json.return_value = {'data': {'labels': {'count': 3}}} manager = LabelManager() count = manager.get_labels_count( project_id="29e6f25e-ac75-4882-9025-6ff73fd94cb1") self.assertEqual(count, 3)
def set_tags(self, tags: list = None): real_tags = [] if tags is not None and isinstance(tags, list): for tag in tags: real_tags.append(Tags(name=tag)) manager = LabelManager() self._data = manager.update_label_tags(label=self._data, tags=real_tags)
def test_get_label_detail_with_right_params(self, mock_response): response = mock_response.return_value response.status_code = 200 response.json.return_value = { "data": { "labels": { "count": 1, "edges": [{ "id": "29e6f25e-ac75-4882-9025-6ff73fd94cb1", "dataset": "dfdf", "dataKey": "Untitled.png", "tags": [{ "id": "2566992b-78a0-4ea0-9677-6811677d5e45", "name": "A" }], "result": { "objects": [{ "id": 1, "class": "person", "shape": { "box": { "x": 67.07317073170731, "y": 52.92682926829268, "width": 53.04878048780488, "height": 202.9268292682927 } }, "properties": [{ "name": "abc", "value": "a" }] }], "categorization": { "value": [] } }, "info_read_presigned_url": None, "info_write_presigned_url": None }] } } } label = Label(id=uuid.uuid4(), project_id=uuid.uuid4()) manager = LabelManager() manager.get_label(project_id=label.project_id, id=label.id)
def get_num_data(self, tags=[], **kwargs): if self._project is None: print('[WARNING] Project is not described') return None manager = LabelManager() tags = [{'name': tag} for tag in tags] option = {'project_id': self._project.id, 'tags': tags, **kwargs} num_data = manager.get_labels_count(**option) if num_data == 0: print('[WARNING] Data list is empty') return num_data
def test_get_0_labels_with_right_params(self, mock_response): response = mock_response.return_value response.status_code = 200 response.json.return_value = { 'data': { 'labels': { 'count': 0, 'edges': [] } } } manager = LabelManager() count, labels = manager.get_labels(project_id=uuid.uuid4(), page=0, page_size=10) self.assertEqual(count, 0) self.assertEqual(len(labels), 0)
def get_data_page(self, page_idx, page_size=10, num_data=None, tags=[], dataset=None, data_key=None, **kwargs): if num_data is None: num_data = self.get_num_data(tags=tags, **kwargs) num_pages = math.ceil(float(num_data) / page_size) if page_idx >= num_pages: print('[WARNING] Index out of bounds. Empty list returned') return [] workapp = self._project.workapp if workapp == 'video-siesta': # Video command = spb.Command(type='describe_videolabel') tags = [{'name': tag} for tag in tags] option = {'project_id': self._project.id, 'tags': tags, **kwargs} data_page, _ = spb.run(command=command, option=option, page=page_idx + 1, page_size=page_size) for data in data_page: yield VideoDataHandle(data, self._project) else: manager = LabelManager() tags = [{'name': tag} for tag in tags] option = { 'project_id': self._project.id, 'tags': tags, 'page': page_idx + 1, 'page_size': page_size, 'dataset': dataset, 'data_key': data_key, **kwargs } count, data_page = manager.get_labels(**option) for data in data_page: yield DataHandle(data, self._project)
def __init__(self, data, project): super().__init__() manager = LabelManager() if data.project_id is None or data.id is None: print('[ERROR] Data Handler cannot be initiated.') return self._data = data self._project = project self._created = time.time() if self._data.workapp == WorkappType.IMAGE_SIESTA.value: self._init_label_build_info()
def setUp(self): self.attrs = { 'id': uuid.uuid4(), 'project_id': uuid.uuid4(), 'tags': [Tags(name='TAG1'), Tags(name='TAG2')], 'status': '', 'stats': [Stats(name='STATS1', count=10)], 'data_id': uuid.uuid4(), 'dataset': 'TEST_DATASET_NAME', # [dataUrl] Init with property name -> To use response to model instance 'dataUrl': 'https://superb-ai.com', 'data': 'NOT YET IMPLEMENTED', 'result': { 'result': [] }, 'work_assignee': '*****@*****.**', 'label_type': '', 'related_label_method': '', 'consensus_status': '', 'consistency_score': 0.0 } self.label_manager = LabelManager()
def test_update_label(self, mock_response): response = mock_response.return_value response.status_code = 200 response.json.return_value = { "data": { "updateLabels": { "id": "29e6f25e-ac75-4882-9025-6ff73fd94cb1", "projectId": "b2a7205f-4f2a-4eb2-b845-3ed6af9a9fc5", "tags": [{ "id": "2566992b-78a0-4ea0-9677-6811677d5e45", "name": "A" }], "status": "SUBMITTED", "stats": [{ "name": "person", "count": 1 }], "workAssignee": "*****@*****.**", "labelType": "MAIN_LABEL", "relatedLabelMethod": "", "consensusStatus": "", "consistencyScore": 0, "dataId": "90722177-24f1-469f-9372-bb180f2a8c5e", "dataset": "dfdf", "dataKey": "Untitled.png", "dataUrl": "https://suite-asset.dev.superb-ai.com/apne2/tenants/pingu/assets/90722177-24f1-469f-9372-bb180f2a8c5e/image.png?Expires=1618384778&Signature=DEBpBduQI83HdfW6rouMxZiF73QvKp3teIpsvwcPvJGlSomN8GxiyOiTVE5R-5piJVhMCzbrAc~kbPFGgkciBceQEJOGMGxRnxlL4esAyMYzy28jETDwQpeXxHb5FYsYVe3YfRABaz8B2OOV1r2KElxW3NntEEc~6kcmbRPXKswZRFiXvYm1QPgAnUuaDHSzRBS8XKhB-jLhGFHfIzrrn47bazp1~aJIVfMRqgH8-7xhvVeEB65ijLuSmELQqg-S~pEmtfXQKeQ0z62Rlgn9IDkNiTo1gZf~r5kx0Wgf-yNyoyII2kiGvkRB8FqRuevU7hHsjk5B9fGj12sJRbm2lw__&Key-Pair-Id=APKAIBKPXKPWUNCICOBA", "result": { "objects": [{ "id": 1, "class": "person", "shape": { "box": { "x": 67.07317073170731, "y": 52.92682926829268, "width": 53.04878048780488, "height": 202.9268292682927 } }, "properties": [{ "name": "abc", "value": "a" }] }], "categorization": { "value": [] } }, "createdBy": "*****@*****.**", "createdAt": "2020-04-23T03:14:08.222649Z", "lastUpdatedBy": "*****@*****.**", "lastUpdatedAt": "2021-04-14T06:19:38.486464Z", "info_read_presigned_url": None, "info_write_presigned_url": None } } } manager = LabelManager() # update_label(self, project_id:uuid.UUID, id:uuid.UUID, result:dict, tags:list=[], **kwargs) label = Label(project_id="b2a7205f-4f2a-4eb2-b845-3ed6af9a9fc5", id="29e6f25e-ac75-4882-9025-6ff73fd94cb1", result={ "objects": [{ "id": 1, "class": "person", "shape": { "box": { "x": 67.07317073170731, "y": 52.92682926829268, "width": 53.04878048780488, "height": 202.9268292682927 } }, "properties": [{ "name": "abc", "value": "a" }] }], "categorization": { "value": [] } }, tags=[{ "name": "A" }]) manager.update_label(label=label)
def __init__(self): self.label_manager = LabelManager()
class LabelData(): def __init__(self): self.label_manager = LabelManager() def upload_data(self, project, dataset_name, directory_path, include_label, is_forced): imgs_path = recursive_glob_image_files(directory_path) if not is_forced: if not click.confirm( f"Uploading {len(imgs_path)} data and {len(recursive_glob_label_files(directory_path)) if include_label else 0 } labels to dataset '{dataset_name}' under project '{project.name}'. Proceed?" ): return asset_images = [] manager = Manager() if len(imgs_path) != 0: for key in imgs_path: file_name = key asset_image = { 'file': imgs_path[key], 'file_name': file_name, 'data_key': key, 'dataset': dataset_name } asset_images.append(asset_image) data_results = manager.list([manager.dict()] * len(asset_images)) console.print(f"Uploading data:") with Pool(NUM_MULTI_PROCESS) as p: list( tqdm.tqdm(p.imap( _upload_asset, zip([project.id] * len(asset_images), asset_images, data_results)), total=len(asset_images))) else: data_results = [{}] label_results = None if include_label: labels_path = recursive_glob_label_files(directory_path) console.print(f"Uploading labels:") if len(labels_path) != 0: label_results = manager.list([manager.dict()] * len(labels_path)) with Pool(NUM_MULTI_PROCESS) as p: list( tqdm.tqdm(p.imap( _update_label, zip([self.label_manager] * len(labels_path), labels_path, [project.id] * len(labels_path), [project.label_interface] * len(labels_path), [dataset_name] * len(labels_path), label_results)), total=len(labels_path))) else: label_results = [{}] console.print('\n[b blue]** Result Summary **[/b blue]') success_data_count = len(asset_images) - len(data_results[0]) data_success_ratio = round( success_data_count / len(asset_images) * 100, 2) if len(data_results[0]) != 0 else 100 console.print( f'Successful upload of {success_data_count} out of {len(asset_images)} data. ({data_success_ratio}%) - [b red]{len(data_results[0])} ERRORS[/b red]' ) if include_label: success_label_count = len(labels_path) - len(label_results[0]) label_success_ratio = round( success_label_count / len(labels_path) * 100, 2) if len(label_results[0]) != 0 else 100 console.print( f'Successful upload of {success_label_count} out of {len(labels_path)} labels. ({label_success_ratio}%) - [b red]{len(label_results[0])} ERRORS[/b red]' ) self._print_error_table(data_error_results=dict(data_results[0]), label_error_results=dict(label_results[0])) else: self._print_error_table(data_error_results=dict(data_results[0])) def upload_label(self, project, dataset_name, directory_path, is_forced): labels_path = recursive_glob_label_files(directory_path) if not is_forced: if not click.confirm( f"Uploading {len(labels_path)} labels to project '{project.name}'. Proceed?" ): return if len(labels_path) != 0: manager = Manager() label_results = manager.list([manager.dict()] * len(labels_path)) with Pool(NUM_MULTI_PROCESS) as p: list( tqdm.tqdm(p.imap( _update_label, zip([self.label_manager] * len(labels_path), labels_path, [project.id] * len(labels_path), [project.label_interface] * len(labels_path), [dataset_name] * len(labels_path), label_results)), total=len(labels_path))) else: label_results = [{}] console.print('\n[b blue]** Result Summary **[/b blue]') success_label_count = len(labels_path) - len(label_results[0]) success_label_ratio = round( success_label_count / len(labels_path) * 100, 2) if len(labels_path) != 0 else 100 console.print( f'Successful upload of {success_label_count} out of {len(labels_path)} labels. ({success_label_ratio}%) - [b red]{len(label_results[0])} ERRORS[/b red]' ) self._print_error_table(label_error_results=dict(label_results[0])) def download(self, project, directory_path, is_forced): process_results = [] success_data_count = 0 success_labels_count = 0 data_error_results = {} label_error_results = {} # get data count main_label_count, labels = self.label_manager.get_labels( project.id, label_type='DEFAULT', page=1, page_size=1) # get labels count total_label_count, labels = self.label_manager.get_labels(project.id, page=1, page_size=1) #Download project configuration try: project_config_path = os.path.join(directory_path, 'project.json') with open(project_config_path, 'w') as input: json.dump(project.label_interface, input, indent=4) is_download_project_config = True except Exception as e: is_download_project_config = False if main_label_count != 0: page_length = int( main_label_count / LABEL_DESCRIBE_PAGE_SIZE ) if main_label_count % LABEL_DESCRIBE_PAGE_SIZE == 0 else int( main_label_count / LABEL_DESCRIBE_PAGE_SIZE) + 1 if not is_forced: if not click.confirm( f"Downloading {main_label_count} data and {total_label_count} labels from project '{project.name}' to '{directory_path}'. Proceed?" ): return manager = Manager() label_results_dict = manager.dict() label_results = manager.list([label_results_dict] * page_length) process_results = manager.list(range(page_length)) with Pool(NUM_MULTI_PROCESS) as p: list( tqdm.tqdm(p.imap( _download_worker, zip([self.label_manager] * page_length, [project.id] * page_length, range(page_length), [directory_path] * page_length, label_results, [process_results] * page_length)), total=page_length)) for key in label_results_dict.keys(): results_error = label_results_dict[key]['error'] success_data_count += 1 success_labels_count += label_results_dict[key][ 'success_labels_count'] if 'data' in results_error: data_error_results[key] = results_error['data'] if 'label' in results_error: label_error_results[key] = results_error['label'] console.print('\n[b blue]** Result Summary **[/b blue]') console.print( f'Download of project configuration - {"[b blue]Success[/b blue]" if is_download_project_config else "[b red]Fail[/b red]"}' ) console.print( f'Successful download of {success_labels_count} out of {total_label_count} labels. ({round(success_labels_count/total_label_count*100,2)}%) - [b red]{total_label_count - success_labels_count} ERRORS[/b red]' ) console.print( f'Successful download of {success_data_count} out of {main_label_count} data. ({round(success_data_count/main_label_count*100,2)}%) - [b red]{main_label_count - success_data_count} ERRORS[/b red]' ) # TODO: Need to refactor Get Labels API Fail Logic for process_result in process_results: is_process_fail = False if not process_result: is_process_fail = True if is_process_fail: console.print( f'[b red]Failed Download Labels from API. Please retry download.[/b red]' ) self._print_error_table( data_error_results=data_error_results, label_error_results=label_error_results, ) def _print_error_table(self, data_error_results=None, label_error_results=None): results = {} if isinstance(data_error_results, dict): for key in data_error_results: results[key] = {} results[key]['data'] = data_error_results[key] results[key]['label'] = None if isinstance(label_error_results, dict): for key in label_error_results: if key in results: results[key]['label'] = label_error_results[key] else: results[key] = { 'label': label_error_results[key], 'data': None } if not next(iter(results), None): return console.print('\n[b red]** Error Table **[/b red]') page = 1 page_length = math.ceil(len(results) / 10) while True: table = rich.table.Table(show_header=True, header_style="bold magenta") table.add_column("FILE NAME") if isinstance(data_error_results, dict): table.add_column("DATA UPLOAD") if isinstance(label_error_results, dict): table.add_column("LABEL UPLOAD") for _ in range(10): key = next(iter(results), None) if not key: break if isinstance(data_error_results, dict) and isinstance( label_error_results, dict): data = results[key]['data'] label = results[key]['label'] table.add_row(key, f"{data if data else '-'}", f"{label if label else '-'}") elif isinstance(data_error_results, dict): data = results[key]['data'] table.add_row(key, f"{data if data else '-'}") else: label = results[key]['label'] table.add_row(key, f"{label if label else '-'}") del results[key] console.print(table) if not next(iter(results), None): break else: click.echo( f'Press any button to continue to the next page ({page}/{page_length}). Otherwise press ‘Q’ to quit.', nl=False) key = click.getchar() click.echo() if key == 'q' or key == 'Q': break console.log(f'[b]Check the log file for more details[/b]') console.log(f'- {simple_logger.handlers[0].baseFilename}') console.log(f'- {logger.handlers[0].baseFilename}')