| label_studio/data_export/api.py | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| label_studio/data_export/mixins.py | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| label_studio/data_export/models.py | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| label_studio/data_import/models.py | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
label_studio/data_export/api.py
@@ -208,14 +208,6 @@ download_resources = query_serializer.validated_data['download_resources'] interpolate_key_frames = query_serializer.validated_data['interpolate_key_frames'] # 调试日志: API 层参数 logger.error(f'[Export API Debug] ========== Export Request Received ==========') logger.error(f'[Export API Debug] Project ID: {project.id}') logger.error(f'[Export API Debug] export_type: {export_type}') logger.error(f'[Export API Debug] download_resources: {download_resources}') logger.error(f'[Export API Debug] only_finished: {only_finished}') logger.error(f'[Export API Debug] Request GET params: {dict(request.GET)}') tasks_ids = request.GET.getlist('ids[]') logger.debug('Get tasks') @@ -227,8 +219,6 @@ query = query.filter(annotations__isnull=False).distinct() task_ids = query.values_list('id', flat=True) logger.error(f'[Export API Debug] Total tasks to export: {len(task_ids)}') logger.debug('Serialize tasks for export') tasks = [] label_studio/data_export/mixins.py
@@ -349,27 +349,10 @@ out_dir = pathlib.Path(tmp_dir) / OUT out_dir.mkdir(mode=0o700, parents=True, exist_ok=True) upload_dir = os.path.join(settings.MEDIA_ROOT, settings.UPLOAD_DIR) # 调试日志:打印关键参数 logger.error(f'[COCO Export Debug] ========== Export Started ==========') logger.error(f'[COCO Export Debug] Project ID: {self.project.id}') logger.error(f'[COCO Export Debug] Export format: {to_format}') logger.error(f'[COCO Export Debug] download_resources: {download_resources}') logger.error(f'[COCO Export Debug] hostname: {hostname}') logger.error(f'[COCO Export Debug] upload_dir: {upload_dir}') logger.error(f'[COCO Export Debug] upload_dir exists: {os.path.exists(upload_dir)}') if os.path.exists(upload_dir): logger.error(f'[COCO Export Debug] upload_dir contents: {os.listdir(upload_dir)}') logger.error(f'[COCO Export Debug] tmp_dir: {tmp_dir}') logger.error(f'[COCO Export Debug] out_dir: {out_dir}') logger.error(f'[COCO Export Debug] settings.MEDIA_ROOT: {settings.MEDIA_ROOT}') logger.error(f'[COCO Export Debug] settings.UPLOAD_DIR: {settings.UPLOAD_DIR}') converter = Converter( config=self.project.get_parsed_config(), project_dir=None, upload_dir=upload_dir, upload_dir=os.path.join(settings.MEDIA_ROOT, settings.UPLOAD_DIR), download_resources=download_resources, # for downloading resource we need access to the API access_token=self.project.organization.created_by.auth_token.key, @@ -378,47 +361,24 @@ input_name = pathlib.Path(self.file.name).name input_file_path = pathlib.Path(tmp_dir) / input_name logger.error(f'[COCO Export Debug] input_name: {input_name}') logger.error(f'[COCO Export Debug] input_file_path: {input_file_path}') with open(input_file_path, 'wb') as file_: file_.write(self.file.open().read()) logger.error(f'[COCO Export Debug] Starting converter.convert...') converter.convert(input_file_path, out_dir, to_format, is_dir=False) logger.error(f'[COCO Export Debug] Converter.convert completed') files = get_all_files_from_dir(out_dir) dirs = get_all_dirs_from_dir(out_dir) logger.error(f'[COCO Export Debug] Output files: {files}') logger.error(f'[COCO Export Debug] Output dirs: {dirs}') # 检查是否有 images 目录 images_dir = out_dir / 'images' if images_dir.exists(): image_files = list(images_dir.glob('*')) logger.error(f'[COCO Export Debug] images/ directory exists with {len(image_files)} files') logger.error(f'[COCO Export Debug] Image files: {[f.name for f in image_files]}') else: logger.error(f'[COCO Export Debug] images/ directory does NOT exist') if len(files) == 0 and len(dirs) == 0: logger.error(f'[COCO Export Debug] No files or dirs in output') return None elif len(files) == 1 and len(dirs) == 0: output_file = files[0] filename = pathlib.Path(input_name).stem + pathlib.Path(output_file).suffix logger.error(f'[COCO Export Debug] Single file output: {output_file}') else: logger.error(f'[COCO Export Debug] Creating zip archive...') shutil.make_archive(out_dir, 'zip', out_dir) output_file = pathlib.Path(tmp_dir) / (str(out_dir.stem) + '.zip') filename = pathlib.Path(input_name).stem + '.zip' logger.error(f'[COCO Export Debug] Zip archive created: {output_file}') logger.error(f'[COCO Export Debug] ========== Export Completed ===========') # TODO(jo): can we avoid the `f.read()` here? with open(output_file, mode='rb') as f: return File( label_studio/data_export/models.py
@@ -156,58 +156,17 @@ input_json = DataExport.save_export_files(project, now, get_args, data, md5, name) upload_dir = os.path.join(settings.MEDIA_ROOT, settings.UPLOAD_DIR) # 调试日志 logger.error(f'[Generate Export Debug] ========== Generate Export Started ==========') logger.error(f'[Generate Export Debug] Project ID: {project.id}') logger.error(f'[Generate Export Debug] Output format: {output_format}') logger.error(f'[Generate Export Debug] download_resources: {download_resources}') logger.error(f'[Generate Export Debug] hostname: {hostname}') logger.error(f'[Generate Export Debug] upload_dir: {upload_dir}') logger.error(f'[Generate Export Debug] upload_dir exists: {os.path.exists(upload_dir)}') if os.path.exists(upload_dir): try: logger.error(f'[Generate Export Debug] upload_dir contents: {os.listdir(upload_dir)}') except Exception as e: logger.error(f'[Generate Export Debug] Error listing upload_dir: {e}') logger.error(f'[Generate Export Debug] Task count: {len(tasks)}') if tasks: first_task = tasks[0] logger.error(f'[Generate Export Debug] First task data: {first_task.get("data", {})}') logger.error(f'[Generate Export Debug] settings.MEDIA_ROOT: {settings.MEDIA_ROOT}') logger.error(f'[Generate Export Debug] settings.UPLOAD_DIR: {settings.UPLOAD_DIR}') converter = Converter( config=project.get_parsed_config(), project_dir=None, upload_dir=upload_dir, upload_dir=os.path.join(settings.MEDIA_ROOT, settings.UPLOAD_DIR), download_resources=download_resources, access_token=project.organization.created_by.auth_token.key, hostname=hostname, ) logger.error(f'[Generate Export Debug] Starting converter.convert...') logger.error(f'[Generate Export Debug] input_json: {input_json}') with get_temp_dir() as tmp_dir: logger.error(f'[Generate Export Debug] tmp_dir: {tmp_dir}') converter.convert(input_json, tmp_dir, output_format, is_dir=False) logger.error(f'[Generate Export Debug] Converter.convert completed') files = get_all_files_from_dir(tmp_dir) logger.error(f'[Generate Export Debug] Output files: {files}') logger.error(f'[Generate Export Debug] tmp_dir listing: {os.listdir(tmp_dir)}') # 检查 images 目录 images_dir = os.path.join(tmp_dir, 'images') if os.path.exists(images_dir): image_files = os.listdir(images_dir) logger.error(f'[Generate Export Debug] images/ directory exists with {len(image_files)} files') logger.error(f'[Generate Export Debug] Image files: {image_files}') else: logger.error(f'[Generate Export Debug] images/ directory does NOT exist') # if only one file is exported - no need to create archive if len(os.listdir(tmp_dir)) == 1: output_file = files[0] @@ -215,18 +174,13 @@ content_type = f'application/{ext}' out = path_to_open_binary_file(output_file) filename = name + os.path.splitext(output_file)[-1] logger.error(f'[Generate Export Debug] Single file export: {filename}') logger.error(f'[Generate Export Debug] ========== Generate Export Completed ==========') return out, content_type, filename # otherwise pack output directory into archive logger.error(f'[Generate Export Debug] Creating zip archive...') shutil.make_archive(tmp_dir, 'zip', tmp_dir) out = path_to_open_binary_file(os.path.abspath(tmp_dir + '.zip')) content_type = 'application/zip' filename = name + '.zip' logger.error(f'[Generate Export Debug] Zip created: {filename}') logger.error(f'[Generate Export Debug] ========== Generate Export Completed ==========') return out, content_type, filename label_studio/data_import/models.py
@@ -238,10 +238,11 @@ def read_task_from_uploaded_file(self): logger.debug('Read 1 task from uploaded file {}'.format(self.filepath)) if settings.CLOUD_FILE_STORAGE_ENABLED: tasks = [{'data': {settings.DATA_UNDEFINED_NAME: self.filepath}}] else: tasks = [{'data': {settings.DATA_UNDEFINED_NAME: self.url}}] # 使用相对路径而不是URL,这样: # 1. 不会暴露完整的系统路径 # 2. Converter 能够正确解析路径(相对于 MEDIA_ROOT/UPLOAD_DIR) # 例如:'upload/1/xxx.png' 而不是 '/data/upload/1/xxx.png' tasks = [{'data': {settings.DATA_UNDEFINED_NAME: self.filepath}}] return tasks @property