diff --git a/label_studio/core/utils/common.py b/label_studio/core/utils/common.py index 64afec5f43a5..df535c1acff9 100644 --- a/label_studio/core/utils/common.py +++ b/label_studio/core/utils/common.py @@ -498,6 +498,9 @@ def collect_versions(force=False): if 'commit' in result[package]: sentry_sdk.set_tag('commit-' + package, result[package]['commit']) + # edition type + result['edition'] = settings.VERSION_EDITION + settings.VERSIONS = result return result diff --git a/label_studio/tests/conftest.py b/label_studio/tests/conftest.py index d0b14097b477..1dbeca21d094 100644 --- a/label_studio/tests/conftest.py +++ b/label_studio/tests/conftest.py @@ -34,6 +34,8 @@ print('\n\n !!! Please, pip install pytest-env \n\n') exit(-100) +from label_studio.tests.sdk.fixtures import * # noqa: F403 + from .utils import ( azure_client_mock, create_business, diff --git a/label_studio/tests/sdk/fixtures.py b/label_studio/tests/sdk/fixtures.py new file mode 100644 index 000000000000..fcd6ad1dcf38 --- /dev/null +++ b/label_studio/tests/sdk/fixtures.py @@ -0,0 +1,29 @@ +import pytest +from label_studio_sdk.client import LabelStudio +from label_studio_sdk.data_manager import Column, Filters, Operator, Type + +from .common import LABEL_CONFIG_AND_TASKS + + +@pytest.fixture +def test_project_with_view(django_live_url, business_client): + ls = LabelStudio(base_url=django_live_url, api_key=business_client.api_key) + p = ls.projects.create(title='New Project', label_config=LABEL_CONFIG_AND_TASKS['label_config']) + + project = ls.projects.get(id=p.id) + + task_data = [{'data': {'my_text': 'Test task ' + str(i)}} for i in range(10)] + ls.projects.import_tasks(id=project.id, request=task_data) + orig_tasks = [] + for task in ls.tasks.list(project=project.id): + orig_tasks.append(task) + + filters = Filters.create( + Filters.OR, + [Filters.item(Column.id, Operator.EQUAL, Type.Number, Filters.value(t.id)) for t in orig_tasks[::2]], + ) + + view = ls.views.create( + project=project.id, data=dict(title='Test View', filters=filters, ordering=['-' + Column.id]) + ) + return ls, project, orig_tasks, view diff --git a/label_studio/tests/sdk/test_export.py b/label_studio/tests/sdk/test_export.py new file mode 100644 index 000000000000..11ee8138e93e --- /dev/null +++ b/label_studio/tests/sdk/test_export.py @@ -0,0 +1,58 @@ +import pandas as pd +import pytest + +from label_studio.tests.sdk.common import LABEL_CONFIG_AND_TASKS + +pytestmark = pytest.mark.django_db +from label_studio_sdk.client import LabelStudio + + +@pytest.fixture +def test_project(django_live_url, business_client): + ls = LabelStudio(base_url=django_live_url, api_key=business_client.api_key) + project = ls.projects.create(title='Export Test Project', label_config=LABEL_CONFIG_AND_TASKS['label_config']) + ls.projects.import_tasks(id=project.id, request=LABEL_CONFIG_AND_TASKS['tasks_for_import']) + return ls, project + + +def test_export_formats(test_project): + ls, project = test_project + + # Get available export formats + formats = ls.projects.exports.list_formats(project.id) + assert len(formats) > 0 + + +def test_direct_export(test_project): + ls, project = test_project + + # Test JSON export + json_data = ls.projects.exports.as_json(project.id) + assert isinstance(json_data, list) + assert len(json_data) == 1 + + # Test pandas export + df = ls.projects.exports.as_pandas(project.id) + assert isinstance(df, pd.DataFrame) + assert len(df) == 1 + + # Test low level export - import new task without annotations + ls.projects.import_tasks( + id=project.id, + request={ + 'data': { + 'my_text': 'Opossums are great', + 'ref_id': 456, + 'meta_info': {'timestamp': '2020-03-09 18:15:28.212882', 'location': 'North Pole'}, + } + }, + ) + data = ls.projects.exports.download_sync(project.id, download_all_tasks=False) + from label_studio_sdk.projects.exports.client_ext import _bytestream_to_json + + assert len(_bytestream_to_json(data)) == 1 + + data = ls.projects.exports.download_sync(project.id, download_all_tasks=True) + from label_studio_sdk.projects.exports.client_ext import _bytestream_to_json + + assert len(_bytestream_to_json(data)) == 2 diff --git a/label_studio/tests/sdk/test_views.py b/label_studio/tests/sdk/test_views.py index e8a9844c96c3..33f011d4538b 100644 --- a/label_studio/tests/sdk/test_views.py +++ b/label_studio/tests/sdk/test_views.py @@ -32,27 +32,13 @@ def test_create_view(django_live_url, business_client): } -def test_get_tasks_from_view(django_live_url, business_client): - ls = LabelStudio(base_url=django_live_url, api_key=business_client.api_key) - p = ls.projects.create(title='New Project', label_config=LABEL_CONFIG_AND_TASKS['label_config']) - - project = ls.projects.get(id=p.id) - - task_data = [{'data': {'my_text': 'Test task ' + str(i)}} for i in range(10)] - ls.projects.import_tasks(id=project.id, request=task_data) - orig_tasks = [] - for task in ls.tasks.list(project=project.id): - orig_tasks.append(task) - - filters = Filters.create( - Filters.OR, - [Filters.item(Column.id, Operator.EQUAL, Type.Number, Filters.value(t.id)) for t in orig_tasks[::2]], - ) - - ls.views.create(project=project.id, data=dict(title='Test View', filters=filters, ordering=['-' + Column.id])) +def test_get_tasks_from_view(test_project_with_view): + ls, project, orig_tasks, view = test_project_with_view views = ls.views.list(project=project.id) assert len(views) == 1 - view = views[0] + found_view = views[0] + + assert found_view.id == view.id tasks = [] for task in ls.tasks.list(view=view.id): tasks.append(task) diff --git a/poetry.lock b/poetry.lock index b5d7ffec5843..b15c35d2883c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2140,7 +2140,7 @@ python-versions = ">=3.9,<4" groups = ["main"] markers = "python_version >= \"3.12\" or python_version <= \"3.11\"" files = [ - {file = "510e71ab176061588a0f7cfec92e43c207bb5d9f.zip", hash = "sha256:0e04dadc233210140e2d38f241c962f998d54ba7f19f58d686d8eff748434333"}, + {file = "09995cf0c72398322af949bb13de034a7bbb785f.zip", hash = "sha256:128dabebcfca42b93396be0650b8a6afa0aad7e9a80d4c46c62d069b6e8ec085"}, ] [package.dependencies] @@ -2165,7 +2165,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/510e71ab176061588a0f7cfec92e43c207bb5d9f.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/09995cf0c72398322af949bb13de034a7bbb785f.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5034,4 +5034,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "9687682016b7a7d1eea5ff7274ca99dde9a378ef65d673799b6b38c0d3e5afe6" +content-hash = "d2cdf4a39058b618cb91b25b0b58584521858cf240dad8a6b382f4c2750d0633" diff --git a/pyproject.toml b/pyproject.toml index 55c9d9f558c6..d8da4fe27781 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -208,7 +208,7 @@ django-migration-linter = "^5.1.0" setuptools = ">=75.4.0" # Humansignal repo dependencies -label-studio-sdk = {url = "https://github.com/HumanSignal/label-studio-sdk/archive/510e71ab176061588a0f7cfec92e43c207bb5d9f.zip"} +label-studio-sdk = {url = "https://github.com/HumanSignal/label-studio-sdk/archive/09995cf0c72398322af949bb13de034a7bbb785f.zip"} [tool.poetry.group.test.dependencies] pytest = "7.2.2"