Integrate Python web apps with Workbench
Following on from #4662, we should update runApplication to detect if we're in Workbench, and if so, find a free port and corresponding proxied URL (possibly related to https://github.com/posit-dev/positron/issues/4274) and pass them both to getTerminalOptions. Unfortunately, some application frameworks need the proxied URL to be configured as the "URL prefix"/"root path".
I ran a Streamlit app in Workbench and it's displaying in the Viewer successfully! It'd be nice if the proxied path was reflected in the Terminal output, but ctrl+clicking on the Local URL results in the URL getting resolved to the correct proxied path (the one shown at the top of the Viewer).
The Quarto preview Terminal output shows the proxied path in addition to the localhost URL:
The Quarto extension code that outputs "Browse at <URL>": https://github.com/quarto-dev/quarto/blob/49abc46be3dbfd5cbd1eadf3d04cb4a7ac690b5c/apps/vscode/src/providers/preview/preview.ts#L532
Additional testing of Python web apps on Workbench: https://github.com/posit-dev/positron/pull/4662#issuecomment-2379487489
- Summary:
- Working with caveats: Streamlit, Dash, Flask
- Not working / partially working: Gradio (styles and images not loading from correct path), FastAPI (request is not proxied properly)
Just to see what would happen, I tried modifying the following to include a call to positron proxy to retrieve the proxied URI. It seemed to fix the issues with Gradio and Fastapi, but Streamlit and Dash stopped working. Flask still remained happy. https://github.com/posit-dev/positron/blob/659e073f18ac58f7b5ae585f68dc3ab670f5f485/extensions/positron-run-app/src/extension.ts#L226-L235
It seems like we're in this situation:
App Framework 👇 please provide proxy url, then I'll tell you the app url 👆 please provide app url, then I'll tell you the proxy url Positron Proxy
@seeM is it possible to preconfigure the app url (host:port) and pass that information to Positron Proxy? I suspect that may involve a bunch of framework-specific handling which may not be preferred. I'll look into what we can do on the Positron Proxy side to provide a proxy url separately from setting up the proxied connection.
@sharon-wang thanks for doing this research! I suspected this and had the following solution in mind:
The app-specific side is already implemented for Python apps here. Note how the various getTerminalOptions implementations use the optional port and urlPrefix to configure the app framework.
What still needs to be done is in the positron-run-app extension. We can detect if we're running in Workbench, and if so, determine a free port (and corresponding URL prefix) and pass that through to getTerminalOptions here:
https://github.com/posit-dev/positron/blob/f1ae7a334694d7c81565f7458a99ae0711bf936b/extensions/positron-run-app/src/extension.ts#L84-L89
Framework Support Summary as of https://github.com/posit-dev/positron/pull/4978
| Framework | Positron Server Web | Positron Desktop | Positron on Workbench | Notes |
|---|---|---|---|---|
| Dash | ✅ yes | ✅ yes | ✅ yes-ish | Workbench extension issue to skip Dash framework handling to avoid conflicting with Positron's Dash framework handling |
| Fastapi | ✅ yes | ✅ yes | 🛑 no | Seems to be a conflict between the way we run a fastapi app and that Workbench is setting UVICORN_ROOT_PATH |
| Flask | ✅ yes | ✅ yes | ✅ yes | Workbench: works when including the code snippet from Workbench docs. |
| Gradio | ✅ yes-ish | ✅ yes-ish | ✅ yes-ish | Working when the following dependency versions are used: gradio==3.3.1 fastapi==0.85.2 httpx==0.24.1. See https://github.com/gradio-app/gradio/issues/9529 for more information on why more recent versions don't work. |
| Streamlit | ✅ yes | ✅ yes | 🟨 partially | Not working on Workbench when SSL is enabled |
| Shiny | ✅ yes | ✅ yes | ✅ yes |
I'll come back to this to investigate Fastapi and Streamlit after looking at the other 2024.11 Workbench-related issues. Moving to Up Next for now.
Opened issues for the remaining frameworks instead of keeping this issue pending. Moving this issue into Verification!
- https://github.com/posit-dev/positron/issues/5026
- https://github.com/posit-dev/positron/issues/5027
- https://github.com/posit-dev/positron/issues/5028
All the apps work as expected with all the noted exceptions.