|
import sys |
|
import subprocess |
|
import gradio as gr |
|
import json |
|
from datetime import datetime, timezone |
|
from huggingface_hub import upload_file, snapshot_download |
|
import shutil |
|
import os |
|
import glob |
|
from pathlib import Path |
|
from huggingface_hub import whoami |
|
import platform |
|
|
|
print(subprocess.check_output( |
|
[sys.executable, "-m", "pip", "list"]).decode("utf-8")) |
|
print({ |
|
"python": platform.python_version(), |
|
"os": platform.system(), |
|
"platform": platform.platform(), |
|
"arch": platform.machine() |
|
}) |
|
print("Account token used to connect to HuggingFace: ", whoami()['name']) |
|
|
|
|
|
SUBMISSION_REPO = "SimulaMet/medvqa-submissions" |
|
hub_path = None |
|
submissions = None |
|
last_submission_update_time = datetime.now(timezone.utc) |
|
|
|
|
|
def refresh_submissions(): |
|
global hub_path, submissions, last_submission_update_time |
|
if hub_path and Path(hub_path).exists(): |
|
shutil.rmtree(hub_path, ignore_errors=True) |
|
print("Deleted existing submissions") |
|
|
|
hub_path = snapshot_download( |
|
repo_type="dataset", repo_id=SUBMISSION_REPO, allow_patterns=['**/*.json']) |
|
print("Downloaded submissions to:", hub_path) |
|
if not os.path.exists(hub_path): |
|
os.makedirs(hub_path) |
|
|
|
all_jsons = glob.glob(hub_path + "/**/*.json", recursive=True) |
|
print("json_files count:", len(all_jsons)) |
|
|
|
submissions = [] |
|
for file in all_jsons: |
|
file_ = file.split("/")[-1] |
|
username, sub_timestamp, task = file_.replace( |
|
".json", "").split("-_-_-") |
|
json_data = json.load(open(file)) |
|
public_score = json.dumps(json_data.get("public_scores", {})) |
|
submissions.append({"user": username, "task": task, "public_score": public_score, |
|
"submitted_time": sub_timestamp}) |
|
|
|
last_submission_update_time = datetime.now(timezone.utc) |
|
return hub_path |
|
|
|
|
|
hub_path = refresh_submissions() |
|
hub_dir = hub_path.split("snapshot")[0] + "snapshot" |
|
|
|
|
|
def time_ago(submitted_time): |
|
return str(datetime.fromtimestamp(int(submitted_time), tz=timezone.utc)) + " UTC" |
|
|
|
|
|
def filter_submissions(task_type, search_query): |
|
if search_query == "": |
|
filtered = [s for s in submissions if task_type == |
|
"all" or s["task"] == task_type] |
|
else: |
|
filtered = [s for s in submissions if ( |
|
task_type == "all" or s["task"] == task_type) and search_query.lower() in s["user"].lower()] |
|
return [{"user": s["user"], "task": s["task"], "public_score": s["public_score"], "submitted_time": time_ago(s["submitted_time"])} for s in filtered] |
|
|
|
|
|
def display_submissions(task_type="all", search_query=""): |
|
if submissions is None or ((datetime.now(timezone.utc) - last_submission_update_time).total_seconds() > 3600): |
|
refresh_submissions() |
|
filtered_submissions = filter_submissions(task_type, search_query) |
|
return [[s["user"], s["task"], s["submitted_time"], s["public_score"]] for s in filtered_submissions] |
|
|
|
|
|
def add_submission(file): |
|
global submissions |
|
try: |
|
with open(file, 'r', encoding='utf-8') as f: |
|
data = json.load(f) |
|
|
|
filename = os.path.basename(file) |
|
username, sub_timestamp, task = filename.replace( |
|
".json", "").split("-_-_-") |
|
submission_time = datetime.fromtimestamp( |
|
int(sub_timestamp), tz=timezone.utc) |
|
|
|
assert task in ["task1", "task2"], "Invalid task type" |
|
assert len(username) > 0, "Invalid username" |
|
assert submission_time < datetime.now( |
|
timezone.utc), "Invalid submission time" |
|
|
|
upload_file( |
|
repo_type="dataset", |
|
path_or_fileobj=file, |
|
path_in_repo=task + "/" + filename, |
|
repo_id=SUBMISSION_REPO |
|
) |
|
refresh_submissions() |
|
return "πͺππ Submissions registered successfully to the system!" |
|
except Exception as e: |
|
return f"β Error adding submission: {e}" |
|
|
|
|
|
def refresh_page(): |
|
return "Pong! Submission server is alive! π" |
|
|
|
|
|
|
|
with gr.Blocks(title="πImageCLEFmed-MEDVQA-GI 2025 Submissions π") as demo: |
|
gr.Markdown(""" |
|
# π Welcome to the official submission portal for the [MEDVQA-GI 2025](https://www.imageclef.org/2025/medical/vqa) challenge! π₯𧬠|
|
### π [**Challenge Homepage** in GitHub](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025) | π [**Register** for ImageCLEF 2025](https://www.imageclef.org/2025#registration) | π
[**Competition Schedule**](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025#:~:text=Schedule) | π¦ [**Submission Instructions**](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025#-submission-system)π₯π₯ |
|
### π₯ [**Available Datasets**](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025#-data) | π‘ [Tasks & Example Training **Notebooks**](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025#-task-descriptions)π₯π₯ |
|
""") |
|
|
|
with gr.Tab("View Submissions"): |
|
gr.Markdown("### Filter and Search Submissions") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
task_type_dropdown = gr.Dropdown( |
|
choices=["all", "task1", "task2"], |
|
value="all", |
|
label="Task Type" |
|
) |
|
search_box = gr.Textbox( |
|
label="Search by Username", |
|
placeholder="Enter username..." |
|
) |
|
|
|
with gr.Column(scale=6): |
|
output_table = gr.Dataframe( |
|
headers=["User", "Task", "Submitted Time", "Public Score"], |
|
interactive=False, |
|
wrap=True, |
|
column_widths=["100px", "50px", "80px", "200px"], |
|
label="Submissions" |
|
) |
|
|
|
task_type_dropdown.change( |
|
fn=display_submissions, |
|
inputs=[task_type_dropdown, search_box], |
|
outputs=output_table |
|
) |
|
search_box.change( |
|
fn=display_submissions, |
|
inputs=[task_type_dropdown, search_box], |
|
outputs=output_table |
|
) |
|
|
|
gr.Markdown( |
|
f''' |
|
π Last refreshed: {last_submission_update_time.strftime('%Y-%m-%d %H:%M:%S')} UTC | π Total Submissions: {len(submissions)} |
|
|
|
π¬ For any questions or issues, [contact the organizers](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025#-organizers) or check the documentation in the [GitHub repo](https://github.com/simula/ImageCLEFmed-MEDVQA-GI-2025). Good luck and thank you for contributing to medical AI research! πͺπ€π |
|
''') |
|
|
|
with gr.Tab("Upload Submission", visible=False): |
|
file_input = gr.File(label="Upload JSON", file_types=[".json"]) |
|
upload_output = gr.Textbox(label="Upload Result") |
|
file_input.upload(fn=add_submission, |
|
inputs=file_input, outputs=upload_output) |
|
|
|
with gr.Tab("Refresh API", visible=False): |
|
refresh_button = gr.Button("Refresh") |
|
status_output = gr.Textbox(label="Status") |
|
refresh_button.click(fn=refresh_page, inputs=[], outputs=status_output) |
|
|
|
demo.load(lambda: display_submissions("all", ""), |
|
inputs=[], outputs=output_table) |
|
|
|
demo.launch() |
|
|