Skip to content

Commit a9dd0fb

Browse files
authored
[BUGFIX] argilla server: prevent errors when returning users progress (#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/)
1 parent 385bf5d commit a9dd0fb

File tree

4 files changed

+94
-12
lines changed

4 files changed

+94
-12
lines changed

argilla-server/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ These are the section headers that we use:
2121
- 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))
2222
- 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))
2323

24+
### Fixed
25+
26+
- 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))
27+
2428
## [2.1.0](https://github.com/argilla-io/argilla/compare/v2.0.0...v2.1.0)
2529

2630
### Added

argilla-server/src/argilla_server/api/handlers/v1/datasets/datasets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ async def get_dataset_progress(
164164
return await datasets.get_dataset_progress(db, dataset.id)
165165

166166

167-
@router.get("/datasets/{dataset_id}/users/progress", response_model=UsersProgress, response_model_exclude_unset=True)
167+
@router.get("/datasets/{dataset_id}/users/progress", response_model=UsersProgress)
168168
async def get_dataset_users_progress(
169169
*,
170170
current_user: User = Security(auth.get_current_user),

argilla-server/src/argilla_server/api/schemas/v1/datasets.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ class DatasetProgress(BaseModel):
8787

8888

8989
class RecordResponseDistribution(BaseModel):
90-
submitted: Optional[int]
91-
discarded: Optional[int]
92-
draft: Optional[int]
90+
submitted: int = 0
91+
discarded: int = 0
92+
draft: int = 0
9393

9494

9595
class UserProgress(BaseModel):
9696
username: str
97-
completed: RecordResponseDistribution
98-
pending: RecordResponseDistribution
97+
completed: RecordResponseDistribution = RecordResponseDistribution()
98+
pending: RecordResponseDistribution = RecordResponseDistribution()
9999

100100

101101
class UsersProgress(BaseModel):

argilla-server/tests/unit/api/handlers/v1/datasets/test_get_dataset_users_progress.py

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,96 @@ async def test_get_dataset_users_progress(self, async_client: AsyncClient, owner
4949
"users": [
5050
{
5151
"username": user_with_submitted.username,
52-
"completed": {"submitted": 3},
53-
"pending": {"submitted": 2},
52+
"completed": {"submitted": 3, "discarded": 0, "draft": 0},
53+
"pending": {"submitted": 2, "discarded": 0, "draft": 0},
5454
},
5555
{
5656
"username": user_with_draft.username,
57-
"completed": {"draft": 3},
58-
"pending": {"draft": 2},
57+
"completed": {"submitted": 0, "discarded": 0, "draft": 3},
58+
"pending": {"submitted": 0, "discarded": 0, "draft": 2},
5959
},
6060
{
6161
"username": user_with_discarded.username,
62-
"completed": {"discarded": 3},
63-
"pending": {"discarded": 2},
62+
"completed": {"submitted": 0, "discarded": 3, "draft": 0},
63+
"pending": {"submitted": 0, "discarded": 2, "draft": 0},
64+
},
65+
]
66+
}
67+
68+
async def test_get_dataset_users_progress_only_with_pending(
69+
self, async_client: AsyncClient, owner_auth_header: dict
70+
):
71+
dataset = await DatasetFactory.create()
72+
73+
user_with_submitted = await AnnotatorFactory.create()
74+
user_with_draft = await AnnotatorFactory.create()
75+
user_with_discarded = await AnnotatorFactory.create()
76+
77+
records_pending = await RecordFactory.create_batch(2, status=RecordStatus.pending, dataset=dataset)
78+
79+
for record in records_pending:
80+
await ResponseFactory.create(record=record, user=user_with_submitted, status=ResponseStatus.submitted)
81+
await ResponseFactory.create(record=record, user=user_with_draft, status=ResponseStatus.draft)
82+
await ResponseFactory.create(record=record, user=user_with_discarded, status=ResponseStatus.discarded)
83+
84+
response = await async_client.get(self.url(dataset.id), headers=owner_auth_header)
85+
86+
assert response.status_code == 200, response.json()
87+
assert response.json() == {
88+
"users": [
89+
{
90+
"username": user_with_submitted.username,
91+
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
92+
"pending": {"submitted": 2, "discarded": 0, "draft": 0},
93+
},
94+
{
95+
"username": user_with_draft.username,
96+
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
97+
"pending": {"submitted": 0, "discarded": 0, "draft": 2},
98+
},
99+
{
100+
"username": user_with_discarded.username,
101+
"completed": {"submitted": 0, "discarded": 0, "draft": 0},
102+
"pending": {"submitted": 0, "discarded": 2, "draft": 0},
103+
},
104+
]
105+
}
106+
107+
async def test_get_dataset_users_progress_only_with_completed(
108+
self, async_client: AsyncClient, owner_auth_header: dict
109+
):
110+
dataset = await DatasetFactory.create()
111+
112+
user_with_submitted = await AnnotatorFactory.create()
113+
user_with_draft = await AnnotatorFactory.create()
114+
user_with_discarded = await AnnotatorFactory.create()
115+
116+
records_completed = await RecordFactory.create_batch(3, status=RecordStatus.completed, dataset=dataset)
117+
118+
for record in records_completed:
119+
await ResponseFactory.create(record=record, user=user_with_submitted, status=ResponseStatus.submitted)
120+
await ResponseFactory.create(record=record, user=user_with_draft, status=ResponseStatus.draft)
121+
await ResponseFactory.create(record=record, user=user_with_discarded, status=ResponseStatus.discarded)
122+
123+
response = await async_client.get(self.url(dataset.id), headers=owner_auth_header)
124+
125+
assert response.status_code == 200, response.json()
126+
assert response.json() == {
127+
"users": [
128+
{
129+
"username": user_with_submitted.username,
130+
"completed": {"submitted": 3, "discarded": 0, "draft": 0},
131+
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
132+
},
133+
{
134+
"username": user_with_draft.username,
135+
"completed": {"submitted": 0, "discarded": 0, "draft": 3},
136+
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
137+
},
138+
{
139+
"username": user_with_discarded.username,
140+
"completed": {"submitted": 0, "discarded": 3, "draft": 0},
141+
"pending": {"submitted": 0, "discarded": 0, "draft": 0},
64142
},
65143
]
66144
}

0 commit comments

Comments
 (0)