Spaces:
Running on Zero
Running on Zero
Add in-app privacy notice for debug logging (closes #14) (#15)
Browse filesThe debug-logging pipeline (LOG-1-9, #13) was only documented for
operators in README.md; end users of the Space saw no disclosure that
their image/video/prompts may be logged when enabled. Add an in-app
notice + Privacy Policy accordion, based on legitimate interest (GDPR
Art. 6(1)(f)), mirroring the FireRed-Image-Edit-1.0-Fast reference
project's equivalent notice. Logging itself is unchanged — still a
silent no-op unless LOG_HF_TOKEN/LOG_DATASET_REPO are set.
Claude-Session: https://claude.ai/code/session_01N8KBjSiiW8dPZc9KZru96q
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
README.md
CHANGED
|
@@ -47,7 +47,9 @@ comment at the top of `postprocess/upscale/upscale.py` for why.
|
|
| 47 |
Each inference call can optionally be logged (prompt, seed, generation/interpolation/upscale
|
| 48 |
settings, input image, pre-upscale output video, timing, success/error) to a private Hugging
|
| 49 |
Face Hub dataset repo. Disabled by default — nothing is logged until both secrets below are set.
|
| 50 |
-
|
|
|
|
|
|
|
| 51 |
|
| 52 |
| variable | type | notes |
|
| 53 |
|---|---|---|
|
|
|
|
| 47 |
Each inference call can optionally be logged (prompt, seed, generation/interpolation/upscale
|
| 48 |
settings, input image, pre-upscale output video, timing, success/error) to a private Hugging
|
| 49 |
Face Hub dataset repo. Disabled by default — nothing is logged until both secrets below are set.
|
| 50 |
+
Logging is based on legitimate interest (GDPR Art. 6(1)(f)), not consent — see the notice and
|
| 51 |
+
Privacy Policy shown in the app for details, including how to request access to or deletion of
|
| 52 |
+
your data. Configure independently per Space under *Settings → Variables and secrets*:
|
| 53 |
|
| 54 |
| variable | type | notes |
|
| 55 |
|---|---|---|
|
app.py
CHANGED
|
@@ -51,6 +51,17 @@ _log_uploader = LogUploader(
|
|
| 51 |
batch_interval=int(os.environ.get("LOG_BATCH_INTERVAL", "60")),
|
| 52 |
)
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
def _gpu_duration(
|
| 56 |
resized_image,
|
|
@@ -305,6 +316,63 @@ with gr.Blocks() as demo:
|
|
| 305 |
gr.Markdown("# High Quality Video Generation")
|
| 306 |
gr.Markdown("Turn a still image into a short video clip guided by a text prompt.")
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
with gr.Row():
|
| 309 |
with gr.Column():
|
| 310 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|
|
|
|
| 51 |
batch_interval=int(os.environ.get("LOG_BATCH_INTERVAL", "60")),
|
| 52 |
)
|
| 53 |
|
| 54 |
+
# SPACE_ID is set automatically by Hugging Face Spaces ("namespace/space_name") — used instead of a
|
| 55 |
+
# hardcoded handle so the privacy notice stays correct for anyone who duplicates this Space.
|
| 56 |
+
_SPACE_ID = os.environ.get("SPACE_ID")
|
| 57 |
+
_OPERATOR_MD = (
|
| 58 |
+
f"[the Space operator](https://huggingface.co/{_SPACE_ID.split('/')[0]})" if _SPACE_ID else "the Space operator"
|
| 59 |
+
)
|
| 60 |
+
_COMMUNITY_MD = (
|
| 61 |
+
f"[this Space's Community tab](https://huggingface.co/spaces/{_SPACE_ID}/discussions)"
|
| 62 |
+
if _SPACE_ID else "this Space's Community tab"
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
|
| 66 |
def _gpu_duration(
|
| 67 |
resized_image,
|
|
|
|
| 316 |
gr.Markdown("# High Quality Video Generation")
|
| 317 |
gr.Markdown("Turn a still image into a short video clip guided by a text prompt.")
|
| 318 |
|
| 319 |
+
gr.Markdown(
|
| 320 |
+
"- Service availability and response times may vary as this Space runs on shared GPU infrastructure.\n"
|
| 321 |
+
"- When using this Space, please comply with the "
|
| 322 |
+
"[Hugging Face Content Policy](https://huggingface.co/content-policy).\n"
|
| 323 |
+
f"- To monitor application performance and improve quality, input data (image/prompt) and generated "
|
| 324 |
+
f"outputs are logged solely for debugging purposes and retained in a private Hugging Face dataset "
|
| 325 |
+
f"accessible only to {_OPERATOR_MD}, automatically pruned once the dataset reaches its configured "
|
| 326 |
+
f"limit (oldest records deleted first). This processing is based on legitimate interest (GDPR Art. "
|
| 327 |
+
f"6(1)(f)) and the data is not shared with or sold to any third party. To request access to or "
|
| 328 |
+
f"deletion of your data, open a discussion on {_COMMUNITY_MD}. See the **Privacy Policy** below for "
|
| 329 |
+
"full details of your rights.\n"
|
| 330 |
+
"- No user account or identifying information (such as IP address or session data) is collected."
|
| 331 |
+
)
|
| 332 |
+
|
| 333 |
+
with gr.Accordion("Privacy Policy", open=False):
|
| 334 |
+
gr.Markdown(
|
| 335 |
+
f"**Space:** High Quality Video Generation \n"
|
| 336 |
+
f"**Operator:** {_OPERATOR_MD} \n"
|
| 337 |
+
f"**Last updated:** 2026-08-30\n"
|
| 338 |
+
"\n"
|
| 339 |
+
"#### What data is collected\n"
|
| 340 |
+
"When you submit a request, the following is logged: your uploaded input image, the generated "
|
| 341 |
+
"output video (pre-upscale, post-interpolation), your prompt and negative prompt, seed, inference "
|
| 342 |
+
"steps, guidance scale, frame-interpolation and upscaling settings, output resolution/fps/duration, "
|
| 343 |
+
"generation duration, and success/error status. No user account, IP address, or session data is "
|
| 344 |
+
"collected.\n"
|
| 345 |
+
"\n"
|
| 346 |
+
"#### Why it is collected\n"
|
| 347 |
+
"Solely for debugging and monitoring application performance (legitimate interest, GDPR Art. "
|
| 348 |
+
"6(1)(f)).\n"
|
| 349 |
+
"\n"
|
| 350 |
+
"#### Where it is stored\n"
|
| 351 |
+
f"In a private Hugging Face dataset accessible only to {_OPERATOR_MD}. The data is not shared with "
|
| 352 |
+
"or sold to any third party.\n"
|
| 353 |
+
"\n"
|
| 354 |
+
"#### How long it is kept\n"
|
| 355 |
+
"Entries are automatically pruned once the dataset reaches its configured storage cap (default "
|
| 356 |
+
"10GB) — the oldest entries are deleted first. The operator may also delete data manually at any "
|
| 357 |
+
"time.\n"
|
| 358 |
+
"\n"
|
| 359 |
+
"#### Your rights\n"
|
| 360 |
+
"Use of this Space and submission of images is entirely voluntary. Under GDPR you have the right "
|
| 361 |
+
"to:\n"
|
| 362 |
+
"- **Access** (Art. 15): request a copy of data held about you\n"
|
| 363 |
+
"- **Erasure** (Art. 17): request deletion of your data\n"
|
| 364 |
+
"- **Restriction** (Art. 18): request that processing be limited\n"
|
| 365 |
+
"- **Portability** (Art. 20): receive your data in a machine-readable format\n"
|
| 366 |
+
"- **Objection** (Art. 21): object to processing based on legitimate interest\n"
|
| 367 |
+
"\n"
|
| 368 |
+
f"To exercise any of these rights, open a discussion on {_COMMUNITY_MD}.\n"
|
| 369 |
+
"\n"
|
| 370 |
+
"#### Right to complain\n"
|
| 371 |
+
"You have the right to lodge a complaint with your national data protection authority, for example: "
|
| 372 |
+
"ICO (UK), CNIL (France), BfDI (Germany), or your local EU member state authority listed at "
|
| 373 |
+
"[edpb.europa.eu](https://www.edpb.europa.eu/about-edpb/about-edpb/members_en)."
|
| 374 |
+
)
|
| 375 |
+
|
| 376 |
with gr.Row():
|
| 377 |
with gr.Column():
|
| 378 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|