pingme-ntfy
Send a push notification to your phone from any Python script with one call:
from pingme_ntfy import ping
ping("Backup finished")
It uses ntfy, a free and open source notification service. No account, no API key and no dependencies outside the Python standard library.
ping() never raises. If something goes wrong (no network, missing configuration, server error), it logs a warning and returns False, so your script keeps running.
Setup from scratch
1. Install the ntfy app on your phone
- Android: Google Play or F-Droid
- iOS: App Store
2. Pick a topic name
A topic is like a private channel. On the public server anyone who knows the name can read and write to it, so pick something long and random. You can generate one with:
python3 -c "import secrets; print('pingme-' + secrets.token_urlsafe(16))"
The examples below use my-test-topic-change-me. Replace it with your own.
3. Subscribe to the topic in the app
Open the ntfy app, tap +, enter your topic name and subscribe. Leave the server as ntfy.sh unless you host your own.
4. Set the environment variable on your computer
System wide (all users, all shells, also visible to most services):
echo 'NTFY_TOPIC=my-test-topic-change-me' | sudo tee -a /etc/environment
Or only for your user:
echo 'export NTFY_TOPIC=my-test-topic-change-me' >> ~/.bashrc
Log out and log back in (or open a new terminal for ~/.bashrc) so the variable is loaded. Check it with:
echo $NTFY_TOPIC
Note: cron jobs do not read ~/.bashrc. If you call ping() from cron, use /etc/environment or define the variable at the top of your crontab.
5. Install the library
With uv, inside the project where you want to use it:
uv add pingme-ntfy
Or with pip:
pip install pingme-ntfy
To get the pingme-ntfy command available everywhere in your shell:
uv tool install pingme-ntfy
6. Test it
uvx pingme-ntfy "Hello from my computer"
uvx runs the command without installing anything permanently. If you installed it with uv tool install, just run pingme-ntfy "Hello from my computer".
You should get a notification on your phone within a few seconds. The command exits with code 0 on success and 1 on failure, so it also works in shell scripts:
./backup.sh && pingme-ntfy "Backup OK" || pingme-ntfy "Backup FAILED"
Usage
from pingme_ntfy import ping
ping("Job done")
ping(
"Disk usage above 90%",
title="Server alert",
priority=5, # 1 (min) to 5 (max), default is 3
tags=["warning"], # tags or emoji shortcodes, shown in the app
)
if not ping("Something"):
print("Notification was not delivered, but the script goes on")
A common pattern is to notify when a long task ends, even if it fails:
from pingme_ntfy import ping
try:
run_long_task()
ping("Task finished", tags=["white_check_mark"])
except Exception as e:
ping(f"Task failed: {e}", priority=5, tags=["x"])
raise
Configuration
All configuration comes from environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
NTFY_TOPIC |
yes | Topic to publish to | |
NTFY_SERVER |
no | https://ntfy.sh |
Server URL, if you self host ntfy |
NTFY_TOKEN |
no | Access token for protected topics or servers |
Errors and logging
Failures are reported through the standard logging module under the pingme_ntfy logger. By default Python prints them to stderr. To silence them:
import logging
logging.getLogger("pingme_ntfy").setLevel(logging.ERROR)
Project layout
pingme-ntfy/
├── LICENSE EUPL-1.2 full text
├── README.md
├── pyproject.toml package metadata, built with uv_build
└── src/pingme_ntfy/
└── __init__.py all the logic
Build a wheel and source distribution with uv build.
License
Licensed under the European Union Public Licence v. 1.2 (EUPL-1.2).
Metadata
Release files for pingme-ntfy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pingme_ntfy-0.1.0.tar.gz | 9.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pingme_ntfy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.1 kB
Release files / pingme_ntfy-0.1.0.tar.gz
| Download URL | pingme_ntfy-0.1.0.tar.gz |
|---|---|
| Size | 9.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6d1190943a7985d6c9c6ff628fb3528c57c6f823d9805a4a389cf846ece405f
|
|
BLAKE2b-256 checksum How to use checksums |
e1d86063080d7d3fbda9085b063f21f8c0dab3373686b51de572b5560d44ec40
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pingme_ntfy-0.1.0-py3-none-any.whl
| Download URL | pingme_ntfy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e787856f67e5f68847232e6b1b755596e58db17697c265c80ad8fe18602ae3b9
|
|
BLAKE2b-256 checksum How to use checksums |
f4955a9f5badeb25ad6ac6c2fcadb5385b224588283a2da2d322bd7212db970a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pingme-ntfy 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.