someone-in-the-world Claude Sonnet 5 commited on
Commit
2a6abee
·
unverified ·
1 Parent(s): e6a95be

Add in-app privacy notice for debug logging (closes #14) (#15)

Browse files

The 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>

Files changed (2) hide show
  1. README.md +3 -1
  2. app.py +68 -0
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
- Configure independently per Space under *Settings Variables and secrets*:
 
 
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"])