Skip to main content

pyxctsk

A Python implementation of XCTrack's task format for paragliding and hang gliding competitions. This library enables parsing, manipulation, and visualization of XCTrack task files used to define competition routes.

pyxctsk provides a comprehensive toolkit for working with the XCTrack task specification, including reading/writing task files, generating QR codes for task sharing, and performing distance calculations on competition routes.

The library implements the full XCTrack Competition Interfaces specification, ensuring compatibility with the XCTrack mobile app and other tools in the paragliding competition ecosystem.

Technical Highlights

  • Immutable Data Model: Core domain objects use Python's dataclasses with strict validation to ensure task integrity (task.py)
  • Advanced Distance Calculation: Implements sophisticated route optimization algorithms to accurately calculate task distances with iterative refinement to avoid look-ahead bias (distance.py, route_optimization.py)
  • Efficient QR Code Representation: Implements XCTrack's compact QR code format with polyline compression for efficient task sharing via small QR codes that work well in direct sunlight (qrcode_task.py)
  • Flexible Parsing Pipeline: Single entry point that intelligently detects and parses multiple input formats (JSON, URL, QR code image) (parser.py)
  • Type Safety: Comprehensive type hints throughout the codebase with strict mypy enforcement

Dependencies and Libraries

Core

  • click: Command-line interface framework for the CLI tools
  • geopy: Geographic calculations for distance and point manipulation
  • polyline: Polyline encoding/decoding for compact coordinate representation
  • pyproj: Projection calculations for accurate distance measurements
  • scipy: Scientific computing library used for route optimization algorithms

Optional

  • Pillow: Image processing for QR code generation and parsing
  • qrcode: QR code generation
  • zxing-cpp: QR code parsing from images (ships binary wheels; no system library needed)

Development

  • pytest: Testing framework
  • ruff: Linting and formatting
  • mypy: Static type checking
  • lefthook: Git hook manager

Project Structure

.
├── src/
│   └── pyxctsk/           # Core package implementation
│       ├── __init__.py    # Package exports
│       ├── task.py        # Core data models
│       ├── parser.py      # Input format parser
│       ├── distance.py    # Distance calculation interface
│       ├── qrcode_task.py # QR code format implementation
│       └── ...
├── tests/                 # Test suite
│   ├── test_basic.py
│   ├── test_distance.py
│   └── ...
├── scripts/               # Utility scripts
├── pyproject.toml         # Project configuration
└── README.md
  • src/pyxctsk/: Core library implementation with immutable data models and parsing logic
  • tests/: Comprehensive test suite with basic tests and specialized distance calculation tests
  • scripts/: Utility scripts for automation and testing

Installation

Core Library Only

pip install pyxctsk

Development Installation

This project uses uv for dependency management.

git clone https://github.com/simonsteiner/pyxctsk.git
cd pyxctsk

# Create the virtual environment and install the project (editable) with the
# dev dependency group plus the web and analysis extras.
uv sync --all-extras

# Run tests
uv run pytest

# Run single test with parameter
# -s: disables output capturing, allowing print statements and other outputs to be shown in the terminal.
# -vv: increases verbosity, providing more detailed test results.
uv run pytest -s tests/test_qrcode.py -vv

# (Optional) To check QR code dependencies, run:
uv run python scripts/check_qr_deps.py

Code Quality & Formatting

The project uses lefthook to run ruff (lint + format), mypy, and cspell on commit:

# Install the git hooks (one-time)
uv run lefthook install

# Run the pre-commit hooks against staged files
uv run lefthook run pre-commit

# Or run the tools directly
uv run ruff check --fix src/ tests/ scripts/
uv run ruff format src/ tests/ scripts/
uv run mypy --config-file mypy.ini src/

Usage Examples

from pyxctsk import parse_task, Task, TaskType, Turnpoint, Waypoint

# Parse from file, URL, or QR code
task = parse_task('task.xctsk')              # From .xctsk file
task = parse_task('XCTSK:{...}')             # From XCTrack URL
task = parse_task('qr_code.png')             # From QR code image

# Access task data
print(f"Task type: {task.task_type}")
print(f"Number of turnpoints: {len(task.turnpoints)}")

# Create a new task
task = Task(
    task_type=TaskType.CLASSIC,
    version=1,
    turnpoints=[
        Turnpoint(
            radius=1000,
            waypoint=Waypoint(
                name="TP01", lat=46.5, lon=8.0, alt_smoothed=1000
            )
        )
    ]
)

# Save as JSON
with open('task.xctsk', 'w') as f:
    f.write(task.to_json())

# Generate QR code
from pyxctsk.qrcode_image import generate_qrcode_image

qr_task = task.to_qr_code_task()
qr_image = generate_qrcode_image(qr_task.to_string())
qr_image.save('task_qr.png')

Command Line Interface

The pyxctsk CLI enables conversion and inspection of XCTrack task files in multiple formats, with strict error handling and clear messaging.

Parameter Options:

  • --format [json|kml|png|qrcode-json]
    Output format.
    • json: Standard JSON representation
    • kml: KML for mapping tools
    • png: QR code image (PNG)
    • qrcode-json: Compact QR string (XCTSK: URL)
      Default: json
  • --output, -o <file>
    Output file (default: stdout). For png, writes a PNG image; for others, writes text.
  • <input_file>
    Input file (optional). If omitted, reads from stdin. Accepts .xctsk files or QR code images.

Examples:

# Convert task to different formats
pyxctsk convert task.xctsk --format json                  # JSON output
pyxctsk convert task.xctsk --format kml -o task.kml       # KML output
pyxctsk convert task.xctsk --format png -o qr.png         # QR code image
pyxctsk convert task.xctsk --format qrcode-json           # XCTSK: URL string

# Parse from different inputs
pyxctsk convert qr_code.png --format json                 # From QR image
cat task.xctsk | pyxctsk convert --format kml             # From stdin

Supported formats:

  • Input: .xctsk (XCTrack task files), QR code image (PNG)
  • Output: JSON, KML, QR code (PNG or XCTSK: URL string)

See the CLI startup message (pyxctsk --help or running the CLI with no arguments) for a quick summary of options and supported formats.

Requirements

  • Python 3.11+
  • Optional dependencies can be installed with extras:
    • pip install pyxctsk[web] for web interface components
    • pip install pyxctsk[analysis] for analysis tools
  • Development tooling lives in the dev dependency group and is installed automatically by uv sync (or uv sync --all-extras to include the extras).

License

This project is licensed under the MIT License - see the LICENSE file for details.

Original Implementation

This Python library is based on the Go implementation by Tom Payne: https://github.com/twpayne/go-xctrack

Metadata

Release files for pyxctsk 0.5.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 pyxctsk 0.5.0
File Size Uploaded
pyxctsk-0.5.0.tar.gz 72.3 kB Details

Built distribution (wheel)

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

Total release size: 122.6 kB

Release files / pyxctsk-0.5.0.tar.gz

Download URL pyxctsk-0.5.0.tar.gz
Size 72.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7d6f3bf362812a56ec60b6bb069f454e69cdcc1b070cd772db5a664d9dbc23ce
BLAKE2b-256 checksum
How to use checksums
24be2d32af2a448d5cc1ff91a21e4a2c03d9ae196fd392fa20ca9ff74722dd2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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 / pyxctsk-0.5.0-py3-none-any.whl

Download URL pyxctsk-0.5.0-py3-none-any.whl
Size 50.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c09fd74710d885125be429fded840184e2434e59822f75b0a2fb0f8a5603681d
BLAKE2b-256 checksum
How to use checksums
88e9a195f1b935be2eee7098fb243e27930eb7a23bd49c9dfe402b16d149061a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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 history Release notifications | RSS feed

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

This release

0.5.0 This release

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

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