StayPresent
🛖 About
A lightweight Python package that keeps your bots and background scripts alive by running a dedicated Flask web server alongside your main application(s).
Perfect for deploying on platforms like Render, Railway, Koyeb, Heroku, or any host that requires an active HTTP port to keep your service running.
📖 This README covers the essentials. For the full guide — every parameter, every staypresent.web option, deployment notes, and a detailed FAQ — see DOCUMENTATION.md. Release notes live in CHANGELOG.md.
✨ Features
- Zero-Friction Setup: Get running with one line of code.
- Production-Ready by Default: Automatically uses
waitresswhen installed, avoiding Flask's "development server" warning. - Multiple Bot Support: Run several bot processes side-by-side under one web server, each monitored and restarted independently.
- Package-Aware Bot Launching: Launch a bot that lives inside a package (and needs relative imports) as a proper module via
bot_module. - Auto-Restarts & Crash Recovery: Automatically respawns a crashed bot process, with configurable delay and consecutive-crash budget, per bot.
- Flexible Responses: Serve plain text, JSON (default), full HTML templates, or rendered Markdown.
- Built-in Markdown Renderer — Zero Extra Dependencies: Headings, emphasis, links, images, nested lists, tables, code blocks, raw HTML passthrough, and a GitHub-flavored stylesheet, with no
markdownpackage required. - Light / Dark / Auto Theming: Markdown pages can follow the visitor's OS preference or be forced to
light/dark. - Custom Paths, Multiple Responses: Host more than one response at once, at different paths (e.g.
/,/status,/dashboard). - Static Asset Serving: CSS, JS, images, and favicons next to your HTML/Markdown files are served automatically.
- Optional Self-Ping / Keep-Warm: Periodically ping your own public URL to stop free-tier hosts spinning your service down — off by default.
See DOCUMENTATION.md for the full feature list, including advanced process control and fail-safe logging.
📦 Installation
pip install staypresent
Recommended for production — installs waitress to suppress Flask's dev-server warning:
pip install staypresent[prod]
If waitress isn't installed, StayPresent falls back to Flask's built-in server and logs a one-time warning — everything else (Markdown rendering, theming, tables, etc.) works with no extra dependencies either way.
🚀 Quickstart
import staypresent
staypresent.run("bot.py")
That's it. This starts a background web server (0.0.0.0:8080, serving {"message": "I'm Present"} at /) and runs bot.py alongside it, automatically restarting it if it ever crashes.
A more complete example
import staypresent
staypresent.web.markdown("CHANGELOG.md") # render a status/changelog page at "/"
staypresent.run(
"bot.py",
host="0.0.0.0",
port=5000,
threads=8,
)
Every staypresent.web function (text, json, html, markdown) accepts a path= argument, so you can host several independent responses — e.g. a JSON status at /, a dashboard at /dashboard, a changelog at /changelog — all from the same server. See Custom Paths & Multiple Responses for the details.
🤖 Running Multiple Bots
import staypresent
staypresent.run(["telegram_bot.py", "discord_bot.py"])
Each bot is supervised and restarted independently. For per-bot arguments/environment, or for a bot that needs python -m (package-relative imports), use bots=[...] / bot_module=... — see Process Execution for the full reference.
📡 Self-Ping / Keep-Warm
import staypresent
handle = staypresent.cron("https://my-bot.onrender.com", interval=300) # every 5 minutes
staypresent.run("bot.py")
Fully optional, off by default. See Self-Ping / Keep-Warm.
⚙️ API Reference (quick glance)
staypresent.run(bot_file=None, host="0.0.0.0", port=8080, ...) |
Launch your bot(s) alongside the web server. |
staypresent.web.text/json/html/markdown(..., path="/") |
Register a response at a path. |
staypresent.web.remove/get/get_all/paths() |
Inspect or remove registered responses. |
staypresent.ping(host, ...) |
Send a single one-off HTTP ping. |
staypresent.cron(host, ...) |
Start a recurring background ping (CronHandle). |
staypresent.active_cron_handles() |
List every currently-running cron pinger. |
Every parameter, default, and validation rule is documented in full in API Reference of DOCUMENTATION.md, along with Process Execution (crash recovery, multi-bot, bot_module) and Web Server Configuration (all response types, theming, static assets).
A built-in /health endpoint ({"status": "ok"}) is available out of the box for uptime monitors — see Built-in Health Check.
🛠 Requirements
- Python 3.8+
- Flask
waitress(optional, recommended for production —pip install staypresent[prod])
Markdown rendering, theming, and tables work with no additional dependencies — StayPresent ships its own built-in Markdown-to-HTML renderer.
💡 Use Cases
- Keeping a Discord/Telegram/Slack bot alive on a free-tier host that requires an open HTTP port.
- Running several bots (e.g. a Telegram bot and a Discord bot) from a single deployed service.
- Exposing a lightweight status page, uptime dashboard, or
CHANGELOG.mdviewer for a background worker. - Giving a hosting platform's health-check probe something to hit while your real work happens in a separate process.
📖 For everything else — full parameter tables, deployment notes, and an FAQ covering restarts, path collisions, bot_module, and more — see DOCUMENTATION.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file staypresent-1.5.10.tar.gz.
File metadata
- Download URL: staypresent-1.5.10.tar.gz
- Upload date:
- Size: 42.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e0abf61f510cf789900e14fbe813f93fcd1aa2b2e967732d30cf2516686df38
|
|
| MD5 |
15baa7a238bc733f4ee79271474e57bb
|
|
| BLAKE2b-256 |
fe46d13baaee1517e2eccc19bcf751a251f301c4b311b6f8dad622db0fcd9791
|
Provenance
The following attestation bundles were made for staypresent-1.5.10.tar.gz:
Publisher:
python-publish.yml on StayElite/StayPresent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
staypresent-1.5.10.tar.gz -
Subject digest:
4e0abf61f510cf789900e14fbe813f93fcd1aa2b2e967732d30cf2516686df38 - Sigstore transparency entry: 2279202888
- Sigstore integration time:
-
Permalink:
StayElite/StayPresent@1210148731ed8e3146bb4ccd36a931b58c9705d8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/StayElite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@1210148731ed8e3146bb4ccd36a931b58c9705d8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file staypresent-1.5.10-py3-none-any.whl.
File metadata
- Download URL: staypresent-1.5.10-py3-none-any.whl
- Upload date:
- Size: 41.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d9a9dd8fac589aff4a1e8079bc35040530a16ba5ac05cf951cc9c24e0c91573
|
|
| MD5 |
c557c42b50541034f72a88093af16517
|
|
| BLAKE2b-256 |
18632ebac9502a0f4b52448713a587642b651697770a3793435e6a859227865a
|
Provenance
The following attestation bundles were made for staypresent-1.5.10-py3-none-any.whl:
Publisher:
python-publish.yml on StayElite/StayPresent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
staypresent-1.5.10-py3-none-any.whl -
Subject digest:
2d9a9dd8fac589aff4a1e8079bc35040530a16ba5ac05cf951cc9c24e0c91573 - Sigstore transparency entry: 2279202931
- Sigstore integration time:
-
Permalink:
StayElite/StayPresent@1210148731ed8e3146bb4ccd36a931b58c9705d8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/StayElite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@1210148731ed8e3146bb4ccd36a931b58c9705d8 -
Trigger Event:
workflow_dispatch
-
Statement type: