Learning objectives
After reading this article you will be able to:
- Prepare a Python project to run outside your machine
- Write a script and an API that read config from the environment and shut down cleanly
- Verify the deploy and fix the most common errors
On this page
A Python app works on your machine because that machine has the right Python, the installed libraries and the variables you configured. Hosting means reproducing that environment on a server that stays on all the time.
There are two common cases. A script does work without receiving visitors: a bot, a data collector, a scheduled task. An API listens on a port and answers requests. The steps are the same for both, with one difference: only the API needs a port. For the big picture, see what is deployment.
What do you need before hosting?#
- A defined Python version. Use the same one locally and in production.
- A
requirements.txtwith your dependencies and their versions. - A main file (here,
main.py) that starts everything. - A place to run it: a VPS, a container or a hosting platform. The difference is covered in VPS vs cloud platform.
Which version? For a new project, prefer a Python version in bugfix status, as long as all your dependencies already publish packages for it. Older versions move to security fixes only and then reach end of life. The official release schedule shows the status of each version.
How do you set up the project with a venv?#
A venv is an isolated environment for this project only, which keeps one app's libraries from clashing with another's.
mkdir my-app && cd my-app
python -m venv .venv
source .venv/bin/activate # Windows (PowerShell): .venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install fastapi uvicorn
python -m pip freeze > requirements.txtpip freeze writes the installed versions to requirements.txt. On the server, python -m pip install -r requirements.txt recreates the same environment. That is why the .venv folder is not uploaded: it holds absolute paths and is not portable. Add .venv/ and .env to .gitignore.
How do you write a script that runs non-stop?#
A long-running script has to read its config from the environment, survive an isolated error and stop cleanly when the server asks. That request arrives as the SIGTERM signal, on restarts and deploys.
import os
import signal
import sys
import time
import urllib.request
stopping = False
def handle_stop(signum, frame):
global stopping
stopping = True
signal.signal(signal.SIGTERM, handle_stop)
signal.signal(signal.SIGINT, handle_stop)
API_URL = os.environ.get("API_URL")
if not API_URL:
sys.exit("API_URL is not set")
INTERVAL = int(os.environ.get("INTERVAL_SECONDS", "60"))
def job():
with urllib.request.urlopen(API_URL, timeout=10) as response:
print(f"status {response.status}", flush=True)
while not stopping:
try:
job()
except Exception as exc: # an isolated error does not kill the process
print(f"job failed: {exc}", flush=True)
for _ in range(INTERVAL): # sleep in 1-second steps to notice SIGTERM quickly
if stopping:
break
time.sleep(1)
print("shutting down", flush=True)What each part does:
os.environ: the URL and interval come from the environment, not the code. IfAPI_URLis missing, the script fails immediately with a clear message.stopping: the handler only flips a variable, and the main loop does the shutdown. The wait runs in 1-second steps, so the script noticesSIGTERMwithin a second, even with a long interval.flush=True: when output is not a terminal, Python buffersprintand logs arrive late. Running withpython -uor settingPYTHONUNBUFFERED=1has the same effect.
Test locally with API_URL=https://example.com python main.py. For tasks that run at fixed times, see what is a cron job.
How do you host a Python API?#
An API needs an ASGI server. The most common one with FastAPI is Uvicorn. The minimal app:
from fastapi import FastAPI
app = FastAPI()
@app.get("/health")
def health():
return {"status": "ok"}Start it with:
uvicorn main:app --host 0.0.0.0 --port "${PORT:-8000}"Two details matter in production. First, --host 0.0.0.0: the default listens only on 127.0.0.1, so nothing outside the container or machine can reach the app. Second, the port comes from the PORT variable when the platform sets it, with 8000 as the development default.
To compare the frameworks, see how to host FastAPI, Flask and Django. What to review before going public is in the API production checklist.
How do you handle environment variables and secrets?#
Tokens, database passwords and API keys live in environment variables, never in the repository. Locally, use a .env file kept out of Git and export the variables before running, or use python-dotenv. In production, set each one in your provider's dashboard. The full pattern is in what are environment variables.
How do you check that it worked?#
- Logs: they should show the script starting or Uvicorn listening, with no traceback after it.
- Request: call
/healthon the public address and expect{"status":"ok"}. - Restart: restart the app and confirm it comes back on its own and that
SIGTERMprints the "shutting down" line.
What are the most common errors?#
ModuleNotFoundError: No module named 'fastapi': the dependency was not installed or is not inrequirements.txt. Runpip freezeagain with the venv active.- Error installing or compiling a package: the server's Python version differs from your local one, and the library has no prebuilt package for it yet. Align the versions.
- App starts but the site won't open: the server listens on
127.0.0.1or on a fixed port. Use0.0.0.0and the port from the environment. - Empty or delayed logs: output buffering. Use
flush=TrueorPYTHONUNBUFFERED=1. - Works locally, crashes in production: a missing environment variable or not enough memory. Compare the two environments. For memory, see RAM and CPU sizing.
- The script dies and stays dead: nothing restarts it. Use a server or container with a restart policy. To package it, see how to dockerize an app.
How to do this on Square Cloud#
The two cases in this guide become two kinds of application on Square Cloud. You upload the project as a ZIP in the dashboard, with the CLI, through GitHub (a push triggers the deploy) or with the VS Code extension, and at start the platform runs pip install -r requirements.txt, the same file you generated in the venv. The install output shows up in the logs, so a ModuleNotFoundError tells you right away which package is missing. The squarecloud.app file is optional: the dashboard generates it on deploy.
The script runs as a background application, with no subdomain: the deploy form detects main.py, and the process uses from 256 MB of the plan's RAM and receives no inbound traffic. The API is a web application, with at least 512 MB and a *.squareweb.app subdomain with HTTPS. Since a FastAPI main.py only defines app, fill in the start command with uvicorn main:app --host 0.0.0.0 --port $PORT; the platform sets the PORT variable.
API_URL and INTERVAL_SECONDS go in as the application's environment variables in the dashboard, which also imports a .env; they already exist during the install and apply on the next restart. The container stays on, and automatic restart, on by default for dashboard deploys, brings the process back when it exits with an error. Running out of memory, by contrast, stops the app until you raise its RAM. Keep flush=True or PYTHONUNBUFFERED=1 so every line reaches the real-time logs.
The plan's RAM is a shared pool: on Hobby, which starts at R$12.49 per month with 1 GB, a script with 256 MB and an API with 512 MB fit together. Python is one of several runtimes, alongside Node.js, Go and Java: see the runtimes available today on Runtimes and the details of the Python runtime.
API hosting
APIs in always-on containers, with no cold starts
FAQs
Which Python version should I use in production?
Use a Python version in bugfix status that your libraries accept. The official Python release schedule shows the status of each version; check it before you pin one in your project.
Should I upload my venv folder with the code?
No. A venv stores absolute paths and depends on the operating system. Upload the code and requirements.txt and let the server recreate the environment with pip install -r requirements.txt.
How do I keep a Python script running 24/7?
Put the script in a loop that waits between runs and run it on a server or container that restarts the process if it crashes. If it depends on your computer, it stops when the computer turns off.
Do I need a web server to host a script?
No. A script that only does work, such as a bot or a data collector, does not need to open a port. Only APIs and sites need to listen on one.
More in APIs
See all 15 articles- How to host an APIHosting an API means running its HTTP server around the clock at a public address with HTTPS. Step-by-step with Node.js and Python, testing and common errors.
- How to host a Node.js appTo host a Node.js app, prepare package.json, read the port and secrets from the environment, pick an LTS version and run it with node. Step-by-step guide.
- How to host a FastAPI, Flask or Django appTo host a FastAPI, Flask or Django app, run it with a production server (Uvicorn or Gunicorn) on 0.0.0.0. Commands, Django settings and common errors included.
- Production checklist for your APIA production checklist for your API: environment variables, health check, graceful shutdown, standard errors, authentication, rate limiting, CORS and logs.