Python apps
What Python apps can and cannot do
The sandbox your code runs in: files, network, memory, packages, configuration and exit codes.
On this page
Every app runs in its own locked-down sandbox on the server. That keeps your code safe from other customers and theirs from you. The rules below explain what that means in practice, so you can design your script to fit before you upload it.
Before you start#
- You have an app, or are planning one. See Run Python apps from the panel.
- You know which plan you are on; your CPU and memory come from it. See Plan limits.
Where your code runs#
- Python 3, the version installed on the server, in a private virtual environment for each app.
- Your account's own user, never root. You cannot install system packages (
apt) or change the server. - Inside your plan's limits. CPU, memory and the number of processes are shared by everything on your plan: your websites' PHP and all your apps. Using too much CPU only slows things down; using more memory than the plan has gets the process killed.
Files#
- The app sees only its own folder,
/apps/<name>, and it can read and write there. It is also the working directory andHOME, soopen("prices.json")reads/apps/<name>/prices.json. - It cannot see your websites' folders, other apps or the rest of the server.
/tmpis private to each run and is wiped when the run ends. Keep anything you need next time in the app folder.- Files count towards your plan's storage and are backed up nightly with your other files.
Network#
| Allowed | Blocked |
|---|---|
| Outbound HTTPS and HTTP to the internet (APIs, websites, Telegram, payment gateways) | Port 25, and SMTP to any server other than FiniteHost's (Gmail, SendGrid SMTP and so on) |
Sending email through mail.finitehost.com on port 587 or 465, signed in with a FiniteHost mailbox | |
Your MariaDB database on localhost port 3306 (web plans) | FiniteHost's own servers and internal network |
| DNS lookups | Other ports on localhost |
Sending email: sign in to mail.finitehost.com (port 587 with STARTTLS, or 465 with SSL/TLS) with a FiniteHost mailbox and its password, using Python's smtplib. The mailbox's daily sending limit applies. Any other SMTP server hangs and then times out; an email service's HTTPS API also works. Example: Send email from your website or app.
Receiving traffic: apps cannot listen for incoming connections from the internet. There is no public port, so a worker cannot serve a website, an API or a webhook. Bots must poll for new messages instead of waiting for webhooks; see the Telegram bot example. Websites belong in /sites/<domain>/public as PHP or static files.
Packages#
- List packages in
requirements.txtin the app folder. They are installed withpipbefore the app starts, and again only when the file changes. - Packages that ship ready-made wheels install fine. A package that must be compiled from source may fail, because the sandbox has no compilers or system libraries. Choose a pure-Python alternative or a version with wheels for Linux.
- The install, plus your app's start, may take up to 15 minutes before the server gives up.
Configuration and secrets#
There is no settings screen for environment variables yet. Keep configuration in a file in the app folder:
{
"telegram_token": "123456:ABC-your-token",
"chat_id": "123456789"
}import json
from pathlib import Path
CONFIG = json.loads(Path("config.json").read_text(encoding="utf-8"))Upload config.json over SFTP, or include it in your zip. Keep a copy somewhere safe.
Output, logs and exit codes#
- Everything your app prints, and every error, appears under Logs on its card (the last 120 lines). Output is unbuffered (
PYTHONUNBUFFERED=1), soprint()lines show up straight away. - Use the
loggingmodule with timestamps for anything long-running. - Exit code 0 means success. Any other exit code, an uncaught exception, being killed for memory, or a job reaching the 1-hour limit counts as failed. Use
sys.exit(1)yourself when something important goes wrong, so the run shows as failed.
Limits at a glance#
| Limit | Value |
|---|---|
| Job run time | 1 hour, then stopped |
| Worker restarts after a crash | after 5 s, slowing to at most every 5 min; it stops retrying after 10 crashes within 10 min |
| Start-up time (including requirements.txt) | 15 minutes |
| Upload size in the panel | 20 MB per file |
| Log shown in the panel | last 120 lines |
Troubleshooting tips#
- SMTP timeouts: you connected to port 25 or to a server other than
mail.finitehost.com. See Send email from your website or app. PermissionErrorwriting a file: write inside the app folder only.Killedwith no traceback: the app used more memory than the plan allows. Process data in smaller pieces or upgrade.- More in Fix a failing Python app.
What's next#
Was this helpful?
Still stuck?
Email support@finitehost.com with your subscription ID (it starts with t, shown on the panel's Dashboard) and what you tried. A person replies, usually within one business day.
Last updated 27 October 2026. Found something wrong? Tell support@finitehost.com.