Spaces:
Running
Running
github-actions[bot]
commited on
Commit
·
8bb8a04
0
Parent(s):
Commit
Browse files- Dockerfile +32 -0
- README.md +10 -0
- deploy_to_hf.sh +42 -0
- main.py +471 -0
- requirements.txt +3 -0
Dockerfile
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.12.7-bullseye
|
2 |
+
|
3 |
+
RUN apt-get update && \
|
4 |
+
apt-get install -y \
|
5 |
+
# General dependencies
|
6 |
+
locales \
|
7 |
+
locales-all && \
|
8 |
+
# Clean local repository of package files since they won't be needed anymore.
|
9 |
+
# Make sure this line is called after all apt-get update/install commands have
|
10 |
+
# run.
|
11 |
+
apt-get clean && \
|
12 |
+
# Also delete the index files which we also don't need anymore.
|
13 |
+
rm -rf /var/lib/apt/lists/*
|
14 |
+
|
15 |
+
ENV LC_ALL en_US.UTF-8
|
16 |
+
ENV LANG en_US.UTF-8
|
17 |
+
ENV LANGUAGE en_US.UTF-8
|
18 |
+
|
19 |
+
# Install dependencies
|
20 |
+
COPY requirements.txt .
|
21 |
+
RUN pip install -r requirements.txt
|
22 |
+
|
23 |
+
# Create non-root user
|
24 |
+
RUN groupadd -g 900 mesop && useradd -u 900 -s /bin/bash -g mesop mesop
|
25 |
+
USER mesop
|
26 |
+
|
27 |
+
# Add app code here
|
28 |
+
COPY . /srv/mesop-app
|
29 |
+
WORKDIR /srv/mesop-app
|
30 |
+
|
31 |
+
# Run Mesop through gunicorn. Should be available at localhost:8080
|
32 |
+
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:me"]
|
README.md
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: Mesop Showcase
|
3 |
+
emoji: 👓
|
4 |
+
colorFrom: red
|
5 |
+
colorTo: yellow
|
6 |
+
sdk: docker
|
7 |
+
pinned: false
|
8 |
+
license: apache-2.0
|
9 |
+
app_port: 8080
|
10 |
+
---
|
deploy_to_hf.sh
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
set -e
|
4 |
+
|
5 |
+
error_handler() {
|
6 |
+
echo "Error: An error occurred. Exiting script."
|
7 |
+
exit 1
|
8 |
+
}
|
9 |
+
|
10 |
+
# Set up error handling
|
11 |
+
trap error_handler ERR
|
12 |
+
|
13 |
+
if [ $# -eq 0 ]; then
|
14 |
+
echo "Error: Please provide a destination path as an argument."
|
15 |
+
exit 1
|
16 |
+
fi
|
17 |
+
|
18 |
+
DEST_PATH="$1"
|
19 |
+
|
20 |
+
if [ ! -d "$DEST_PATH" ]; then
|
21 |
+
echo "Destination path does not exist. Creating it now."
|
22 |
+
mkdir -p "$DEST_PATH"
|
23 |
+
fi
|
24 |
+
|
25 |
+
# Get the path of this script which is the demo dir.
|
26 |
+
DEMO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
27 |
+
cp -R "$DEMO_DIR/" "$DEST_PATH"
|
28 |
+
echo "Demo files have been copied to $DEST_PATH"
|
29 |
+
cd "$DEST_PATH/showcase"
|
30 |
+
echo "Changed directory to $DEST_PATH"
|
31 |
+
|
32 |
+
git init
|
33 |
+
git branch -m main
|
34 |
+
git config user.name github-actions[bot]
|
35 |
+
git config user.email github-actions[bot]@users.noreply.github.com
|
36 |
+
echo "Configured git user"
|
37 |
+
git add .
|
38 |
+
git commit -m "Commit"
|
39 |
+
git remote add hf https://wwwillchen:$HF_TOKEN@huggingface.co/spaces/wwwillchen/mesop-showcase || true
|
40 |
+
git push --force --set-upstream hf main
|
41 |
+
|
42 |
+
echo "Pushed to: https://huggingface.co/spaces/wwwillchen/mesop-showcase. Check the logs to see that it's deployed correctly."
|
main.py
ADDED
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
|
3 |
+
import mesop as me
|
4 |
+
|
5 |
+
CARD_WIDTH = "320px"
|
6 |
+
|
7 |
+
|
8 |
+
@dataclass
|
9 |
+
class Resource:
|
10 |
+
title: str
|
11 |
+
description: str
|
12 |
+
github_url: str
|
13 |
+
github_username: str
|
14 |
+
img_url: str
|
15 |
+
app_url: str | None = None
|
16 |
+
|
17 |
+
|
18 |
+
@dataclass
|
19 |
+
class Section:
|
20 |
+
name: str
|
21 |
+
resources: list[Resource]
|
22 |
+
icon: str
|
23 |
+
|
24 |
+
|
25 |
+
SECTIONS = [
|
26 |
+
Section(
|
27 |
+
name="Featured",
|
28 |
+
icon="star",
|
29 |
+
resources=[
|
30 |
+
Resource(
|
31 |
+
title="Mesop Duo Chat",
|
32 |
+
description="Chat with multiple models at once.",
|
33 |
+
github_url="https://github.com/wwwillchen/mesop-duo-chat",
|
34 |
+
github_username="wwwillchen",
|
35 |
+
app_url="https://huggingface.co/spaces/wwwillchen/mesop-duo-chat",
|
36 |
+
img_url="https://github.com/user-attachments/assets/107afb9c-f08c-4f27-bd00-e122415c069e",
|
37 |
+
),
|
38 |
+
Resource(
|
39 |
+
title="Mesop Prompt Tuner",
|
40 |
+
description="Prompt tuning app heavily inspired by Anthropic Console Workbench.",
|
41 |
+
app_url="https://huggingface.co/spaces/richard-to/mesop-prompt-tuner",
|
42 |
+
img_url="https://github.com/user-attachments/assets/2ec6cbfb-c28b-4f60-98f9-34bfca1f6938",
|
43 |
+
github_url="https://github.com/richard-to/mesop-prompt-tuner",
|
44 |
+
github_username="richard-to",
|
45 |
+
),
|
46 |
+
],
|
47 |
+
),
|
48 |
+
Section(
|
49 |
+
name="Apps",
|
50 |
+
icon="computer",
|
51 |
+
resources=[
|
52 |
+
Resource(
|
53 |
+
title="Mesop Arena",
|
54 |
+
description="Rate generated images head-to-head. Includes ELO leaderboard and voting history.",
|
55 |
+
img_url="https://raw.githubusercontent.com/ghchinoy/mesop-arena/refs/heads/main/assets/arena_view.png",
|
56 |
+
github_url="https://github.com/ghchinoy/mesop-arena",
|
57 |
+
github_username="ghchinoy",
|
58 |
+
),
|
59 |
+
Resource(
|
60 |
+
title="Mesop Jeopardy Live",
|
61 |
+
description="Jeopardy using Gemini Multimodal Live API (audio/text).",
|
62 |
+
app_url="https://huggingface.co/spaces/richard-to/mesop-jeopardy-live",
|
63 |
+
img_url="https://github.com/user-attachments/assets/97d704e1-6df6-4a05-8a77-8e91363295fa",
|
64 |
+
github_url="https://github.com/richard-to/mesop-jeopardy-live",
|
65 |
+
github_username="richard-to",
|
66 |
+
),
|
67 |
+
Resource(
|
68 |
+
title="Multimodal Embeddings Retail Search",
|
69 |
+
description="Using multimodal embeddings to search retail product images and titles.",
|
70 |
+
img_url="https://github.com/user-attachments/assets/ece910c7-5c2c-4d27-ab6a-0febc7affb12",
|
71 |
+
github_url="https://github.com/mandieq/retail_embeddings",
|
72 |
+
github_username="mandieq",
|
73 |
+
),
|
74 |
+
Resource(
|
75 |
+
title="Mesop Jeopardy",
|
76 |
+
description="Jeopardy using Mesop + Gemini 1.5 (text only)",
|
77 |
+
app_url="https://huggingface.co/spaces/richard-to/mesop-jeopardy",
|
78 |
+
img_url="https://github.com/richard-to/mesop-jeopardy/assets/539889/bc27447d-129f-47ae-b0b1-8f5c546762ed",
|
79 |
+
github_url="https://github.com/richard-to/mesop-jeopardy",
|
80 |
+
github_username="richard-to",
|
81 |
+
),
|
82 |
+
Resource(
|
83 |
+
title="Mesop App Maker",
|
84 |
+
description="Generate apps with Mesop using LLMs.",
|
85 |
+
app_url="https://huggingface.co/spaces/richard-to/mesop-app-maker",
|
86 |
+
img_url="https://github.com/user-attachments/assets/1a826d44-c87b-4c79-aeaf-29bc8da3b1c0",
|
87 |
+
github_url="https://github.com/richard-to/mesop-app-maker",
|
88 |
+
github_username="richard-to",
|
89 |
+
),
|
90 |
+
],
|
91 |
+
),
|
92 |
+
Section(
|
93 |
+
name="Web components",
|
94 |
+
icon="code_blocks",
|
95 |
+
resources=[
|
96 |
+
Resource(
|
97 |
+
title="Mesop Markmap",
|
98 |
+
description="Mesop web component for the Markmap library.",
|
99 |
+
img_url="https://github.com/user-attachments/assets/6aa40ca3-d98a-42b2-adea-3f49b134445d",
|
100 |
+
github_url="https://github.com/lianggecm/mesop_markmap",
|
101 |
+
app_url="https://colab.research.google.com/drive/17gXlsXPDeo6hcFl1oOyrZ58FTozviN45?usp=sharing",
|
102 |
+
github_username="lianggecm",
|
103 |
+
),
|
104 |
+
],
|
105 |
+
),
|
106 |
+
Section(
|
107 |
+
name="Notebooks",
|
108 |
+
icon="description",
|
109 |
+
resources=[
|
110 |
+
Resource(
|
111 |
+
title="Mesop Getting Started Colab",
|
112 |
+
description="Get started with Mesop in Colab.",
|
113 |
+
img_url="https://github.com/user-attachments/assets/37efbe69-ac97-4d26-8fda-d1b7b2b4976a",
|
114 |
+
github_url="https://github.com/mesop-dev/mesop/blob/main/notebooks/mesop_colab_getting_started.ipynb",
|
115 |
+
app_url="https://colab.research.google.com/github/mesop-dev/mesop/blob/main/notebooks/mesop_colab_getting_started.ipynb",
|
116 |
+
github_username="google",
|
117 |
+
),
|
118 |
+
Resource(
|
119 |
+
title="Gemma with Mesop Notebook",
|
120 |
+
description="Use Gemma with Mesop in Colab.",
|
121 |
+
img_url="https://github.com/user-attachments/assets/a52ebf01-7f24-469b-9ad9-b271fdb19e37",
|
122 |
+
github_url="https://github.com/google-gemini/gemma-cookbook/blob/main/Gemma/%5BGemma_2%5DUsing_with_Mesop.ipynb",
|
123 |
+
app_url="https://colab.research.google.com/github/google-gemini/gemma-cookbook/blob/main/Gemma/%5BGemma_2%5DUsing_with_Mesop.ipynb",
|
124 |
+
github_username="google-gemini",
|
125 |
+
),
|
126 |
+
Resource(
|
127 |
+
title="PaliGemma with Mesop Notebook",
|
128 |
+
description="Use PaliGemma with Mesop in Colab.",
|
129 |
+
img_url="https://github.com/user-attachments/assets/8cb456a1-f7be-4187-9a3f-f6b48bde73e9",
|
130 |
+
github_url="https://github.com/google-gemini/gemma-cookbook/blob/main/PaliGemma/%5BPaliGemma_1%5DUsing_with_Mesop.ipynb",
|
131 |
+
app_url="https://colab.research.google.com/github/google-gemini/gemma-cookbook/blob/main/PaliGemma/%5BPaliGemma_1%5DUsing_with_Mesop.ipynb",
|
132 |
+
github_username="google-gemini",
|
133 |
+
),
|
134 |
+
],
|
135 |
+
),
|
136 |
+
]
|
137 |
+
|
138 |
+
|
139 |
+
def scroll_to_section(e: me.ClickEvent):
|
140 |
+
me.scroll_into_view(key="section-" + e.key)
|
141 |
+
me.state(State).sidenav_menu_open = False
|
142 |
+
|
143 |
+
|
144 |
+
def toggle_theme(e: me.ClickEvent):
|
145 |
+
if me.theme_brightness() == "light":
|
146 |
+
me.set_theme_mode("dark")
|
147 |
+
else:
|
148 |
+
me.set_theme_mode("light")
|
149 |
+
|
150 |
+
|
151 |
+
def on_load(e: me.LoadEvent):
|
152 |
+
me.set_theme_mode("system")
|
153 |
+
|
154 |
+
|
155 |
+
@me.stateclass
|
156 |
+
class State:
|
157 |
+
sidenav_menu_open: bool
|
158 |
+
|
159 |
+
|
160 |
+
def toggle_menu_button(e: me.ClickEvent):
|
161 |
+
s = me.state(State)
|
162 |
+
s.sidenav_menu_open = not s.sidenav_menu_open
|
163 |
+
|
164 |
+
|
165 |
+
def is_mobile():
|
166 |
+
return me.viewport_size().width < 640
|
167 |
+
|
168 |
+
|
169 |
+
@me.page(
|
170 |
+
title="Mesop Showcase",
|
171 |
+
on_load=on_load,
|
172 |
+
security_policy=me.SecurityPolicy(
|
173 |
+
allowed_iframe_parents=["https://huggingface.co"],
|
174 |
+
),
|
175 |
+
)
|
176 |
+
def page():
|
177 |
+
with me.box(style=me.Style(display="flex", height="100%")):
|
178 |
+
if is_mobile():
|
179 |
+
with me.content_button(
|
180 |
+
type="icon",
|
181 |
+
style=me.Style(top=6, left=8, position="absolute", z_index=9),
|
182 |
+
on_click=toggle_menu_button,
|
183 |
+
):
|
184 |
+
me.icon("menu")
|
185 |
+
with me.sidenav(
|
186 |
+
opened=me.state(State).sidenav_menu_open,
|
187 |
+
style=me.Style(
|
188 |
+
background=me.theme_var("surface-container-low"),
|
189 |
+
),
|
190 |
+
):
|
191 |
+
sidenav()
|
192 |
+
else:
|
193 |
+
sidenav()
|
194 |
+
with me.box(
|
195 |
+
style=me.Style(
|
196 |
+
background=me.theme_var("surface-container-low"),
|
197 |
+
display="flex",
|
198 |
+
flex_direction="column",
|
199 |
+
flex_grow=1,
|
200 |
+
)
|
201 |
+
):
|
202 |
+
with me.box(
|
203 |
+
style=me.Style(
|
204 |
+
height=240,
|
205 |
+
width="100%",
|
206 |
+
padding=me.Padding.all(16),
|
207 |
+
display="flex",
|
208 |
+
align_items="center",
|
209 |
+
),
|
210 |
+
):
|
211 |
+
me.text(
|
212 |
+
"Mesop Showcase",
|
213 |
+
style=me.Style(
|
214 |
+
color=me.theme_var("on-background"),
|
215 |
+
font_size=22,
|
216 |
+
font_weight=500,
|
217 |
+
letter_spacing="0.8px",
|
218 |
+
padding=me.Padding(left=36) if is_mobile() else None,
|
219 |
+
),
|
220 |
+
)
|
221 |
+
|
222 |
+
with me.content_button(
|
223 |
+
type="icon",
|
224 |
+
style=me.Style(position="absolute", right=4, top=8),
|
225 |
+
on_click=toggle_theme,
|
226 |
+
):
|
227 |
+
me.icon(
|
228 |
+
"light_mode" if me.theme_brightness() == "dark" else "dark_mode"
|
229 |
+
)
|
230 |
+
with me.box(
|
231 |
+
style=me.Style(
|
232 |
+
background=me.theme_var("background"),
|
233 |
+
flex_grow=1,
|
234 |
+
padding=me.Padding(
|
235 |
+
left=32,
|
236 |
+
right=32,
|
237 |
+
bottom=64,
|
238 |
+
),
|
239 |
+
border_radius=16,
|
240 |
+
overflow_y="auto",
|
241 |
+
)
|
242 |
+
):
|
243 |
+
for section in SECTIONS:
|
244 |
+
me.text(
|
245 |
+
section.name,
|
246 |
+
style=me.Style(
|
247 |
+
font_size=18,
|
248 |
+
font_weight=500,
|
249 |
+
padding=me.Padding(top=32, bottom=16),
|
250 |
+
),
|
251 |
+
key="section-" + section.name,
|
252 |
+
)
|
253 |
+
with me.box(
|
254 |
+
style=me.Style(
|
255 |
+
display="grid",
|
256 |
+
grid_template_columns=f"repeat(auto-fit, minmax({CARD_WIDTH}, 1fr))",
|
257 |
+
gap=24,
|
258 |
+
margin=me.Margin(
|
259 |
+
bottom=24,
|
260 |
+
),
|
261 |
+
)
|
262 |
+
):
|
263 |
+
for resource in section.resources:
|
264 |
+
card(resource)
|
265 |
+
with me.box(
|
266 |
+
on_click=lambda e: me.navigate(
|
267 |
+
"https://github.com/mesop-dev/mesop/issues/new/choose"
|
268 |
+
),
|
269 |
+
style=me.Style(
|
270 |
+
cursor="pointer",
|
271 |
+
max_width=300,
|
272 |
+
background=me.theme_var("surface-container-lowest"),
|
273 |
+
box_shadow="0 2px 4px rgba(0, 0, 0, 0.1)",
|
274 |
+
# margin=me.Margin.symmetric(horizontal="auto"),
|
275 |
+
display="flex",
|
276 |
+
justify_content="center",
|
277 |
+
align_items="center",
|
278 |
+
border_radius=16,
|
279 |
+
height=120,
|
280 |
+
),
|
281 |
+
):
|
282 |
+
me.icon(
|
283 |
+
"add_circle",
|
284 |
+
style=me.Style(
|
285 |
+
color=me.theme_var("primary"),
|
286 |
+
font_size=24,
|
287 |
+
margin=me.Margin(right=4, top=2),
|
288 |
+
),
|
289 |
+
)
|
290 |
+
me.link(
|
291 |
+
text="Submit your showcase",
|
292 |
+
url="https://github.com/mesop-dev/mesop/issues/new/choose",
|
293 |
+
style=me.Style(
|
294 |
+
font_size=24,
|
295 |
+
color=me.theme_var("on-background"),
|
296 |
+
text_decoration="none",
|
297 |
+
),
|
298 |
+
)
|
299 |
+
|
300 |
+
|
301 |
+
def sidenav():
|
302 |
+
with me.box(
|
303 |
+
style=me.Style(
|
304 |
+
width=216,
|
305 |
+
height="100%",
|
306 |
+
background=me.theme_var("surface-container-low"),
|
307 |
+
padding=me.Padding.all(16),
|
308 |
+
)
|
309 |
+
):
|
310 |
+
with me.box(
|
311 |
+
style=me.Style(
|
312 |
+
display="flex", flex_direction="column", margin=me.Margin(top=48)
|
313 |
+
)
|
314 |
+
):
|
315 |
+
with me.content_button(
|
316 |
+
type="icon",
|
317 |
+
on_click=lambda e: me.navigate("https://mesop-dev.github.io/mesop/"),
|
318 |
+
):
|
319 |
+
with me.box(
|
320 |
+
style=me.Style(display="flex", align_items="center", gap=12)
|
321 |
+
):
|
322 |
+
me.icon("home")
|
323 |
+
me.text(
|
324 |
+
"Home",
|
325 |
+
style=me.Style(
|
326 |
+
font_size=16,
|
327 |
+
margin=me.Margin(bottom=4),
|
328 |
+
),
|
329 |
+
)
|
330 |
+
with me.content_button(
|
331 |
+
type="icon",
|
332 |
+
on_click=lambda e: me.navigate(
|
333 |
+
"https://mesop-dev.github.io/mesop/demo/"
|
334 |
+
),
|
335 |
+
):
|
336 |
+
with me.box(
|
337 |
+
style=me.Style(
|
338 |
+
display="flex",
|
339 |
+
align_items="center",
|
340 |
+
gap=8,
|
341 |
+
)
|
342 |
+
):
|
343 |
+
me.icon("gallery_thumbnail")
|
344 |
+
me.text(
|
345 |
+
"Demos",
|
346 |
+
style=me.Style(
|
347 |
+
font_size=16,
|
348 |
+
margin=me.Margin(bottom=6, left=4),
|
349 |
+
),
|
350 |
+
)
|
351 |
+
with me.box(
|
352 |
+
style=me.Style(
|
353 |
+
padding=me.Padding(top=24),
|
354 |
+
display="flex",
|
355 |
+
flex_direction="column",
|
356 |
+
gap=8,
|
357 |
+
),
|
358 |
+
):
|
359 |
+
me.text(
|
360 |
+
"Categories",
|
361 |
+
style=me.Style(
|
362 |
+
font_weight=500,
|
363 |
+
letter_spacing="0.4px",
|
364 |
+
padding=me.Padding(left=12),
|
365 |
+
),
|
366 |
+
)
|
367 |
+
for section in SECTIONS:
|
368 |
+
with me.box(
|
369 |
+
style=me.Style(
|
370 |
+
display="flex",
|
371 |
+
align_items="center",
|
372 |
+
cursor="pointer",
|
373 |
+
),
|
374 |
+
on_click=scroll_to_section,
|
375 |
+
key=section.name,
|
376 |
+
):
|
377 |
+
with me.content_button(type="icon"):
|
378 |
+
me.icon(section.icon)
|
379 |
+
me.text(section.name)
|
380 |
+
with me.box(
|
381 |
+
style=me.Style(
|
382 |
+
display="flex",
|
383 |
+
align_items="center",
|
384 |
+
cursor="pointer",
|
385 |
+
padding=me.Padding(top=16),
|
386 |
+
),
|
387 |
+
on_click=lambda e: me.navigate(
|
388 |
+
"https://github.com/mesop-dev/mesop/issues/new/choose"
|
389 |
+
),
|
390 |
+
):
|
391 |
+
with me.content_button(type="icon"):
|
392 |
+
me.icon("add_circle")
|
393 |
+
me.text("Submit your showcase")
|
394 |
+
|
395 |
+
|
396 |
+
def card(resource: Resource):
|
397 |
+
with me.box(
|
398 |
+
style=me.Style(
|
399 |
+
display="flex",
|
400 |
+
flex_direction="column",
|
401 |
+
gap=12,
|
402 |
+
box_shadow="0 2px 4px rgba(0, 0, 0, 0.1)",
|
403 |
+
border_radius=16,
|
404 |
+
min_width=CARD_WIDTH,
|
405 |
+
max_width=480,
|
406 |
+
background=me.theme_var("surface-container-lowest"),
|
407 |
+
)
|
408 |
+
):
|
409 |
+
me.box(
|
410 |
+
style=me.Style(
|
411 |
+
background=f"url('{resource.img_url}') center/cover no-repeat",
|
412 |
+
cursor="pointer",
|
413 |
+
height=200,
|
414 |
+
width="100%",
|
415 |
+
border_radius=16,
|
416 |
+
margin=me.Margin(bottom=8),
|
417 |
+
),
|
418 |
+
key=resource.app_url or resource.github_url,
|
419 |
+
on_click=lambda e: me.navigate(e.key),
|
420 |
+
)
|
421 |
+
with me.box(
|
422 |
+
style=me.Style(
|
423 |
+
padding=me.Padding(left=16),
|
424 |
+
display="flex",
|
425 |
+
flex_direction="column",
|
426 |
+
gap=8,
|
427 |
+
)
|
428 |
+
):
|
429 |
+
me.text(resource.title, style=me.Style(font_weight="bold"))
|
430 |
+
with me.box(
|
431 |
+
style=me.Style(
|
432 |
+
display="flex",
|
433 |
+
flex_direction="row",
|
434 |
+
align_items="center",
|
435 |
+
gap=8,
|
436 |
+
cursor="pointer",
|
437 |
+
),
|
438 |
+
key="https://github.com/" + resource.github_username,
|
439 |
+
on_click=lambda e: me.navigate(e.key),
|
440 |
+
):
|
441 |
+
me.image(
|
442 |
+
src="https://avatars.githubusercontent.com/"
|
443 |
+
+ resource.github_username,
|
444 |
+
style=me.Style(height=32, width=32, border_radius=16),
|
445 |
+
)
|
446 |
+
me.text(
|
447 |
+
resource.github_username,
|
448 |
+
style=me.Style(
|
449 |
+
letter_spacing="0.2px",
|
450 |
+
),
|
451 |
+
)
|
452 |
+
me.text(resource.description, style=me.Style(height=50))
|
453 |
+
with me.box(
|
454 |
+
style=me.Style(
|
455 |
+
display="flex",
|
456 |
+
justify_content="space-between",
|
457 |
+
padding=me.Padding(left=8, right=8, bottom=8),
|
458 |
+
)
|
459 |
+
):
|
460 |
+
if resource.github_url:
|
461 |
+
me.button(
|
462 |
+
"Open repo",
|
463 |
+
on_click=lambda e: me.navigate(e.key),
|
464 |
+
key=resource.github_url,
|
465 |
+
)
|
466 |
+
if resource.app_url:
|
467 |
+
me.button(
|
468 |
+
"Open app",
|
469 |
+
on_click=lambda e: me.navigate(e.key),
|
470 |
+
key=resource.app_url,
|
471 |
+
)
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
mesop>=0.11.1
|
2 |
+
gunicorn>=22.0.0
|
3 |
+
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability
|