Skip to content

Commit bd73f15

Browse files
committed
fix(training): enforce verified HF dataset privacy before export
1 parent 286ce31 commit bd73f15

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

‎app/services/hf_dataset_service.py‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,62 @@ def _env_flag(name: str, default: bool) -> bool:
132132
else True
133133
)
134134

135+
# Remote visibility must be read from the Hub itself; the push argument alone
136+
# is not proof of the existing repository's current privacy.
137+
try:
138+
from huggingface_hub import HfApi
139+
except ImportError: # pragma: no cover - covered by fail-closed tests
140+
HfApi = None
141+
142+
143+
def _verify_remote_dataset_privacy() -> bool:
144+
"""Verify actual Hub visibility before reading or writing dataset data.
145+
146+
Public export is allowed only with the exact explicit opt-in
147+
OMNI_HF_DATASET_PRIVATE=false and only for metadata-only exports. Any API
148+
failure or unknown visibility fails closed. Returns the verified private
149+
state, never a guessed/default value.
150+
"""
151+
if HfApi is None:
152+
raise RuntimeError(
153+
"HF export aborted: huggingface_hub privacy verification is unavailable"
154+
)
155+
try:
156+
api = HfApi(token=HF_TOKEN)
157+
info = api.dataset_info(repo_id=HF_DATASET, token=HF_TOKEN)
158+
actual_private = getattr(info, "private", None)
159+
except Exception as exc:
160+
raise RuntimeError(
161+
"HF export aborted: remote dataset privacy could not be verified; "
162+
"no remote write was attempted and staged rows were retained"
163+
) from exc
164+
165+
if not isinstance(actual_private, bool):
166+
raise RuntimeError(
167+
"HF export aborted: remote dataset privacy is unknown; "
168+
"no remote write was attempted and staged rows were retained"
169+
)
170+
171+
if OMNI_HF_DATASET_PRIVATE:
172+
if actual_private is not True:
173+
raise RuntimeError(
174+
"HF export aborted: private dataset required but remote dataset is public; "
175+
"make the dataset private before retrying"
176+
)
177+
else:
178+
if _dataset_private_env is None or _dataset_private_env.strip() != "false":
179+
raise RuntimeError(
180+
"HF export aborted: public visibility requires explicit "
181+
"OMNI_HF_DATASET_PRIVATE=false opt-in"
182+
)
183+
if OMNI_HF_EXPORT_RAW_TEXT:
184+
raise RuntimeError(
185+
"HF export aborted: public datasets are incompatible with "
186+
"OMNI_HF_EXPORT_RAW_TEXT=true"
187+
)
188+
189+
return actual_private
190+
135191
# Staging directory: where pending rows live until they're pushed.
136192
# Default: ``~/.omni/hf_dataset_queue/``. Override with ``$OMNI_HF_QUEUE_DIR``.
137193
_STAGE_DIR = Path(
@@ -515,6 +571,9 @@ def flush_queue() -> str:
515571
# A failed remote read is not evidence that the dataset is empty or absent.
516572
# Fail closed before any write; the operator must make the target dataset
517573
# readable (or explicitly provision it) before export can proceed.
574+
# Verify the actual Hub visibility before any dataset read/write.
575+
_verify_remote_dataset_privacy()
576+
518577
try:
519578
# Capture one exact remote revision, enumerate its data layout, and
520579
# load that exact revision. The eventual write uses this same SHA as

0 commit comments

Comments
 (0)