github-actions[bot] commited on
Commit
a9c5ec3
·
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 +478 -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:[email protected]/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,478 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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="Custom AI Jira Agent",
61
+ description="Mesop with Django, LangChain Agents, CO-STAR & CoT prompting combined with the Jira API to better automate Jira.",
62
+ img_url="https://github.com/user-attachments/assets/20ab297d-a4d0-4825-b5e6-3e79dc205405",
63
+ github_url="https://github.com/lewisExternal/Custom-AI-Jira-Agent",
64
+ github_username="lewisExternal",
65
+ ),
66
+ Resource(
67
+ title="Multimodal Embeddings Retail Search",
68
+ description="Using multimodal embeddings to search retail product images and titles.",
69
+ img_url="https://github.com/user-attachments/assets/ece910c7-5c2c-4d27-ab6a-0febc7affb12",
70
+ github_url="https://github.com/mandieq/retail_embeddings",
71
+ github_username="mandieq",
72
+ ),
73
+ Resource(
74
+ title="Mesop Jeopardy Live",
75
+ description="Jeopardy using Gemini Multimodal Live API (audio/text).",
76
+ app_url="https://huggingface.co/spaces/richard-to/mesop-jeopardy-live",
77
+ img_url="https://github.com/user-attachments/assets/97d704e1-6df6-4a05-8a77-8e91363295fa",
78
+ github_url="https://github.com/richard-to/mesop-jeopardy-live",
79
+ github_username="richard-to",
80
+ ),
81
+ Resource(
82
+ title="Mesop App Maker",
83
+ description="Generate apps with Mesop using LLMs.",
84
+ app_url="https://huggingface.co/spaces/richard-to/mesop-app-maker",
85
+ img_url="https://github.com/user-attachments/assets/1a826d44-c87b-4c79-aeaf-29bc8da3b1c0",
86
+ github_url="https://github.com/richard-to/mesop-app-maker",
87
+ github_username="richard-to",
88
+ ),
89
+ Resource(
90
+ title="Mesop Jeopardy",
91
+ description="Jeopardy using Mesop + Gemini 1.5 (text only)",
92
+ app_url="https://huggingface.co/spaces/richard-to/mesop-jeopardy",
93
+ img_url="https://github.com/richard-to/mesop-jeopardy/assets/539889/bc27447d-129f-47ae-b0b1-8f5c546762ed",
94
+ github_url="https://github.com/richard-to/mesop-jeopardy",
95
+ github_username="richard-to",
96
+ ),
97
+ ],
98
+ ),
99
+ Section(
100
+ name="Web components",
101
+ icon="code_blocks",
102
+ resources=[
103
+ Resource(
104
+ title="Mesop Markmap",
105
+ description="Mesop web component for the Markmap library.",
106
+ img_url="https://github.com/user-attachments/assets/6aa40ca3-d98a-42b2-adea-3f49b134445d",
107
+ github_url="https://github.com/lianggecm/mesop_markmap",
108
+ app_url="https://colab.research.google.com/drive/17gXlsXPDeo6hcFl1oOyrZ58FTozviN45?usp=sharing",
109
+ github_username="lianggecm",
110
+ ),
111
+ ],
112
+ ),
113
+ Section(
114
+ name="Notebooks",
115
+ icon="description",
116
+ resources=[
117
+ Resource(
118
+ title="Mesop Getting Started Colab",
119
+ description="Get started with Mesop in Colab.",
120
+ img_url="https://github.com/user-attachments/assets/37efbe69-ac97-4d26-8fda-d1b7b2b4976a",
121
+ github_url="https://github.com/mesop-dev/mesop/blob/main/notebooks/mesop_colab_getting_started.ipynb",
122
+ app_url="https://colab.research.google.com/github/mesop-dev/mesop/blob/main/notebooks/mesop_colab_getting_started.ipynb",
123
+ github_username="google",
124
+ ),
125
+ Resource(
126
+ title="Gemma with Mesop Notebook",
127
+ description="Use Gemma with Mesop in Colab.",
128
+ img_url="https://github.com/user-attachments/assets/a52ebf01-7f24-469b-9ad9-b271fdb19e37",
129
+ github_url="https://github.com/google-gemini/gemma-cookbook/blob/main/Gemma/%5BGemma_2%5DUsing_with_Mesop.ipynb",
130
+ app_url="https://colab.research.google.com/github/google-gemini/gemma-cookbook/blob/main/Gemma/%5BGemma_2%5DUsing_with_Mesop.ipynb",
131
+ github_username="google-gemini",
132
+ ),
133
+ Resource(
134
+ title="PaliGemma with Mesop Notebook",
135
+ description="Use PaliGemma with Mesop in Colab.",
136
+ img_url="https://github.com/user-attachments/assets/8cb456a1-f7be-4187-9a3f-f6b48bde73e9",
137
+ github_url="https://github.com/google-gemini/gemma-cookbook/blob/main/PaliGemma/%5BPaliGemma_1%5DUsing_with_Mesop.ipynb",
138
+ app_url="https://colab.research.google.com/github/google-gemini/gemma-cookbook/blob/main/PaliGemma/%5BPaliGemma_1%5DUsing_with_Mesop.ipynb",
139
+ github_username="google-gemini",
140
+ ),
141
+ ],
142
+ ),
143
+ ]
144
+
145
+
146
+ def scroll_to_section(e: me.ClickEvent):
147
+ me.scroll_into_view(key="section-" + e.key)
148
+ me.state(State).sidenav_menu_open = False
149
+
150
+
151
+ def toggle_theme(e: me.ClickEvent):
152
+ if me.theme_brightness() == "light":
153
+ me.set_theme_mode("dark")
154
+ else:
155
+ me.set_theme_mode("light")
156
+
157
+
158
+ def on_load(e: me.LoadEvent):
159
+ me.set_theme_mode("system")
160
+
161
+
162
+ @me.stateclass
163
+ class State:
164
+ sidenav_menu_open: bool
165
+
166
+
167
+ def toggle_menu_button(e: me.ClickEvent):
168
+ s = me.state(State)
169
+ s.sidenav_menu_open = not s.sidenav_menu_open
170
+
171
+
172
+ def is_mobile():
173
+ return me.viewport_size().width < 640
174
+
175
+
176
+ @me.page(
177
+ title="Mesop Showcase",
178
+ on_load=on_load,
179
+ security_policy=me.SecurityPolicy(
180
+ allowed_iframe_parents=["https://huggingface.co"],
181
+ ),
182
+ )
183
+ def page():
184
+ with me.box(style=me.Style(display="flex", height="100%")):
185
+ if is_mobile():
186
+ with me.content_button(
187
+ type="icon",
188
+ style=me.Style(top=6, left=8, position="absolute", z_index=9),
189
+ on_click=toggle_menu_button,
190
+ ):
191
+ me.icon("menu")
192
+ with me.sidenav(
193
+ opened=me.state(State).sidenav_menu_open,
194
+ style=me.Style(
195
+ background=me.theme_var("surface-container-low"),
196
+ ),
197
+ ):
198
+ sidenav()
199
+ else:
200
+ sidenav()
201
+ with me.box(
202
+ style=me.Style(
203
+ background=me.theme_var("surface-container-low"),
204
+ display="flex",
205
+ flex_direction="column",
206
+ flex_grow=1,
207
+ )
208
+ ):
209
+ with me.box(
210
+ style=me.Style(
211
+ height=240,
212
+ width="100%",
213
+ padding=me.Padding.all(16),
214
+ display="flex",
215
+ align_items="center",
216
+ ),
217
+ ):
218
+ me.text(
219
+ "Mesop Showcase",
220
+ style=me.Style(
221
+ color=me.theme_var("on-background"),
222
+ font_size=22,
223
+ font_weight=500,
224
+ letter_spacing="0.8px",
225
+ padding=me.Padding(left=36) if is_mobile() else None,
226
+ ),
227
+ )
228
+
229
+ with me.content_button(
230
+ type="icon",
231
+ style=me.Style(position="absolute", right=4, top=8),
232
+ on_click=toggle_theme,
233
+ ):
234
+ me.icon(
235
+ "light_mode" if me.theme_brightness() == "dark" else "dark_mode"
236
+ )
237
+ with me.box(
238
+ style=me.Style(
239
+ background=me.theme_var("background"),
240
+ flex_grow=1,
241
+ padding=me.Padding(
242
+ left=32,
243
+ right=32,
244
+ bottom=64,
245
+ ),
246
+ border_radius=16,
247
+ overflow_y="auto",
248
+ )
249
+ ):
250
+ for section in SECTIONS:
251
+ me.text(
252
+ section.name,
253
+ style=me.Style(
254
+ font_size=18,
255
+ font_weight=500,
256
+ padding=me.Padding(top=32, bottom=16),
257
+ ),
258
+ key="section-" + section.name,
259
+ )
260
+ with me.box(
261
+ style=me.Style(
262
+ display="grid",
263
+ grid_template_columns=f"repeat(auto-fit, minmax({CARD_WIDTH}, 1fr))",
264
+ gap=24,
265
+ margin=me.Margin(
266
+ bottom=24,
267
+ ),
268
+ )
269
+ ):
270
+ for resource in section.resources:
271
+ card(resource)
272
+ with me.box(
273
+ on_click=lambda e: me.navigate(
274
+ "https://github.com/mesop-dev/mesop/issues/new/choose"
275
+ ),
276
+ style=me.Style(
277
+ cursor="pointer",
278
+ max_width=300,
279
+ background=me.theme_var("surface-container-lowest"),
280
+ box_shadow="0 2px 4px rgba(0, 0, 0, 0.1)",
281
+ # margin=me.Margin.symmetric(horizontal="auto"),
282
+ display="flex",
283
+ justify_content="center",
284
+ align_items="center",
285
+ border_radius=16,
286
+ height=120,
287
+ ),
288
+ ):
289
+ me.icon(
290
+ "add_circle",
291
+ style=me.Style(
292
+ color=me.theme_var("primary"),
293
+ font_size=24,
294
+ margin=me.Margin(right=4, top=2),
295
+ ),
296
+ )
297
+ me.link(
298
+ text="Submit your showcase",
299
+ url="https://github.com/mesop-dev/mesop/issues/new/choose",
300
+ style=me.Style(
301
+ font_size=24,
302
+ color=me.theme_var("on-background"),
303
+ text_decoration="none",
304
+ ),
305
+ )
306
+
307
+
308
+ def sidenav():
309
+ with me.box(
310
+ style=me.Style(
311
+ width=216,
312
+ height="100%",
313
+ background=me.theme_var("surface-container-low"),
314
+ padding=me.Padding.all(16),
315
+ )
316
+ ):
317
+ with me.box(
318
+ style=me.Style(
319
+ display="flex", flex_direction="column", margin=me.Margin(top=48)
320
+ )
321
+ ):
322
+ with me.content_button(
323
+ type="icon",
324
+ on_click=lambda e: me.navigate("https://mesop-dev.github.io/mesop/"),
325
+ ):
326
+ with me.box(
327
+ style=me.Style(display="flex", align_items="center", gap=12)
328
+ ):
329
+ me.icon("home")
330
+ me.text(
331
+ "Home",
332
+ style=me.Style(
333
+ font_size=16,
334
+ margin=me.Margin(bottom=4),
335
+ ),
336
+ )
337
+ with me.content_button(
338
+ type="icon",
339
+ on_click=lambda e: me.navigate(
340
+ "https://mesop-dev.github.io/mesop/demo/"
341
+ ),
342
+ ):
343
+ with me.box(
344
+ style=me.Style(
345
+ display="flex",
346
+ align_items="center",
347
+ gap=8,
348
+ )
349
+ ):
350
+ me.icon("gallery_thumbnail")
351
+ me.text(
352
+ "Demos",
353
+ style=me.Style(
354
+ font_size=16,
355
+ margin=me.Margin(bottom=6, left=4),
356
+ ),
357
+ )
358
+ with me.box(
359
+ style=me.Style(
360
+ padding=me.Padding(top=24),
361
+ display="flex",
362
+ flex_direction="column",
363
+ gap=8,
364
+ ),
365
+ ):
366
+ me.text(
367
+ "Categories",
368
+ style=me.Style(
369
+ font_weight=500,
370
+ letter_spacing="0.4px",
371
+ padding=me.Padding(left=12),
372
+ ),
373
+ )
374
+ for section in SECTIONS:
375
+ with me.box(
376
+ style=me.Style(
377
+ display="flex",
378
+ align_items="center",
379
+ cursor="pointer",
380
+ ),
381
+ on_click=scroll_to_section,
382
+ key=section.name,
383
+ ):
384
+ with me.content_button(type="icon"):
385
+ me.icon(section.icon)
386
+ me.text(section.name)
387
+ with me.box(
388
+ style=me.Style(
389
+ display="flex",
390
+ align_items="center",
391
+ cursor="pointer",
392
+ padding=me.Padding(top=16),
393
+ ),
394
+ on_click=lambda e: me.navigate(
395
+ "https://github.com/mesop-dev/mesop/issues/new/choose"
396
+ ),
397
+ ):
398
+ with me.content_button(type="icon"):
399
+ me.icon("add_circle")
400
+ me.text("Submit your showcase")
401
+
402
+
403
+ def card(resource: Resource):
404
+ with me.box(
405
+ style=me.Style(
406
+ display="flex",
407
+ flex_direction="column",
408
+ gap=12,
409
+ box_shadow="0 2px 4px rgba(0, 0, 0, 0.1)",
410
+ border_radius=16,
411
+ min_width=CARD_WIDTH,
412
+ max_width=480,
413
+ background=me.theme_var("surface-container-lowest"),
414
+ )
415
+ ):
416
+ me.box(
417
+ style=me.Style(
418
+ background=f"url('{resource.img_url}') center/cover no-repeat",
419
+ cursor="pointer",
420
+ height=200,
421
+ width="100%",
422
+ border_radius=16,
423
+ margin=me.Margin(bottom=8),
424
+ ),
425
+ key=resource.app_url or resource.github_url,
426
+ on_click=lambda e: me.navigate(e.key),
427
+ )
428
+ with me.box(
429
+ style=me.Style(
430
+ padding=me.Padding(left=16),
431
+ display="flex",
432
+ flex_direction="column",
433
+ gap=8,
434
+ )
435
+ ):
436
+ me.text(resource.title, style=me.Style(font_weight="bold"))
437
+ with me.box(
438
+ style=me.Style(
439
+ display="flex",
440
+ flex_direction="row",
441
+ align_items="center",
442
+ gap=8,
443
+ cursor="pointer",
444
+ ),
445
+ key="https://github.com/" + resource.github_username,
446
+ on_click=lambda e: me.navigate(e.key),
447
+ ):
448
+ me.image(
449
+ src="https://avatars.githubusercontent.com/"
450
+ + resource.github_username,
451
+ style=me.Style(height=32, width=32, border_radius=16),
452
+ )
453
+ me.text(
454
+ resource.github_username,
455
+ style=me.Style(
456
+ letter_spacing="0.2px",
457
+ ),
458
+ )
459
+ me.text(resource.description, style=me.Style(height=50))
460
+ with me.box(
461
+ style=me.Style(
462
+ display="flex",
463
+ justify_content="space-between",
464
+ padding=me.Padding(left=8, right=8, bottom=8),
465
+ )
466
+ ):
467
+ if resource.github_url:
468
+ me.button(
469
+ "Open repo",
470
+ on_click=lambda e: me.navigate(e.key),
471
+ key=resource.github_url,
472
+ )
473
+ if resource.app_url:
474
+ me.button(
475
+ "Open app",
476
+ on_click=lambda e: me.navigate(e.key),
477
+ key=resource.app_url,
478
+ )
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