Shiny for Python Demo: An R Shiny Developer's thoughts on Shiny for Python
Appsilon prides itself on building the <a href="https://appsilon.com/" target="_blank" rel="noopener">best Shiny dashboards</a>. So naturally, when RStudio (Posit) announced <a href="https://www.appsilon.com/shiny-for-python-introduction/" target="_blank" rel="noopener">Shiny for Python</a> (<strong>Shiny for Python</strong>) we got very excited. And of course, we had to try it out for ourselves with a Shiny for Python demo. We'll cover our initial thoughts, but if you want the tl;dr: Shiny for Python is a great addition for Python fans and you can make a decent dashboard, but it still needs a lot of improvement to be on par with R Shiny. R Shiny developers can sleep peacefully for another 6-12 months.
<blockquote>Did you know <a href="https://appsilon.com/posit-rstudio-rebrands/" target="_blank" rel="noopener">RStudio is rebranding to Posit</a>? See why we think that's a good thing and <a href="https://appsilon.com/why-posit-means-growth-for-r/" target="_blank" rel="noopener">what it means for the R community</a>.</blockquote>
Python is a great programming language for both Data Science and Software Development. As Shiny (and RStudio) move to combine these two worlds, Shiny for Python sounds like a perfect match.
After the announcement, Appsilon had a team of three developers test Shiny for Python. Because we know the R/Shiny realm quite well, it seemed natural to challenge the new framework by trying to port one of our R Shiny apps built during an app sprint - {Respiratory Disease}.
<a href="https://connect.appsilon.com/respiratory_disease_app_sprint/" target="_blank" rel="noopener"><img class="wp-image-15426 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d516cd8f7584c809882_Appsilon-R-Shiny-demo.webp" alt="Appsilon R Shiny demo example" width="600" height="338" /></a>
We wanted to see what problems we would face along the way using the alpha version of Shiny for Python. You can explore the result of our experiment and read our commentary on our first impressions below.
<a href="https://connect.appsilon.com/respiratory_disease_pyshiny/" target="_blank" rel="noopener"><img class="wp-image-15424 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d52ce6734eff835fa1b_Appsilon-PyShiny-demo.webp" alt="Shiny for Python demo example" width="600" height="338" /></a>
Table of Contents:
<ul><li><a href="#good">The Good</a></li><li><a href="#bad">The Bad</a></li><li><a href="#beautiful">The Beautiful</a></li></ul>
<hr />
<h2 id="good">The Good in Shiny for Python</h2>
<h3>Shiny for Python backend</h3>
First, I would like to highlight that Shiny for Python relies on uvicorn web server as its backend. You might have heard of uvicorn before; it powers one of Python’s most popular backend frameworks and in Web Development in general - FastAPI. It is very robust and performant, so there is no doubt that PyShiny applications will be fast and scalable if built right.
<img class="aligncenter wp-image-15410" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d542c0cf4fd2c9632b8_pyshiny-and-uvicorn.webp" alt="univcorn powers PyShiny backend" width="200" height="200" />
<h3>Shiny for Python is appealing for software development</h3>
As a Software Developer, I noticed a few improvements that we get “for free” from Python itself. Like type hints. It’s not a strongly typed approach like in TypeScript, but it still allows developers to catch some bugs at build-time, rather than run-time.<img class="size-full wp-image-15422 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d5692a26c843b61b974_pyshiny-type-hints-and-code-suggestions.webp" alt="PyShiny type hints and code suggestions" width="1600" height="835" />
Not to mention that even advanced R Shiny developers need to open the Shiny reference page from time to time to check what methods and properties exist in the `session` object. In Shiny for Python, you can see that immediately in the IDE.
<h3>IDE's for Shiny for Python</h3>
Speaking of IDE - Visual Studio Code is the recommended tool for writing Shiny for Python applications. Shoutout to Shiny Team for creating a special VSCode extension! This is a great choice since VSCode is a multilingual code editor. It makes it easy to write Python, JavaScript, CSS, etc in one project using a single code editor.
<blockquote>Quarto, Python, and VS Code? Level up your reporting with <a href="https://appsilon.com/quarto-python-and-vscode/" target="_blank" rel="noopener">Quarto Reports in VS Code</a>!</blockquote>
<h3>Bonus features of Shiny for Python</h3>
Another cool VSCode feature that is supported in Python and also in Shiny for Python, is the ability to see not only the definition of a user-defined function but also the references - places in the code, where this function is called.
<img class="size-full wp-image-15414 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d567b599ca044810d10_pyshiny-definitions-and-references.webp" alt="PyShiny user defined function and references" width="1600" height="835" />
<ul><li>Async/await out of the box. Even `session.send_custom_message()` is implemented as an asynchronous function</li></ul>
<img class="size-full wp-image-15412 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d57b4ab7b08c201ab75_pyshiny-async-wait.webp" alt="PyShiny Async/Wait" width="1600" height="835" />
<ul><li>Hierarchical project structure and modularity (something that Rhino achieves by leveraging `box` package), </li></ul>
<img class="size-full wp-image-15416 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d58e9613f3f72cb6123_pyshiny-modularity.webp" alt="PyShiny Modularity" width="1600" height="835" />
<ul><li>Naming conventions. `snake_case` for functions and variables, and `PascalCase` for classes. Also, you will notice immediately that instead of familiar `reactive` and `observe`, Shiny for Python now has `reactive.Calc` and `reactive.Effect` - which makes a lot of sense. Even Joe Cheng gave credit to this during the Panel Discussion during the 2022 Appsilon conference.</li><li>Trailing commas inside UI components. It might sound minor, but this is a nice bonus for those reading git diff regularly. On the screenshot below, notice how adding `style` parameter results only in one line being changed:</li></ul>
<img class="size-full wp-image-15420 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d5aa597077171bd03ac_pyshiny-trailing-commas.webp" alt="PyShiny trialing commas" width="1600" height="835" />
<h2 id="bad">The Bad in Shiny for Python</h2>
<h3>Lack of packages</h3>
Shiny is a great framework for developing web applications in R <i>because </i>of the ecosystem of related packages: development tools, charts, tables, UI components, etc. At this stage, Shiny for Python lacks such an ecosystem.
While Shiny developers have access to such great component libraries like shiny.semantic or shinyWidgets, in Python everything has to be written from scratch. Of course, we could implement almost anything using JavaScript to directly access the APIs of some popular visualization or component libraries, but this would dissolve the very spirit of Shiny - simplicity, and accessibility for everyone.
<blockquote>The Shiny for Python ecosystem might be lacking, but R is booming. Build better <a href="https://appsilon.github.io/rhino/" target="_blank" rel="noopener">Shiny apps the Appsilon way with Rhino</a>.</blockquote>
Kudos to the Shiny Team for their efforts to leverage the existing ecosystem of ipywidgets with the help of shinywidgets - so that Shiny for Python users/developers have something to work with. However, we tested ipyleaflet which was featured in one of the Shiny for Python demos, and we struggled with it. Its R counterpart (leaflet) feels more flexible, well-documented, and feature-rich.
<h3>Unfamiliar implementations</h3>
Implementation of some familiar Shiny features is different in Shiny for Python. For example, shiny.ui.tags.head - it’s not <i>the <head />. </i>This will still work if you need to reference a local JS or CSS file, but in some cases, it’s crucial to add something to <i>the head</i> tag (e.g. the PWA worker). In some cases, things could be broken in unexpected ways: when created inside a UI module, selectize input with multiple selection would not render or work properly.
At the time of code writing, the issue above was already fixed in the development version on Github. But it’s an important reminder that Shiny for Python is still in its infancy.
<h3>Running hot</h3>
Last but not least, something’s off with how Shiny for Python runs the application - starting the app makes the CPU immediately hot. This behavior was observed both on a Linux and a macOS machine.
Let us know in the comments below if you found the same issue.
<h2 id="beautiful">The Beauty of Shiny for Python</h2>
<h3>ShinyLive</h3>
During the rstudio::conf(2022) RStudio also announced ShinyLive [<a href="https://shiny.rstudio.com/py/docs/shinylive.html">https://shiny.rstudio.com/py/docs/shinylive.html</a>] - Python code compiled to WebAssembly (WASM) which runs entirely in the browser! It is a new and exciting thing that could become a killer (cool) feature of Shiny for Python.
Why is this exciting? First, WASM allows a serverless architecture (not <i>serverless</i> serverless, but the true absence of a server!). The entire app bundle is downloaded into the client, and everything happens in a browser. Another great feature of WASM applications is that once downloaded, they can be run completely offline. It’s not always straightforward to make a ShinyLive out of a Shiny for Python app, but we were able to do it!
This technology still has its limitations though. Packages used in such Python projects are limited. For example, we had problems with packages that are not written in pure Python. It’s also noteworthy that the bundle that needs to be downloaded is quite large, which negatively affects the start time of the application.
<h3>PWA - Progressive Web App</h3>
There is already a solution for R Shiny apps to be downloaded as a PWA. The good news is that we were able to make it work with a Shiny for Python app as well. It was not trivial though and required some extra effort, but the result is worth it.
We look forward to combining ShinyLive and PWA technologies, to get an offline client app for a mobile device. Think of <i>Shiny Native </i>for all you React fans out there.
<h2>Summing up Shiny for Python - an unfinished story</h2>
The problems described above are not surprising; Afterall, Shiny for Python is still in the alpha stage. The package is being rapidly developed by the RStudio Team and some issues are being fixed on the fly. And as more people test Shiny for Python, we’re bound to see quick progress.
<blockquote><a href="https://appsilon.com/dash-vs-shiny/" target="_blank" rel="noopener">Python Dash or R Shiny</a>? See which you should choose for your use case.</blockquote>
Personally, it’s clear that these problems are only temporary. The ecosystem of packages will eventually grow around Shiny for Python - just as with the early days of Shiny for R. The Appsilon team is excited at the chance to contribute to its success. And we look forward to adding to the Shiny for Python ecosystem.
<a href="https://www.linkedin.com/feed/update/urn:li:activity:6962447045102055424" target="_blank" rel="noopener"><img class="wp-image-15418 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d5ac1b48d7cae11f457_pyshiny-or-shiny-for-python-shorthand.webp" alt="Shiny for Python or Shiny for Python name vote on social media" width="500" height="385" /></a>
In case you didn't notice, we've been using Shiny for Python and Shiny for Python interchangeably. So what is the official name of RStudio’s Shiny version for Python?
The official name is "Shiny for Python." However, some folks are already using the unofficial, condensed version: Py Shiny or Shiny for Python.
What's the official name of R Shiny? The official name for RStudio's Shiny for R is "Shiny." However, this to began to change with the community (somewhat clairvoyantly) dubbing it R Shiny or R/Shiny.
<blockquote>Want to get started with Shiny for Python? Check out our <a href="https://appsilon.com/shiny-for-python-introduction/">tutorial introducing Shiny for Python</a>.</blockquote>
Moving forward, these unofficial names might actually be easier to distinguish in conversation which language is being used for a given project. What do you think?