API Reference
Use ox as a Python library to parse and analyze your training logs.
Basic Usage
from ox import parse
# Parse a training log file
log = parse("training.ox")
# Access all sessions
for session in log.sessions:
print(f"{session.date}: {session.name}")
for movement in session.movements:
print(f" {movement.name}: {movement.sets}")
Data Structures
TrainingSession
Represents a single workout session.
Attributes:
- date: datetime.date - The date of the session
- name: str | None - Session name (e.g., "Upper Body")
- flag: str - Session flag ("*", "!", or "W")
- movements: tuple[Movement, ...] - Exercises in this session
- note: str | None - Session-level notes
Example:
session = log.sessions[0]
print(session.date) # 2024-01-15
print(session.name) # "Upper Body"
print(session.flag) # "*"
print(len(session.movements)) # 3
Movement
Represents a single exercise/movement.
Attributes:
- name: str - Exercise name (e.g., "squat", "bench-press")
- sets: list[TrainingSet] - List of sets performed
- note: str | None - Movement-specific notes
Example:
movement = session.movements[0]
print(movement.name) # "squat"
print(len(movement.sets)) # 5
print(movement.note) # "felt heavy"
TrainingSet
Represents a single set of an exercise.
Attributes:
- reps: int - Number of repetitions
- weight: Quantity - Weight used (using pint units)
Example:
training_set = movement.sets[0]
print(training_set.reps) # 5
print(training_set.weight) # 135 <Unit('pound')>
print(training_set.weight.to('kg')) # 61.23 kilogram
Common Tasks
Filter by Exercise
Get all instances of a specific exercise:
from ox import parse
log = parse("training.ox")
# Find all squat sessions
for session in log.sessions:
for movement in session.movements:
if movement.name == "squat":
print(f"{session.date}: {len(movement.sets)} sets")
Track Progress Over Time
from ox import parse
log = parse("training.ox")
# Track squat progress
squat_history = []
for session in log.sessions:
for movement in session.movements:
if movement.name == "squat":
max_weight = max(s.weight for s in movement.sets)
squat_history.append((session.date, max_weight))
# Sort by date
squat_history.sort()
# Print progression
for date, weight in squat_history:
print(f"{date}: {weight}")
Calculate Volume
from ox import parse
log = parse("training.ox")
# Calculate total volume for a session
for session in log.sessions:
total_volume = 0
for movement in session.movements:
for training_set in movement.sets:
# Volume = reps × weight
volume = training_set.reps * training_set.weight.to('kg').magnitude
total_volume += volume
print(f"{session.date}: {total_volume:.1f} kg total volume")
Working with Units
ox uses pint for unit handling:
from ox import parse
log = parse("training.ox")
movement = log.sessions[0].movements[0]
weight = movement.sets[0].weight
# Convert units
print(weight.to('kg')) # Convert to kilograms
print(weight.to('lbs')) # Convert to pounds
# Get numeric value
print(weight.magnitude) # Just the number
print(weight.units) # Just the unit
# Compare weights
if weight > 100 * ureg.pounds:
print("Heavy!")
Filter by Date Range
from datetime import date
from ox import parse
log = parse("training.ox")
start_date = date(2024, 1, 1)
end_date = date(2024, 1, 31)
# Get sessions in date range
january_sessions = [
s for s in log.sessions
if start_date <= s.date <= end_date
]
print(f"Sessions in January: {len(january_sessions)}")
Export to Dictionary
from ox import parse
import json
log = parse("training.ox")
# Convert to dict for JSON export (example structure)
data = []
for session in log.sessions:
session_data = {
"date": session.date.isoformat(),
"name": session.name,
"movements": []
}
for movement in session.movements:
movement_data = {
"name": movement.name,
"sets": [
{
"reps": s.reps,
"weight": str(s.weight)
}
for s in movement.sets
]
}
session_data["movements"].append(movement_data)
data.append(session_data)
# Save to JSON
with open("training_data.json", "w") as f:
json.dump(data, f, indent=2)
Advanced Usage
Custom Analysis
Build your own analytics:
from ox import parse
from collections import defaultdict
log = parse("training.ox")
# Track frequency of each exercise
exercise_count = defaultdict(int)
for session in log.sessions:
for movement in session.movements:
exercise_count[movement.name] += 1
# Sort by frequency
sorted_exercises = sorted(
exercise_count.items(),
key=lambda x: x[1],
reverse=True
)
print("Most frequent exercises:")
for exercise, count in sorted_exercises[:5]:
print(f"{exercise}: {count} times")
Weekly Summaries
from ox import parse
from datetime import timedelta
log = parse("training.ox")
# Group by week
weekly_sessions = defaultdict(list)
for session in log.sessions:
week_start = session.date - timedelta(days=session.date.weekday())
weekly_sessions[week_start].append(session)
# Print weekly summaries
for week_start, sessions in sorted(weekly_sessions.items()):
print(f"\nWeek of {week_start}:")
print(f" Sessions: {len(sessions)}")
# Count total sets
total_sets = sum(
len(m.sets)
for s in sessions
for m in s.movements
)
print(f" Total sets: {total_sets}")
API Documentation
For complete API documentation, see the source code in src/ox/:
data.py- Core data structuresparse.py- Parser functionsunits.py- Unit registry configuration