HumanSignal/label-studio-sdk

Ordering in get_tasks crashes

konradmalik opened this issue · 1 comments

Hi, I encountered this bug today.

This works ok:

    def _get_tasks(
        self,
        project_client: Project,
        larger_than_id: int,
        only_without_predictions: bool,
    ) -> List[JSONDict]:
        """
        Download all labeled tasks from project using the Label Studio SDK.
        Read more about SDK here https://labelstud.io/sdk/
        project_id: project ID
        only_without_predictions: get only those tasks that do not have predictions yet
        larger_than_id: filters results to tasks GREATER than this id
        :return:
        """
        items = [
            Filters.item(
                name=Column.id,
                operator=Operator.GREATER,
                column_type=Type.Number,
                value=Filters.value(larger_than_id),
            )
        ]
        if only_without_predictions:
            items.append(
                Filters.item(
                    name=Column.total_predictions,
                    operator=Operator.EQUAL,
                    column_type=Type.Number,
                    value=Filters.value(0),
                )
            )
        filters = Filters.create(
            conjunction="and",
            items=items,
        )
        return sorted(
            project_client.get_tasks(filters=filters), key=lambda x: x["id"]
        )

While this (adding seemingly proper ordering) crashes:

    def _get_tasks(
        self,
        project_client: Project,
        larger_than_id: int,
        only_without_predictions: bool,
    ) -> List[JSONDict]:
        """
        Download all labeled tasks from project using the Label Studio SDK.
        Read more about SDK here https://labelstud.io/sdk/
        project_id: project ID
        only_without_predictions: get only those tasks that do not have predictions yet
        larger_than_id: filters results to tasks GREATER than this id
        :return:
        """
        items = [
            Filters.item(
                name=Column.id,
                operator=Operator.GREATER,
                column_type=Type.Number,
                value=Filters.value(larger_than_id),
            )
        ]
        if only_without_predictions:
            items.append(
                Filters.item(
                    name=Column.total_predictions,
                    operator=Operator.EQUAL,
                    column_type=Type.Number,
                    value=Filters.value(0),
                )
            )
        filters = Filters.create(
            conjunction="and",
            items=items,
        )
        ordering = [Column.id]
        return project_client.get_tasks(filters=filters, ordering=ordering)

Looks like the column from the ordering arguments gets badly translated along the road.

Versions:
label-studio-ml == 1.0.4
label-studio-sdk == 0.0.8
label-studio server == 1.4.0

This is the exception:

studio  | [01/Mar/2022 14:58:21] "GET /api/projects/2 HTTP/1.1" 200 10822                                                                                                      [788/7125]
studio  | [2022-03-01 14:58:21,851] [core.utils.common::custom_exception_handler::83] [ERROR] d24ed865-9792-4971-b8ea-9b45d8d207d2 Cannot resolve keyword 'filter:id' into field. Choices
 are: annotations, created_at, data, drafts, file_upload, file_upload_id, id, io_storages_azureblobimportstoragelink, io_storages_gcsimportstoragelink, io_storages_localfilesimportstora
gelink, io_storages_redisimportstoragelink, io_storages_s3importstoragelink, is_labeled, locks, meta, overlap, predictions, project, project_id, total_predictions, updated_at
studio  | Traceback (most recent call last):
studio  |   File "/usr/local/lib/python3.8/dist-packages/rest_framework/views.py", line 506, in dispatch
studio  |     response = handler(request, *args, **kwargs)
studio  |   File "/label-studio/label_studio/data_manager/api.py", line 230, in get
studio  |     page = self.paginate_queryset(queryset)
studio  |   File "/usr/local/lib/python3.8/dist-packages/rest_framework/generics.py", line 171, in paginate_queryset
studio  |     return self.paginator.paginate_queryset(queryset, self.request, view=self)
studio  |   File "/label-studio/label_studio/data_manager/api.py", line 138, in paginate_queryset
studio  |     return super().paginate_queryset(queryset, request, view)
studio  |   File "/usr/local/lib/python3.8/dist-packages/rest_framework/pagination.py", line 216, in paginate_queryset
studio  |     return list(self.page)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/core/paginator.py", line 143, in __len__
studio  |     return len(self.object_list)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 269, in __len__
studio  |     self._fetch_all()
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 1308, in _fetch_all
studio  |     self._result_cache = list(self._iterable_class(self))
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 53, in __iter__
studio  |     results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1143, in execute_sql
studio  |     sql, params = self.as_sql()
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 498, in as_sql
studio  |     extra_select, order_by, group_by = self.pre_sql_setup()
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 56, in pre_sql_setup
studio  |     order_by = self.get_order_by()
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 361, in get_order_by
studio  |     resolved = expr.resolve_expression(self.query, allow_joins=True, reuse=None)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/expressions.py", line 249, in resolve_expression
studio  |     c.set_source_expressions([
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/expressions.py", line 250, in <listcomp>
studio  |     expr.resolve_expression(query, allow_joins, reuse, summarize)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/expressions.py", line 539, in resolve_expression
studio  |     return query.resolve_ref(self.name, allow_joins, reuse, summarize)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/query.py", line 1685, in resolve_ref
studio  |     join_info = self.setup_joins(field_list, self.get_meta(), self.get_initial_alias(), can_reuse=reuse)
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/query.py", line 1567, in setup_joins
studio  |     path, final_field, targets, rest = self.names_to_path(
studio  |   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/query.py", line 1483, in names_to_path
studio  |     raise FieldError("Cannot resolve keyword '%s' into field. "
studio  | django.core.exceptions.FieldError: Cannot resolve keyword 'filter:id' into field. Choices are: annotations, created_at, data, drafts, file_upload, file_upload_id, id, io_stora
ges_azureblobimportstoragelink, io_storages_gcsimportstoragelink, io_storages_localfilesimportstoragelink, io_storages_redisimportstoragelink, io_storages_s3importstoragelink, is_labele
d, locks, meta, overlap, predictions, project, project_id, total_predictions, updated_at
studio  | [2022-03-01 14:58:21,871] [django.request::log_response::224] [ERROR] Internal Server Error: /api/dm/tasks/
studio  | [01/Mar/2022 14:58:21] "GET /api/dm/tasks?project=2&page=1&page_size=-1&query=%7B%22filters%22%3A+%7B%22conjunction%22%3A+%22and%22%2C+%22items%22%3A+%5B%7B%22filter%22%3A+%22
filter%3Atasks%3Aid%22%2C+%22operator%22%3A+%22greater%22%2C+%22type%22%3A+%22Number%22%2C+%22value%22%3A+-1%7D%2C+%7B%22filter%22%3A+%22filter%3Atasks%3Atotal_predictions%22%2C+%22oper
ator%22%3A+%22equal%22%2C+%22type%22%3A+%22Number%22%2C+%22value%22%3A+0%7D%5D%7D%2C+%22ordering%22%3A+%5B%22filter%3Atasks%3Aid%22%5D%2C+%22selectedItems%22%3A+%7B%22all%22%3A+true%2C+
%22excluded%22%3A+%5B%5D%7D%7D&fields=all HTTP/1.1" 500 4091

Please, check the latest master branch of SDK with the latest LS develop branch. This issue is fixed there.