request-moderator / submissions.py
EmmaScharfmann's picture
EmmaScharfmann HF Staff
Add type filter to Pending/History tabs; review feedback.jsonl alongside requests.jsonl
c716b25
Raw
History Blame Contribute Delete
3.37 kB
"""Submissions queue backed by the existing hugging-science/feedback HF Dataset.
`requests.jsonl` holds every non-"feedback" type (dataset/model/organization/
blog/challenge/collaboration); `feedback.jsonl` holds "feedback". Both are
written by the feedback-api Space's /submit endpoint. Ingestion happens
there, not here — this module only reads those files and updates a row's
status when the reviewer approves/rejects/acknowledges it.
"""
import json
import threading
from datetime import datetime, timezone
from huggingface_hub import HfApi
from huggingface_hub.utils import EntryNotFoundError
from about import DATASET_REPO, FEEDBACK_FILE, REQUESTS_FILE, TOKEN
_api = HfApi(token=TOKEN)
_lock = threading.Lock()
ALL_FILES = (REQUESTS_FILE, FEEDBACK_FILE)
def _now() -> str:
return datetime.now(timezone.utc).isoformat()
def _read_file(filename: str) -> list[dict]:
try:
path = _api.hf_hub_download(
repo_id=DATASET_REPO, repo_type="dataset", filename=filename
)
except EntryNotFoundError:
return []
with open(path, encoding="utf-8") as f:
return [json.loads(line) for line in f if line.strip()]
def _write_file(filename: str, rows: list[dict]) -> None:
content = "\n".join(json.dumps(row) for row in rows) + "\n"
_api.upload_file(
path_or_fileobj=content.encode("utf-8"),
path_in_repo=filename,
repo_id=DATASET_REPO,
repo_type="dataset",
commit_message="Update requests queue",
)
def _read_all() -> list[dict]:
return [row for filename in ALL_FILES for row in _read_file(filename)]
def list_submissions(status: str | None = None, type_: str | None = None) -> list[dict]:
rows = _read_all()
if status is not None:
rows = [r for r in rows if r["status"] == status]
if type_ is not None:
rows = [r for r in rows if r["type"] == type_]
return rows
def get_submission(submission_id: str) -> dict | None:
for row in _read_all():
if row["id"] == submission_id:
return row
return None
def _update_row(submission_id: str, mutate_fn) -> None:
"""Find `submission_id` in whichever file its type lives in, mutate it in
place, and rewrite only that file."""
with _lock:
for filename in ALL_FILES:
rows = _read_file(filename)
for row in rows:
if row["id"] == submission_id:
mutate_fn(row)
_write_file(filename, rows)
return
def mark_approved(submission_id: str, pr_url: str) -> None:
def mutate(row):
row["status"] = "approved"
row["reviewed_at"] = _now()
row["pr_url"] = pr_url
_update_row(submission_id, mutate)
def mark_acknowledged(submission_id: str) -> None:
"""For non-PR types (feedback, collaboration, challenge): close out a
submission without opening a PR — e.g. once it's been read or the
requester has been emailed."""
def mutate(row):
row["status"] = "acknowledged"
row["reviewed_at"] = _now()
_update_row(submission_id, mutate)
def mark_rejected(submission_id: str, reason: str | None) -> None:
def mutate(row):
row["status"] = "rejected"
row["reviewed_at"] = _now()
row["reject_reason"] = reason
_update_row(submission_id, mutate)