Skip to content

Issue deploying modular apps #1768

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

Closed
davidrsch opened this issue Nov 12, 2024 · 11 comments
Closed

Issue deploying modular apps #1768

davidrsch opened this issue Nov 12, 2024 · 11 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\n@module.ui\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\n@module.server\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

@davidrsch
Copy link
Author

davidrsch commented Jan 17, 2025

@gadenbuie the error showed in the previous comment seems to be an issue related to how the app.json it's created in Windows. In windows \\ is added instead of / in the name field:

Image

Replacing \\ with / in the app.json fix the issue of deploying shinylive python apps in windows

Thanks to @DrEntropy who figured this out

@gadenbuie
Copy link
Collaborator

gadenbuie commented Jan 17, 2025

I just pushed a fix to the shinylive Python package at posit-dev/py-shinylive#47.

@davidrsch Would you mind giving it a try on your Windows machine with your example?

pip install git+https://github.com/posit-dev/py-shinylive@fix/46-posix-app-json-path-names

@DrEntropy
Copy link

I can confirm it does work for my windows machine as well !

@davidrsch
Copy link
Author

Yes, now is working as expect

@davidrsch
Copy link
Author

Now, only the issue regarding Posit Connect Cloud will remain.

(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.)

Have you had any news regarding this @gadenbuie?

@gadenbuie
Copy link
Collaborator

Now, only the issue regarding Posit Connect Cloud will remain.

Are you deploying the Shiny app directly or the shinylive export of the Shiny app to Posit Connect Cloud?

If the Shiny app directly, then the answer is to create a manifest.json, which Connect Cloud needs in order to know which file is primary in your repo. This is required because the app lives in a subdirectory; IIRC Connect Cloud only looks for app.R or app.py at the top level of the repo. (Or it might be that the presence of requirements.txt not next to the app.py is where the signal is lost.)

If you're deploying the exported shinylive app to Connect Cloud, it'd be helpful if you could share the commands you're running to do so.

@gadenbuie
Copy link
Collaborator

Thanks for the confirmation @DrEntropy @davidrsch and for spotting the issue!

@davidrsch
Copy link
Author

I see your point now; I got confused. As I was trying to deploy using shinylive both locally and on GitHub Pages I thought that somehow Posit Connect Cloud was using my publish.yml workflow or something. But now I get it — it isn't. It’s just trying to publish the app as a standard Shiny app, which requires the manifest.json. Did I get it right this time? If so, the issue can be closed.

@gadenbuie
Copy link
Collaborator

Yeah that sounds right! Glad we've figured it all out and thanks again!

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

3 participants