Wauplin HF staff commited on
Commit
50c63ac
1 Parent(s): f8a22a4

instructions

Browse files
Files changed (3) hide show
  1. README.md +70 -1
  2. app.py +4 -1
  3. user_history.py +8 -3
README.md CHANGED
@@ -10,4 +10,73 @@ pinned: false
10
  hf_oauth: true
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  hf_oauth: true
11
  ---
12
 
13
+ # Bring User History to your Spaces 🚀
14
+
15
+ ***User History*** is a plugin that you can add to your Spaces to cache generated images for your users.
16
+
17
+ ## Key features:
18
+
19
+ - 🤗 **Sign in with Hugging Face**
20
+ - **Save** generated images with their metadata: prompts, timestamp, hyper-parameters, etc.
21
+ - **Export** your history as zip.
22
+ - **Delete** your history to respect privacy.
23
+ - Compatible with **Persistent Storage** for long-term storage.
24
+ - **Admin** panel to check configuration and disk usage .
25
+
26
+ Want more? Please open an issue in the [Community Tab](https://huggingface.co/spaces/Wauplin/gradio-user-history/discussions)! This is meant to be a community-driven implementation, enhanced by user feedback and contributions!
27
+
28
+ ## Integration
29
+
30
+ To integrate ***User History***, only a few steps are required:
31
+ 1. Enable OAuth in your Space by adding `oauth: true` to your README (see [here](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/README.md?code=true#L10))
32
+ 2. Add a Persistent Storage in your Space settings. Without it, the history will not be saved permanently. Every restart of your Space will erase all the data. If you start with a small tier, it's always possible to increase the disk space later without loosing the data.
33
+ 3. Copy [`user_history.py`](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/user_history.py) at the root of your project.
34
+ 4. Import in your main file with `import user_history` (see [here](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/app.py#L10))
35
+ 5. Integrate to your `generate`-like methods. Any function called by Gradio and that generates one or multiple images is a good candidate.
36
+ 1. Add `profile: gr.OAuthProfile | None` as argument to the function (see [here](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/app.py#L16)). This will tell Gradio that it needs to inject the user profile for you.
37
+ 2. Use `user_history.save_image(label=..., image=..., profile=profile, metadata=...)` (as done [here](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/app.py#L32))
38
+ 1. `label` is the label of the image. Usually the prompt used to generate it.
39
+ 2. `image` is the generated image. It can be a path to a stored image, a `PIL.Image` object or a numpy array.
40
+ 3. `profile` is the user profile injected by Gradio
41
+ 4. `metadata` (optional) is any additional information you want to add. It has to be a json-able dictionary.
42
+ 3. Finally use `user_history.render()` to render the "Past generations" section (see [here](https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/app.py#L53)). A good practice is to set it in a different tab to avoid overloading your first page. You don't have to modify anything of your existing `gr.Blocks` section: just render it inside a Tab.
43
+
44
+ ## Example
45
+
46
+ Here is a minimal example illustrating what we saw above.
47
+
48
+ ```py
49
+ import gradio as gr
50
+ import user_history # 0. Import user_history
51
+
52
+ # 1. Inject user profile
53
+ def generate(prompt: str, profile: gr.OAuthProfile | None):
54
+ image = ...
55
+
56
+ # 2. Save image
57
+ user_history.save_image(label=prompt, image=image, profile=profile)
58
+ return image
59
+
60
+
61
+ with gr.Blocks(css="style.css") as demo:
62
+ with gr.Group():
63
+ prompt = gr.Text(show_label=False, placeholder="Prompt")
64
+ gallery = gr.Image()
65
+ prompt.submit(fn=generate, inputs=prompt, outputs=gallery)
66
+
67
+ # 3. Render user history
68
+ with gr.Blocks() as demo_with_history:
69
+ with gr.Tab("Demo"):
70
+ demo.render()
71
+ with gr.Tab("Past generations"):
72
+ user_history.render()
73
+
74
+ demo_with_history.queue().launch()
75
+ ```
76
+
77
+ ## Useful links
78
+
79
+ - **Demo:** https://huggingface.co/spaces/Wauplin/gradio-user-history
80
+ - **README:** https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/README.md
81
+ - **Source file:** https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/user_history.py
82
+ - **Discussions:** https://huggingface.co/spaces/Wauplin/gradio-user-history/discussions
app.py CHANGED
@@ -3,6 +3,7 @@
3
  import json
4
  import pathlib
5
  import tempfile
 
6
 
7
  import gradio as gr
8
  from gradio_client import Client
@@ -47,10 +48,12 @@ with gr.Blocks(css="style.css") as demo:
47
  prompt.submit(fn=generate, inputs=prompt, outputs=gallery)
48
 
49
  with gr.Blocks() as demo_with_history:
50
- with gr.Tab("App"):
51
  demo.render()
52
  with gr.Tab("Past generations"):
53
  user_history.render()
 
 
54
 
55
  if __name__ == "__main__":
56
  demo_with_history.queue().launch()
 
3
  import json
4
  import pathlib
5
  import tempfile
6
+ from pathlib import Path
7
 
8
  import gradio as gr
9
  from gradio_client import Client
 
48
  prompt.submit(fn=generate, inputs=prompt, outputs=gallery)
49
 
50
  with gr.Blocks() as demo_with_history:
51
+ with gr.Tab("Demo"):
52
  demo.render()
53
  with gr.Tab("Past generations"):
54
  user_history.render()
55
+ with gr.Tab("README"):
56
+ gr.Markdown(Path("README.md").read_text().split("---")[-1])
57
 
58
  if __name__ == "__main__":
59
  demo_with_history.queue().launch()
user_history.py CHANGED
@@ -31,8 +31,9 @@ def render() -> None:
31
 
32
  # Render user history tab
33
  gr.Markdown(
34
- "## Your past generations\n\n(Log in to keep a gallery of your previous generations."
35
- " Your history will be saved and available on your next visit.)"
 
36
  )
37
 
38
  if os.getenv("SYSTEM") == "spaces" and not os.path.exists("/data"):
@@ -70,7 +71,11 @@ def render() -> None:
70
  show_share_button=False,
71
  show_download_button=False,
72
  )
73
- gr.Markdown("Make sure to save your images from time to time, this gallery may be deleted in the future.")
 
 
 
 
74
  gallery.attach_load_event(_fetch_user_history, every=None)
75
 
76
  # Interactions
 
31
 
32
  # Render user history tab
33
  gr.Markdown(
34
+ "## Your past generations\n\nLog in to keep a gallery of your previous generations. Your history will be saved"
35
+ " and available on your next visit. Make sure to export your images from time to time as this gallery may be"
36
+ " deleted in the future."
37
  )
38
 
39
  if os.getenv("SYSTEM") == "spaces" and not os.path.exists("/data"):
 
71
  show_share_button=False,
72
  show_download_button=False,
73
  )
74
+ gr.Markdown(
75
+ "User history is powered by"
76
+ " [Wauplin/gradio-user-history](https://huggingface.co/spaces/Wauplin/gradio-user-history). Integrate it to"
77
+ " your own Space in just a few lines of code!"
78
+ )
79
  gallery.attach_load_event(_fetch_user_history, every=None)
80
 
81
  # Interactions