Skip to content

Commit

Permalink
add rest endpoint to doanload submissions
Browse files Browse the repository at this point in the history
  • Loading branch information
mam10eks committed Dec 10, 2024
1 parent 71c710f commit 76e1433
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
50 changes: 49 additions & 1 deletion application/src/tira_app/endpoints/v1/_anonymous.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import html
import io
import json
import zipfile
from pathlib import Path

from django.conf import settings
from django.core.cache import cache
from django.http import HttpResponseServerError
from django.http import FileResponse, HttpResponseServerError
from django.urls import path
from rest_framework.decorators import api_view
from rest_framework.request import Request
Expand Down Expand Up @@ -40,6 +42,51 @@ def read_anonymous_submission(request: Request, submission_uuid: str) -> Respons
)


@api_view(["GET"])
def download_anonymous_submission(request: Request, submission_uuid: str) -> Response:
"""Download an anonymous submission identified by the ownership uuid.
Args:
request (Request): The request that triggered the REST API call.
submission_uuid (str): The ownership uuid of the anonymous submission
Returns:
Response: The uploaded data
"""
submission_uuid = secure_filename(submission_uuid)
try:
upload = modeldb.AnonymousUploads.objects.get(uuid=submission_uuid)
except:
return HttpResponseServerError(
json.dumps({"status": 1, "message": f"Run with uuid {html.escape(submission_uuid)} does not exist."})
)

if (
not upload
or not upload.dataset
or not upload.dataset.format
or not upload.dataset.default_task
or not upload.dataset.default_task.task_id
):
return HttpResponseServerError(json.dumps({"status": 1, "message": f"Unexpected format."}))

result_dir = Path(settings.TIRA_ROOT) / "data" / "anonymous-uploads" / submission_uuid
format = json.loads(upload.dataset.format)[0]
format = secure_filename(format)
status_code, message = check_format(result_dir, format)

if status_code != _fmt.OK:
HttpResponseServerError(json.dumps({"status": 1, "message": message}))

ret = io.BytesIO()
with zipfile.ZipFile(ret, "w") as zipf:
for f in result_dir.rglob("*"):
zipf.write(f, arcname=f.relative_to(result_dir.parent))

ret.seek(0)
return FileResponse(ret, as_attachment=True, filename=f"{submission_uuid}.zip")


@api_view(["POST", "GET"])
@check_permissions
def claim_submission(request: Request, vm_id: str, submission_uuid: str) -> Response:
Expand Down Expand Up @@ -108,4 +155,5 @@ def chunks(self):
endpoints = [
path("claim/<str:vm_id>/<str:submission_uuid>", claim_submission),
path("<str:submission_uuid>", read_anonymous_submission),
path("download/<str:submission_uuid>", download_anonymous_submission),
]
11 changes: 11 additions & 0 deletions application/test/api_access_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,17 @@
ADMIN: 500,
},
),
route_to_test(
url_pattern="v1/anonymous/download/<str:submission_uuid>",
params={"submission_uuid": "12345"},
group_to_expected_status_code={
GUEST: 500,
PARTICIPANT: 500,
ORGANIZER_WRONG_TASK: 500,
ORGANIZER: 500,
ADMIN: 500,
},
),
route_to_test(
url_pattern="v1/anonymous/claim/<str:vm_id>/<str:submission_uuid>",
params={"vm_id": "does-not-exist", "submission_uuid": "does-not-exist"},
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/ClaimSubmission.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<span v-if="link_chatnoir === undefined && link_ir_datasets !== undefined">
(browse in <a :href="link_ir_datasets" target="_blank">ir_datasets</a>)
</span>
for task <a :href="'/task-overview/' + dataset.default_task">{{ dataset.default_task }}</a>.
for task <a :href="'/task-overview/' + dataset.default_task">{{ dataset.default_task }}</a> <span v-if="download_link !== undefined">(<a :href="download_link" target="_blank">Download</a></span>).
</p>

<div class="py-2"></div>
Expand Down Expand Up @@ -157,6 +157,11 @@ export default {
},
computed: {
link_chatnoir() { return chatNoirUrl(this.dataset) },
download_link() {
if (this.submissionToClaim && this.submissionToClaim.dataset_id && this.dataset) {
return this.rest_url + `/v1/anonymous/download/` + this.submissionToClaim.uuid
}
},
registered() { return this.vm_id && this.vm_id !== undefined && ('' + this.vm_id) !== 'undefined' && ('' + this.vm_id) !== 'null'},
link_ir_datasets() {
let ret = irDatasetsUrls(this.dataset)
Expand Down
7 changes: 5 additions & 2 deletions python-client/tira/third_party_integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def register_rerank_data_to_ir_datasets(path_to_rerank_file, ir_dataset_id, orig
register_dataset_from_re_rank_file(ir_dataset_id, default_input, original_ir_datasets_id)


def persist_and_normalize_run(run, system_name, default_output=None, output_file=None, depth=1000, upload_to_tira=None):
def persist_and_normalize_run(run, system_name, default_output=None, output_file=None, depth=1000, upload_to_tira=None, tira_client=None):
if output_file is None and default_output is None:
print(
'I use the environment variable "TIRA_OUTPUT_DIR" to determine where I should store the run file using "."'
Expand All @@ -148,7 +148,10 @@ def persist_and_normalize_run(run, system_name, default_output=None, output_file
if upload_to_tira and not in_tira_sandbox():
from tira.rest_api_client import Client as RestClient

tira = RestClient()
if tira_client:
tira = tira_client
else:
tira = RestClient()
upload_to_tira = tira.get_dataset(upload_to_tira)
else:
upload_to_tira = None
Expand Down

0 comments on commit 76e1433

Please sign in to comment.