Wauplin HF staff commited on
Commit
48675d9
1 Parent(s): 63c295c

make user history installable

Browse files
README.md CHANGED
@@ -12,7 +12,7 @@ hf_oauth: true
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
 
@@ -27,59 +27,61 @@ Want more? Please open an issue in the [Community Tab](https://huggingface.co/sp
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
83
 
84
  ## Preview
85
 
 
12
 
13
  # Bring User History to your Spaces 🚀
14
 
15
+ **Gradio User History** is a plugin (and package) that caches generated images for your Space users.
16
 
17
  ## Key features:
18
 
 
27
 
28
  ## Integration
29
 
30
+ Integrate *Gradio User History* in just a few steps:
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ 1. Enable OAuth
33
 
34
+ ```yaml
35
+ # README.md
36
+ ---
37
+ hf_oauth: true
38
+ ---
39
+ ```
40
+
41
+ 2. Add dependency in `requirements.txt`
42
+
43
+ ```bash
44
+ # requirements.txt
45
+ git+https://huggingface.co/spaces/Wauplin/gradio-user-history
46
+ ```
47
+
48
+ 3. Integrate into your Gradio app
49
 
50
  ```py
51
+ # app.py
52
  import gradio as gr
53
+ import gradio_user_history as gr_user_history
54
+ (...)
55
 
56
+ # => Inject gr.OAuthProfile
57
  def generate(prompt: str, profile: gr.OAuthProfile | None):
58
  image = ...
59
 
60
+ # => Save generated image(s)
61
+ gr_user_history.save_image(label=prompt, image=image, profile=profile)
62
  return image
63
 
64
 
65
+ # => Render user history
66
+ with gr.Blocks() as demo:
67
+ (...)
 
 
 
 
 
 
 
 
 
68
 
69
+ # or `with gr.Tab("Past generations"):`
70
+ with gr.Accordion("Past generations", open=False):
71
+ gr_user_history.render()
72
  ```
73
 
74
+ 4. (optional) Add Persistent Storage in your Space settings.
75
+ Persistent Storage is suggested but not mandatory. If not enabled, the history is lost each time the Space restarts.
76
+
77
+ And you're done!
78
+
79
  ## Useful links
80
 
81
  - **Demo:** https://huggingface.co/spaces/Wauplin/gradio-user-history
82
  - **README:** https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/README.md
83
  - **Source file:** https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/user_history.py
84
+ - **Questions and feedback:** https://huggingface.co/spaces/Wauplin/gradio-user-history/discussions
85
 
86
  ## Preview
87
 
app.py CHANGED
@@ -1,15 +1,13 @@
1
  #!/usr/bin/env python
2
-
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
10
 
11
- import user_history
12
-
13
 
14
  client = Client("runwayml/stable-diffusion-v1-5")
15
 
@@ -30,7 +28,7 @@ def generate(prompt: str, profile: gr.OAuthProfile | None) -> tuple[str, list[st
30
 
31
  # Saving user history
32
  for path in paths:
33
- user_history.save_image(label=prompt, image=path, profile=profile, metadata=metadata)
34
 
35
  return paths # type: ignore
36
 
@@ -53,7 +51,7 @@ with gr.Blocks() as demo_with_history:
53
  with gr.Tab("Demo"):
54
  demo.render()
55
  with gr.Tab("Past generations"):
56
- user_history.render()
57
 
58
  if __name__ == "__main__":
59
  demo_with_history.queue().launch()
 
1
  #!/usr/bin/env python
 
2
  import json
3
  import pathlib
4
  import tempfile
5
  from pathlib import Path
6
 
7
  import gradio as gr
8
+ import gradio_user_history as gr_user_history
9
  from gradio_client import Client
10
 
 
 
11
 
12
  client = Client("runwayml/stable-diffusion-v1-5")
13
 
 
28
 
29
  # Saving user history
30
  for path in paths:
31
+ gr_user_history.save_image(label=prompt, image=path, profile=profile, metadata=metadata)
32
 
33
  return paths # type: ignore
34
 
 
51
  with gr.Tab("Demo"):
52
  demo.render()
53
  with gr.Tab("Past generations"):
54
+ gr_user_history.render()
55
 
56
  if __name__ == "__main__":
57
  demo_with_history.queue().launch()
setup.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from setuptools import find_packages, setup
2
+
3
+
4
+ def get_version() -> str:
5
+ rel_path = "src/gradio_user_history/__init__.py"
6
+ with open(rel_path, "r") as fp:
7
+ for line in fp.read().splitlines():
8
+ if line.startswith("__version__"):
9
+ delim = '"' if '"' in line else "'"
10
+ return line.split(delim)[1]
11
+ raise RuntimeError("Unable to find version string.")
12
+
13
+
14
+ install_requires = [
15
+ "gradio[oauth]>=3.44",
16
+ ]
17
+
18
+ extras = {}
19
+
20
+ extras["dev"] = [
21
+ "ruff",
22
+ "black",
23
+ "mypy",
24
+ ]
25
+
26
+
27
+ setup(
28
+ name="gradio_user_history",
29
+ version=get_version(),
30
+ author="Lucain Pouget",
31
+ author_email="lucain@huggingface.co",
32
+ description="A package to store user history in a gradio app.",
33
+ long_description=open("README.md", "r", encoding="utf-8").read(),
34
+ long_description_content_type="text/markdown",
35
+ keywords="gradio oauth machine-learning",
36
+ license="Apache",
37
+ url="https://huggingface.co/spaces/Wauplin/gradio-user-history",
38
+ package_dir={"": "src"},
39
+ packages=find_packages("src"),
40
+ extras_require=extras,
41
+ python_requires=">=3.8.0",
42
+ install_requires=install_requires,
43
+ classifiers=[
44
+ "Intended Audience :: Developers",
45
+ "Intended Audience :: Education",
46
+ "Intended Audience :: Science/Research",
47
+ "License :: OSI Approved :: Apache Software License",
48
+ "Operating System :: OS Independent",
49
+ "Programming Language :: Python :: 3",
50
+ "Programming Language :: Python :: 3 :: Only",
51
+ "Programming Language :: Python :: 3.8",
52
+ "Programming Language :: Python :: 3.9",
53
+ "Programming Language :: Python :: 3.10",
54
+ "Programming Language :: Python :: 3.11",
55
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
56
+ ],
57
+ )
src/gradio_user_history/__init__.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ User History is a plugin that you can add to your Spaces to cache generated images for your users.
3
+
4
+ Key features:
5
+ - 🤗 Sign in with Hugging Face
6
+ - Save generated images with their metadata: prompts, timestamp, hyper-parameters, etc.
7
+ - Export your history as zip.
8
+ - Delete your history to respect privacy.
9
+ - Compatible with Persistent Storage for long-term storage.
10
+ - Admin panel to check configuration and disk usage .
11
+
12
+ Useful links:
13
+ - Demo: https://huggingface.co/spaces/Wauplin/gradio-user-history
14
+ - README: https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/README.md
15
+ - Source file: https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/user_history.py
16
+ - Discussions: https://huggingface.co/spaces/Wauplin/gradio-user-history/discussions
17
+ """
18
+ from ._user_history import render, save_image, setup # noqa: F401
19
+
20
+
21
+ __version__ = "0.1.0"
user_history.py → src/gradio_user_history/_user_history.py RENAMED
@@ -1,20 +1,3 @@
1
- """
2
- User History is a plugin that you can add to your Spaces to cache generated images for your users.
3
-
4
- Key features:
5
- - 🤗 Sign in with Hugging Face
6
- - Save generated images with their metadata: prompts, timestamp, hyper-parameters, etc.
7
- - Export your history as zip.
8
- - Delete your history to respect privacy.
9
- - Compatible with Persistent Storage for long-term storage.
10
- - Admin panel to check configuration and disk usage .
11
-
12
- Useful links:
13
- - Demo: https://huggingface.co/spaces/Wauplin/gradio-user-history
14
- - README: https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/README.md
15
- - Source file: https://huggingface.co/spaces/Wauplin/gradio-user-history/blob/main/user_history.py
16
- - Discussions: https://huggingface.co/spaces/Wauplin/gradio-user-history/discussions
17
- """
18
  import json
19
  import os
20
  import shutil
@@ -89,7 +72,7 @@ def render() -> None:
89
  gallery = gr.Gallery(
90
  label="Past images",
91
  show_label=True,
92
- elem_id="gallery",
93
  object_fit="contain",
94
  columns=5,
95
  height=600,
@@ -295,7 +278,7 @@ def _resolve_folder_path(folder_path: str | Path | None) -> Path:
295
  return Path("/data") / "_user_history"
296
 
297
  # Not in a Space or Persistent storage not enabled => local folder
298
- return Path(__file__).parent / "_user_history"
299
 
300
 
301
  def _archives_path() -> Path:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import json
2
  import os
3
  import shutil
 
72
  gallery = gr.Gallery(
73
  label="Past images",
74
  show_label=True,
75
+ elem_id="gradio_user_history_gallery",
76
  object_fit="contain",
77
  columns=5,
78
  height=600,
 
278
  return Path("/data") / "_user_history"
279
 
280
  # Not in a Space or Persistent storage not enabled => local folder
281
+ return Path("_user_history").resolve()
282
 
283
 
284
  def _archives_path() -> Path: