Spaces:
Runtime error
Runtime error
espejelomar
commited on
Commit
•
2ced9d2
1
Parent(s):
3a44c44
upload code
Browse files- README.md +13 -7
- app.py +60 -0
- assets/1_streamlit_space.png +0 -0
- assets/1_thumbnail.png +0 -0
- assets/1_token.png +0 -0
- assets/2_gradio_space.png +0 -0
- assets/2_secret.png +0 -0
- assets/2_thumbnail.png +0 -0
- assets/2_token.png +0 -0
- posts/1_blog_in_spaces.py +134 -0
- posts/2_private_models.py +173 -0
- requirements.txt +4 -0
README.md
CHANGED
@@ -1,13 +1,19 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: streamlit
|
7 |
-
sdk_version: 1.10.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
-
license: mit
|
11 |
---
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
+
title: HF Tips & Tricks
|
3 |
+
emoji: 🤗
|
4 |
+
colorFrom: blue
|
5 |
+
colorTo: red
|
6 |
sdk: streamlit
|
|
|
7 |
app_file: app.py
|
8 |
pinned: false
|
|
|
9 |
---
|
10 |
|
11 |
+
# Host a Blog on HuggingFace Spaces
|
12 |
+
|
13 |
+
[![Generic badge](https://img.shields.io/badge/🤗-Open%20In%20Spaces-blue.svg)](https://huggingface.co/spaces/osanseviero/tips-and-tricks)
|
14 |
+
|
15 |
+
How to host a blog on 🤗
|
16 |
+
|
17 |
+
---
|
18 |
+
|
19 |
+
Autogenerated using [this template](https://github.com/nateraw/spaces-template)
|
app.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import re
|
3 |
+
from pathlib import Path
|
4 |
+
import importlib
|
5 |
+
|
6 |
+
|
7 |
+
def render_preview(imagen, titulo, descripcion):
|
8 |
+
with st.container():
|
9 |
+
image_col, text_col = st.columns((1,2))
|
10 |
+
with image_col:
|
11 |
+
st.image(imagen)
|
12 |
+
|
13 |
+
with text_col:
|
14 |
+
st.subheader(titulo)
|
15 |
+
st.write(descripcion)
|
16 |
+
clicked = st.button("Lee más dando click aquí...", key=titulo)
|
17 |
+
return clicked
|
18 |
+
|
19 |
+
|
20 |
+
def render_page(post_path: Path):
|
21 |
+
mod = importlib.import_module(str(post_path))
|
22 |
+
mod.run_article()
|
23 |
+
|
24 |
+
|
25 |
+
def get_page_data(post_path: Path):
|
26 |
+
mod = importlib.import_module(str(post_path))
|
27 |
+
return {
|
28 |
+
"titutlo": mod.titulo,
|
29 |
+
"descripcion": mod.descripcion,
|
30 |
+
"fecha": mod.fecha,
|
31 |
+
"thumbnail": mod.thumbnail,
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
def main():
|
36 |
+
st.set_page_config(layout="wide")
|
37 |
+
posts = [
|
38 |
+
'posts.2_private_models',
|
39 |
+
'posts.1_blog_in_spaces'
|
40 |
+
]
|
41 |
+
page_to_show = posts[0]
|
42 |
+
with st.sidebar:
|
43 |
+
|
44 |
+
st.markdown('''
|
45 |
+
<div align="center">
|
46 |
+
<h1>El blog de Platzi</h1>
|
47 |
+
<p>La comunidad de Platzi en Hugging Face comparte conocimiento 🤗</p>
|
48 |
+
''', unsafe_allow_html=True)
|
49 |
+
st.markdown('---')
|
50 |
+
|
51 |
+
for post in posts:
|
52 |
+
data = get_page_data(Path(post))
|
53 |
+
clicked = render_preview(data.get("thumbnail"), data.get("titulo"), data.get("descripcion"))
|
54 |
+
if clicked:
|
55 |
+
page_to_show = post
|
56 |
+
|
57 |
+
if page_to_show:
|
58 |
+
render_page(Path(page_to_show))
|
59 |
+
|
60 |
+
main()
|
assets/1_streamlit_space.png
ADDED
assets/1_thumbnail.png
ADDED
assets/1_token.png
ADDED
assets/2_gradio_space.png
ADDED
assets/2_secret.png
ADDED
assets/2_thumbnail.png
ADDED
assets/2_token.png
ADDED
posts/1_blog_in_spaces.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
from stmol import showmol
|
4 |
+
import py3Dmol
|
5 |
+
|
6 |
+
title = "T&T1 - Create interactive blog posts with Streamlit and Spaces"
|
7 |
+
description = "Learn about how to host interactive blogs using Streamlit, GitHub and Spaces."
|
8 |
+
date = "2022-01-20"
|
9 |
+
thumbnail = "assets/1_thumbnail.png"
|
10 |
+
|
11 |
+
def run_article():
|
12 |
+
st.markdown("""
|
13 |
+
# 🤗 Tips & Tricks Edition 1
|
14 |
+
# Create interactive blog posts with Streamlit and Spaces
|
15 |
+
|
16 |
+
Welcome to the first post of the 🤗 Tips and Tricks blog! Each post can be read in <5 minutes and shares features you might not know about that will allow you to leverage the Hub platform and Open Source ecosystem to its full extent.
|
17 |
+
|
18 |
+
In today's post, you'll learn how this blog was actually done! This is actually very easy and the initial setup takes less than 10 minutes!
|
19 |
+
|
20 |
+
**How much will it cost me? 🤑 **
|
21 |
+
|
22 |
+
Nothing! We'll be using Open Source and free tools to achieve it.
|
23 |
+
|
24 |
+
I'm a strong believer that there are different tools for different jobs, so today you'll use:
|
25 |
+
|
26 |
+
* **Streamlit**: A very cool Open Source library that allows to build apps in Python in a very straightforward way.
|
27 |
+
* **GitHub**: The main platform in which we're going to be hosting the code.
|
28 |
+
* **Hugging Face Hub**: The platform in which the demo will be hosted using [Spaces](http://hf.co/spaces/launch). Spaces is a platform through which you can freely share ML demos using Streamlit, Gradio or even static sites (HTML & JavaScript if you're into that stuff).
|
29 |
+
|
30 |
+
**This is cool! Will I get subscriptions, likes, RSS, comments, ...**
|
31 |
+
|
32 |
+
No 😢 this is not a fully-fledged blog platform. It's just a cool proof of concept that can be interesting for having interactive articles.
|
33 |
+
|
34 |
+
**Sure sure...but how does it work?**
|
35 |
+
|
36 |
+
So you will have a Streamlit-based application in which you'll have your articles. The code will be in GitHub, and through GitHub Action workflows, the blog will be automatically sync'ed to a Hugging Face Space. All the way automated!
|
37 |
+
|
38 |
+
**Sounds fun, let's do it!**
|
39 |
+
|
40 |
+
Cool! 🔥 So Nate has built a [nice template](https://github.com/nateraw/host-a-blog-on-huggingface-spaces) we can already use out of the box. Isn't that cool? Let's begin by clicking that **Fork** button in GitHub. Let's quickly explore what we have here
|
41 |
+
|
42 |
+
- **.github/workflows/**: There is a GitHub Actions workflow that will automatically sync to the Hugging Face Hub each time you push into the repo.
|
43 |
+
- **images/**: Well...it contains images.
|
44 |
+
* **posts/**: You can write your articles here directly with Markdown!.
|
45 |
+
* **app.py**: This is the main application file that has the structure of the blog.
|
46 |
+
* **packages.txt** and **requirements.txt** allow you to specify any dependencies you'll want to have installed in the blog. If you want to show some cool visualization using library X, you can add X here!
|
47 |
+
|
48 |
+
**Can we get this started?**
|
49 |
+
|
50 |
+
""")
|
51 |
+
|
52 |
+
col1, col2 = st.columns(2)
|
53 |
+
|
54 |
+
with col1:
|
55 |
+
st.markdown("""
|
56 |
+
Yes, let's do it.
|
57 |
+
|
58 |
+
First, create a [new Space](https://huggingface.co/new-space) at Hugging Face. You will need to specify the Streamlit SDK. Since it's still being written, you can make it private so others don't see it. The Space can have any name you want.
|
59 |
+
|
60 |
+
The second step is to create a [write token](https://huggingface.co/settings/token). This will allow GitHub to push whenever there are changes to the Space.
|
61 |
+
|
62 |
+
Make sure to copy the token and...
|
63 |
+
|
64 |
+
**I won't expose my token! They will hack me! 🚨🚨🚨**
|
65 |
+
|
66 |
+
No worries, we'll be adding a **secret** in GitHub, which allows to add environment variables that can be accessed but not viewed by anyone. You can go to your **GitHub repo**, go to Settings -> SECRETS, and click ** New secret**. The name can be `HF_TOKEN` and the value is the one you got from the Hub.
|
67 |
+
|
68 |
+
🦙
|
69 |
+
""")
|
70 |
+
|
71 |
+
with col2:
|
72 |
+
st.image("https://github.com/osanseviero/hf-tips-and-tricks/raw/main/assets/1_streamlit_space.png", width=300)
|
73 |
+
st.image("https://github.com/osanseviero/hf-tips-and-tricks/raw/main/assets/1_token.png", width=300)
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
st.markdown("""
|
78 |
+
**Ok this is actually not that hard**
|
79 |
+
|
80 |
+
I know!
|
81 |
+
|
82 |
+
Now, if you go to your GitHub repo, to **workflows/sync-to-hub**, you'll see the last line makes a reference to the original Space repository and your token variable. Let's switch the path to your own Space.
|
83 |
+
|
84 |
+
So I changed
|
85 |
+
|
86 |
+
```
|
87 |
+
run: git push https://nateraw:[email protected]/spaces/nateraw/host-a-blog-on-huggingface-spaces main --force
|
88 |
+
```
|
89 |
+
|
90 |
+
to
|
91 |
+
|
92 |
+
```
|
93 |
+
run: git push https://osanseviero:[email protected]/spaces/osanseviero/tips-and-tricks main --force
|
94 |
+
```
|
95 |
+
|
96 |
+
As you can see, I never exposed my token!
|
97 |
+
|
98 |
+
**Cool**
|
99 |
+
|
100 |
+
What is even cooler is that now each time you do any change in the GitHub repository, it will be automatically deployed in HF Spaces and re-deployed!
|
101 |
+
|
102 |
+
**What's next?**
|
103 |
+
|
104 |
+
Well, you just finished the setup! There are a couple of places where you will want to change stuff and then write your first article. Once you're ready, you should make your Spaces repo public, share it in social media and get likes from the community!
|
105 |
+
|
106 |
+
**Isn't this just the same as having my content in GitHub Pages?**
|
107 |
+
|
108 |
+
The cool thing of doing the blog post with Streamlit is that your blog posts can be interactive.
|
109 |
+
|
110 |
+
**I don't get it**
|
111 |
+
|
112 |
+
Check this example to interact with a protein visualization! This is directly in the blog article and leverages [great work](https://towardsdatascience.com/molecular-visualization-in-streamlit-using-rdkit-and-py3dmol-part-2-657d28152753) done by the open source community.
|
113 |
+
""")
|
114 |
+
|
115 |
+
prot_str='1A2C,1BML,1D5M,1D5X,1D5Z,1D6E,1DEE,1E9F,1FC2,1FCC,1G4U,1GZS,1HE1,1HEZ,1HQR,1HXY,1IBX,1JBU,1JWM,1JWS'
|
116 |
+
prot_list=prot_str.split(',')
|
117 |
+
bcolor = st.color_picker('Pick A Color', '#6D73A6')
|
118 |
+
protein=st.selectbox('select protein',prot_list)
|
119 |
+
xyzview = py3Dmol.view(query='pdb:'+protein)
|
120 |
+
xyzview.setStyle({"stick":{'color':'spectrum'}})
|
121 |
+
xyzview.setBackgroundColor(bcolor)
|
122 |
+
showmol(xyzview, height = 500,width=800)
|
123 |
+
|
124 |
+
st.markdown("""
|
125 |
+
**🤯 cool**
|
126 |
+
|
127 |
+
Yes! Now imagine all the cool, ML interactive blogs you could have. You could nicely mix ML demos with great explanations in a very interactive way. Next time you release a model, you could embed it directly in the announcement article and readers would be able to try it out directly in their browsers!
|
128 |
+
|
129 |
+
I hope this was useful! Until the next time!
|
130 |
+
|
131 |
+
**A Hacker Llama 🦙**
|
132 |
+
|
133 |
+
[osanseviero](https://twitter.com/osanseviero)
|
134 |
+
""")
|
posts/2_private_models.py
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import streamlit.components.v1 as components
|
3 |
+
|
4 |
+
title = "T&T2 - Craft demos of private models"
|
5 |
+
description = "Build public, shareable models of private models."
|
6 |
+
date = "2022-01-27"
|
7 |
+
thumbnail = "assets/2_thumbnail.png"
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
def run_article():
|
12 |
+
st.markdown("""
|
13 |
+
# 🤗 Tips & Tricks Edition 2
|
14 |
+
# Using private models in your public ML demos
|
15 |
+
|
16 |
+
Welcome to a new post of 🤗 Tips and Tricks! Each post can be read in <5 minutes and shares features you might not know about that will allow you
|
17 |
+
to leverage the Hub platform to its full extent.
|
18 |
+
|
19 |
+
In today's post, you'll learn how you can create public demos of your private models. This can be useful if you're not ready to share the model
|
20 |
+
or are worried of ethical concerns, but would still like to share the work with the community to try it out.
|
21 |
+
|
22 |
+
**Is this expensive?**
|
23 |
+
|
24 |
+
It will cost...nothing! You can host private models on Hugging Face right now in a couple of clicks! Note: This works not just for transformers,
|
25 |
+
but for any ML library!
|
26 |
+
|
27 |
+
**Which is the model?**
|
28 |
+
|
29 |
+
The super secret model we won't want to share publicly but still showcase is a super powerful Scikit-learn model for...wine quality classification!
|
30 |
+
For the purposes of this demo, assume there exists a private model repository with `id=osanseviero/wine-quality`.
|
31 |
+
""")
|
32 |
+
|
33 |
+
col1, col2 = st.columns(2)
|
34 |
+
|
35 |
+
with col1:
|
36 |
+
st.markdown("""
|
37 |
+
**🍷Cheers. And what is the demo?**
|
38 |
+
|
39 |
+
Let's build it right now! You first need to create a [new Space](https://huggingface.co/new-space). I like to use the Gradio SDK, but you are
|
40 |
+
also encouraged to try Streamlit and static Spaces.
|
41 |
+
|
42 |
+
The second step is to create a [read token](https://huggingface.co/settings/token). A read token allows reading repositories, which is useful when
|
43 |
+
you don't need to modify them. This token will allow the Space to access the model from the private model repository.
|
44 |
+
|
45 |
+
The third step is to create a secret in the Space, which you can do in the settings tab.
|
46 |
+
|
47 |
+
**What's a secret?**
|
48 |
+
|
49 |
+
If you hardcode your token, other people will be able to access your repository, which is what you're trying to avoid. Remember that the Space is
|
50 |
+
public so the code of the Space is also public! By using secrets + tokens, you are having a way in which the Space can read a private model repo
|
51 |
+
without exposing the raw model nor the token. Secrets can be very useful as well if you are making calls to APIs and don't want to expose it.
|
52 |
+
|
53 |
+
So you can add a token, with any name you want, and paste the value you should have coppied from your settings.
|
54 |
+
""")
|
55 |
+
|
56 |
+
with col2:
|
57 |
+
st.image("https://github.com/osanseviero/hf-tips-and-tricks/raw/main/assets/2_gradio_space.png", width=300)
|
58 |
+
st.image("https://github.com/osanseviero/hf-tips-and-tricks/raw/main/assets/2_token.png", width=300)
|
59 |
+
st.image("https://github.com/osanseviero/hf-tips-and-tricks/raw/main/assets/2_secret.png", width=300)
|
60 |
+
|
61 |
+
|
62 |
+
st.markdown("""
|
63 |
+
**🤯 That's neat! What happens next?**
|
64 |
+
|
65 |
+
The secret is made available available to the gradio Space as a. environment variable. Let's write the code for the Gradio demo.
|
66 |
+
|
67 |
+
The first step is adding the `requirements.txt` files with used dependencies.
|
68 |
+
|
69 |
+
```
|
70 |
+
scikit-learn
|
71 |
+
joblib
|
72 |
+
```
|
73 |
+
|
74 |
+
As always in Spaces, you create a file called `app.py`. Let's go through each section of the file
|
75 |
+
|
76 |
+
1. Imports...nothing special
|
77 |
+
|
78 |
+
```python
|
79 |
+
import joblib
|
80 |
+
import os
|
81 |
+
|
82 |
+
import gradio as gr
|
83 |
+
|
84 |
+
from huggingface_hub import hf_hub_download
|
85 |
+
```
|
86 |
+
|
87 |
+
2. Downloading model from private repo
|
88 |
+
|
89 |
+
You can use `hf_hub_download` from the `huggingface_hub` library to download (and cache) a file from a model repository. Using the
|
90 |
+
`use_auth_token` param, you can access the secret `TOKEN`, which has the read token you created before. I want to download the file
|
91 |
+
`sklearn_model.joblib`, which is how `sklearn` encourages to save the models.
|
92 |
+
|
93 |
+
|
94 |
+
```python
|
95 |
+
file_path = hf_hub_download("osanseviero/wine-quality", "sklearn_model.joblib",
|
96 |
+
use_auth_token=os.environ['TOKEN'])
|
97 |
+
```
|
98 |
+
|
99 |
+
3. Loading model
|
100 |
+
|
101 |
+
The path right now points to the cached local joblib model. You can easily load it now:
|
102 |
+
|
103 |
+
```python
|
104 |
+
model = joblib.load(file_path)
|
105 |
+
```
|
106 |
+
|
107 |
+
4. Inference function
|
108 |
+
|
109 |
+
One of the most important concepts in Gradio is the inference function. The inference function receives an input and has an output. It can
|
110 |
+
receive multiple types of inputs (images, videos, audios, text, etc) and multiple outputs. This is a simple sklearn inference
|
111 |
+
|
112 |
+
```python
|
113 |
+
def predict(data):
|
114 |
+
return model.predict(data.to_numpy())
|
115 |
+
```
|
116 |
+
|
117 |
+
5. Build and launch the interface
|
118 |
+
|
119 |
+
Building Gradio interfaces is very simple. You need to specify the prediction function, the type of input and output. You can add more things such
|
120 |
+
as the title and descriptions. In this case, the input is a dataframe since that's the kind of data managed by this model.
|
121 |
+
|
122 |
+
```
|
123 |
+
iface = gr.Interface(
|
124 |
+
predict,
|
125 |
+
title="Wine Quality predictor with SKLearn",
|
126 |
+
inputs=gr.inputs.Dataframe(
|
127 |
+
headers=headers,
|
128 |
+
default=default,
|
129 |
+
),
|
130 |
+
outputs="numpy",
|
131 |
+
)
|
132 |
+
iface.launch()
|
133 |
+
```
|
134 |
+
|
135 |
+
We're done!!!!
|
136 |
+
|
137 |
+
You can find the Space at [https://huggingface.co/spaces/osanseviero/wine_quality](https://huggingface.co/spaces/osanseviero/wine_quality)
|
138 |
+
and try it yourself! It's not great, but the main idea of the article was to showcase a workflow of public demo with private model. This can also
|
139 |
+
work for datasets! With Gradio, you can create datasets with flagged content from users!
|
140 |
+
|
141 |
+
**Wait wait wait! I don't want to click more links!**
|
142 |
+
|
143 |
+
Ahm...ok. The link above is cool because you can share it with anyone, but you can also show Spaces-hosted Gradio demos with a couple of
|
144 |
+
HTML lines in your own website. Here you can see the Gradio Space.
|
145 |
+
""")
|
146 |
+
|
147 |
+
embed_gradio = components.html(
|
148 |
+
"""
|
149 |
+
<head>
|
150 |
+
<link rel="stylesheet" href="https://gradio.s3-us-west-2.amazonaws.com/2.6.2/static/bundle.css">
|
151 |
+
</head>
|
152 |
+
<body>
|
153 |
+
<div id="target"></div>
|
154 |
+
<script src="https://gradio.s3-us-west-2.amazonaws.com/2.6.2/static/bundle.js"></script>
|
155 |
+
<script>
|
156 |
+
launchGradioFromSpaces("osanseviero/wine_quality", "#target")
|
157 |
+
</script>
|
158 |
+
</body>
|
159 |
+
""",
|
160 |
+
height=600,
|
161 |
+
)
|
162 |
+
|
163 |
+
st.markdown("""
|
164 |
+
**🤯 Is that...a Gradio Space embedded within a Streamlit Space about creating Spaces?**
|
165 |
+
|
166 |
+
Yes, that's right! I hope this was useful! Until the next time!
|
167 |
+
|
168 |
+
**A Hacker Llama 🦙**
|
169 |
+
|
170 |
+
[osanseviero](https://twitter.com/osanseviero)
|
171 |
+
""")
|
172 |
+
|
173 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
pyyaml
|
3 |
+
py3Dmol
|
4 |
+
stmol==0.0.7
|