pythonpy-shiny

Running a shiny python app from a script with `reload`


I was trying to run the example python shiny app directly from a script

"""Test shiny app."""

import argparse

from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.input_slider("n", "N", 0, 100, 20),
    ui.output_text_verbatim("txt"),
)


def server(input, output, _session):
    @output
    @render.text
    def txt():
        return f"n*2 is {input.n() * 2}."


app = App(app_ui, server)
if __name__ == "__main__":
    ap = argparse.ArgumentParser(description="Parse args passed into the Shiny app")
    ap.add_argument("--host", help="URL of host", default="127.0.0.1")
    ap.add_argument("--port", help="Port to use", type=int, default=8888)
    ap.add_argument("--reload", help="Enable auto-reload", action=argparse.BooleanOptionalAction, default=True)
    args = ap.parse_args()

    app.run(host=args.host, port=args.port, reload=args.reload)

When I run this script from a python environment which has shiny installed as

python test_app.py

I see the following error

WARNING:  Current configuration will not reload as not all conditions are met,please refer to documentation.
WARNING:  You must pass the application as an import string to enable 'reload' or 'workers'.

It works well if I set reload=False. Is there a workaround for this?

(EDIT: Fixed argparse issue pointed out by @relent95 in the answer)


Solution

  • It's not recommended to run a shiny app directly inside an application main module.

    If you insist, use the run_app() like the following. But I'm not sure it will not be broken in the future.

    # This is the test_app.py file.
    ...
    app = App(app_ui, server)
    
    if __name__ == "__main__":
        ...
        from shiny import run_app
        run_app('test_app:app', host=args.host, port=args.port, reload=True)
    

    As a side note, you incorrectly implemented the --reload option. See the reference.