-
Notifications
You must be signed in to change notification settings - Fork 8
/
load_file.qmd
128 lines (97 loc) · 3.38 KB
/
load_file.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
---
title: Loading files in Shinylive apps in Quarto
format: html
filters:
- shinylive
resources:
- fruit_data.csv
---
The following application shows three different ways of adding files to a Shinylive app embedded in a Quarto document.
The first is a text file embedded in the code block, like this:
```{{shinylive-python}}
## file: fruit.csv
id,name,count
1,"apple",20
2,"orange",12
3,"grape",100
```
The second is a binary file embedded in the code block.
```{{shinylive-python}}
## file: fruit.pickle
## type: binary
gASVVAAAAAAAAABdlCh9lCiMAmlklEsEjARuYW1llIwEcGVhcpSMBWNvdW50lEsIdX2UKGgCSwVoA4wGYmFuYW5hlGgFSwZ1fZQoaAJLBmgDjARwbHVtlGgFSwt1ZS4=
```
The third is a text file that is deployed as part of the Quarto-generated website, and loaded via http request, by using `pyodide.http.pyfetch()`. Note that `pyodide.http.pyfetch()` will only work in Shinylive; a normal Shiny deployment will not have `pyodide` available. If you want to abstract the code so that you can use the same function in both normal Shiny and Shinylive, see the `get_url()` function in this [download demo app](https://shinylive.io/py/examples/#fetch-data-from-a-web-api).
```{shinylive-python}
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from pathlib import Path
from os.path import dirname
import pickle as pkl
from shiny import App, render, ui, Inputs, Outputs, Session
appdir = Path(__file__).parent
app_ui = ui.page_fluid(
ui.row(
ui.h4("Embedded CSV:"),
ui.output_text_verbatim("embedded_csv"),
ui.h4("Embedded pickle file:"),
ui.output_text_verbatim("embedded_pickle"),
ui.h4("Downloaded CSV:"),
ui.output_text_verbatim("download_csv"),
)
)
def server(input: Inputs, output: Outputs, session: Session):
@output
@render.text
def embedded_csv():
with open(appdir / "fruit.csv", "r") as file:
content = file.read()
return content
@output
@render.text
def embedded_pickle():
with open(appdir / "fruit.pickle", "rb") as file:
data = pkl.load(file)
return str(data)
@output
@render.text
async def download_csv():
file_url = dirname(dirname(get_current_url(input))) + "/fruit_data.csv"
resp = await fetch_url(file_url)
return str(resp)
app = App(app_ui, server)
def get_current_url(input: Inputs) -> str:
return (
input[".clientdata_url_protocol"]()
+ "//"
+ input[".clientdata_url_hostname"]()
+ ":"
+ input[".clientdata_url_port"]()
+ input[".clientdata_url_pathname"]()
)
async def fetch_url(url: str, type: str = "string"):
import pyodide.http
response = await pyodide.http.pyfetch(url)
if type == "json":
# .json() parses the response as JSON and converts to dictionary.
return await response.json()
elif type == "string":
# .string() returns the response as a string.
return await response.string()
elif type == "bytes":
# .bytes() returns the response as a byte object.
return await response.bytes()
else:
return None
## file: fruit.csv
id,name,count
1,"apple",20
2,"orange",12
3,"grape",100
## file: fruit.pickle
## type: binary
gASVVAAAAAAAAABdlCh9lCiMAmlklEsEjARuYW1llIwEcGVhcpSMBWNvdW50lEsIdX2UKGgCSwVoA4wGYmFuYW5hlGgFSwZ1fZQoaAJLBmgDjARwbHVtlGgFSwt1ZS4=
```