|
1 | 1 | # TODO: The functions here should be moved into the `evaluation_services.py` file, once this branch is rebased onto those changes. |
2 | 2 |
|
3 | 3 | import json |
4 | | -from typing import TYPE_CHECKING, List, Optional |
| 4 | +from typing import TYPE_CHECKING, Optional |
5 | 5 |
|
6 | 6 | if TYPE_CHECKING: |
7 | 7 | from synapseclient import Synapse |
@@ -222,3 +222,259 @@ async def cancel_submission( |
222 | 222 | response = await client.rest_put_async(uri) |
223 | 223 |
|
224 | 224 | return response |
| 225 | + |
| 226 | + |
| 227 | +async def get_submission_status( |
| 228 | + submission_id: str, synapse_client: Optional["Synapse"] = None |
| 229 | +) -> dict: |
| 230 | + """ |
| 231 | + Gets the SubmissionStatus object associated with a specified Submission. |
| 232 | +
|
| 233 | + <https://rest-docs.synapse.org/rest/GET/evaluation/submission/subId/status.html> |
| 234 | +
|
| 235 | + Arguments: |
| 236 | + submission_id: The ID of the submission to get the status for. |
| 237 | + synapse_client: If not passed in and caching was not disabled by |
| 238 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 239 | + instance from the Synapse class constructor. |
| 240 | +
|
| 241 | + Returns: |
| 242 | + The SubmissionStatus object as a JSON dict. |
| 243 | +
|
| 244 | + Note: |
| 245 | + The caller must be granted the ACCESS_TYPE.READ on the specified Evaluation. |
| 246 | + Furthermore, the caller must be granted the ACCESS_TYPE.READ_PRIVATE_SUBMISSION |
| 247 | + to see all data marked as "private" in the SubmissionStatus. |
| 248 | + """ |
| 249 | + from synapseclient import Synapse |
| 250 | + |
| 251 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 252 | + |
| 253 | + uri = f"/evaluation/submission/{submission_id}/status" |
| 254 | + |
| 255 | + response = await client.rest_get_async(uri) |
| 256 | + |
| 257 | + return response |
| 258 | + |
| 259 | + |
| 260 | +async def update_submission_status( |
| 261 | + submission_id: str, request_body: dict, synapse_client: Optional["Synapse"] = None |
| 262 | +) -> dict: |
| 263 | + """ |
| 264 | + Updates a SubmissionStatus object. |
| 265 | +
|
| 266 | + <https://rest-docs.synapse.org/rest/PUT/evaluation/submission/subId/status.html> |
| 267 | +
|
| 268 | + Arguments: |
| 269 | + submission_id: The ID of the SubmissionStatus being updated. |
| 270 | + request_body: The SubmissionStatus object to update as a dictionary. |
| 271 | + synapse_client: If not passed in and caching was not disabled by |
| 272 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 273 | + instance from the Synapse class constructor. |
| 274 | +
|
| 275 | + Returns: |
| 276 | + The updated SubmissionStatus object as a JSON dict. |
| 277 | +
|
| 278 | + Note: |
| 279 | + Synapse employs an Optimistic Concurrency Control (OCC) scheme to handle |
| 280 | + concurrent updates. Each time a SubmissionStatus is updated a new etag will be |
| 281 | + issued to the SubmissionStatus. When an update is requested, Synapse will compare |
| 282 | + the etag of the passed SubmissionStatus with the current etag of the SubmissionStatus. |
| 283 | + If the etags do not match, then the update will be rejected with a PRECONDITION_FAILED |
| 284 | + (412) response. When this occurs, the caller should fetch the latest copy of the |
| 285 | + SubmissionStatus and re-apply any changes, then re-attempt the SubmissionStatus update. |
| 286 | +
|
| 287 | + The caller must be granted the ACCESS_TYPE.UPDATE_SUBMISSION on the specified Evaluation. |
| 288 | + """ |
| 289 | + from synapseclient import Synapse |
| 290 | + |
| 291 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 292 | + |
| 293 | + uri = f"/evaluation/submission/{submission_id}/status" |
| 294 | + |
| 295 | + response = await client.rest_put_async(uri, body=json.dumps(request_body)) |
| 296 | + |
| 297 | + return response |
| 298 | + |
| 299 | + |
| 300 | +async def get_all_submission_statuses( |
| 301 | + evaluation_id: str, |
| 302 | + status: Optional[str] = None, |
| 303 | + limit: int = 10, |
| 304 | + offset: int = 0, |
| 305 | + synapse_client: Optional["Synapse"] = None, |
| 306 | +) -> dict: |
| 307 | + """ |
| 308 | + Gets a collection of SubmissionStatuses to a specified Evaluation. |
| 309 | +
|
| 310 | + <https://rest-docs.synapse.org/rest/GET/evaluation/evalId/submission/status/all.html> |
| 311 | +
|
| 312 | + Arguments: |
| 313 | + evaluation_id: The ID of the specified Evaluation. |
| 314 | + status: Optionally filter submission statuses by status. |
| 315 | + limit: Limits the number of entities that will be fetched for this page. |
| 316 | + When null it will default to 10, max value 100. Default to 10. |
| 317 | + offset: The offset index determines where this page will start from. |
| 318 | + An index of 0 is the first entity. Default to 0. |
| 319 | + synapse_client: If not passed in and caching was not disabled by |
| 320 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 321 | + instance from the Synapse class constructor. |
| 322 | +
|
| 323 | + Returns: |
| 324 | + A PaginatedResults<SubmissionStatus> object as a JSON dict containing |
| 325 | + a paginated list of submission statuses for the evaluation queue. |
| 326 | +
|
| 327 | + Note: |
| 328 | + The caller must be granted the ACCESS_TYPE.READ on the specified Evaluation. |
| 329 | + Furthermore, the caller must be granted the ACCESS_TYPE.READ_PRIVATE_SUBMISSION |
| 330 | + to see all data marked as "private" in the SubmissionStatuses. |
| 331 | + """ |
| 332 | + from synapseclient import Synapse |
| 333 | + |
| 334 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 335 | + |
| 336 | + uri = f"/evaluation/{evaluation_id}/submission/status/all" |
| 337 | + query_params = {"limit": limit, "offset": offset} |
| 338 | + |
| 339 | + if status: |
| 340 | + query_params["status"] = status |
| 341 | + |
| 342 | + response = await client.rest_get_async(uri, **query_params) |
| 343 | + |
| 344 | + return response |
| 345 | + |
| 346 | + |
| 347 | +async def batch_update_submission_statuses( |
| 348 | + evaluation_id: str, request_body: dict, synapse_client: Optional["Synapse"] = None |
| 349 | +) -> dict: |
| 350 | + """ |
| 351 | + Update multiple SubmissionStatuses. The maximum batch size is 500. |
| 352 | +
|
| 353 | + <https://rest-docs.synapse.org/rest/PUT/evaluation/evalId/statusBatch.html> |
| 354 | +
|
| 355 | + Arguments: |
| 356 | + evaluation_id: The ID of the Evaluation to which the SubmissionStatus objects belong. |
| 357 | + request_body: The SubmissionStatusBatch object as a dictionary containing: |
| 358 | + - statuses: List of SubmissionStatus objects to update |
| 359 | + - isFirstBatch: Boolean indicating if this is the first batch in the series |
| 360 | + - isLastBatch: Boolean indicating if this is the last batch in the series |
| 361 | + - batchToken: Token from previous batch response (required for all but first batch) |
| 362 | + synapse_client: If not passed in and caching was not disabled by |
| 363 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 364 | + instance from the Synapse class constructor. |
| 365 | +
|
| 366 | + Returns: |
| 367 | + A BatchUploadResponse object as a JSON dict containing the batch token |
| 368 | + and other response information. |
| 369 | +
|
| 370 | + Note: |
| 371 | + To allow upload of more than the maximum batch size (500), the system supports |
| 372 | + uploading a series of batches. Synapse employs optimistic concurrency on the |
| 373 | + series in the form of a batch token. Each request (except the first) must include |
| 374 | + the 'batch token' returned in the response to the previous batch. If another client |
| 375 | + begins batch upload simultaneously, a PRECONDITION_FAILED (412) response will be |
| 376 | + generated and upload must restart from the first batch. |
| 377 | +
|
| 378 | + After the final batch is uploaded, the data for the Evaluation queue will be |
| 379 | + mirrored to the tables which support querying. Therefore uploaded data will not |
| 380 | + appear in Evaluation queries until after the final batch is successfully uploaded. |
| 381 | +
|
| 382 | + It is the client's responsibility to note in each batch request: |
| 383 | + 1. Whether it is the first batch in the series (isFirstBatch) |
| 384 | + 2. Whether it is the last batch (isLastBatch) |
| 385 | +
|
| 386 | + For a single batch both flags are set to 'true'. |
| 387 | +
|
| 388 | + The caller must be granted the ACCESS_TYPE.UPDATE_SUBMISSION on the specified Evaluation. |
| 389 | + """ |
| 390 | + from synapseclient import Synapse |
| 391 | + |
| 392 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 393 | + |
| 394 | + uri = f"/evaluation/{evaluation_id}/statusBatch" |
| 395 | + |
| 396 | + response = await client.rest_put_async(uri, body=json.dumps(request_body)) |
| 397 | + |
| 398 | + return response |
| 399 | + |
| 400 | + |
| 401 | +async def get_evaluation_submission_bundles( |
| 402 | + evaluation_id: str, |
| 403 | + status: Optional[str] = None, |
| 404 | + limit: int = 10, |
| 405 | + offset: int = 0, |
| 406 | + synapse_client: Optional["Synapse"] = None, |
| 407 | +) -> dict: |
| 408 | + """ |
| 409 | + Gets a collection of bundled Submissions and SubmissionStatuses to a given Evaluation. |
| 410 | +
|
| 411 | + <https://rest-docs.synapse.org/rest/GET/evaluation/evalId/submission/bundle/all.html> |
| 412 | +
|
| 413 | + Arguments: |
| 414 | + evaluation_id: The ID of the specified Evaluation. |
| 415 | + status: Optionally filter submission bundles by status. |
| 416 | + limit: Limits the number of entities that will be fetched for this page. |
| 417 | + When null it will default to 10, max value 100. Default to 10. |
| 418 | + offset: The offset index determines where this page will start from. |
| 419 | + An index of 0 is the first entity. Default to 0. |
| 420 | + synapse_client: If not passed in and caching was not disabled by |
| 421 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 422 | + instance from the Synapse class constructor. |
| 423 | +
|
| 424 | + Returns: |
| 425 | + A PaginatedResults<SubmissionBundle> object as a JSON dict containing |
| 426 | + a paginated list of submission bundles for the evaluation queue. |
| 427 | +
|
| 428 | + Note: |
| 429 | + The caller must be granted the ACCESS_TYPE.READ_PRIVATE_SUBMISSION on the specified Evaluation. |
| 430 | + """ |
| 431 | + from synapseclient import Synapse |
| 432 | + |
| 433 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 434 | + |
| 435 | + uri = f"/evaluation/{evaluation_id}/submission/bundle/all" |
| 436 | + query_params = {"limit": limit, "offset": offset} |
| 437 | + |
| 438 | + if status: |
| 439 | + query_params["status"] = status |
| 440 | + |
| 441 | + response = await client.rest_get_async(uri, **query_params) |
| 442 | + |
| 443 | + return response |
| 444 | + |
| 445 | + |
| 446 | +async def get_user_submission_bundles( |
| 447 | + evaluation_id: str, |
| 448 | + limit: int = 10, |
| 449 | + offset: int = 0, |
| 450 | + synapse_client: Optional["Synapse"] = None, |
| 451 | +) -> dict: |
| 452 | + """ |
| 453 | + Gets the requesting user's bundled Submissions and SubmissionStatuses to a specified Evaluation. |
| 454 | +
|
| 455 | + <https://rest-docs.synapse.org/rest/GET/evaluation/evalId/submission/bundle.html> |
| 456 | +
|
| 457 | + Arguments: |
| 458 | + evaluation_id: The ID of the specified Evaluation. |
| 459 | + limit: Limits the number of entities that will be fetched for this page. |
| 460 | + When null it will default to 10. Default to 10. |
| 461 | + offset: The offset index determines where this page will start from. |
| 462 | + An index of 0 is the first entity. Default to 0. |
| 463 | + synapse_client: If not passed in and caching was not disabled by |
| 464 | + `Synapse.allow_client_caching(False)` this will use the last created |
| 465 | + instance from the Synapse class constructor. |
| 466 | +
|
| 467 | + Returns: |
| 468 | + A PaginatedResults<SubmissionBundle> object as a JSON dict containing |
| 469 | + a paginated list of the requesting user's submission bundles for the evaluation queue. |
| 470 | + """ |
| 471 | + from synapseclient import Synapse |
| 472 | + |
| 473 | + client = Synapse.get_client(synapse_client=synapse_client) |
| 474 | + |
| 475 | + uri = f"/evaluation/{evaluation_id}/submission/bundle" |
| 476 | + query_params = {"limit": limit, "offset": offset} |
| 477 | + |
| 478 | + response = await client.rest_get_async(uri, **query_params) |
| 479 | + |
| 480 | + return response |
0 commit comments