Your lab's Streamlit or Shiny app works. Can another scientist depend on it?
The app works until its author goes on holiday. Keep the science and the screens people know; make access, runs, recovery and ownership dependable.
On this page
The short version
- Keep the approved calculation and the screens people know; change the operating layer around them.
- Sign-in identifies a user. Check permission on every request, result, cache entry and download.
- Give each run a durable identity, so a refresh or a retry never loses or duplicates work.
- Accept the release on reference outputs, recovery tests and a handover someone else can operate.
Use the platform you already have
Check what your hosting already provides before anyone proposes a rebuild. Streamlit supports OpenID Connect sign-in. For Shiny, Posit Connect content settings limit an app to logged-in users or to specific users and groups.
Those controls decide who can open the app, not which project, run or file a signed-in partner may see inside it. Write a small access table with the workflow owner, listing groups, projects and actions, then enforce it in the app.
- Runs on one laptop or shared server
- Anyone with the link sees every project
- A refresh can lose a long run
- Failures live in the author’s terminal
- Only the author can deploy a fix
- Deployed on the platform you already run
- Project permission checked on every result
- Each run has an ID that survives refreshes
- Failures visible to users and an operator
- A named owner deploys and rolls back
Make a submitted run survive the browser
Keep short interactions simple. When computation must outlive a closed tab, use your existing job service or add the smallest durable queue that works. Streamlit session state keeps values during a session; it is not storage for a run that must survive a server restart.
- Authorize
Check the user and project.
- Record
Save request, input and method versions.
- Execute
Track queued, running and terminal states.
- Check
Reconcile the expected outputs.
- Retrieve
Recheck access before serving results.
Give each request a stable ID. Retrying after a timeout must not launch a second copy, while a deliberate rerun gets a new run ID linked to the first. Save parameters, input references, outputs and failure details outside the session, so a user who refreshes returns to the same run and sees whether it is queued, running, finished, failed or cancelled.
A corrected assay export becomes a new input version even when its filename is unchanged. Reusing a result because a filename matches can serve an old calculation after the scientist believes the correction ran.
Test permissions on the result, not the menu
Hiding another project in a dropdown is interface design, not access control. Check permission when accepting a request, reporting its status and serving every result or download link, including links generated from backend storage.
Caches leak quietly. Streamlit’s caching documentation says cached values are available to all users by default. Shiny’s bindCache() is scoped to the application by default, so every user session shares it. Choose the scope deliberately and keep an authorization check in front of cached results.
Sign-in decides who arrives. The app still has to decide what each person may see.
In the acceptance test, the partner signs in, copies an internal run ID and requests its result directly. Access is denied. Repeat with a warm cache and an old download link, then revoke the partner and confirm that sessions and links expire as agreed.
Prove the calculation and the recovery
Keep a small scientist-approved reference dataset with expected outputs. Compare the deployed calculation against it under an agreed rule: exact values where possible, justified tolerances where not. A good-looking chart is no evidence that the numbers stayed right.
- Interrupt
Stop a worker during the fixture run.
- Inspect
Show failure without partial success.
- Recover
Retry according to the run policy.
- Compare
Check outputs and duplicate handling.
Also submit an unsupported file, double-click submit and drop the connection mid-run. Errors should say what to fix without exposing another project, and a failed run must never leave half-written outputs that look complete.
Hand over an operation, not just a repository
Name who owns deployment, access changes, failed jobs and scientific updates. Before sign-off, someone other than the author should deploy an approved revision, find a failed run, restore retained data and roll back a release.
Measure completed tasks, manual interventions, support time and running cost against today. Hosting, sign-in and tests do not confer scientific or regulatory approval: the scientific owner decides whether outputs stay valid for their intended use.
Scope the first team release
- Agree users, projects, inputs, method version and expected outputs.
- Check native hosting, sign-in and job capabilities first.
- Deny unauthorized status, result and download requests.
- Test cache scope and the agreed access-revocation policy.
- Persist runs through refreshes, failures and safe retries.
- Compare reference outputs and expose failed or partial work.
- Have another operator deploy, recover and roll back.
Request a call from this article and tell us in a few lines what the app does and what broke last. The first conversation needs no data; confidential code and files can wait for an NDA or your approved access process. See how we work with biotech teams. If the app wraps a multi-step pipeline, the bioinformatics handover guide covers its run evidence.
Questions we hear
Does a Streamlit or Shiny app need a rewrite for production?
Not by default. Keep the approved calculation and the interface people know, then add what is missing: project permissions, durable runs, deployment, recovery and support. A new frontend needs a demonstrated requirement, not just the fact that a scientist wrote version one.
Is adding sign-in enough for partner access?
No. Sign-in identifies a user. The app must separately enforce what that user can read or run, including direct result requests, caches and downloads. Test two groups with deliberately different permissions, and agree how sessions and links behave after access is revoked.
What belongs in a first release?
One existing app, a defined user group, representative data and an approved reference result, plus a failed-run recovery test and a handover to a named operator. Price more partners, more scale or method changes once those requirements are understood.
Sources
- User authentication and informationStreamlit
- Content settingsPosit Connect documentation
- Add statefulness to appsStreamlit
- Caching overviewStreamlit
- bindCache: add caching with reactivity to an objectShiny for R reference