Skip to content

Commit d344306

Browse files
authored
Merge pull request #51 from rstudio/api-change
2 parents 2e70cd2 + 7202b22 commit d344306

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1017
-915
lines changed

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
"editor.formatOnSave": true,
99
"editor.tabSize": 4,
1010
},
11+
"python.analysis.diagnosticSeverityOverrides": {
12+
"reportImportCycles": "none",
13+
"reportUnusedFunction": "none",
14+
"reportPrivateUsage": "none",
15+
"reportUnnecessaryIsInstance": "none"
16+
},
1117
"editor.rulers": [
1218
88
1319
],

HISTORY.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ History
55
0.0.0.9000 (2021-08-10)
66
------------------
77

8-
* First release on PyPI.
8+
* Initial version

examples/bind_event/app.py

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import asyncio
2+
import shiny.ui_toolkit as st
13
from shiny import *
4+
from htmltools import tags
25

3-
ui = page_fluid(
6+
ui = st.page_fluid(
47
tags.p(
58
"""
69
The first time you click the button, you should see a 1 appear below the button,
@@ -9,68 +12,72 @@
912
print the number of clicks in the console twice.
1013
"""
1114
),
12-
navs_tab_card(
13-
nav(
15+
st.navs_tab_card(
16+
st.nav(
1417
"Sync",
15-
input_action_button("btn", "Click me"),
16-
output_ui("foo"),
18+
st.input_action_button("btn", "Click me"),
19+
st.output_ui("btn_value"),
1720
),
18-
nav(
21+
st.nav(
1922
"Async",
20-
input_action_button("btn_async", "Click me"),
21-
output_ui("foo_async"),
23+
st.input_action_button("btn_async", "Click me"),
24+
st.output_ui("btn_async_value"),
2225
),
2326
),
2427
)
2528

2629

27-
def server(session: ShinySession):
30+
def server(input: Inputs, output: Outputs, session: Session):
2831

2932
# i.e., observeEvent(once=False)
30-
@observe()
31-
@event(lambda: session.input["btn"])
33+
@reactive.effect()
34+
@event(input.btn)
3235
def _():
33-
print("@observe() event: ", str(session.input["btn"]))
36+
print("@effect() event: ", str(input.btn()))
3437

3538
# i.e., eventReactive()
36-
@reactive()
37-
@event(lambda: session.input["btn"])
39+
@reactive.calc()
40+
@event(input.btn)
3841
def btn() -> int:
39-
return session.input["btn"]
42+
return input.btn()
4043

41-
@observe()
44+
@reactive.effect()
4245
def _():
43-
print("@reactive() event: ", str(btn()))
46+
print("@calc() event: ", str(btn()))
4447

45-
@session.output("foo")
48+
@output()
4649
@render_ui()
47-
@event(lambda: session.input["btn"])
48-
def _():
49-
return session.input["btn"]
50+
@event(input.btn)
51+
def btn_value():
52+
return str(input.btn())
5053

5154
# -----------------------------------------------------------------------------
5255
# Async
5356
# -----------------------------------------------------------------------------
54-
@observe_async()
55-
@event(lambda: session.input["btn_async"])
57+
@reactive.effect_async()
58+
@event(input.btn_async)
5659
async def _():
57-
print("@observe_async() event: ", str(session.input["btn_async"]))
60+
await asyncio.sleep(0)
61+
print("@effect_async() event: ", str(input.btn_async()))
5862

59-
@reactive_async()
60-
@event(lambda: session.input["btn_async"])
61-
async def btn_async() -> int:
62-
return session.input["btn_async"]
63+
@reactive.calc_async()
64+
@event(input.btn_async)
65+
async def btn_async_r() -> int:
66+
await asyncio.sleep(0)
67+
return input.btn_async()
6368

64-
@observe_async()
69+
@reactive.effect_async()
6570
async def _():
66-
val = await btn_async()
67-
print("@reactive_async() event: ", str(val))
71+
val = await btn_async_r()
72+
print("@calc_async() event: ", str(val))
6873

69-
@session.output("foo_async")
74+
@output()
7075
@render_ui()
71-
@event(lambda: session.input["btn_async"])
72-
async def _():
73-
return session.input["btn_async"]
76+
@event(btn_async_r)
77+
async def btn_async_value():
78+
val = await btn_async_r()
79+
print("== " + str(val))
80+
return str(val)
7481

7582

76-
ShinyApp(ui, server).run()
83+
app = App(ui, server, debug=True)

examples/download/app.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,74 +4,77 @@
44
# Then point web browser to:
55
# http://localhost:8000/
66
import asyncio
7-
from datetime import date
87
import os
98
import io
10-
import matplotlib.pyplot as plt
11-
import numpy as np
9+
from datetime import date
10+
from typing import Any
1211

12+
import shiny.ui_toolkit as st
1313
from shiny import *
14+
from htmltools import *
15+
16+
import matplotlib.pyplot as plt
17+
import numpy as np
1418

1519

1620
def make_example(id: str, label: str, title: str, desc: str, extra: Any = None):
17-
return column(
18-
3,
19-
tags.div(
21+
return st.column(
22+
4,
23+
div(
2024
class_="card mb-4",
2125
children=[
22-
tags.div(title, class_="card-header"),
23-
tags.div(
26+
div(title, class_="card-header"),
27+
div(
2428
class_="card-body",
2529
children=[
26-
tags.p(desc, class_="card-text text-muted"),
30+
p(desc, class_="card-text text-muted"),
2731
extra,
28-
download_button(id, label, class_="btn-primary"),
32+
st.download_button(id, label, class_="btn-primary"),
2933
],
3034
),
3135
],
3236
),
3337
)
3438

3539

36-
ui = page_fluid(
37-
tags.h1("Download examples"),
38-
row(
40+
ui = st.page_fluid(
41+
st.row(
3942
make_example(
4043
"download1",
4144
label="Download CSV",
4245
title="Simple case",
4346
desc="Downloads a pre-existing file, using its existing name on disk.",
4447
),
4548
),
46-
row(
49+
st.row(
4750
make_example(
4851
"download2",
4952
label="Download plot",
5053
title="Dynamic data generation",
5154
desc="Downloads a PNG that's generated on the fly.",
5255
extra=[
53-
input_text("title", "Plot title", "Random scatter plot"),
54-
input_slider("num_points", "Number of data points", 1, 100, 50),
56+
st.input_text("title", "Plot title", "Random scatter plot"),
57+
st.input_slider("num_points", "Number of data points", 1, 100, 50),
5558
],
5659
),
5760
),
58-
row(
61+
st.row(
5962
make_example(
6063
"download3",
6164
"Download",
6265
"Dynamic filename",
6366
"Demonstrates that filenames can be generated on the fly (and use Unicode characters!).",
6467
),
6568
),
66-
row(
69+
st.row(
6770
make_example(
6871
"download4",
6972
"Download",
7073
"Failed downloads",
7174
"Throws an error in the download handler, download should not succeed.",
7275
),
7376
),
74-
row(
77+
st.row(
7578
make_example(
7679
"download5",
7780
"Download",
@@ -82,7 +85,7 @@ def make_example(id: str, label: str, title: str, desc: str, extra: Any = None):
8285
)
8386

8487

85-
def server(session: ShinySession):
88+
def server(input: Inputs, output: Outputs, session: Session):
8689
@session.download()
8790
def download1():
8891
"""
@@ -107,7 +110,7 @@ def download2():
107110
y = np.random.uniform(size=session.input["num_points"])
108111
plt.figure()
109112
plt.scatter(x, y)
110-
plt.title(session.input["title"])
113+
plt.title(input.title())
111114
with io.BytesIO() as buf:
112115
plt.savefig(buf, format="png")
113116
yield buf.getvalue()
@@ -127,9 +130,4 @@ async def _():
127130
raise Exception("This error was caused intentionally")
128131

129132

130-
app = ShinyApp(ui, server)
131-
132-
if __name__ == "__main__":
133-
app.run()
134-
# Alternately, to listen on a TCP port:
135-
# app.run(conn_type = "tcp")
133+
app = App(ui, server)

examples/dynamic_ui/app.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,66 @@
44
# Then point web browser to:
55
# http://localhost:8000/
66

7+
import shiny.ui_toolkit as st
78
from shiny import *
9+
from htmltools import *
810

911
# For plot rendering
1012
import numpy as np
1113
import matplotlib.pyplot as plt
1214

13-
ui = page_fluid(
14-
layout_sidebar(
15-
panel_sidebar(
16-
h2("Dynamic UI"),
17-
output_ui("ui"),
18-
input_action_button("btn", "Trigger insert/remove ui"),
15+
ui = st.page_fluid(
16+
st.layout_sidebar(
17+
st.panel_sidebar(
18+
st.h2("Dynamic UI"),
19+
st.output_ui("ui"),
20+
st.input_action_button("btn", "Trigger insert/remove ui"),
1921
),
20-
panel_main(
21-
output_text_verbatim("txt"),
22-
output_plot("plot"),
22+
st.panel_main(
23+
st.output_text_verbatim("txt"),
24+
st.output_plot("plot"),
2325
),
2426
),
2527
)
2628

2729

28-
def server(session: ShinySession):
29-
@reactive()
30+
def server(input: Inputs, output: Outputs, session: Session):
31+
@reactive.calc()
3032
def r():
31-
if session.input["n"] is None:
33+
if input.n() is None:
3234
return
33-
return session.input["n"] * 2
35+
return input.n() * 2
3436

35-
@session.output("txt")
36-
async def _():
37+
@output()
38+
@render_text()
39+
async def txt():
3740
val = r()
38-
return f"n*2 is {val}, session id is {get_current_session().id}"
41+
return f"n*2 is {val}, session id is {session.id}"
3942

40-
@session.output("plot")
43+
@output()
4144
@render_plot(alt="A histogram")
42-
def _():
45+
def plot():
4346
np.random.seed(19680801)
4447
x = 100 + 15 * np.random.randn(437)
4548

4649
fig, ax = plt.subplots()
47-
ax.hist(x, session.input["n"], density=True)
50+
ax.hist(x, input.n(), density=True)
4851
return fig
4952

50-
@session.output("ui")
53+
@output()
5154
@render_ui()
52-
def _():
53-
return input_slider("This slider is rendered via @render_ui()", "N", 0, 100, 20)
55+
def ui():
56+
return st.input_slider(
57+
"This slider is rendered via @render_ui()", "N", 0, 100, 20
58+
)
5459

55-
@observe()
60+
@reactive.effect()
5661
def _():
57-
btn = session.input["btn"]
62+
btn = input.btn()
5863
if btn % 2 == 1:
5964
ui_insert(tags.p("Thanks for clicking!", id="thanks"), "body")
6065
elif btn > 0:
6166
ui_remove("#thanks")
6267

6368

64-
app = ShinyApp(ui, server)
65-
66-
if __name__ == "__main__":
67-
app.run()
68-
# Alternately, to listen on a TCP port:
69-
# app.run(conn_type = "tcp")
69+
app = App(ui, server)

0 commit comments

Comments
 (0)