github-actions[bot] commited on
Commit
8bb8a04
·
0 Parent(s):
Files changed (5) hide show
  1. Dockerfile +32 -0
  2. README.md +10 -0
  3. deploy_to_hf.sh +42 -0
  4. main.py +471 -0
  5. 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