pyfconfig

A clone of ifconfig.me built on the kaya framework (kaya-core + kaya-rsgi), served by Granian over the RSGI protocol.

Stack

  • kaya-core — routing and HTTP request/response handling
  • kaya-rsgi — Granian (RSGI) adapter
  • granian — application server
  • httpx + pwo — test client over kaya's ASGI transport

No database, sessions, or authentication — the app is stateless.

Endpoints

Method Path Response
GET / HTML page for browsers (Accept: text/html), plain-text IP otherwise
GET /ip Client IP address
GET /ua User-Agent header
GET /lang Accept-Language header
GET /encoding Accept-Encoding header
GET /mime Accept header
GET /charset Accept-Charset header
GET /forwarded X-Forwarded-For header
GET /all All connection fields as key: value lines (empty fields included; remote_host shown as unavailable)
GET /all.json Same fields as a JSON object, empty fields omitted
GET /api/health Liveness probe ({"status":"ok"})

The /all field order mirrors the reference site: ip_addr, remote_host, user_agent, port, language, referer, connection, keep_alive, method, encoding, mime, charset, via, forwarded.

Example:

$ curl http://localhost:8080/
203.0.113.7
$ curl http://localhost:8080/all.json
{"ip_addr":"203.0.113.7","user_agent":"curl/8.21.0","port":"51342","method":"GET","mime":"*/*"}

Running

docker compose up -d --build
# App published at http://localhost:8080

On the host

cp .env.example .env   # optional; all settings have defaults
python -m venv .venv && . .venv/bin/activate
pip install --index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple \
            --extra-index-url https://pypi.org/simple \
            -e .
granian --interface rsgi --host 0.0.0.0 --port 8000 pyfconfig.app:app

Configuration

Environment variables (see .env.example):

Variable Default Description
SITE_NAME pyfconfig Public name used in the HTML page title and the curl examples (set to your domain, e.g. ifconfig.example.com)

The bind address is configured through Granian itself (GRANIAN_HOST / GRANIAN_PORT env vars or --host / --port CLI flags).

Tests

. .venv/bin/activate
python -m unittest discover -s tests -t .

The tests drive the app in-process through kaya's ASGI interface using httpx.ASGITransport; no external services are needed.

Project layout

src/pyfconfig/
├── app.py              # KayaApp assembly; imports route modules
├── config.py           # env-driven Settings dataclass
├── page.py             # HTML landing page builder (kaya has no templating)
└── routes/
    ├── health.py       # GET /api/health
    ├── root.py         # GET / with content negotiation
    └── connection.py   # /ip /ua /lang /encoding /mime /charset /forwarded /all /all.json
tests/
└── test_routes.py      # unittest + httpx.ASGITransport

Route modules import the module-level app from pyfconfig.app and register handlers with @app.GET(...) decorators at import time — pyfconfig.app imports them last to complete the wiring.

Deployment

The Dockerfile is a multi-stage alpine build producing a minimal, non-root runtime image; pushing a release/* tag triggers the Gitea Actions workflow in .gitea/workflows/build.yaml, which builds and publishes the image to gitea.woggioni.net/woggioni-opencode-agent/pyfconfig.

S
Description
No description provided
Readme
69 KiB
Languages
Python 91.8%
Dockerfile 8.2%