A Python module for parsing and manipulating LiveSplit .lss files
Project description
LiveSplit LSS File Parser
A comprehensive Python module for parsing and manipulating LiveSplit .lss files. This module converts XML-based LSS files into easy-to-use Python objects, allowing for programmatic analysis and manipulation of speedrun data.
Features
- Complete LSS File Support: Parse all elements of LSS files including metadata, attempts, segments, and timing data
- Pydantic-Based Models: Robust data validation and serialization using Pydantic BaseModel
- Bidirectional Conversion: Load LSS files into Python objects and save them back to LSS format
- Type Safety: Full type annotations with automatic validation for better IDE support and code reliability
- JSON Serialization: Built-in support for JSON export/import via Pydantic
- Data Validation: Automatic type conversion and validation (e.g., integers to strings where needed)
- Comprehensive API: Simple interface with just two main functions:
load_lss_file()andsave_lss_file()
Installation
This module requires Pydantic. Install dependencies:
pip install pydantic
Then copy the lss_parser.py file to your project directory or install it as a module.
import lss_parser
Quick Start
Loading an LSS File
import lss_parser
# Load a LiveSplit file
run = lss_parser.load_lss_file("my_speedrun.lss")
# Access basic information
print(f"Game: {run.game_name}")
print(f"Category: {run.category_name}")
print(f"Total Attempts: {run.attempt_count}")
print(f"Number of Segments: {len(run.segments)}")
Saving an LSS File
# Modify the run data
run.game_name = "Modified Game Name"
run.category_name = "Any% Modified"
# Save the modified run
lss_parser.save_lss_file(run, "modified_speedrun.lss")
Data Structure
The module provides several Pydantic models to represent LSS file structure:
Run - Main Container
game_name: Name of the gamecategory_name: Speedrun categoryversion: LSS file versionattempt_count: Total number of attemptssegments: List of segments (splits)attempt_history: List of all attemptsmetadata: Platform, region, and other metadataauto_splitter_settings: Auto-splitter configuration
Segment - Individual Splits
name: Segment nameicon: Icon path/datasplit_times: List of split times with different timing methodsbest_segment_time: Best time for this segmentsegment_history: Historical times for this segment
Attempt - Run Attempts
id: Unique attempt identifierstarted: Start time/dateended: End time/datetime: Timing data (real time, game time, pause time)
Time - Timing Information
real_time: Real world timegame_time: In-game timepause_time: Paused time
Pydantic Features
The module leverages Pydantic's powerful features:
Data Validation
import lss_parser
# Automatic type conversion
time = lss_parser.Time(real_time=123) # Converts to "123"
print(time.real_time) # "123"
# Validation on assignment
run = lss_parser.Run(game_name="Test Game")
run.attempt_count = "42" # Automatically converted to int
JSON Serialization
# Export to JSON
run = lss_parser.load_lss_file("speedrun.lss")
run_dict = run.model_dump() # or run.dict() for older Pydantic versions
# Import from JSON
run_data = {...} # JSON data
run = lss_parser.Run(**run_data)
Type Safety
# IDE support with type hints
def analyze_run(run: lss_parser.Run) -> None:
for segment in run.segments: # Full IDE autocomplete
print(f"Segment: {segment.name}")
print(f"Best time: {segment.best_segment_time.real_time}")
Usage Examples
Analyzing Speedrun Data
import lss_parser
# Load the file
run = lss_parser.load_lss_file("my_speedrun.lss")
# Find completed attempts
completed_attempts = [a for a in run.attempt_history if a.time.real_time]
print(f"Completed {len(completed_attempts)} out of {len(run.attempt_history)} attempts")
# Analyze segment times
for segment in run.segments:
print(f"{segment.name}: Best {segment.best_segment_time.real_time or 'N/A'}")
# Get personal best
pb_attempts = [a for a in completed_attempts if a.time.real_time]
if pb_attempts:
best_time = min(pb_attempts, key=lambda x: x.time.real_time)
print(f"Personal Best: {best_time.time.real_time}")
Creating a New Run
import lss_parser
# Create a new run
new_run = lss_parser.Run(
game_name="My Game",
category_name="Any%"
)
# Add segments
segments = [
lss_parser.Segment(
name="Level 1",
best_segment_time=lss_parser.Time(real_time="00:01:30.0000000")
),
lss_parser.Segment(
name="Level 2",
best_segment_time=lss_parser.Time(real_time="00:02:15.0000000")
),
lss_parser.Segment(
name="Boss",
best_segment_time=lss_parser.Time(real_time="00:03:45.0000000")
)
]
new_run.segments = segments
# Add metadata
new_run.metadata.platform = "PC"
new_run.metadata.region = "USA"
# Save the new run
lss_parser.save_lss_file(new_run, "new_speedrun.lss")
Modifying Existing Data
import lss_parser
# Load existing file
run = lss_parser.load_lss_file("existing_run.lss")
# Modify segment names
for segment in run.segments:
segment.name = f"Modified {segment.name}"
# Add a new segment
new_segment = lss_parser.Segment(
name="New Final Boss",
best_segment_time=lss_parser.Time(real_time="00:05:00.0000000")
)
run.segments.append(new_segment)
# Update attempt count
run.attempt_count = len(run.attempt_history)
# Save changes
lss_parser.save_lss_file(run, "modified_run.lss")
API Reference
Main Functions
load_lss_file(file_path: Union[str, Path]) -> Run
Loads and parses an LSS file into a Run object.
Parameters:
file_path: Path to the .lss file
Returns:
Runobject containing all parsed data
Raises:
FileNotFoundError: If the file doesn't existValueError: If the file is not a valid LSS filexml.etree.ElementTree.ParseError: If the XML is malformed
save_lss_file(run: Run, file_path: Union[str, Path]) -> None
Saves a Run object to an LSS file.
Parameters:
run: Run object to savefile_path: Path where to save the .lss file
Raises:
ValueError: If the file path is invalid
Data Models
All data models are implemented using Pydantic's BaseModel and include:
- Type annotations with automatic validation
- Default values where appropriate
- Automatic data conversion and validation
- JSON serialization/deserialization support
- IDE support with full type hints
Error Handling
The module includes comprehensive error handling:
import lss_parser
try:
run = lss_parser.load_lss_file("nonexistent.lss")
except FileNotFoundError:
print("File not found!")
except ValueError as e:
print(f"Invalid file: {e}")
except Exception as e:
print(f"Parse error: {e}")
Testing
The module includes comprehensive tests. Run them with:
python test_parser.py
Demo
See demo.py for a comprehensive demonstration of all features:
python demo.py
File Format Support
This parser supports LiveSplit LSS files version 1.7.0 and should be compatible with other versions. The parser handles:
- Game metadata (name, category, platform, region)
- Attempt history with timestamps and timing data
- Segment information with split times and history
- Auto-splitter settings
- Custom variables and platform-specific data
License
This module is provided as-is for educational and personal use. It is not affiliated with LiveSplit or the LiveSplit development team.
Contributing
This is a complete, self-contained module designed for parsing LSS files. Feel free to extend it for your specific needs.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lss_parser-0.1.0.tar.gz.
File metadata
- Download URL: lss_parser-0.1.0.tar.gz
- Upload date:
- Size: 57.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e8f46f1aa320a753db62f3d83cef399acde8de16ccda5f73b562ecf92f7b250
|
|
| MD5 |
c6c080ec127d23f2e0b7ed51f5c546f2
|
|
| BLAKE2b-256 |
95c56204b158364ecb31d324d769cad25983ff4ac451f0d4bddcb55913c560e3
|
File details
Details for the file lss_parser-0.1.0-py3-none-any.whl.
File metadata
- Download URL: lss_parser-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b9581410111356ef63347bfb9dc6c157eff5a22a4274224be86e2aef87d6e9c
|
|
| MD5 |
bb3050f455dee8f7e0d989dc3b5ebece
|
|
| BLAKE2b-256 |
63bd01694fb41b065103663b2f5d78fdc4304db82e65e6ffa7bcce9835d98b50
|