Skip to main content

USA Swimming meet result (.cl2 / SDIF v3) parser and analysis library

Project description

tunas

PyPI Python License: MIT

A Python library for parsing USA Swimming meet result files (.cl2 / Hy-Tek SDIF v3) into structured Python objects and performing offline qualifying time standard lookups.

📖 Documentation: https://ajoe2.github.io/tunas/

Installation

pip install tunas

Requires Python 3.12+ and has zero runtime dependencies outside the standard library.

Quick Start

read_cl2 is the main entry point. It parses files, directories, lists of paths, or text streams, returning a list of Meet objects and a ParseReport:

from tunas import read_cl2

meets, report = read_cl2("results.cl2")

for meet in meets:
    print(f"{meet.name} ({meet.start_date})")
    for swim in meet.individual_swims:
        outcome = swim.time if swim.time is not None else swim.status.value
        print(f"  {swim.swimmer.full_name:<24} {swim.event.name:<16} {outcome}")

if report.warnings:
    print(f"{len(report.warnings)} records flagged — inspect report.warnings")

Core Concepts

All parsed data is contained in independent Meet objects:

  • Meet: Owns swimmers, clubs, and results (split into meet.individual_swims and meet.relays).
  • Swim: Has a .time (Time or None) and .status (ResultStatus e.g., OK, DQ, NS). Scratches and disqualifications are preserved.
  • Event: An enum of (distance, stroke, course). Filter with swimmer.swims_in(event) or meet.individual_swims_for(event).
  • Relays: Contain RelaySwim legs. Each leg reports its individual event, sorting alongside flat-start swims.
  • Scoping: Meets are independent; swimmers and clubs are scoped to their respective meet. Group by id_short (or id_long) to track athletes across meets.
from tunas import read_cl2, Event

meets, _ = read_cl2("season/")
for meet in meets:
    for swim in meet.swimmers[0].swims_in(Event.FREE_100_SCY):
        print(meet.name, swim.session.value, swim.time)

Offline Time Standards

USA Swimming motivational standards (B through AAAA) are bundled locally for offline lookup:

from tunas import qualifies_for, Sex, Event, Time

# Get the fastest standard achieved (or None):
qualifies_for(Time.parse("1:05.23"), Event.FREE_100_SCY, age=12, sex=Sex.FEMALE)
# → TimeStandard.BB

Also supports all_qualified(...) and standard_time(...) lookups.

Error Handling

Parsing is lenient by default to recover from common exporter bugs; warnings are collected in a ParseReport.

meets, report = read_cl2("messy/")
for w in report.warnings:
    print(f"{w.source}:{w.line_no} [{w.severity.value}] {w.record_type}: {w.reason}")

Use strict=True to fail fast and raise ParseError on the first warning. Structural violations always raise.

Features

  • SDIF v3 Parser: Parses .cl2 meet result files including relays and splits.
  • Clean Object Model: Slotted dataclasses with direct object references and zero global state.
  • Offline Standards: Local O(1) lookup of USA Swimming B through AAAA motivational cuts.
  • Lenient Parsing: Detailed warning reports by default; strict validation mode available.
  • Parallel Execution: Deterministic concurrent parsing of multiple files on thread pool.
  • Type-Safe: Fully typed (py.typed).

Documentation

Full docs site: https://ajoe2.github.io/tunas/

Development

Managed with uv:

uv sync                                      # Setup environment
uv run pytest                                # Run offline test suite
uv run pytest --cov=tunas                    # Run with coverage check (95% gate)
uv run ruff check && uv run mypy src/tunas   # Lint and type check

Status

tunas is in alpha. The public API is stable, but subject to revision before 1.0.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tunas-0.1.1.tar.gz (71.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tunas-0.1.1-py3-none-any.whl (77.0 kB view details)

Uploaded Python 3

File details

Details for the file tunas-0.1.1.tar.gz.

File metadata

  • Download URL: tunas-0.1.1.tar.gz
  • Upload date:
  • Size: 71.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tunas-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ec23c38cb14a97e923163b2d6e32e4f4f0cd0e80a76ba8b3aa9aa7ffb3a8271f
MD5 910e06030a0f6c30722b8b9418172980
BLAKE2b-256 23bc08423cab0a73ce3a0b1dc12f479a6d1ef99b75e618203b44ff09d7a42115

See more details on using hashes here.

Provenance

The following attestation bundles were made for tunas-0.1.1.tar.gz:

Publisher: publish.yml on ajoe2/tunas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tunas-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tunas-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 77.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tunas-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2a01c9749d9d927ef7e62776b7e2cab07f4041dd58b4aa5643539d0e6b2c7d85
MD5 98177cabfddc7b99271dea9950c893ab
BLAKE2b-256 5aef0dc427903a8665dbefcdf8862e4e67b1cb68f569b8484691094b00ae630e

See more details on using hashes here.

Provenance

The following attestation bundles were made for tunas-0.1.1-py3-none-any.whl:

Publisher: publish.yml on ajoe2/tunas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page