Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]: starlette request object does not have the query parameters in shinylive #1794

Open
JoseBlanca opened this issue Dec 7, 2024 · 3 comments

Comments

@JoseBlanca
Copy link

I want to access the query parameters to configure my app UI and behavior according to them.

To get the query parameters I have followed the method given in this comment.

A test App.

from shiny import App, ui, render


def app_ui(request):
    ui_elements = []
    ui_elements.append(ui.p(f"request: {request}"))

    url_query = request.url.query
    ui_elements.append(ui.p(f"url_query: {url_query}"))

    greeting = request.query_params.get("param")
    ui_elements.append(f"param: {greeting}")

    return ui.page_fixed(ui_elements)


def server(inputs, outputs, sessions):
    @render.code
    def greeting():
        return "Hi!."


app = App(app_ui, server)

While I was developing my App inside Visual Studio Code I was getting the correct result:

URL: http://localhost:32997/?param=hi
Html ouput:

request: <starlette.requests.Request object at 0x7f7d26702600>
url_query: param=hi&vscodeBrowserReqId=1733558209861
param: hi

Serving the App with uvicorn also works as expected.

Shell command:$ uv run uvicorn app:app
URL: http://127.0.0.1:8000/?param=hi
Html ouput:

request: <starlette.requests.Request object at 0x7fe7578c7770>
url_query: param=hi
param: hi

However, when I try to use shiny live, and that was my original intention, I loose the query parameters.

Shell command:$ rm -r tmp_shiny_site; uv run shinylive export src/apps/request_test_app/ tmp_shiny_site/; uv run python -m http.server --directory tmp_shiny_site --bind localhost 8008
URL: http://[::1]:8008/?param=hi
Html ouput:

request: <starlette.requests.Request object at 0x104e330>
url_query:
param: None

Best,

Jose Blanca

@JoseBlanca JoseBlanca changed the title [bug]: starlette request object does not have ther query parameters in shinylive [bug]: starlette request object does not have the query parameters in shinylive Dec 7, 2024
@gadenbuie
Copy link
Collaborator

Hi @JoseBlanca, thanks for your question. Unfortunately, query parameters in shinylive aren't as easily handled as they are for normal Shiny apps. The technical reason for this is that shinylive apps are run inside <iframe> elements and there could potentially be more than one app on a page, which makes it difficult to route query parameters from the top-level page to individual apps.

We've discussed this in posit-dev/r-shinylive#28 and have done some exploratory work in this direction in posit-dev/shinylive#79.

If you only have a single app on your page, another Shiny user has shared this JavaScript snippet that you could use to reflect the parent page hash to the Shiny app (you'd need to update it to reflect query parameters too).

$(function() {
  $(window.parent).on('hashchange', function (e) {
    $('#currentHash').val(window.parent.location.hash).change();
  });
});

@JoseBlanca
Copy link
Author

Now I get it. Thanks.

This behavior has been quite surprising to me because it worked during the development in Visual Studio Code and it failed when I tried to deploy the application. The application is supposed to changed the UI according to the url query params, but that's not working, now I understand why.

Thanks for the javascript tip, but I don't think I will be able to fix it. I don't know enough JavaScript, that's one of my motivations for using shiny and not just pyscript. Moreover, given my limited knowledge of both javascript and the shinylive internals, I don't know how reliable and stable that fix would be and I don't know if it would stable enough to use it in production.
Best,

Jose Blanca

@JoseBlanca
Copy link
Author

A friend has help me out, and she has created a workaround that seems to work.
She has added a Javascript line that I have added as the first line in my ui.page_fixed

page = ui.page_fixed(
        # This javascript code is a workaround for a shinylive behaviour.
        # In shinylive the app is located inside an iframe, and that prevents it
        # from accessing the query parameters directly. This javascript code tries to fix that
        ui.tags.script(
            "if(window.location.search !== window.parent.location.search) { window.location.search = window.parent.location.search }",
            type="text/JavaScript",
        ),
        ui.h1(config["title"]),
        input_card,
        output_card,
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants