From 3a33100dfa681c7fca8a76a2d4c396b9a021f2c1 Mon Sep 17 00:00:00 2001 From: "paperclip-resolver[bot]" <3736210+paperclip-resolver[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:41:22 -0400 Subject: [PATCH] feat: add optional team_side + market_segment to odds/EV/closing models (#76, #689) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OddsLine, EVOpportunity, ClosingOddsLine each gain optional team_side ("home"|"away"|"draw") + market_segment ("full_game","1st_half",...). Surfaces the structured axes the API now emits (sharp-api-go #76 Phase C / #689). Additive, default None. Bump 0.4.0 → 0.4.1. Type: feat Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 13 +++++++++++++ pyproject.toml | 2 +- src/sharpapi/models.py | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7c1cf3..5fecaba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to the `sharpapi` Python SDK are documented here. +## 0.4.1 — 2026-06-02 + +### Added — structured `team_side` + `market_segment` (issue #76 / #689) + +- `OddsLine`, `EVOpportunity`, and `ClosingOddsLine` gain two optional fields: + - `team_side` — the raw structured side (`"home"` | `"away"` | `"draw"`) + decomposed out of the compound `selection_type` vocabulary. Prefer this over + parsing compound prefixes like `"home_over"`. + - `market_segment` — the canonical contest slice (`"full_game"`, `"1st_half"`, + `"1st_5_innings"`, ...). +- Both are additive and default to `None`; existing code is unaffected. The API + continues to emit the compound `selection_type` for back-compat. + ## 0.4.0 — 2026-06-02 ### Changed diff --git a/pyproject.toml b/pyproject.toml index 338d3b8..10df3a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "sharpapi" -version = "0.4.0" +version = "0.4.1" description = "Official Python SDK for the SharpAPI real-time sports betting odds API" readme = "README.md" license = "MIT" diff --git a/src/sharpapi/models.py b/src/sharpapi/models.py index 1cd74bc..13abc6e 100644 --- a/src/sharpapi/models.py +++ b/src/sharpapi/models.py @@ -214,6 +214,12 @@ class OddsLine(BaseModel): market_type: str selection: str selection_type: str | None = None + # Structured side/segment axes (issue #76 / #689). team_side is the raw + # "home"|"away"|"draw" decomposed out of the compound selection_type vocab; + # market_segment is the contest slice ("full_game", "1st_half", ...). Both + # optional + additive — absent on rows the adapter didn't stamp. + team_side: str | None = None + market_segment: str | None = None odds_american: int | float odds_decimal: float probability: float @@ -293,6 +299,9 @@ class EVOpportunity(BaseModel): detected_at: str | None = None external_event_id: str | None = None selection_id: str | None = None + # Structured side/segment axes (issue #76 / #689), additive + optional. + team_side: str | None = None + market_segment: str | None = None # Optional structured refs (additive, non-breaking). home: TeamRef | None = None away: TeamRef | None = None @@ -572,6 +581,9 @@ class ClosingOddsLine(BaseModel): market_type: str selection: str selection_type: str | None = None + # Structured side/segment axes (issue #76 / #689), additive + optional. + team_side: str | None = None + market_segment: str | None = None odds_american: int | float odds_decimal: float line: float | None = None