fix(models): flatten MiddleSide to the wire; alias confidence; add quality_tier - #20
Merged
Conversation
…ality_tier MiddleSide declared a required `odds: OddsValue`. The wire sends odds flat, so client.middles() raised ValidationError on every response carrying a side. EVOpportunity.confidence_score had no alias for the wire's `confidence`, so it silently read None on every row. Added quality_tier (shipped 2026-07-14). Also syncs __version__ 0.4.0 -> 0.4.1; #13 bumped pyproject and missed it, so published 0.4.1 reports __version__ == 0.4.0. Adds tests/test_wire_contract.py pinning all of it against captured live payloads. Fixes #18 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The workflow is named "Tests" and has never run one — it installed ruff and pyright, linted and type-checked tests/, and stopped there. tests/test_base_url.py has existed since 0.3.x without ever executing in CI. #18 asks for a fixture round-trip 'so model drift fails CI'. That only works if the suite runs. Also fixes the pyright failure this PR surfaced: 'import pytest could not be resolved', because the test extra was never installed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18.
The two defects, reproduced against live payloads
client.middles()could not parse any successful response.confidence_scorereadNoneon every row.One correction to the issue
#18 says the wire sends
sportsbookrather thanbook. It doesn't — live sides sendbook, which the model already accepted. The only field that broke parsing was the nestedodds. Changingbookon that report would have introduced a bug rather than fixed one.Live side shape, all 12 fields present on 4/4 sampled sides:
Choices worth flagging
confidence_scoreis aliased, not renamed.AliasChoices("confidence", "confidence_score")matches the file's existing idiom (fair_probability/true_probability,sharp_book/devig_book) and keeps the public attribute name, so nobody's code breaks.MiddleSideis a hard shape change —side.odds.americanbecomesside.odds_american. Normally breaking; here it cannot be, because the model never parsed a response, so no working consumer exists to break.Bonus defect found while checking the release path
pyproject.toml=0.4.1,__init__.py=0.4.0. #13 bumped one and missed the other, and 0.4.1 is already on PyPI — so the published package reportssharpapi.__version__ == "0.4.0". PyPI is immutable, so that stays wrong for 0.4.1 forever; the test here only stops the next one. Synced to 0.4.1 (matching what is published), which is a correction, not a release bump.Tests — 9 new, all against captured live payloads
tests/test_wire_contract.py+tests/fixtures/{middles,ev}_live.json. Hand-written dicts could never have caught this: they'd be written from the same wrong belief as the model.Two notes on what is deliberately not asserted, both discovered by writing the check and watching it misfire:
sharp_odds_american,is_suspendedand the*_refobjects, all legitimately conditional.importlib.metadata.version()for the version check — replaced with a direct read ofpyproject.toml. Dist metadata is only as fresh as the lastpip install; the editable install on the dev box reports0.2.0, so that test would have passed in CI and failed locally for a reason unrelated to the bug.Run locally with
PYTHONPATH=src— the editable install resolves to the canonical checkout, not a worktree.Release
Not bumping the release version — this repo lands those as separate
chore(release):commits, and PyPI needs agh release createto publish. This fix should land before the docs audit's Wave 1, since the docs mirror these model shapes and the SDK is the source they follow.Type: fix