solara-ui 1.39.0__py2.py3-none-any.whl → 1.41.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/__main__.py +23 -10
- solara/components/__init__.py +1 -0
- solara/components/component_vue.py +3 -2
- 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 +4 -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/qt.py +113 -0
- solara/server/server.py +6 -1
- solara/server/settings.py +1 -0
- solara/server/starlette.py +18 -6
- solara/server/static/highlight-dark.css +1 -1
- solara/server/static/main-vuetify.js +11 -1
- solara/server/static/solara_bootstrap.py +1 -1
- solara/server/templates/loader-solara.html +1 -1
- solara/server/templates/solara.html.j2 +36 -7
- 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 +9 -1
- solara/website/pages/__init__.py +93 -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/40-routing.md +17 -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 +14 -22
- solara/website/pages/documentation/examples/ai/chatbot.py +1 -1
- solara/website/pages/documentation/examples/general/vue_component.py +1 -1
- solara/website/pages/documentation/examples/libraries/altair.py +1 -0
- solara/website/pages/documentation/examples/libraries/bqplot.py +1 -1
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +1 -1
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +1 -1
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +18 -20
- solara/website/pages/documentation/examples/visualization/annotator.py +1 -3
- solara/website/pages/documentation/examples/visualization/linked_views.py +4 -4
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +18 -0
- 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/widgets/vue/navigator.vue +46 -16
- solara/widgets/vue/vegalite.vue +18 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/METADATA +2 -2
- {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/RECORD +83 -66
- solara/website/components/hero.py +0 -15
- solara/website/pages/contact/contact.md +0 -17
- {solara_ui-1.39.0.data → solara_ui-1.41.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
- {solara_ui-1.39.0.data → solara_ui-1.41.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/WHEEL +0 -0
- {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import solara
|
|
2
|
-
from
|
|
2
|
+
from .markdown import MarkdownWithMetadata
|
|
3
|
+
from .breadcrumbs import BreadCrumbs
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
@solara.component
|
|
@@ -66,18 +67,19 @@ def NoPage():
|
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
@solara.component
|
|
69
|
-
def WithCode(
|
|
70
|
-
component = getattr(module, "Page", None)
|
|
71
|
-
with
|
|
70
|
+
def WithCode(route_current):
|
|
71
|
+
component = getattr(route_current.module, "Page", None)
|
|
72
|
+
with solara.Column(style={"flex-grow": 1, "padding-top": "56px"}) as main:
|
|
73
|
+
BreadCrumbs()
|
|
72
74
|
# It renders code better
|
|
73
|
-
|
|
74
|
-
module.__doc__ or "# no docs yet",
|
|
75
|
+
MarkdownWithMetadata(
|
|
76
|
+
route_current.module.__doc__ or "# no docs yet",
|
|
75
77
|
unsafe_solara_execute=True,
|
|
76
78
|
)
|
|
77
79
|
if component and component != NoPage:
|
|
78
80
|
with solara.Card("Example", margin=0, classes=["mt-8"]):
|
|
79
81
|
component()
|
|
80
|
-
github_url = solara.util.github_url(module.__file__)
|
|
82
|
+
github_url = solara.util.github_url(route_current.module.__file__)
|
|
81
83
|
solara.Button(
|
|
82
84
|
label="View source",
|
|
83
85
|
icon_name="mdi-github-circle",
|
|
@@ -97,7 +99,7 @@ def SubCategoryLayout(children=[]):
|
|
|
97
99
|
elif route_current.path == "/":
|
|
98
100
|
return solara.Error("Not supposed to be rendered")
|
|
99
101
|
elif route_current.module:
|
|
100
|
-
WithCode(route_current
|
|
102
|
+
WithCode(route_current)
|
|
101
103
|
else:
|
|
102
104
|
with solara.Column(align="center", children=children, style={"flex-grow": 1, "padding": "0"}) as main:
|
|
103
105
|
pass
|
|
@@ -113,6 +115,6 @@ def CategoryLayout(children=[]):
|
|
|
113
115
|
if route_current.path == "/":
|
|
114
116
|
return Gallery()
|
|
115
117
|
else:
|
|
116
|
-
with solara.Column(align="stretch", style={"width": "
|
|
118
|
+
with solara.Column(align="stretch", children=children, style={"max-width": "100%"}) as main:
|
|
117
119
|
pass
|
|
118
120
|
return main
|
|
@@ -20,34 +20,44 @@ def Header(
|
|
|
20
20
|
|
|
21
21
|
# set states for menu
|
|
22
22
|
with solara.Column(gap="0px"):
|
|
23
|
-
with solara.Div(classes=["news"]):
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
with solara.v.AppBar(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
# with solara.Div(classes=["news"]):
|
|
24
|
+
# solara.HTML(
|
|
25
|
+
# "div",
|
|
26
|
+
# unsafe_innerHTML="<a href='https://github.com/widgetti/solara' target='_blank' >Star us on github 🤩</a>",
|
|
27
|
+
# )
|
|
28
|
+
with solara.v.AppBar(
|
|
29
|
+
tag="header", flat=True, clipped_left=True, style_="background-color: transparent; border-bottom: 1px solid var(--color-border-appbar);"
|
|
30
|
+
):
|
|
31
|
+
if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
|
|
32
|
+
with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_left_menu and on_toggle_left_menu()):
|
|
33
|
+
rv.Icon(children=["mdi-menu"])
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
display = " d-none d-sm-flex" if route_current is not None and route_current.path not in ["about", "pricing", "careers"] else " d-flex"
|
|
36
|
+
with solara.v.Html(
|
|
37
|
+
tag="div",
|
|
38
|
+
class_="header-logo-container" + display,
|
|
39
|
+
style_="""
|
|
40
|
+
background-color: transparent;
|
|
41
|
+
flex-grow: 1;
|
|
42
|
+
align-items: stretch;
|
|
43
|
+
max-height: 65%;
|
|
44
|
+
""",
|
|
36
45
|
):
|
|
37
|
-
with solara.Link(path_or_route="/"):
|
|
46
|
+
with solara.Link(path_or_route="/", style={"display": "flex", "align-items": "center", "flex-direction": "row", "gap": "10px"}):
|
|
38
47
|
solara.Image(router.root_path + f"/static/assets/images/logo{'_white' if dark_effective else ''}.svg", classes=["header-logo"])
|
|
48
|
+
solara.Text("API", style={"font-size": "20px", "font-weight": "600"})
|
|
39
49
|
|
|
40
|
-
|
|
50
|
+
if route_current is not None and route_current.path not in ["about", "pricing", "careers"]:
|
|
41
51
|
if settings.search.enabled:
|
|
42
52
|
from solara_enterprise.search.search import Search
|
|
43
53
|
|
|
44
54
|
Search()
|
|
45
55
|
else:
|
|
46
|
-
|
|
47
|
-
Algolia()
|
|
56
|
+
Algolia()
|
|
48
57
|
|
|
58
|
+
with rv.Html(tag="ul", class_="main-menu menu d-none d-md-flex", style_="justify-content: flex-end;"):
|
|
49
59
|
for route in all_routes:
|
|
50
|
-
if route.path in ["apps", "contact", "changelog"]:
|
|
60
|
+
if route.path in ["apps", "contact", "changelog", "our_team", "about", "pricing", "roadmap", "careers"]:
|
|
51
61
|
continue
|
|
52
62
|
current = route_current == route
|
|
53
63
|
with rv.Html(tag="li", class_="active" if current else None):
|
|
@@ -58,7 +68,8 @@ def Header(
|
|
|
58
68
|
with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": "https://discord.solara.dev", "target": "_blank"}):
|
|
59
69
|
rv.Icon(children=["mdi-discord"])
|
|
60
70
|
|
|
61
|
-
solara.
|
|
71
|
+
with solara.v.Html(tag="div", class_="d-none d-md-flex"):
|
|
72
|
+
solara.lab.ThemeToggle()
|
|
62
73
|
|
|
63
|
-
with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_right_menu and on_toggle_right_menu()):
|
|
64
|
-
|
|
74
|
+
# with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_right_menu and on_toggle_right_menu()):
|
|
75
|
+
# rv.Icon(children=["mdi-menu"])
|
|
@@ -27,4 +27,15 @@ def MarkdownWithMetadata(content: str, unsafe_solara_execute=True):
|
|
|
27
27
|
solara.Meta(property=key, content=value)
|
|
28
28
|
else:
|
|
29
29
|
solara.Meta(name=key, content=value)
|
|
30
|
-
solara.
|
|
30
|
+
with solara.v.Html(
|
|
31
|
+
tag="div",
|
|
32
|
+
style_="display: flex; flex-direction: row; justify-content: center; gap: 15px; max-width: 90%; margin: 0 auto;",
|
|
33
|
+
attributes={"id": "markdown-to-navigate"},
|
|
34
|
+
):
|
|
35
|
+
solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute, style="flex-grow: 1; max-width: min(100%, 1024px);")
|
|
36
|
+
MarkdownNavigation(id="markdown-to-navigate").key("markdown-nav" + str(hash(content)))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@solara.component_vue("markdown_nav.vue")
|
|
40
|
+
def MarkdownNavigation(id: str):
|
|
41
|
+
pass
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-list dense :style="`margin: 40px 24px 0 24px; position: sticky; top: 88px; align-self: flex-start;`" class="d-none d-lg-inline-block">
|
|
3
|
+
<v-list-item
|
|
4
|
+
v-for="(element, index) in this.sections"
|
|
5
|
+
:key="index"
|
|
6
|
+
:href="'#' + element.id"
|
|
7
|
+
:style="'padding-left: ' + (16 + (element.nodeName[1] - 1) * 20) + 'px;'"
|
|
8
|
+
>
|
|
9
|
+
<v-list-item-content>
|
|
10
|
+
<v-list-item-title>
|
|
11
|
+
{{ element.innerText }}
|
|
12
|
+
</v-list-item-title>
|
|
13
|
+
</v-list-item-content>
|
|
14
|
+
</v-list-item>
|
|
15
|
+
</v-list>
|
|
16
|
+
</template>
|
|
17
|
+
<script>
|
|
18
|
+
module.exports = {
|
|
19
|
+
mounted() {
|
|
20
|
+
this.getSections();
|
|
21
|
+
},
|
|
22
|
+
methods: {
|
|
23
|
+
getSections() {
|
|
24
|
+
const parentToSearch = document.getElementById(this.id);
|
|
25
|
+
this.sections = parentToSearch.querySelectorAll('h1, h2, h3, h4');
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
data() {
|
|
29
|
+
return {
|
|
30
|
+
sections: []
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
@@ -14,7 +14,11 @@ def Sidebar():
|
|
|
14
14
|
all_routes = route.children
|
|
15
15
|
break
|
|
16
16
|
|
|
17
|
-
with solara.v.List(
|
|
17
|
+
with solara.v.List(
|
|
18
|
+
expand=True,
|
|
19
|
+
nav=True,
|
|
20
|
+
style_="height: 100%; max-height: 100vh; display: flex; flex-direction: column; background-color: var(--color-material-background); overflow-y: auto;",
|
|
21
|
+
) as main:
|
|
18
22
|
with solara.v.ListItemGroup(v_model=router.path):
|
|
19
23
|
# e.g. getting_started, examples, components, api, advanced, faq
|
|
20
24
|
for route in all_routes:
|
|
@@ -93,5 +97,9 @@ def Sidebar():
|
|
|
93
97
|
with solara.v.ListItem(value="/changelog"):
|
|
94
98
|
solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-history"])])
|
|
95
99
|
solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Changelog"])
|
|
100
|
+
with solara.Link("/roadmap"):
|
|
101
|
+
with solara.v.ListItem(value="/roadmap"):
|
|
102
|
+
solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-road"])])
|
|
103
|
+
solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Roadmap"])
|
|
96
104
|
|
|
97
105
|
return main
|
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,100 @@ 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.Sheet(
|
|
284
|
+
style_="""
|
|
285
|
+
height: 100vh;
|
|
286
|
+
width: 20rem;
|
|
287
|
+
overflow: auto;
|
|
288
|
+
border-right: 1px solid var(--color-border-appbar);
|
|
289
|
+
position: sticky;
|
|
290
|
+
top: 0;
|
|
291
|
+
flex-direction: column;
|
|
292
|
+
gap: 0;
|
|
293
|
+
""",
|
|
294
|
+
class_="d-md-flex d-none",
|
|
295
|
+
elevation=0,
|
|
296
|
+
):
|
|
297
|
+
route_current.module.Sidebar()
|
|
298
|
+
with rv.Col(
|
|
299
|
+
tag="main",
|
|
300
|
+
md=True,
|
|
301
|
+
class_="pa-0",
|
|
302
|
+
style_="max-width: 1024px" if route_current.path == "showcase" else "",
|
|
470
303
|
):
|
|
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)
|
|
304
|
+
with solara.Row(
|
|
305
|
+
children=children,
|
|
306
|
+
justify="center",
|
|
307
|
+
classes=["solara-page-content-search"],
|
|
308
|
+
style="height: unset",
|
|
309
|
+
):
|
|
310
|
+
pass
|
|
494
311
|
|
|
495
|
-
|
|
496
|
-
|
|
312
|
+
# absolute = True prevents the drawer from being below the overlay it generates
|
|
313
|
+
# Drawer navigation for top menu
|
|
314
|
+
with rv.NavigationDrawer(
|
|
315
|
+
v_model=show_right_menu,
|
|
316
|
+
on_v_model=set_show_right_menu,
|
|
317
|
+
fixed=True,
|
|
497
318
|
absolute=True,
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
on_v_model=set_show_left_menu,
|
|
504
|
-
width="20rem",
|
|
319
|
+
right=True,
|
|
320
|
+
hide_overlay=False,
|
|
321
|
+
overlay_color="#000000",
|
|
322
|
+
overlay_opacity=0.5,
|
|
323
|
+
style_="height: 100vh",
|
|
505
324
|
):
|
|
506
|
-
|
|
325
|
+
Algolia()
|
|
326
|
+
with rv.List(nav=True):
|
|
327
|
+
with rv.ListItemGroup(active_class="text--primary"):
|
|
328
|
+
for route in all_routes:
|
|
329
|
+
if route.path == "apps":
|
|
330
|
+
continue
|
|
331
|
+
with solara.Link(route):
|
|
332
|
+
solara.ListItem(route.label)
|
|
333
|
+
|
|
334
|
+
if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
|
|
335
|
+
with solara.v.NavigationDrawer(
|
|
336
|
+
absolute=True,
|
|
337
|
+
clipped=True,
|
|
338
|
+
class_="d-md-none d-block",
|
|
339
|
+
height="unset",
|
|
340
|
+
style_="min-height: 100vh;",
|
|
341
|
+
v_model=show_left_menu,
|
|
342
|
+
on_v_model=set_show_left_menu,
|
|
343
|
+
width="20rem",
|
|
344
|
+
):
|
|
345
|
+
route_current.module.Sidebar()
|
|
507
346
|
|
|
508
|
-
|
|
347
|
+
return main
|
|
509
348
|
|
|
510
349
|
|
|
511
350
|
@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
|