Skip to content

Commit

Permalink
[BUGFIX] argilla server: prevent errors when returning users progre…
Browse files Browse the repository at this point in the history
…ss (#5484)

# Description
<!-- Please include a summary of the changes and the related issue.
Please also include relevant motivation and context. List any
dependencies that are required for this change. -->

This PR fixes the error when getting dataset progress by users with
partial record annotations (only pending or completed). In those cases,
the server raises an error since `pending` or `responses` in the
response schema cannot be filled.

The solution is to normalize and always send the same response
structure, filling values with `0`'s.


Refs: This error was found when working on
#5479, which also includes the
fix

**Type of change**
<!-- Please delete options that are not relevant. Remember to title the
PR according to the type of change -->

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- Refactor (change restructuring the codebase without changing
functionality)
- Improvement (change adding some improvement to an existing
functionality)
- Documentation update

**How Has This Been Tested**
<!-- Please add some reference about how your feature has been tested.
-->

**Checklist**
<!-- Please go over the list and make sure you've taken everything into
account -->

- I added relevant documentation
- I followed the style guidelines of this project
- I did a self-review of my code
- I made corresponding changes to the documentation
- I confirm My changes generate no new warnings
- I have added tests that prove my fix is effective or that my feature
works
- I have added relevant notes to the CHANGELOG.md file (See
https://keepachangelog.com/)
  • Loading branch information
frascuchon authored Sep 13, 2024
1 parent 385bf5d commit a9dd0fb
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 12 deletions.
4 changes: 4 additions & 0 deletions argilla-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ These are the section headers that we use:
- Added [`rq`](https://python-rq.org) library to process background jobs using [Redis](https://redis.io) as a dependency. ([#5432](https://github.com/argilla-io/argilla/pull/5432))
- Added a new background job to update records status when a dataset distribution strategy is updated. ([#5432](https://github.com/argilla-io/argilla/pull/5432))

### Fixed

- Fixed error when computing dataset progress by users without responses related to pending or completed records. ([#5484](https://github.com/argilla-io/argilla/pull/5484))

## [2.1.0](https://github.com/argilla-io/argilla/compare/v2.0.0...v2.1.0)

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ async def get_dataset_progress(
return await datasets.get_dataset_progress(db, dataset.id)


@router.get("/datasets/{dataset_id}/users/progress", response_model=UsersProgress, response_model_exclude_unset=True)
@router.get("/datasets/{dataset_id}/users/progress", response_model=UsersProgress)
async def get_dataset_users_progress(
*,
current_user: User = Security(auth.get_current_user),
Expand Down
10 changes: 5 additions & 5 deletions argilla-server/src/argilla_server/api/schemas/v1/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ class DatasetProgress(BaseModel):


class RecordResponseDistribution(BaseModel):
submitted: Optional[int]
discarded: Optional[int]
draft: Optional[int]
submitted: int = 0
discarded: int = 0
draft: int = 0


class UserProgress(BaseModel):
username: str
completed: RecordResponseDistribution
pending: RecordResponseDistribution
completed: RecordResponseDistribution = RecordResponseDistribution()
pending: RecordResponseDistribution = RecordResponseDistribution()


class UsersProgress(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,96 @@ async def test_get_dataset_users_progress(self, async_client: AsyncClient, owner
"users": [
{
"username": user_with_submitted.username,
"completed": {"submitted": 3},
"pending": {"submitted": 2},
"completed": {"submitted": 3, "discarded": 0, "draft": 0},
"pending": {"submitted": 2, "discarded": 0, "draft": 0},
},
{
"username": user_with_draft.username,
"completed": {"draft": 3},
"pending": {"draft": 2},
"completed": {"submitted": 0, "discarded": 0, "draft": 3},
"pending": {"submitted": 0, "discarded": 0, "draft": 2},
},
{
"username": user_with_discarded.username,
"completed": {"discarded": 3},
"pending": {"discarded": 2},
"completed": {"submitted": 0, "discarded": 3, "draft": 0},
"pending": {"submitted": 0, "discarded": 2, "draft": 0},
},
]
}

async def test_get_dataset_users_progress_only_with_pending(
self, async_client: AsyncClient, owner_auth_header: dict
):
dataset = await DatasetFactory.create()

user_with_submitted = await AnnotatorFactory.create()
user_with_draft = await AnnotatorFactory.create()
user_with_discarded = await AnnotatorFactory.create()

records_pending = await RecordFactory.create_batch(2, status=RecordStatus.pending, dataset=dataset)

for record in records_pending:
await ResponseFactory.create(record=record, user=user_with_submitted, status=ResponseStatus.submitted)
await ResponseFactory.create(record=record, user=user_with_draft, status=ResponseStatus.draft)
await ResponseFactory.create(record=record, user=user_with_discarded, status=ResponseStatus.discarded)

response = await async_client.get(self.url(dataset.id), headers=owner_auth_header)

assert response.status_code == 200, response.json()
assert response.json() == {
"users": [
{
"username": user_with_submitted.username,
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
"pending": {"submitted": 2, "discarded": 0, "draft": 0},
},
{
"username": user_with_draft.username,
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
"pending": {"submitted": 0, "discarded": 0, "draft": 2},
},
{
"username": user_with_discarded.username,
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
"pending": {"submitted": 0, "discarded": 2, "draft": 0},
},
]
}

async def test_get_dataset_users_progress_only_with_completed(
self, async_client: AsyncClient, owner_auth_header: dict
):
dataset = await DatasetFactory.create()

user_with_submitted = await AnnotatorFactory.create()
user_with_draft = await AnnotatorFactory.create()
user_with_discarded = await AnnotatorFactory.create()

records_completed = await RecordFactory.create_batch(3, status=RecordStatus.completed, dataset=dataset)

for record in records_completed:
await ResponseFactory.create(record=record, user=user_with_submitted, status=ResponseStatus.submitted)
await ResponseFactory.create(record=record, user=user_with_draft, status=ResponseStatus.draft)
await ResponseFactory.create(record=record, user=user_with_discarded, status=ResponseStatus.discarded)

response = await async_client.get(self.url(dataset.id), headers=owner_auth_header)

assert response.status_code == 200, response.json()
assert response.json() == {
"users": [
{
"username": user_with_submitted.username,
"completed": {"submitted": 3, "discarded": 0, "draft": 0},
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
},
{
"username": user_with_draft.username,
"completed": {"submitted": 0, "discarded": 0, "draft": 3},
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
},
{
"username": user_with_discarded.username,
"completed": {"submitted": 0, "discarded": 3, "draft": 0},
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
},
]
}
Expand Down

0 comments on commit a9dd0fb

Please sign in to comment.