Open JoeHasell opened 1 year ago
Hey, I am actually having trouble with this as I am unable to work with multiple files within a quarto document and I have no clue whether it is even possible to make this work in that kind of setting.
For what you want, however, the nomenclature should be something akin to:
from pathlib import Path
def server(input, output, session):
@output
@render.table
def table():
infile = Path(__file__).parent / "your_file.csv"
df = pd.read_csv(infile)
return df
What I am struggling to get, however, is that file.csv
bundled in a standalone shinylive-python cell... I will open an issue for that, however.
Hey @AlFontal – thanks for your comment!
I also tried reading in the data in a python or r cell and then passing the object to the sinylive-python cell, but didn't have any luck with that either.
Glad to hear this isn't me just being dumb! Thanks again for your help.
Hey @JoeHasell, I made some advances with this issue today and came up with a horrible solution, but it works.
Hopefully, a way to bundle extra files into the shinylive/pyodide
environment using a tag or something will come up...
Basically, the way I solved it is by adapting what is described in another issue (#5) to include a requirements.txt
file, which means that you need to completely paste your csv file contents in there. For example, this standalone cell is working within quarto:
```{shinylive-python}
#| standalone: true
#| viewerHeight: 400
## file: app.py
import jinja2
from shiny import *
import pandas as pd
from pathlib import Path
app_ui = ui.page_fluid(
ui.output_table(id="table"),
)
def server(input, output, session):
@output
@render.table
def table():
infile = Path(__file__).parent / "example_table.csv"
df = pd.read_csv(infile)
return df
app = App(app_ui, server)
## file: example_table.csv
name,x,y
foo,1,1
bar,2,3
waldo,2
fred,4
plugh,5
thud,7
## file: requirements.txt
Jinja2
It's definitely an incredibly ugly solution (specially because the `csv` is way bigger for most real use-cases), but if you need a hacky-working solution, this does it...
Oh wow! Thanks for thinking outside the box. I guess for smaller datasets, it's also best to just pull it in with an HTTP request. It was because the data is pretty large that I was thinking of reading it locally (and hence is also not very compatible with the work around you are suggesting). Thanks again for you help though!
Indeed, it's just an ugly patch so far hahaha
In any case, I did try the HTTP request solution beforehand, but couldn't make it work since shinylive
runs on pyodide
under the hood, and since pyodide runs completely on the client's browser, it is very limited on the external requests it can make (and it doesn't handle sockets so far). I am way out of depth here on my very limited networking knowledge but you can read pyodide's docs on the issue.
You can't run a simple pd.read_csv(url)
since it probably uses either requests
or urllib
under the hood which are not supported... but I suspect some solution using pyodide
's API might exist.
Indeed, turns out it was way easier than that, you can do HTTP requests but using pyodide.http.open_url
, so just do:
from pyodide.http import open_url
df = pd.read_csv(open_url('url_to_your_table.csv'))
That seems to be working with no issues on my end.
I believe the Quarto team is planning on making it easier to embed multiple files in a code chunk, but I don't know the exact plans and roadmap.
Is this still an issue? Have we found a solution for this? (besides just uploading the file somewhere)
There are now a couple of ways to handle external data for a Shinylive app in Quarto. Either of the two following methods can be used:
1) Include the data as part of additional resources in your Quarto document's YAML header, then load the data from the static web server using Pyodide's open_url()
. For example, if there is the file mtcars.csv
in the directory data/
:
---
title: Shinylive in Quarto
format: html
filters:
- shinylive
resources:
- data/mtcars.csv
---
:::{.column-screen}
```{shinylive-python}
#| standalone: true
#| viewerHeight: 600
from shiny import *
from pyodide.http import open_url
import pandas as pd
app_ui = ui.page_fluid(
ui.output_table(id="table"),
)
def server(input, output, session):
@output
@render.table
def table():
df = pd.read_csv(open_url('/data/mtcars.csv'))
return df
app = App(app_ui, server)
:::
2) Or, use Garrick's `quarto-base64` extension to include the additional content directly in your Shinylive blocks, embedded as a base64 encoded binary file: [Further documentation](https://pkg.garrickadenbuie.com/quarto-base64/).
Hi there!
Thanks very much for your amazing work.
I came to shinylive because I was looking for a way to get my shiny apps onto my netlify webpage without having to host them at e.g. shinyapp.io (where I'd have to pay above a certain useage).
I'm fairly comfortable making shiny apps and with R and RMarkdown. But I'm pretty new to Python, and my technical knowledge of what's going on behind the scenes here is very limited.
My apologies for asking what seems like a very basic question. I managed to get your example up and running in a Quarto web project published to netlify, but I'm struggling to figure out how to make an app that is reading data locally. I don't really get what is going on with the file structures and how to refer to them.
For instance, what I'd like to do is something like this:
I tried various guesses at 'WHAT_GOES_HERE', and various file structures but couldn't ever find a way to read in the data.
I'd really appreciate it if you could explain, or perhaps put up an example that would help me see how to do this.
Many thanks in advance!