Repository navigation
v3.19.0
✨ Highlights ✨
- Write Support: Added comprehensive write capabilities to kloppy. You can now write data to local files or S3 URIs with automatic support for compression formats (
.gz,.bz2,.xz). This feature is a first step towards implementing the Common Data Format (CDF) exporter (#519), which will allow users to output tracking data in the CDF specification. (#515)
import json
from kloppy import io, statsbomb
# 1. Load StatsBomb data
dataset = statsbomb.load_open_data(match_id="3788741")
# 2. Use the low-level 'open_as_file' with write mode
with io.open_as_file("event_data_export.json.gz", mode="wb") as f:
# Extract just the event names and IDs for this example
data_to_save = [
{"id": event.event_id, "type": event.event_name}
for event in dataset.records[:100]
]
# Serialize to JSON and write to the stream
# The '.gz' extension triggers automatic compression
f.write(json.dumps(data_to_save).encode("utf-8"))- Sportscode Serializer Enhancement: The Sportscode serializer can now handle multiple labels per group. This allows for generating multiple XML elements for a single group by using a list of label values, making serialized data richer and more structured. (#499)
code = Code(
period=period,
timestamp=timedelta(seconds=10),
statistics=[],
ball_owning_team=None,
ball_state=None,
code_id="1",
code="Shot",
end_timestamp=timedelta(seconds=12),
labels={
"Player": "Lionel Messi",
"Action": ["Goal", "Left Foot", "Outside Box"] # Multiple labels for 'Action' group
}
)When serialized, each item in the list becomes its own element while maintaining the same name:
<?xml version='1.0' encoding='utf-8'?>
<file>
<ALL_INSTANCES>
<instance>
<ID>1</ID>
<start>10.0</start>
<end>12.0</end>
<code>Shot</code>
<label>
<group>Player</group>
<text>Lionel Messi</text>
</label>
<label>
<group>Action</group>
<text>Goal</text>
</label>
<label>
<group>Action</group>
<text>Left Foot</text>
</label>
<label>
<group>Action</group>
<text>Outside Box</text>
</label>
</instance>
</ALL_INSTANCES>
</file>- Switch to uv & ruff: We've overhauled our internal tooling, switching from pip to uv for dependency management and adopting ruff for linting and formatting. The development environment setup and CI pipelines are now significantly faster and more reliable. (#487, #517)
⚠️ Breaking Changes
- Changed
only_alivedefault toFalsefor all providers: Previously, theonly_aliveparameter defaulted toTruefor StatsPerform, SecondSpectrum and Skillcorner, meaning that only frames for which the ball was in play were included in the output. This default has now been changed toFalseacross all providers. If your code relies on the old behavior, you should now explicitly passonly_alive=Truewhen loading data. (#556)
🚀 Features
- SkillCorner: Improved the mapping of SkillCorner position IDs to kloppy's internal
PositionTypeenum, adding support for previously missing IDs likeGoalkeeperandLeftBack. (#516) - Metadata Restructuring: Moved coach information from the top-level
Metadataobject to theTeamobject (accessible viateam.coach). For backward compatibility, the oldhome_coachandaway_coachproperties are deprecated but still work. (#520) - Sequence State Builder: Improved the builder to create more logical action sequences by including more events (like goalkeeper pickups and successful interceptions) as sequence starters and correctly handling duels and defensive actions. (#484)
🪲 Fixes
- Tracab: Fixed an issue where player names were being parsed as
StringElementobjects instead of standard Python strings. (#505) - SecondSpectrum: Resolved an issue with JSONL files containing a UTF-8 BOM (Byte Order Mark) by using the
utf-8-sigencoding, ensuring they are parsed correctly. (#522) - Sportec IDSSE: Updated the source for the IDSSE open dataset from Figshare to HuggingFace, as the original Figshare URLs were broken. Also updated the documentation to reflect the dataset's publication status. (#529, #542)
- StatsBomb:
- Fixed two bugs in the coordinate transformation for freeze frames, which prevented correct transformation when no orientation change was needed and caused the ball's coordinates to be transformed twice. (#526)
- Added missing formation mappings, including the 3-2-4-1 formation, to prevent
KeyErrorexceptions when deserializing tactical shift events. (#553, #554)
- HTTP Basic Auth: The configuration for HTTP Basic Auth now accepts both a dictionary and a tuple, making it easier to use. The documentation has also been corrected to reflect the proper
loginandpasswordkeys. (#534) - General:
- Made
end_timestampandend_coordinatesoptional fields forCarryEventandend_timestampoptional forPressureEvent, aligning them with other event classes and preventingTypeErrorexceptions when these fields are missing. (#557) - Added support for XML feeds containing a BOM (Byte Order Mark) by correctly handling the encoding. (#540)
- Fixed an issue in the SkillCorrener adapter where a coordinate value of exactly 0.0 was being handled incorrectly. (#538)
- Made
📚 Documentation
- A brand new and improved Contributor's Guide is now available to help new developers get started. (#488)
- Fixed numerous typos and grammatical errors across the documentation for a smoother reading experience. (#558)
- Corrected typos and an incorrect function call (
load_open_data→load) in the Jupyter notebooks that demonstrate how to load data. (#547)
👷 Refactoring
- Removed the deprecated
to_pandasmethod. (#518) - Refactored dataset filtering and event deserialization logic for better maintainability. (#521)
⚙️ CI/CD
- Switched from
piptouvfor faster and more reliable dependency management. (#487) - Replaced the
blackcode formatter withruff, which is faster and also handles linting. (#517) - Made the release workflow more robust. (#560)
Contributors
This release was made possible by the following contributors:
- @Alek050 made their first contribution in #540
- @cb-jodv made their first contribution in #553
- @DriesDeprest
- @EoinTrial made their first contribution in #547
- @koenvo
- @lode-mgp
- @probberechts
- @stephTchembeu made their first contribution in #513 and #519
- @UnravelSports
Full Changelog: v3.18.0...v3.19.0