diff --git a/label_studio_converter/converter.py b/label_studio_converter/converter.py index f652a28b..836eb25f 100644 --- a/label_studio_converter/converter.py +++ b/label_studio_converter/converter.py @@ -465,6 +465,7 @@ def get_data(task, outputs, annotation): 'created_at': annotation.get('created_at'), 'updated_at': annotation.get('updated_at'), 'lead_time': annotation.get('lead_time'), + 'history': annotation.get('history'), } def _check_format(self, fmt): diff --git a/label_studio_converter/exports/csv2.py b/label_studio_converter/exports/csv2.py index 65808ae5..67daf124 100644 --- a/label_studio_converter/exports/csv2.py +++ b/label_studio_converter/exports/csv2.py @@ -80,6 +80,9 @@ def prepare_annotation(item): if 'agreement' in item: record['agreement'] = item['agreement'] + if 'history' in item and item['history']: + record['history'] = json.dumps(item['history'], ensure_ascii=False) + return record @@ -94,4 +97,7 @@ def prepare_annotation_keys(item): if 'agreement' in item: record.add('agreement') + if 'history' in item and item['history']: + record.add('history') + return record diff --git a/tests/data/test_export_csv/csv_test_history.json b/tests/data/test_export_csv/csv_test_history.json new file mode 100644 index 00000000..7bc5e3cd --- /dev/null +++ b/tests/data/test_export_csv/csv_test_history.json @@ -0,0 +1,99 @@ +[ + { + "id": 6141, + "annotations": [ + { + "id": 18047, + "completed_by": { + "id": 14, + "email": "sergei@heartex.e2e", + "first_name": "", + "last_name": "" + }, + "result": [ + { + "id": "d1uGfhDvN6", + "type": "choices", + "value": { + "choices": [ + "Positive" + ] + }, + "origin": "manual", + "to_name": "text", + "from_name": "sentiment" + } + ], + "reviews": [], + "history": [ + { + "id": 18070, + "comment": null, + "organization_id": 12, + "project_id": 24, + "annotation_id": 18047, + "draft_id": null, + "review_id": null, + "task_id": 6141, + "result": [ + { + "id": "d1uGfhDvN6", + "type": "choices", + "value": { + "choices": [ + "Positive" + ] + }, + "origin": "manual", + "to_name": "text", + "from_name": "sentiment" + } + ], + "action": "submitted", + "created_at": "2024-05-15T12:09:17.000572Z", + "created_by": 14, + "comment_id": null + } + ], + "was_cancelled": false, + "ground_truth": false, + "created_at": "2024-05-15T12:09:16.789536Z", + "updated_at": "2024-05-15T12:09:16.789563Z", + "draft_created_at": null, + "lead_time": 1.849, + "prediction": {}, + "result_count": 0, + "unique_id": "de253957-8959-4e6f-9022-30d08bbea9f3", + "import_id": null, + "last_action": "submitted", + "task": 6141, + "project": 24, + "updated_by": 14, + "parent_prediction": null, + "parent_annotation": null, + "last_created_by": 14 + } + ], + "file_upload": "de982d35-text_data10.json", + "drafts": [], + "predictions": [], + "agreement": 100, + "data": { + "text": "Calif. wildfires signal the arrival of a planetary fire age https://t.co/Vvo9noqQfA" + }, + "meta": {}, + "created_at": "2024-05-15T12:08:36.422297Z", + "updated_at": "2024-05-15T12:09:16.934164Z", + "inner_id": 1, + "total_annotations": 1, + "cancelled_annotations": 0, + "total_predictions": 0, + "comment_count": 0, + "unresolved_comment_count": 0, + "last_comment_updated_at": null, + "project": 24, + "updated_by": 14, + "comment_authors": [] + } +] + diff --git a/tests/test_export_csv.py b/tests/test_export_csv.py index 017e4d7d..1ba0467f 100644 --- a/tests/test_export_csv.py +++ b/tests/test_export_csv.py @@ -38,3 +38,14 @@ def test_csv_export_complex_fields_with_json(): json.loads(df.iloc[0].iswcs_1) assert open(result_csv).read() == open(assert_csv).read() + + +def test_csv_history(): + converter = Converter({}, '/tmp') + output_dir = '/tmp/lsc-pytest' + result_csv = output_dir + '/result.csv' + input_data = os.path.abspath(os.path.dirname(__file__)) + '/data/test_export_csv/csv_test_history.json' + sep = '\t' + converter.convert_to_csv(input_data, output_dir, sep=sep, header=True, is_dir=False) + df = read_csv(result_csv, sep=sep) + assert 'history' in df.columns, "'history' column is not in the CSV"