Spaces:
Runtime error
Runtime error
make user history installable
Browse files- README.md +36 -34
- app.py +3 -5
- setup.py +57 -0
- src/gradio_user_history/__init__.py +21 -0
- user_history.py → src/gradio_user_history/_user_history.py +2 -19
README.md
CHANGED
@@ -12,7 +12,7 @@ hf_oauth: true
|
|
12 |
|
13 |
# Bring User History to your Spaces 🚀
|
14 |
|
15 |
-
|
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 |
-
|
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 |
-
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
```py
|
|
|
49 |
import gradio as gr
|
50 |
-
import
|
|
|
51 |
|
52 |
-
#
|
53 |
def generate(prompt: str, profile: gr.OAuthProfile | None):
|
54 |
image = ...
|
55 |
|
56 |
-
#
|
57 |
-
|
58 |
return image
|
59 |
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
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 |
-
|
|
|
|
|
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 |
-
- **
|
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 |
-
|
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 |
-
|
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="
|
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(
|
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:
|