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

Issue deploying modular apps #1768

Open
davidrsch opened this issue Nov 12, 2024 · 2 comments
Open

Issue deploying modular apps #1768

davidrsch opened this issue Nov 12, 2024 · 2 comments

Comments

@davidrsch
Copy link

Hello I am giving a try to shiny for python and shinylive for python and have found some issues when deploying modular apps. I have created the following app as an example, you can see that is properly deployed to gh-pages when using shinylive, and is also woeking properly when clicking on the run button at Positron. The issue comes when I try to deployed using shinylive locally or as is in Posit Connect cloud. In both cases I receive the same error message:

from modules.counter_module import counter_ui, counter_server
ModuleNotFoundError: No module named 'modules'
@gadenbuie
Copy link
Collaborator

gadenbuie commented Nov 12, 2024

The issue comes when I try to deployed using shinylive locally

Could you clarify what you mean by "deployed using shinylive locally"?

or as is in Posit Connect cloud. In both cases I receive the same error message:

For Posit Connect Cloud, I can get your app to deploy if I create a manifest.json file for it locally. Here's the command I ran (using uv)

uvx --from rsconnect-python --with shiny -p 3.12 rsconnect write-manifest shiny app/

After that the app deployed to Posit Connect Cloud. (I'll be sharing this issue with the Connect Cloud team since it seems less-than-ideal that the manifest.json is required for this kind of app to work.)

Edit: If you run uvx --from rsconnect-python rsconnect write-manifest shiny by itself, rsconnect won't include shiny because it's not installed in the temporary venv created by uvx for the command. Make sure you include --with shiny if you use this command.

@davidrsch
Copy link
Author

davidrsch commented Nov 12, 2024

By "deployed using shinylive locally" I meant executing:

shinylive export app docs
python3.12 -m http.server --directory docs --bind localhost 8008

I specied python 3.12 because I have multiple python vesions in my pc, and the result is:
Image
Even though the app.json in docs looks like this:

[
  {
    "name": "app.py",
     "content": "from shiny import App, ui\nfrom modules.counter_module import counter_ui, counter_server\n\n# Main app UI\napp_ui = ui.page_fluid(\n    ui.h2(\"Demonstration of Shiny Modules\"),\n    ui.row(\n        ui.column(6,\n            ui.card(\n                \"Counter 1 (increments by 1)\",\n                counter_ui(\"counter1\", increment=1)\n            )\n        ),\n        ui.column(6,\n            ui.card(\n                \"Counter 2 (increments by 10)\",\n                counter_ui(\"counter2\", increment=10)\n            )\n        )\n    )\n)\n\n# Main app server\ndef server(input, output, session):\n    # Initialize counter modules with different configurations\n    counter_server(\"counter1\", increment=1)\n    counter_server(\"counter2\", increment=10)\n\napp = App(app_ui, server)", 
     "type": "text"
  },
  {
     "name": "modules\\__init__.py",
     "content": "",
     "type": "text"
  },
  {
     "name": "modules\\counter_module.py",
     "content": "from shiny import ui, module, render, reactive\n\n# Module UI function\[email protected]\ndef counter_ui(increment):\n     # Create namespace for IDs\n    return ui.div(\n        ui.input_action_button(\"button\", f\"Add {increment}\"),\n        ui.output_text(\"value\"),\n        ui.tags.br(),\n        ui.output_text(\"total_clicks\")\n    )\n\n# Module server function\[email protected]\ndef counter_server(input, output, session, increment):\n    @reactive.calc\n    def count():\n        return input.button() * increment\n\n    @output\n    @render.text\n    def value():\n        return f\"Current value: {count()}\"\n    \n    @output\n    @render.text\n    def total_clicks():\n        return f\"Number of clicks: {input.button()}\"",
     "type": "text"
  }
]

Which evidentiate that the structure is properly exported but for some reason modules folder doesn't get recognized as a module even though it has init.py in it

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