Skip to content

ihor-developer/untis-simple-API

Repository files navigation

untis-simple-api

Small QR-first Python client for fetching your own WebUntis timetable.

This project uses the Untis Mobile QR secret as the only supported authentication flow. It does not use the browser password login path.

What It Does

  • Imports a full untis://setschool?... QR string or equivalent manual values.
  • Derives a 6-digit TOTP from the QR secret.
  • Authenticates against the Untis Mobile JSON-RPC endpoint.
  • Mints a bearer token from /WebUntis/api/token/new.
  • Fetches your timetable from the WebUntis REST endpoint.
  • Keeps the last successful timetable payload in .untis-cache/.

Requirements

  • Python 3.11+
  • A WebUntis account with a valid Untis Mobile QR secret

No third-party runtime dependencies are required.

Install

pip install .

Or run it directly from the repo:

python -m untis_simple_api.cli --help

Configuration

The normalized .env contract is:

UNTIS_BASE_URL=https://scholl-gymnasium.webuntis.com
UNTIS_SCHOOL=scholl-gymnasium
UNTIS_USERNAME=ihor.oleksiuk
UNTIS_SECRET=BASE32SECRET

You can populate that file from a full QR string:

untis-simple-api import-qr --qr "untis://setschool?url=...&school=...&user=...&key=..." --write-env

Or from manual values:

untis-simple-api import-qr \
  --base-url "https://scholl-gymnasium.webuntis.com" \
  --school "scholl-gymnasium" \
  --user "ihor.oleksiuk" \
  --secret "BASE32SECRET" \
  --write-env

import-qr --write-env removes legacy USERNAME and PASSWORD entries from the target .env and writes the normalized UNTIS_* keys instead.

CLI

Import Credentials

untis-simple-api import-qr --qr "untis://setschool?..."

Fetch Today

untis-simple-api day
untis-simple-api day --date 2026-05-20
untis-simple-api day --json
untis-simple-api day --use-cache-on-failure

Fetch Week

Uses the week containing the supplied date, or today if no date is provided.

untis-simple-api week
untis-simple-api week --date 2026-05-20

Fetch Arbitrary Range

untis-simple-api range --start 2026-05-19 --end 2026-05-23
untis-simple-api range --start 2026-05-19 --end 2026-05-23 --json

Inspect Auth State

untis-simple-api inspect-auth
untis-simple-api inspect-auth --json

Output

Default terminal output is concise:

DAY 2026-05-20 | 5 lessons | live
2026-05-20 08:00-08:45 | Mathematics | Smith | A201
...

--json returns a machine-readable payload with:

  • raw
  • resolved
  • meta

The meta object includes:

  • freshness
  • cache_used
  • warning
  • fetched_at
  • jwt_iat
  • jwt_exp
  • resource_id
  • resource_type
  • tenant_id
  • current_schoolyear_id
  • range_start
  • range_end

Cache Behavior

Successful timetable responses are written to .untis-cache/.

Cached data is only returned when you explicitly opt in with --use-cache-on-failure or use_cache_on_failure=True.

When cached data is returned after an auth failure:

  • meta.freshness is set to "stale_cache"
  • meta.cache_used is true
  • meta.warning explains why cached data was used
  • the original meta.fetched_at is preserved

Live and cached data are not silently mixed.

Python API

from untis_simple_api import UntisClient

client = UntisClient.from_env()
today = client.fetch_day()
week = client.fetch_week("2026-05-20")
custom = client.fetch_range(start="2026-05-19", end="2026-05-23")
auth = client.inspect_auth()

You can also construct the client directly from a QR string:

client = UntisClient.from_qr_string(
    "untis://setschool?url=...&school=...&user=...&key=..."
)

Authentication Flow

The current flow is:

  1. Parse a QR string or normalized .env values.
  2. Generate a 6-digit TOTP from UNTIS_SECRET.
  3. Call POST /WebUntis/jsonrpc_intern.do?m=getUserData2017&school=...&v=i2.2.
  4. Keep the returned school/session cookies.
  5. Call GET /WebUntis/api/token/new.
  6. Call the timetable REST endpoint with cookies and bearer token.

Development

Run tests with:

python -m unittest discover -s tests -v

Notes

  • This client is intentionally limited to fetching the authenticated user's own timetable.
  • Password-based WebUntis login is not supported.
  • The QR secret should be treated like a long-lived credential.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages