Spaces:
Running
Running
Shiyu Zhao
commited on
Commit
·
4438381
1
Parent(s):
2e5b4ed
Forum
Browse files- app.py +1 -1
- review_submission.py +144 -0
- utils/hub_storage.py +44 -25
app.py
CHANGED
@@ -122,7 +122,7 @@ class SubmissionForum:
|
|
122 |
|
123 |
# Initialize storage once at startup
|
124 |
try:
|
125 |
-
REPO_ID = "snap-stanford/stark-leaderboard"
|
126 |
hub_storage = HubStorage(REPO_ID)
|
127 |
forum = SubmissionForum(hub_storage=hub_storage)
|
128 |
except Exception as e:
|
|
|
122 |
|
123 |
# Initialize storage once at startup
|
124 |
try:
|
125 |
+
REPO_ID = "snap-stanford/stark-leaderboard"
|
126 |
hub_storage = HubStorage(REPO_ID)
|
127 |
forum = SubmissionForum(hub_storage=hub_storage)
|
128 |
except Exception as e:
|
review_submission.py
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import os
|
3 |
+
from datetime import datetime
|
4 |
+
import glob
|
5 |
+
from app import SubmissionForum
|
6 |
+
from utils.hub_storage import HubStorage
|
7 |
+
|
8 |
+
|
9 |
+
|
10 |
+
def read_json_file(file_path: str) -> dict:
|
11 |
+
"""Read and parse local JSON file."""
|
12 |
+
try:
|
13 |
+
with open(file_path, 'r') as f:
|
14 |
+
return json.load(f)
|
15 |
+
except Exception as e:
|
16 |
+
print(f"Error reading {file_path}: {str(e)}")
|
17 |
+
return None
|
18 |
+
|
19 |
+
def update_json_file(file_path: str, content: dict, method_name: str = None, new_status: str = None) -> bool:
|
20 |
+
"""Update local JSON file and add forum post if status changed"""
|
21 |
+
try:
|
22 |
+
with open(file_path, 'w') as f:
|
23 |
+
json.dump(content, f, indent=4)
|
24 |
+
|
25 |
+
# Add forum post if this is a status update
|
26 |
+
if method_name and new_status:
|
27 |
+
forum.add_status_update(method_name, new_status)
|
28 |
+
|
29 |
+
return True
|
30 |
+
except Exception as e:
|
31 |
+
print(f"Error updating {file_path}: {str(e)}")
|
32 |
+
return False
|
33 |
+
|
34 |
+
def review_pending_submissions(submissions_dir: str = "submissions"):
|
35 |
+
"""Review all pending submissions and allow admin to approve/reject them."""
|
36 |
+
try:
|
37 |
+
REPO_ID = "snap-stanford/stark-leaderboard"
|
38 |
+
hub_storage = HubStorage(REPO_ID)
|
39 |
+
forum = SubmissionForum(hub_storage=hub_storage)
|
40 |
+
# Find all latest.json files
|
41 |
+
latest_files = glob.glob(os.path.join(submissions_dir, "**", "latest.json"), recursive=True)
|
42 |
+
|
43 |
+
if not latest_files:
|
44 |
+
print("No submissions found.")
|
45 |
+
return
|
46 |
+
|
47 |
+
changes_made = False
|
48 |
+
|
49 |
+
# Process each submission
|
50 |
+
for latest_file in latest_files:
|
51 |
+
folder_path = os.path.dirname(latest_file)
|
52 |
+
latest_info = read_json_file(latest_file)
|
53 |
+
|
54 |
+
if not latest_info:
|
55 |
+
print(f"Could not read {latest_file}, skipping...")
|
56 |
+
continue
|
57 |
+
|
58 |
+
if latest_info.get('status') != 'pending_review':
|
59 |
+
continue
|
60 |
+
|
61 |
+
# Find corresponding metadata file
|
62 |
+
timestamp = latest_info.get('latest_submission')
|
63 |
+
if not timestamp:
|
64 |
+
print(f"No timestamp found in {latest_file}, skipping...")
|
65 |
+
continue
|
66 |
+
|
67 |
+
metadata_file = os.path.join(folder_path, f"metadata_{timestamp}.json")
|
68 |
+
metadata = read_json_file(metadata_file)
|
69 |
+
|
70 |
+
if not metadata:
|
71 |
+
print(f"Could not read metadata for {latest_file}, skipping...")
|
72 |
+
continue
|
73 |
+
|
74 |
+
# Display submission details
|
75 |
+
print("\n" + "="*80)
|
76 |
+
print(f"Submission Details:")
|
77 |
+
print(f"Method Name: {metadata.get('Method Name')}")
|
78 |
+
print(f"Team Name: {metadata.get('Team Name')}")
|
79 |
+
print(f"Dataset: {metadata.get('Dataset')}")
|
80 |
+
print(f"Split: {metadata.get('Split')}")
|
81 |
+
print(f"Contact Email(s): {metadata.get('Contact Email(s)')}")
|
82 |
+
print(f"Code Repository: {metadata.get('Code Repository')}")
|
83 |
+
print("\nModel Description:")
|
84 |
+
print(metadata.get('Model Description', 'No description provided'))
|
85 |
+
print("\nResults:")
|
86 |
+
if 'results' in metadata:
|
87 |
+
for metric, value in metadata['results'].items():
|
88 |
+
print(f"{metric}: {value}")
|
89 |
+
print("\nSubmission Date:", metadata.get('submission_date', 'Unknown'))
|
90 |
+
print("="*80)
|
91 |
+
|
92 |
+
# Get admin decision
|
93 |
+
while True:
|
94 |
+
decision = input("\nApprove this submission? (y/n/skip/quit): ").lower()
|
95 |
+
if decision in ['y', 'n', 'skip', 'quit']:
|
96 |
+
break
|
97 |
+
print("Invalid input. Please enter 'y', 'n', 'skip', or 'quit'")
|
98 |
+
|
99 |
+
if decision == 'quit':
|
100 |
+
print("Exiting review process...")
|
101 |
+
break
|
102 |
+
|
103 |
+
if decision == 'skip':
|
104 |
+
continue
|
105 |
+
|
106 |
+
# Update status
|
107 |
+
new_status = 'approved' if decision == 'y' else 'rejected'
|
108 |
+
review_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
109 |
+
|
110 |
+
# Update latest.json
|
111 |
+
latest_info['status'] = new_status
|
112 |
+
latest_info['reviewed_at'] = review_timestamp
|
113 |
+
if not update_json_file(
|
114 |
+
latest_file,
|
115 |
+
latest_info,
|
116 |
+
method_name=metadata.get('Method Name'),
|
117 |
+
new_status=new_status
|
118 |
+
):
|
119 |
+
print("Failed to update latest.json")
|
120 |
+
continue
|
121 |
+
|
122 |
+
# Update metadata
|
123 |
+
metadata['status'] = new_status
|
124 |
+
metadata['reviewed_at'] = review_timestamp
|
125 |
+
if not update_json_file(metadata_file, metadata):
|
126 |
+
print("Failed to update metadata file")
|
127 |
+
continue
|
128 |
+
|
129 |
+
forum.add_status_update(metadata.get('Method Name'), new_status)
|
130 |
+
print(f"Submission {new_status}")
|
131 |
+
changes_made = True
|
132 |
+
|
133 |
+
if changes_made:
|
134 |
+
print("\nChanges have been made to the following files:")
|
135 |
+
print("Please push these changes to HuggingFace manually.")
|
136 |
+
|
137 |
+
except Exception as e:
|
138 |
+
print(f"Error during review process: {str(e)}")
|
139 |
+
|
140 |
+
if __name__ == "__main__":
|
141 |
+
print("Starting submission review process...")
|
142 |
+
# You can specify a different submissions directory if needed
|
143 |
+
review_pending_submissions("submissions")
|
144 |
+
print("\nReview process completed.")
|
utils/hub_storage.py
CHANGED
@@ -1,36 +1,55 @@
|
|
1 |
from pathlib import Path
|
2 |
from huggingface_hub import HfApi
|
3 |
from .token_handler import TokenHandler
|
|
|
4 |
|
5 |
class HubStorage:
|
6 |
def __init__(self, repo_id):
|
7 |
self.repo_id = repo_id
|
8 |
self.api = HfApi()
|
9 |
-
|
10 |
-
|
|
|
11 |
try:
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
except Exception as e:
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
raise RuntimeError(f"Failed to save file after {max_retries} attempts: {e}")
|
34 |
-
print(f"Attempt {attempt + 1} failed, retrying in {retry_delay} seconds...")
|
35 |
-
time.sleep(retry_delay)
|
36 |
-
retry_delay *= 2 # Exponential backoff
|
|
|
1 |
from pathlib import Path
|
2 |
from huggingface_hub import HfApi
|
3 |
from .token_handler import TokenHandler
|
4 |
+
import time
|
5 |
|
6 |
class HubStorage:
|
7 |
def __init__(self, repo_id):
|
8 |
self.repo_id = repo_id
|
9 |
self.api = HfApi()
|
10 |
+
|
11 |
+
def get_file_content(self, path_in_repo):
|
12 |
+
"""Get content of a file from the hub"""
|
13 |
try:
|
14 |
+
# Download the file content as bytes
|
15 |
+
path = self.api.hf_hub_download(
|
16 |
+
repo_id=self.repo_id,
|
17 |
+
filename=path_in_repo,
|
18 |
+
repo_type="space"
|
19 |
+
)
|
20 |
+
# Read file content
|
21 |
+
with open(path, 'r') as f:
|
22 |
+
return f.read()
|
23 |
except Exception as e:
|
24 |
+
print(f"Error reading file {path_in_repo}: {str(e)}")
|
25 |
+
return None
|
26 |
+
|
27 |
+
def save_to_hub(self, file_content, path_in_repo, commit_message="Update file"):
|
28 |
+
"""Save content to hub"""
|
29 |
+
try:
|
30 |
+
# If file_content is a string (like JSON), write it to a temporary file first
|
31 |
+
if isinstance(file_content, str):
|
32 |
+
with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file:
|
33 |
+
temp_file.write(file_content)
|
34 |
+
temp_path = temp_file.name
|
35 |
+
else:
|
36 |
+
# If it's already a file path, use it directly
|
37 |
+
temp_path = file_content
|
38 |
|
39 |
+
# Upload to hub
|
40 |
+
self.api.upload_file(
|
41 |
+
path_or_fileobj=temp_path,
|
42 |
+
path_in_repo=path_in_repo,
|
43 |
+
repo_id=self.repo_id,
|
44 |
+
repo_type="space",
|
45 |
+
commit_message=commit_message
|
46 |
+
)
|
47 |
+
|
48 |
+
# Clean up temporary file if we created one
|
49 |
+
if isinstance(file_content, str):
|
50 |
+
os.unlink(temp_path)
|
51 |
+
|
52 |
+
return True
|
53 |
+
except Exception as e:
|
54 |
+
print(f"Error saving to hub: {str(e)}")
|
55 |
+
return False
|
|
|
|
|
|
|
|