Skip to main content

runlight

Runlight is privacy friendly web analytics that runs inside your own Python app. It counts visitors without cookies and without storing anyone’s IP address. The numbers stay in your database, and the dashboard is served from your domain at /runlight.

This package is the Python version of Runlight. It works in Django, Flask, FastAPI, or any WSGI or ASGI app on Python 3.11 or later, and it can also run on its own domain as a standalone server. It answers every request the way the TypeScript library does and uses the same tables, so either one can read the other’s database.

Get started

Install it with pip.

pip install runlight

SQLite comes with Python. For Postgres, install runlight[postgres], and for MySQL or MariaDB, runlight[mysql]. On Windows, add the tzdata extra for time zones.

Create one instance for your app.

from runlight import Runlight
from runlight.store import Stores

rl = Runlight(
    store=Stores.sqlite("data/runlight.db"),
    site={"name": "example.com", "hostnames": ["example.com"], "timezone": "Europe/London"},
)

Runlight reads the visitor's address from X-Forwarded-For and similar headers only when the request comes from this computer or a private network, where proxies and load balancers connect from, so a visitor who reaches your app straight from the internet cannot pick their own address. Behind a CDN that connects from public addresses, such as Cloudflare in front of your server, add trust_proxy="cf-connecting-ip" (the header it sets) or trust_proxy=True. Runlight logs a warning once when a public address sends forwarding headers that the default did not believe. trust_proxy=False never reads them.

Put it in front of your app. In Flask that is one line.

import runlight.flask

runlight.flask.init_app(app, rl)

Add the script to every page, just before </head>.

<script defer src="/runlight/s.js"></script>

Set RUNLIGHT_TOKEN to a long random string, then open /runlight/?token= followed by that string to sign in.

A token passed to rl.routes() works the same way. None counts as not given, so os.environ.get() of a variable that is not set falls back to RUNLIGHT_TOKEN and never opens the dashboard. To leave it open on purpose, behind your own sign-in, pass token=runlight.OPEN.

The Python guide has the code for Django, FastAPI, and plain WSGI or ASGI apps, the Postgres, MySQL, and MariaDB stores, the scheduled check, and the standalone server.

License

Runlight is MIT licensed.

Metadata

Release files for runlight 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for runlight 0.3.0
File Size Uploaded Provenance
runlight-0.3.0.tar.gz 557.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for runlight 0.3.0
File Interpreter ABI Platform
runlight-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / runlight-0.3.0.tar.gz

Download URL runlight-0.3.0.tar.gz
Size 557.8 kB
Tags Source
SHA-256 checksum
How to use checksums
63ccc5cfeed4866307ec58f23a2c10ac414a8255fc460f9f61531220412d08c4
BLAKE2b-256 checksum
How to use checksums
5cfaf240dd62005331342f6b05e1a127046a64c211d6ce3bb64e0e548ff62995
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
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":true}

Release files / runlight-0.3.0-py3-none-any.whl

Download URL runlight-0.3.0-py3-none-any.whl
Size 603.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
73b6ba13ac59784b7d028cb0623b246c2ac2b5d8e1271f731952f11640723614
BLAKE2b-256 checksum
How to use checksums
3298007df7075130f6ef1a7abca6a9b87e9548cb4d6dc88f9cb73b6ebc0ea21e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
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":true}

Security for runlight 0.3.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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page