solara-ui 1.39.0__py2.py3-none-any.whl → 1.40.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- solara/__init__.py +1 -1
- solara/components/__init__.py +1 -0
- solara/components/input_text_area.py +86 -0
- solara/components/markdown.py +1 -1
- solara/hooks/use_thread.py +4 -4
- solara/lab/components/chat.py +8 -2
- solara/server/assets/style.css +2 -1
- solara/server/flask.py +1 -1
- solara/server/jupyter/server_extension.py +11 -1
- solara/server/jupyter/solara.py +91 -0
- solara/server/patch.py +1 -0
- solara/server/pyinstaller/__init__.py +9 -0
- solara/server/pyinstaller/hook-ipyreact.py +5 -0
- solara/server/pyinstaller/hook-ipyvuetify.py +5 -0
- solara/server/pyinstaller/hook-solara.py +9 -0
- solara/server/server.py +6 -1
- solara/server/starlette.py +18 -6
- solara/server/static/highlight-dark.css +1 -1
- solara/server/static/main-vuetify.js +1 -1
- solara/server/static/solara_bootstrap.py +1 -1
- solara/server/templates/solara.html.j2 +30 -6
- solara/website/assets/custom.css +20 -57
- solara/website/components/__init__.py +2 -2
- solara/website/components/algolia_api.vue +23 -6
- solara/website/components/breadcrumbs.py +28 -0
- solara/website/components/contact.py +144 -0
- solara/website/components/docs.py +11 -9
- solara/website/components/header.py +31 -20
- solara/website/components/markdown.py +12 -1
- solara/website/components/markdown_nav.vue +34 -0
- solara/website/components/sidebar.py +7 -1
- solara/website/pages/__init__.py +87 -254
- solara/website/pages/about/__init__.py +9 -0
- solara/website/pages/about/about.md +3 -0
- solara/website/pages/careers/__init__.py +27 -0
- solara/website/pages/changelog/__init__.py +2 -2
- solara/website/pages/changelog/changelog.md +12 -0
- solara/website/pages/contact/__init__.py +30 -6
- solara/website/pages/documentation/__init__.py +25 -33
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +2 -1
- solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +1 -1
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +2 -1
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -1
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +5 -2
- solara/website/pages/documentation/api/hooks/use_thread.md +6 -0
- solara/website/pages/documentation/components/data/pivot_table.py +2 -2
- solara/website/pages/documentation/components/input/input.py +2 -0
- solara/website/pages/documentation/components/output/sql_code.py +3 -3
- solara/website/pages/documentation/examples/__init__.py +2 -2
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +2 -2
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +19 -14
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +205 -15
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +3 -1
- solara/website/pages/home.vue +1199 -0
- solara/website/pages/our_team/__init__.py +83 -0
- solara/website/pages/pricing/__init__.py +31 -0
- solara/website/pages/roadmap/__init__.py +11 -0
- solara/website/pages/roadmap/roadmap.md +41 -0
- solara/website/pages/scale_ipywidgets.py +45 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.40.0.dist-info}/METADATA +2 -2
- {solara_ui-1.39.0.dist-info → solara_ui-1.40.0.dist-info}/RECORD +65 -49
- solara/website/components/hero.py +0 -15
- solara/website/pages/contact/contact.md +0 -17
- {solara_ui-1.39.0.data → solara_ui-1.40.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
- {solara_ui-1.39.0.data → solara_ui-1.40.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.40.0.dist-info}/WHEEL +0 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.40.0.dist-info}/licenses/LICENSE +0 -0
solara/website/pages/__init__.py
CHANGED
|
@@ -5,12 +5,11 @@ from solara.components.title import Title
|
|
|
5
5
|
from solara.server import server
|
|
6
6
|
from solara.website.components.algolia import Algolia
|
|
7
7
|
|
|
8
|
-
from ..components import Header
|
|
9
|
-
from ..components.mailchimp import MailChimp
|
|
8
|
+
from ..components import Header
|
|
10
9
|
|
|
11
10
|
title = "Home"
|
|
12
11
|
|
|
13
|
-
route_order = ["/", "showcase", "documentation", "apps", "contact", "changelog"]
|
|
12
|
+
route_order = ["/", "showcase", "documentation", "apps", "contact", "changelog", "roadmap", "pricing", "our_team", "careers", "about", "scale_ipywidgets"]
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
_redirects = {
|
|
@@ -236,6 +235,11 @@ def List(children=[], class_: str = None):
|
|
|
236
235
|
return rv.Html(tag="ul", children=children, attributes={"class": class_})
|
|
237
236
|
|
|
238
237
|
|
|
238
|
+
@solara.component_vue("home.vue")
|
|
239
|
+
def Home(children=[]):
|
|
240
|
+
pass
|
|
241
|
+
|
|
242
|
+
|
|
239
243
|
@solara.component
|
|
240
244
|
def Layout(children=[]):
|
|
241
245
|
router = solara.use_router()
|
|
@@ -247,265 +251,94 @@ def Layout(children=[]):
|
|
|
247
251
|
|
|
248
252
|
target, set_target = solara.use_state(0)
|
|
249
253
|
|
|
250
|
-
if route_current
|
|
254
|
+
if route_current is not None:
|
|
255
|
+
with solara.Div(style={"display": "none"}):
|
|
256
|
+
solara.Meta(name="twitter:card", content="summary_large_image")
|
|
257
|
+
solara.Meta(name="twitter:site", content="@solara_dev")
|
|
258
|
+
solara.Meta(name="twitter:image", content="https://solara.dev/static/assets/images/logo-small.png")
|
|
259
|
+
solara.Meta(property="og:url", content="https://solara.dev" + router.path)
|
|
260
|
+
solara.Meta(property="og:image", content="https://solara.dev/static/assets/images/logo-small.png")
|
|
261
|
+
solara.Meta(property="og:type", content="website")
|
|
262
|
+
if route_current is not None and route_current.path == "apps":
|
|
251
263
|
return children[0]
|
|
252
|
-
|
|
253
|
-
Title(title="Solara
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
solara.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
on_toggle_left_menu=lambda: set_show_left_menu(not show_left_menu),
|
|
262
|
-
on_toggle_right_menu=lambda: set_show_right_menu(not show_right_menu),
|
|
263
|
-
)
|
|
264
|
-
if route_current is not None and route_current.path == "/":
|
|
265
|
-
Hero(
|
|
266
|
-
title="A pure Python, React-style web framework",
|
|
267
|
-
sub_title="Solara helps you build powerful & scalable Jupyter and web apps <b>faster</b> and <b>easier</b>.",
|
|
268
|
-
button_text="Quickstart",
|
|
264
|
+
elif route_current is not None and route_current.path == "/":
|
|
265
|
+
Title(title="Solara: Build high-quality web applications in pure Python")
|
|
266
|
+
Home()
|
|
267
|
+
else:
|
|
268
|
+
with solara.VBox(grow=False) as main:
|
|
269
|
+
Title(title="Solara documentation")
|
|
270
|
+
Header(
|
|
271
|
+
on_toggle_left_menu=lambda: set_show_left_menu(not show_left_menu),
|
|
272
|
+
on_toggle_right_menu=lambda: set_show_right_menu(not show_right_menu),
|
|
269
273
|
)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
solara.Meta(name="description", property="og:description", content=description)
|
|
278
|
-
solara.Meta(name="twitter:description", content=description)
|
|
279
|
-
solara.Meta(property="og:title", content="Solara documentation")
|
|
280
|
-
solara.Meta(name="twitter:title", content="Solara documentation")
|
|
281
|
-
|
|
282
|
-
with rv.Row(class_="ma-2"):
|
|
283
|
-
with rv.Col(md=6, offset_md=3, sm=8, offset_sm=2):
|
|
284
|
-
solara.Markdown(
|
|
285
|
-
"""
|
|
286
|
-
# What is Solara?
|
|
287
|
-
|
|
288
|
-
Solara lets you build web apps from pure Python using ipywidgets or a React-like API on
|
|
289
|
-
top of ipywidgets.
|
|
290
|
-
These apps work both inside the Jupyter Notebook and as standalone web apps with frameworks like FastAPI.
|
|
291
|
-
|
|
292
|
-
With Solara, you benefit from a paradigm that promotes component-based code and simplifies state management,
|
|
293
|
-
making your development process more efficient and your applications more maintainable.
|
|
294
|
-
|
|
295
|
-
Solara provides you with access to the full strength of the Python ecosystem.
|
|
296
|
-
This means you can continue using your favorite libraries while expanding your web development capabilities.
|
|
297
|
-
"""
|
|
298
|
-
)
|
|
299
|
-
with solara.HBox():
|
|
300
|
-
with solara.Link("/documentation"):
|
|
301
|
-
solara.Button(label="Read more", class_="ma-1 homepage-button", href="/documentation", color="primary", dark=True)
|
|
302
|
-
with solara.Link("/documentation/getting_started"):
|
|
303
|
-
solara.Button(label="Quickstart", class_="ma-1 homepage-button", color="primary", dark=True)
|
|
304
|
-
# with rv.Col(md=4, sm=5):
|
|
305
|
-
# rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/what.webp", style_="width:900px")
|
|
306
|
-
|
|
307
|
-
with solara.Column(style={"width": "100%"}, gap="2.5em", classes=["pt-10", "mt-8"], align="center"):
|
|
308
|
-
with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
|
|
309
|
-
rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/complexity.webp", contain=True)
|
|
310
|
-
solara.Markdown(
|
|
311
|
-
"""
|
|
312
|
-
# Build **large** apps with **low** code complexity
|
|
313
|
-
|
|
314
|
-
With Solara, you can build large scale apps without hitting a complexity wall.
|
|
315
|
-
|
|
316
|
-
With other tools you may hit a dead end due to missing features or implementing features
|
|
317
|
-
adds too much complexity to your code base.
|
|
318
|
-
|
|
319
|
-
Solara offers the **flexibility** to build complex apps, but keeps the **simplicity** of a small code base.
|
|
320
|
-
"""
|
|
321
|
-
)
|
|
322
|
-
with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
|
|
323
|
-
solara.Markdown(
|
|
324
|
-
"""
|
|
325
|
-
# The trustworthiness of React
|
|
326
|
-
|
|
327
|
-
Using the same API as React, but ported to Python, Solara lets you build apps with the same
|
|
328
|
-
trustworthiness as React.
|
|
329
|
-
|
|
330
|
-
With a decade of experience, React is battle-tested and proven to be
|
|
331
|
-
a reliable and robust framework to build large scale apps.
|
|
332
|
-
"""
|
|
333
|
-
)
|
|
334
|
-
with solara.Row(justify="center", style={"width": "500px"}):
|
|
335
|
-
rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/python-love-react.webp", style_="max-width:300px", contain=True)
|
|
336
|
-
with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
|
|
337
|
-
with solara.Column():
|
|
338
|
-
if target == 0:
|
|
339
|
-
solara.Markdown("#### Running in: Jupyter notebook")
|
|
340
|
-
solara.Image(
|
|
341
|
-
"https://global.discourse-cdn.com/standard11/uploads/jupyter/original/2X/8/8bc875c0c3845ae077168575a4f8a49cf1b35bc6.gif"
|
|
342
|
-
)
|
|
343
|
-
else:
|
|
344
|
-
solara.Markdown("#### Running in: FastAPI")
|
|
345
|
-
solara.Image(
|
|
346
|
-
"https://global.discourse-cdn.com/standard11/uploads/jupyter/original/2X/9/9442fc70e2a1fcd201f4f900fa073698a1f8c937.gif"
|
|
347
|
-
)
|
|
348
|
-
import solara.website.pages.apps.scatter as scatter
|
|
349
|
-
|
|
350
|
-
github_url = solara.util.github_url(scatter.__file__)
|
|
351
|
-
solara.Button(
|
|
352
|
-
label="View source",
|
|
353
|
-
icon_name="mdi-github-circle",
|
|
354
|
-
attributes={"href": github_url, "target": "_blank"},
|
|
355
|
-
text=True,
|
|
356
|
-
outlined=False,
|
|
357
|
-
)
|
|
358
|
-
with solara.Link("/documentation/examples"):
|
|
359
|
-
with solara.Column(style="width: 100%;"):
|
|
360
|
-
solara.Button(
|
|
361
|
-
label="More examples",
|
|
362
|
-
icon_name="mdi-brain",
|
|
363
|
-
text=True,
|
|
364
|
-
outlined=False,
|
|
365
|
-
)
|
|
366
|
-
with solara.Column():
|
|
367
|
-
solara.Markdown(
|
|
368
|
-
"""
|
|
369
|
-
## Create apps
|
|
370
|
-
|
|
371
|
-
In Jupyter or standalone, and run them in production
|
|
372
|
-
using FastAPI or starlette.
|
|
373
|
-
|
|
374
|
-
Get more inspiration from our [examples](/documentation/examples).
|
|
375
|
-
"""
|
|
376
|
-
)
|
|
377
|
-
with rv.ExpansionPanels(v_model=target, on_v_model=set_target, mandatory=True, flat=True):
|
|
378
|
-
with rv.ExpansionPanel():
|
|
379
|
-
rv.ExpansionPanelHeader(children=["Jupyter notebook"])
|
|
380
|
-
with rv.ExpansionPanelContent():
|
|
381
|
-
solara.Markdown("Build on top of ipywidgets, solara components work in all Jupyter notebook environments.")
|
|
382
|
-
with rv.ExpansionPanel():
|
|
383
|
-
rv.ExpansionPanelHeader(children=["FastAPI"])
|
|
384
|
-
with rv.ExpansionPanelContent():
|
|
385
|
-
solara.Markdown(
|
|
386
|
-
"""Using [solara-server](documentation/advanced/understanding/solara-server),
|
|
387
|
-
we can run our app in production using FastAPI."""
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
with solara.Column(style={"width": "100%"}):
|
|
391
|
-
solara.v.Divider()
|
|
392
|
-
|
|
393
|
-
with solara.Column(align="center", gap="2.5em", style={"width": "100%", "padding-bottom": "50px"}):
|
|
394
|
-
solara.Markdown("# Testimonials", style="text-align:center")
|
|
395
|
-
with solara.Row(justify="center", gap="2.5em", style={"align-items": "stretch", "flex-wrap": "wrap", "row-gap": "2.5em"}):
|
|
396
|
-
Testimonial(
|
|
397
|
-
"Solara is like streamlit, but for Jupyter. I am really excited to see where this goes!",
|
|
398
|
-
"Jack Parmer",
|
|
399
|
-
"Former CEO and Co-Founder of Plotly",
|
|
400
|
-
"https://dxhl76zpt6fap.cloudfront.net/public/avatar/jack-parmer.jpg",
|
|
401
|
-
)
|
|
402
|
-
Testimonial(
|
|
403
|
-
"Solara has been transformative, allowing us to rapidly create a Jupyter app and iterate with impressive speed.",
|
|
404
|
-
"Nick Elprin",
|
|
405
|
-
"CEO and Co-Founder of Domino Data Lab",
|
|
406
|
-
"https://dxhl76zpt6fap.cloudfront.net/public/avatar/nick-elprin.jpg",
|
|
407
|
-
)
|
|
408
|
-
Testimonial(
|
|
409
|
-
"Solara allows us to go from prototype to production with the same stack.",
|
|
410
|
-
"Jonathan Chambers",
|
|
411
|
-
"Co-founder of Planeto",
|
|
412
|
-
"https://dxhl76zpt6fap.cloudfront.net/public/avatar/jonathan-chambers.jpg",
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
with solara.Column(style={"width": "100%"}):
|
|
416
|
-
solara.v.Divider()
|
|
417
|
-
|
|
418
|
-
with solara.Column(align="center", gap="2.5em", style={"width": "100%", "padding-bottom": "50px"}):
|
|
419
|
-
solara.Markdown("# Sponsors", style="text-align:center")
|
|
420
|
-
with solara.Row(justify="center", gap="2.5em", style={"align-items": "stretch"}):
|
|
421
|
-
with solara.v.Html(tag="a", attributes={"href": "https://www.dominodatalab.com/", "target": "_blank"}):
|
|
422
|
-
solara.Image("https://dxhl76zpt6fap.cloudfront.net/public/sponsors/domino.png", width="300px")
|
|
423
|
-
|
|
424
|
-
with solara.Column(style={"width": "100%"}):
|
|
425
|
-
solara.v.Divider()
|
|
426
|
-
|
|
427
|
-
with solara.Row(justify="center", gap="2.5em", classes=["footer-wrapper"]):
|
|
428
|
-
with solara.Column(align="center", style={"min-width": "300px"}):
|
|
429
|
-
solara.Markdown(
|
|
430
|
-
"""
|
|
431
|
-
#### For any consulting, training or support needs
|
|
432
|
-
[contact@solara.dev](mailto:contact@solara.dev)
|
|
433
|
-
"""
|
|
434
|
-
)
|
|
435
|
-
solara.v.Divider(vertical=True)
|
|
436
|
-
with solara.Column(align="center", style={"min-width": "300px"}):
|
|
437
|
-
solara.Markdown("#### Join our Mailing list to get the latest news")
|
|
438
|
-
with solara.Div(style={"width": "80%"}):
|
|
439
|
-
MailChimp(location=router.path)
|
|
440
|
-
else:
|
|
441
|
-
with rv.Row(
|
|
442
|
-
style_="flex-wrap: nowrap; margin: 0; min-height: calc(100vh - 215.5px);",
|
|
443
|
-
justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start",
|
|
444
|
-
):
|
|
445
|
-
if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
|
|
446
|
-
with solara.v.NavigationDrawer(
|
|
447
|
-
clipped=True,
|
|
448
|
-
class_="d-none d-md-block",
|
|
449
|
-
height="unset",
|
|
450
|
-
style_="min-height: calc(100vh - 215.5px);",
|
|
451
|
-
width="20rem",
|
|
452
|
-
v_model=True, # Forces menu to display even if it had somehow been closed
|
|
453
|
-
):
|
|
454
|
-
route_current.module.Sidebar()
|
|
455
|
-
with rv.Col(
|
|
456
|
-
tag="main",
|
|
457
|
-
md=True,
|
|
458
|
-
class_="pa-0",
|
|
459
|
-
style_=f"""max-width: {'1024px' if route_current.path not in ['documentation', 'contact', 'changelog']
|
|
460
|
-
else 'unset'}; overflow-x: hidden;""",
|
|
274
|
+
with rv.Container(tag="section", fluid=True, ma_0=True, pa_0=True, class_="fill-height solara-content-main"):
|
|
275
|
+
if route_current is None:
|
|
276
|
+
return solara.Error("Page not found")
|
|
277
|
+
else:
|
|
278
|
+
with rv.Row(
|
|
279
|
+
style_="flex-wrap: nowrap; margin: 0; min-height: calc(100vh - 64px);",
|
|
280
|
+
justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start",
|
|
461
281
|
):
|
|
462
|
-
if route_current is not None and route_current.
|
|
463
|
-
with
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
282
|
+
if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
|
|
283
|
+
with solara.v.NavigationDrawer(
|
|
284
|
+
clipped=True,
|
|
285
|
+
class_="d-none d-md-block",
|
|
286
|
+
height="unset",
|
|
287
|
+
style_="min-height: calc(100vh - 64px);",
|
|
288
|
+
width="20rem",
|
|
289
|
+
v_model=True, # Forces menu to display even if it had somehow been closed
|
|
290
|
+
):
|
|
291
|
+
route_current.module.Sidebar()
|
|
292
|
+
with rv.Col(
|
|
293
|
+
tag="main",
|
|
294
|
+
md=True,
|
|
295
|
+
class_="pa-0",
|
|
296
|
+
style_="max-width: 1024px" if route_current.path == "showcase" else "",
|
|
470
297
|
):
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
fixed=True,
|
|
479
|
-
absolute=True,
|
|
480
|
-
right=True,
|
|
481
|
-
hide_overlay=False,
|
|
482
|
-
overlay_color="#000000",
|
|
483
|
-
overlay_opacity=0.5,
|
|
484
|
-
style_="height: 100vh",
|
|
485
|
-
):
|
|
486
|
-
Algolia()
|
|
487
|
-
with rv.List(nav=True):
|
|
488
|
-
with rv.ListItemGroup(active_class="text--primary"):
|
|
489
|
-
for route in all_routes:
|
|
490
|
-
if route.path == "apps":
|
|
491
|
-
continue
|
|
492
|
-
with solara.Link(route):
|
|
493
|
-
solara.ListItem(route.label)
|
|
298
|
+
with solara.Row(
|
|
299
|
+
children=children,
|
|
300
|
+
justify="center",
|
|
301
|
+
classes=["solara-page-content-search"],
|
|
302
|
+
style="height: unset",
|
|
303
|
+
):
|
|
304
|
+
pass
|
|
494
305
|
|
|
495
|
-
|
|
496
|
-
|
|
306
|
+
# absolute = True prevents the drawer from being below the overlay it generates
|
|
307
|
+
# Drawer navigation for top menu
|
|
308
|
+
with rv.NavigationDrawer(
|
|
309
|
+
v_model=show_right_menu,
|
|
310
|
+
on_v_model=set_show_right_menu,
|
|
311
|
+
fixed=True,
|
|
497
312
|
absolute=True,
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
on_v_model=set_show_left_menu,
|
|
504
|
-
width="20rem",
|
|
313
|
+
right=True,
|
|
314
|
+
hide_overlay=False,
|
|
315
|
+
overlay_color="#000000",
|
|
316
|
+
overlay_opacity=0.5,
|
|
317
|
+
style_="height: 100vh",
|
|
505
318
|
):
|
|
506
|
-
|
|
319
|
+
Algolia()
|
|
320
|
+
with rv.List(nav=True):
|
|
321
|
+
with rv.ListItemGroup(active_class="text--primary"):
|
|
322
|
+
for route in all_routes:
|
|
323
|
+
if route.path == "apps":
|
|
324
|
+
continue
|
|
325
|
+
with solara.Link(route):
|
|
326
|
+
solara.ListItem(route.label)
|
|
327
|
+
|
|
328
|
+
if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
|
|
329
|
+
with solara.v.NavigationDrawer(
|
|
330
|
+
absolute=True,
|
|
331
|
+
clipped=True,
|
|
332
|
+
class_="d-md-none d-block",
|
|
333
|
+
height="unset",
|
|
334
|
+
style_="min-height: 100vh;",
|
|
335
|
+
v_model=show_left_menu,
|
|
336
|
+
on_v_model=set_show_left_menu,
|
|
337
|
+
width="20rem",
|
|
338
|
+
):
|
|
339
|
+
route_current.module.Sidebar()
|
|
507
340
|
|
|
508
|
-
|
|
341
|
+
return main
|
|
509
342
|
|
|
510
343
|
|
|
511
344
|
@solara.component
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# About Us
|
|
2
|
+
|
|
3
|
+
Solara is a framework created by Maarten Breddels, and developed by [Widgetti](https://widgetti.io). Widgetti is a small company based in the Netherlands, focusing on developing tools for the Jupyter ecosystem. We combine ipywidgets and python experience with expertise in front-end development to help data scientists and python app developers make the most of their time. If you could use our years of diverse industry experience, reach out [here](/contact). You can find out more about Solara [here](/documentation/getting_started/introduction), or get to know our team [here](/our_team).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import solara
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@solara.component
|
|
5
|
+
def Page():
|
|
6
|
+
with solara.Column():
|
|
7
|
+
solara.Markdown(
|
|
8
|
+
"""
|
|
9
|
+
# Careers
|
|
10
|
+
We are always looking for talented individuals to join our team. If you're still be interested after reading the rest of this page, reach out at [contact@widgetti.io](mailto:contact@widgetti.io).
|
|
11
|
+
|
|
12
|
+
## Who Are We?
|
|
13
|
+
We are a small team of developers working in the gap between Jupyter notebooks and web applications. We are passionate about making data science more accessible and app development painless.
|
|
14
|
+
We are based in Groningen, The Netherlands, but work remote first.
|
|
15
|
+
|
|
16
|
+
## What Do We Offer?
|
|
17
|
+
We offer a flexible work environment, competitive salary, and the opportunity to do meaningful, crossdisciplinary work with scientists and companies worldwide.
|
|
18
|
+
We are a small team, so you will have a lot of freedom in your work, and the chance to get your hands dirty with many projects.
|
|
19
|
+
|
|
20
|
+
### Open Source
|
|
21
|
+
We are strong believers in open source software. When working with us, you can expect the majority of the software you write to be open source, with contributions to Solara as well as other open source projects.
|
|
22
|
+
|
|
23
|
+
## Who Are We Looking For?
|
|
24
|
+
We are looking for developers, technical writers, designers, and everything in between.
|
|
25
|
+
""",
|
|
26
|
+
style={"max-width": "90%", "margin": "0 auto"},
|
|
27
|
+
)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
import solara
|
|
4
3
|
from solara.website.components.sidebar import Sidebar
|
|
4
|
+
from solara.website.components import MarkdownWithMetadata
|
|
5
5
|
|
|
6
6
|
title = "Changelog"
|
|
7
7
|
HERE = Path(__file__)
|
|
8
8
|
|
|
9
|
-
Page =
|
|
9
|
+
Page = MarkdownWithMetadata(Path(HERE.parent / "changelog.md").read_text())
|
|
10
10
|
Sidebar = Sidebar
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Solara Changelog
|
|
2
2
|
|
|
3
|
+
## Version 1.40.0
|
|
4
|
+
* Feature: In Jupyter Notebook and Lab, Solara (server) now renders the [ipypopout](https://github.com/widgetti/ipypopout) window instead of Voila [#805](render ipypopout content in jupyter notebook and lab)
|
|
5
|
+
* Feature: Support styling input field of [ChatInput component](https://solara.dev/documentation/components/lab/chat). [#800](https://github.com/widgetti/solara/pull/800).
|
|
6
|
+
* Feature: [InputTextArea component](https://solara.dev/documentation/components/input/input) for multi line text input. [#801](https://github.com/widgetti/solara/pull/801). Contributed by [Alonso Silva](https://github.com/alonsosilvaallende)
|
|
7
|
+
* Bug Fix: Markdown links triggered a JavaScript error. [#765](https://github.com/widgetti/solara/pull/765)
|
|
8
|
+
|
|
9
|
+
## Version 1.39.0
|
|
10
|
+
|
|
11
|
+
* Feature: Add option to start Solara server on a random unused port (using `--port=0`). [#762](https://github.com/widgetti/solara/pull/762)
|
|
12
|
+
* Bug Fix: Extension checking for e.g. ipyleaflet now work correctly on Amazon SageMaker Studio Lab. [#757](https://github.com/widgetti/solara/pull/757)
|
|
13
|
+
* Bug Fix: Various solara components should now work correctly in notebooks viewed on vscode, colab and voila. [#763](https://github.com/widgetti/solara/pull/763)
|
|
14
|
+
|
|
3
15
|
## Version 1.38.0
|
|
4
16
|
|
|
5
17
|
* Feature: We detect and warn when there are possible reverse proxy or uvicorn misconfigurations. [#745](https://github.com/widgetti/solara/pull/745)
|
|
@@ -1,10 +1,34 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
1
|
import solara
|
|
4
2
|
from solara.website.components.sidebar import Sidebar
|
|
3
|
+
from solara.website.components.contact import Contact
|
|
5
4
|
|
|
6
|
-
title = "Contact"
|
|
7
|
-
HERE = Path(__file__)
|
|
8
|
-
|
|
9
|
-
Page = solara.Markdown(Path(HERE.parent / "contact.md").read_text())
|
|
10
5
|
Sidebar = Sidebar
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@solara.component
|
|
9
|
+
def Page():
|
|
10
|
+
solara.Markdown("""
|
|
11
|
+
# Contact
|
|
12
|
+
|
|
13
|
+
## Business
|
|
14
|
+
|
|
15
|
+
Solara is developed mostly by Maarten Breddels and Mario Buikhuizen, Founders
|
|
16
|
+
of [Widgetti](https://widgetti.io/).
|
|
17
|
+
|
|
18
|
+
For business inquiries, please reach out using the form below, or send an email to [contact@solara.dev](mailto:contact@solara.dev) regarding Solara, or [info@widgetti.io](mailto:info@widgetti.io) regarding more general Jupyter related matters.
|
|
19
|
+
""")
|
|
20
|
+
Contact(
|
|
21
|
+
title="Contact Us", subtitle="Please fill out the form below and we will get back to you as soon as possible.", email_subject="Contact Form Submission"
|
|
22
|
+
)
|
|
23
|
+
solara.Markdown(
|
|
24
|
+
"""
|
|
25
|
+
## Community
|
|
26
|
+
|
|
27
|
+
If you want to share your thoughts, share your experiences, or just want to talk
|
|
28
|
+
to other people using and developing on Solara, consider using [GitHub discussions](https://github.com/widgetti/solara/discussions) for asynchronous discussions
|
|
29
|
+
or consider joining discord for more synchronous discussions.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
[](https://discord.gg/dm4GKNDjXN)
|
|
33
|
+
"""
|
|
34
|
+
)
|
|
@@ -17,34 +17,28 @@ def Algolia():
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@solara.component
|
|
20
|
-
def Page(
|
|
20
|
+
def Page():
|
|
21
21
|
# show a gallery of all the api pages
|
|
22
22
|
router = solara.use_router()
|
|
23
23
|
route_current = router.path_routes[-2]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
},
|
|
41
|
-
):
|
|
42
|
-
with solara.Column(style={"height": "100%", "flex-grow": "1", "background-color": "transparent"}):
|
|
43
|
-
solara.HTML(tag="h2", unsafe_innerHTML=route.label, style={"color": "white", "padding": "1.5rem"})
|
|
44
|
-
with solara.Column(style={"justify-content": "center", "height": "100%", "background-color": "transparent"}):
|
|
24
|
+
if route_current.path == "documentation":
|
|
25
|
+
with solara.Column(style={"width": "100%", "max-width": "1024px"}, gap="40px"):
|
|
26
|
+
with solara.Column(style={"width": "100%", "align-items": "center"}, gap="40px"):
|
|
27
|
+
with solara.Column(gap="20px", classes=["docs-card-container"], style={"max-width": "80%", "padding-top": "64px"}, align="stretch"):
|
|
28
|
+
for route in route_current.children:
|
|
29
|
+
if route.path in ["/", "advanced", "faq"]:
|
|
30
|
+
continue
|
|
31
|
+
with solara.Link("/documentation/" + route.path):
|
|
32
|
+
with solara.Row(
|
|
33
|
+
classes=["docs-card"],
|
|
34
|
+
style={
|
|
35
|
+
"background-color": f"var({'--docs-color-grey' if route.path != 'getting_started' else '--color-primary'})",
|
|
36
|
+
"align-items": "center",
|
|
37
|
+
},
|
|
38
|
+
):
|
|
39
|
+
solara.HTML(tag="h2", unsafe_innerHTML=route.label, style={"color": "white", "display": "block", "flex-grow": "1"})
|
|
45
40
|
solara.v.Icon(children=["mdi-arrow-right"], color="var(--color-grey-light)", x_large=True, class_="docs-card-icon")
|
|
46
|
-
|
|
47
|
-
with solara.Column(style={"padding-left": "10%"}):
|
|
41
|
+
with solara.Column(gap="10px", style={"flex-wrap": "wrap", "max-width": "80%"}):
|
|
48
42
|
solara.HTML(tag="h2", unsafe_innerHTML="How to use our documentation:", style={"padding": "1.5rem"})
|
|
49
43
|
solara.Markdown(
|
|
50
44
|
"""
|
|
@@ -58,28 +52,23 @@ def Page(children=[]):
|
|
|
58
52
|
If a component you would like to use is not available in Solara, you can use the underlying library directly.
|
|
59
53
|
"""
|
|
60
54
|
)
|
|
61
|
-
with solara.Column(style={"justify-content": "center", "height": "100%"}):
|
|
62
55
|
solara.HTML(tag="h2", unsafe_innerHTML="Also Check Out", style={"padding": "1.5rem"})
|
|
63
|
-
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}):
|
|
56
|
+
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center", "padding-left": "24px"}):
|
|
64
57
|
with solara.v.Html(tag="a", attributes={"href": "https://discord.solara.dev", "target": "_blank"}):
|
|
65
58
|
with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-discord)"}):
|
|
66
59
|
solara.v.Html(tag="img", attributes={"src": "/static/public/social/discord.svg"}, style_="height: 1.5rem; width: auto;")
|
|
67
60
|
solara.Text("We use discord to provide support and answer questions there actively.")
|
|
68
|
-
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}):
|
|
61
|
+
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center", "padding-left": "24px"}):
|
|
69
62
|
with solara.v.Html(tag="a", attributes={"href": "https://github.com/widgetti/solara", "target": "_blank"}):
|
|
70
63
|
with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-github)"}):
|
|
71
64
|
solara.v.Html(tag="img", attributes={"src": "/static/public/social/github.svg"}, style_="height: 1.5rem; width: auto;")
|
|
72
65
|
solara.Text("Search for solutions on Github issues, or report bugs.")
|
|
73
|
-
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}):
|
|
66
|
+
with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center", "padding-left": "24px"}):
|
|
74
67
|
with solara.v.Html(tag="a", attributes={"href": "https://twitter.com/solara_dev", "target": "_blank"}):
|
|
75
68
|
with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-twitter)"}):
|
|
76
69
|
solara.v.Html(tag="img", attributes={"src": "/static/public/social/twitter.svg"}, style_="height: 1.5rem; width: auto;")
|
|
77
70
|
solara.Text("Get announcements about Solara features, showcases, and events!.")
|
|
78
71
|
|
|
79
|
-
else:
|
|
80
|
-
with solara.Column(align="center", children=children, style={"padding": "0"}):
|
|
81
|
-
pass
|
|
82
|
-
|
|
83
72
|
|
|
84
73
|
@solara.component
|
|
85
74
|
def Layout(children=[]):
|
|
@@ -90,7 +79,10 @@ def Layout(children=[]):
|
|
|
90
79
|
if route_current.path == "/":
|
|
91
80
|
return Page()
|
|
92
81
|
else:
|
|
93
|
-
|
|
82
|
+
with solara.Column(
|
|
83
|
+
align="center", children=children, style={"padding": "0 0 40px 0", "max-width": "90%"}
|
|
84
|
+
): # 40px bottom margin for "runs on Solara" text
|
|
85
|
+
pass
|
|
94
86
|
|
|
95
87
|
|
|
96
88
|
@solara.component
|
|
@@ -41,7 +41,8 @@ If you do not see your app, you can open the browser developer tools in your bro
|
|
|
41
41
|
|
|
42
42
|
### Security considerations
|
|
43
43
|
|
|
44
|
-
Solara uses a cookie to implement sessions. To support cookies
|
|
44
|
+
Solara uses a cookie to implement sessions. To support setting cookies in an iframe, we set the session cookie using `Secure`, and `SameSite=Strict`. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) for more details. This means that we can only support iframes via https or localhost. Note that proxy servers can tell
|
|
45
|
+
solara-server that the connection is secure by forwarding the `X-Forwarded-Proto` header, see [our self hosted deployment documentation for more information](https://solara.dev/documentation/getting_started/deploying/self-hosted).
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
## Embed into an existing page
|
|
@@ -6,7 +6,7 @@ description: Solara looks for overrides of certain style and asset files in the
|
|
|
6
6
|
|
|
7
7
|
Asset files are special files with are loaded by Solara-server and thus have a special meaning, and come with defaults. Current supported assets files are:
|
|
8
8
|
|
|
9
|
-
* `favicon.png` - Image shown by the browser (usually in the tab).
|
|
9
|
+
* `favicon.png` and/or `favicon.svg` - Image shown by the browser (usually in the tab). If SVG is not provided, default `favicon.svg` of the solara server may override your custom favicon.png depending on the browser. Providing both PNG and SVG versions is recommended.
|
|
10
10
|
* `style.css` - Default `CSS` used by Solara.
|
|
11
11
|
* `custom.css` - Custom `CSS` you can override for your project (empty `CSS` file by default).
|
|
12
12
|
* `custom.js` - Custom Javascript you can use for your project (empty Javascript file by default).
|
|
@@ -38,7 +38,8 @@ Each virtual kernel runs in its own thread, this ensures that one particular use
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
## Handling Multiple Workers
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
In setups with multiple workers, it's possible for a page to (re)connect to a different worker than its original. This can happen after a lost network connection is restored, or when [ipypopout](https://github.com/widgetti/ipypopout) is used, since ipypopout creates a new connection, which can end up at a different worker. This can result in a loss of the virtual kernel, since it lives on the worker that was first connected to. The Solara app will then initiate a fresh start, or simply fail when ipypopout is used. To prevent this scenario, a sticky session configuration is recommended, ensuring consistent client-worker connections. A load balancer, such as [nginx](https://www.nginx.com/), can be used to achieve this. Note that using multiple workers (e.g. by using gunicorn) cannot work since a connection will be made to a different worker each time.
|
|
42
43
|
|
|
43
44
|
If you have questions about setting this up, or require assistance, please [contact us](https://solara.dev/docs/contact).
|
|
44
45
|
|