Button guide
Turn a Python script into a web app without writing one a form with file uploads and downloads, compared with Flask, Streamlit and Gradio
If you want colleagues to run your Python script through a browser without you writing web code, Button (https://button.bitgate.dev) turns the script on your computer into a web form with file uploads and downloads. The Free plan is $0 for 1 published tool, 3 people and 100 runs per month, and files up to 25 MB each work out of the box. If you need interactive charts, live widgets that update as someone drags a slider, or a public demo, use Streamlit or Gradio instead.
What a web app around a script actually needs
When you run a script for yourself, you edit a path at the top of the file or pass a couple of arguments in the terminal. Putting that same script in front of other people means handling six things that your script doesn't do on its own:
- A form for the inputs, so people can type text, pick a number, choose from a list or check a box instead of editing Python.
- File uploads that take a file from someone's browser and put it somewhere your script can read it.
- Running the job, including jobs that take several minutes without the browser timing out or two runs stepping on each other.
- Returning the output files to the browser as downloads, and cleaning up temporary files afterward.
- Login and access control, so only the colleagues you picked can open the tool and you know who ran what.
- Hosting, which means a URL other people can reach and a machine where your Python environment and packages already exist.
Flask, FastAPI, Streamlit, Gradio and Button divide that list up very differently.
How the four options compare
| Piece | Flask / FastAPI | Streamlit | Gradio | Button |
|---|---|---|---|---|
| How you build the UI | Write HTML forms and routes | Write Python (st.file_uploader, st.download_button) |
Wrap a function in Python | Pick your script and list its inputs in a setup page |
| Default max upload | You configure it | 200 MB (server.maxUploadSize) |
No default limit (launch(max_file_size=...) sets one) |
25 MB per file, up to 8 files and 100 MB per run |
| Where the job runs | A server you deploy and maintain | Your machine on your LAN, or Streamlit Community Cloud (sleeps after 12 hours idle) | Your machine via a *.gradio.live share link, or your own server |
Your own computer (the runner) |
| Concurrency | You build a background queue | Runs inside the app process | 1 request per handler by default (default_concurrency_limit is 1) |
1 run at a time per computer, up to 30 minutes per run |
| Login and who gets in | You build it | None by default; email invites for 1 private app on Community Cloud; or st.login() plus your own allowlist check |
Username/password pairs or a function via launch(auth=...); no email invites |
Email invite; colleagues sign in with Google or a one-time email code |
| Cost | Your server hosting | Free and open source; Community Cloud hosts 1 private app free | Free and open source | $0 for 1 tool, 3 people, 100 runs/month; Pro $15/month for 50 tools, 250 people, 5,000 runs/month |
When to use which
Pick Streamlit or Gradio when the page itself is the point - you want people exploring data with charts, tweaking parameters with live widgets, or trying a model on a public demo link.
Pick Flask or FastAPI when you're building a permanent web application with its own database, custom pages and deployment, and you don't mind writing and maintaining the web layer yourself.
Pick Button when the job is "inputs in, files out" for named colleagues, and you want the script to stay on your own computer where it already works. You don't write UI code, and you don't move your Python environment to a cloud server.
Option 1: Button (no web code, runs on your computer)
With Button, your script stays a normal command-line script on your machine. Button's servers relay the form values and files between your colleague's browser and your computer, and the job runs locally on your machine.
- Make your script take command-line arguments. Instead of hard-coded file paths or
input()prompts, useargparseso each input value, each input file path, and the output folder path come in as arguments. Fixed flags stay in the command you approve; colleagues only fill in the form fields.
import argparse
import pathlib
parser = argparse.ArgumentParser()
parser.add_argument("input_csv")
parser.add_argument("region")
parser.add_argument("output_dir")
args = parser.parse_args()
out = pathlib.Path(args.output_dir) / "result.csv"
# ... run your existing logic and write files into args.output_dir ...
- Install the Button runner. Sign in at
https://button.bitgate.devand run the one-line install command shown on the site (it usescurlon macOS and Linux, or PowerShell on Windows). - Pick your script and describe its inputs. In the runner's local setup page, select your program, add the inputs it expects (text, number, yes/no, choice, or files), and publish. Button pins the exact command you approved by hash, passes every form value as its own argument with no shell, and rejects values that start with
-. - Invite your colleagues. Enter their emails. They open the link from their invite email, sign in with Google or a one-time email code, fill in the form, press Run and download the output files. They install nothing and never pay.
While you're away from your desk, your computer does have to stay on and online (the tool page shows Ready, Busy or Offline). If you change the tool later, colleagues have to confirm the new version before running it. Every run is logged with who ran it and when, and you can revoke someone's access or set it to expire whenever you want.
Option 2: Streamlit (for interactive data apps)
Streamlit is a good fit when your colleagues need to look at charts and tables inside the browser rather than just downloading a file at the end.
- Rewrite the script's inputs and outputs using Streamlit widgets. Use
st.file_uploader(200 MB per file by default) to take files in, andst.download_buttonto hand results back. - Test it locally. Run
streamlit run app.py. Streamlit prints a Local URL (http://localhost:8501) and a Network URL that anyone on your network can open, with no login by default. - Decide how to host and lock it down.
- For one private app, deploy from GitHub to Streamlit Community Cloud (free) and invite viewers by email. Apps with no traffic for 12 hours go to sleep and wake on the next visit.
- If you host it yourself,
st.login()connects to an OpenID Connect provider such as Google or Microsoft Entra ID. It only checks who the user is; you write the allowlist check yourself withst.user.emailandst.stop().
Option 3: Gradio (for quick function UIs and ML demos)
Gradio wraps a Python function in a browser UI and is popular for demos.
- Wrap your script's main logic in a single function that takes the inputs and returns the output file paths, then pass that function to Gradio in Python.
- Set a file size limit if you need one with
launch(max_file_size=...); there's no default maximum. Each event handler runs one request at a time by default. - Share the link.
launch(share=True)gives you a public*.gradio.livelink tunneled to your machine. It only works while your computer and the Python process stay on, and it expires after a week at most.launch(auth=...)adds a login with username/password pairs; there's no invite by email.
Option 4: Flask or FastAPI (when you want to build a real web service)
If you want full control and don't mind maintaining a web app, you can build one from scratch with Flask or FastAPI.
- Write the HTTP routes and an HTML form that accepts
multipart/form-datauploads, saves the uploaded files to a temporary directory, and validates them. - Move the script into a background worker if a run takes more than a few seconds, so HTTP requests don't time out mid-job, and add a status page that polls until the output files are ready to download.
- Add authentication so the form isn't open to the internet.
- Deploy the app and your Python dependencies to a server and put HTTPS in front of it.
FAQ
Does my script have to be in Python to use Button?
No. Any program you can run from the command line on macOS, Linux or Windows works, including Python, Node, R, PowerShell, shell scripts and compiled binaries.
Where do the files go when someone runs a Button tool?
Form values and files pass through Button's servers to get between your colleague's browser and your computer, and the job itself runs on your computer. Button deletes inputs 24 hours after a run ends and outputs after 7 days.
What are the limits on the free Button plan?
Free is $0 and includes 1 published tool, 3 invited people (you don't count toward the 3), 100 runs per month (including your own test runs) and 1 GB of file transfer per month. Each run can take up to 8 files (25 MB per file, 100 MB total), run for up to 30 minutes and produce up to 1 MB of logs.
What happens if I downgrade from Button Pro to Free?
Nothing is deleted. If you're over the Free limits (1 tool, 3 people, 100 runs and 1 GB of transfer per month), you can't add tools or people, and runs follow the Free monthly cap.
Last updated
Put your script behind a form
Button turns a script on your computer into a web form. Colleagues sign in, fill it in, press Run and download the results. Free for 1 tool and 3 people.