This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
RT Tools is a Python package for interacting with RT (Request Tracker) systems. The project provides a command-line tool and Python library for authenticating with RT servers and querying ticket information.
The codebase follows a standard Python package structure with src layout:
src/rt_tools/- Main package directorycli.py- Command-line interface with argument parsing and logging configurationsession.py-RTSessionclass that extendsrequests.Sessionfor RT-specific authentication and operationsdownloader.py-TicketDownloaderclass for comprehensive ticket data download and organizationparser.py- Centralized RT response parsing with dataclasses and filtering logicutils.py- Utility functions for cookie management, password fetching, and response handling__init__.py- Package initialization with dynamic version loading
RTSession Class: Inherits from requests.Session and handles:
- RT server authentication using stored cookies
- SSL certificate verification with bundled certificate (loaded from package data)
- Cookie persistence using Mozilla cookie jar format
- Authentication status checking via RT API responses
TicketDownloader Class: Handles comprehensive ticket data retrieval:
- Downloads ticket metadata, complete history, and all attachments
- Creates organized directory structure with individual history directories
- Uses centralized parser module for consistent data handling
- Filters outgoing emails and zero-byte attachments automatically
- Uses n-prefixed attachment naming for proper sorting (
n800.pdf) - Automatically converts XLSX attachments to TSV format
- Provides detailed logging of all file creation operations
Parser Module: Provides centralized RT response parsing:
- Defines structured dataclasses for RT data (AttachmentMeta, HistoryMessage, etc.)
- Parses attachment lists, history items, and individual messages
- Parses ticket status from
ticket/{id}responses viaparse_ticket_status() - Filters outgoing emails during history parsing
- Uses string-based dataclasses to match RT API format
- Handles multi-line content and attachment extraction
Authentication Flow:
- Attempts to load existing cookies from
cookies.txt - Checks authorization status by parsing RT server response
- If unauthorized, fetches password from macOS keychain using
/usr/bin/security - Performs authentication POST and saves new cookies
Logging: Uses Python's logging module with three levels controlled by CLI flags:
- Default: INFO level
--verbose: DEBUG level (shows detailed request/response info)--quiet: WARNING level (suppresses routine messages)
# Install package in development mode with dev dependencies
uv pip install -e '.[dev]'
# Or using pip (slower)
pip install -e '.[dev]'# Formatting code (similar to black)
ruff format src
# Run linting (configured with pycodestyle, Pyflakes, isort, flake8-bugbear)
ruff check src/rt_tools/
# Auto-fix linting issues
ruff check --fix src/rt_tools/
# Run tests
pytest
# Run specific test modules
pytest tests/test_parser.py
pytest tests/test_ticket_downloader.py
# Run tests with verbose output
pytest -v# Build package
python -m build
# The package uses setuptools with src layout discovery# Available console scripts:
download-ticket <ticket_id> [--output-dir DIR] # Download complete RT ticket data to rt{ticket_id} subdirectory
dump-ticket <ticket_id> [additional_path_parts] # Dump RT ticket information
dump-rest [rest_path_parts] # Dump content from RT REST API URLs
dump-url [url_path_parts] # Dump content from RT URLs
# Target directory resolution (in order of priority):
# 1. --output-dir command-line option
# 2. $DOWNLOAD_TICKET_DIR environment variable
# 3. ~/.config/download-ticket/config.toml (default_dir setting)
# 4. Current working directory (fallback)
# Examples:
download-ticket 37603 # Downloads to ./rt37603/
download-ticket 37603 --output-dir local/output # Downloads to local/output/rt37603/
export DOWNLOAD_TICKET_DIR=~/tickets && download-ticket 37603 # Downloads to ~/tickets/rt37603/
# With logging options
dump-ticket --verbose <ticket_id> # Debug level logging
dump-ticket --quiet <ticket_id> # Only warnings/errors
download-ticket --verbose 37603 --output-dir /tmp # Verbose download to /tmp/rt37603/The package expects:
- Keychain Access: macOS keychain entry with service "foobar" containing RT password
- RT Server: Configured to work with
https://rt.hgsc.bcm.edu/REST/1.0/endpoint
Note: The SSL certificate for RT server verification is bundled as package data and loaded automatically.
The download-ticket command supports flexible target directory configuration through multiple methods:
-
Command-line option (highest priority):
download-ticket 37603 --output-dir /path/to/output
-
Environment variable:
export DOWNLOAD_TICKET_DIR="~/Downloads/rt-tickets" download-ticket 37603 # Uses ~/Downloads/rt-tickets/
-
Config file (
~/.config/download-ticket/config.toml):default_dir = "~/Documents/rt-data"
-
Current working directory (fallback):
cd /tmp && download-ticket 37603 # Creates /tmp/rt37603/
The resolution follows this exact priority order, with higher-numbered options overriding lower-numbered ones.
Parsing Architecture: Uses centralized parser module (parser.py) to eliminate duplicate parsing logic. All RT responses are parsed into structured dataclasses with string attributes to match RT API format.
Cookie Management: Uses http.cookiejar.MozillaCookieJar for persistent authentication across sessions. Cookies are automatically loaded on RTSession initialization and saved after successful authentication.
Error Handling: Authentication and request failures cause immediate program exit with error logging. The package does not implement retry logic.
URL Construction: RT ticket URLs are built using static methods that concatenate base URL with ticket ID and optional path components.
Response Data: RT REST API returns attachments surrounded by a prefix and a possible suffix. The prefix is b"RT/x.x.x 200 Ok\n\n", where x.x.x is the RT version. Anything other than this indicates an error. The suffix is present only when the URL ends with "/content/" or "/content". When present, the suffix is 3 newlines: b"\n\n\n". The three newlines never contain carraige returns. Downloading an attachment uses a content URL and requires validating the suffix and removing both suffix and prefix.
Directory Structure: The downloader creates an organized structure with individual history directories. The resolved target directory (from --output-dir, environment variable, config file, or current directory) is the parent directory containing multiple ticket directories:
resolved_target_dir/ # From resolution order: --output-dir > env var > config > cwd
├── rt37603/ # Ticket directory (rt{ticket_id} format)
│ ├── metadata.txt # Basic ticket information
│ ├── 1492666/ # History entry directory
│ │ ├── message.txt # Full RT history entry (raw format)
│ │ ├── content.txt # New content only (quoted replies stripped)
│ │ ├── n800.pdf # Attachment with n-prefix for sorting
│ │ └── n801.xlsx # Additional attachments
│ └── 1492934/ # Additional history entries
│ ├── message.txt
│ └── content.txt
└── rt37604/ # Another ticket directory
├── metadata.txt
└── ...
File Naming Conventions: Attachments use n-prefixed naming (n{attachment_id}.{ext}) to ensure proper alphabetical sorting, preventing issues where 10.pdf would sort before 2.pdf.
Content Filtering: The downloader automatically filters out:
- Outgoing emails (identified by X-RT-Loop-Prevention headers)
- Zero-byte attachments that contain no useful data
- System-generated notifications that don't contain user content
Testing Architecture: Comprehensive test suite with:
- Parser tests covering all parsing functions and dataclasses (14 tests)
- Downloader tests covering all methods and error scenarios (25 tests)
- Mock fixtures for RT responses using real captured data
- Session-scoped fixtures for optimal performance
- Edge case and error handling validation
Security: Passwords are fetched from macOS keychain rather than being stored in code or configuration files. The keychain lookup uses partial command ["/usr/bin/security", "find-generic-password", "-w", "-s", "foobar", "-a"] with username appended.
Primary Reference: docs/rt-rest-1-subset.md - Documents only the RT REST API endpoints used by this project, including:
- Authentication endpoints and session management
- Ticket metadata retrieval (
/REST/1.0/ticket/{id}) - History operations (recursive fetching due to broken
format=lparameter) - Attachment list, metadata, and content endpoints
- Response formats and parsing requirements
Complete Reference: docs/rt-rest-1-snapshot.html - Full RT REST 1.0 API documentation snapshot for reference