rivalsdata-api 1.2.2__tar.gz → 1.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rivalsdata-api
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: Python client and MCP server for public Marvel Rivals stats from RivalsData
5
5
  Project-URL: Homepage, https://github.com/GS-Rionnag/rivalsdata-api
6
6
  Project-URL: Repository, https://github.com/GS-Rionnag/rivalsdata-api
@@ -116,8 +116,12 @@ the same class response structure.
116
116
 
117
117
  Win rates are `total wins / (total wins + total losses)`, rounded to an integer
118
118
  percent. They are weighted by hero records, rather than averaging hero win
119
- rates. Switching heroes can make one match contribute to multiple records;
120
- these totals describe hero participation, not distinct matches. Empty modes
119
+ rates. The response's `metadata` identifies the source, formula, and requested
120
+ season scope. Upstream hero-switch attribution is unknown; hero records may
121
+ overlap within a match, so these totals cannot establish distinct match counts
122
+ or the player's overall match win rate. All-seasons coverage is limited to
123
+ records returned by the source; complete lifetime coverage is unverified.
124
+ Excluded rows also produce a metadata warning. Empty modes
121
125
  have a `None` win rate. Role mappings were observed on RivalsData on
122
126
  2026-09-30, including Deadpool's separate role IDs; generic Deadpool and unknown
123
127
  IDs are excluded rather than assigned a guessed class.
@@ -80,8 +80,12 @@ the same class response structure.
80
80
 
81
81
  Win rates are `total wins / (total wins + total losses)`, rounded to an integer
82
82
  percent. They are weighted by hero records, rather than averaging hero win
83
- rates. Switching heroes can make one match contribute to multiple records;
84
- these totals describe hero participation, not distinct matches. Empty modes
83
+ rates. The response's `metadata` identifies the source, formula, and requested
84
+ season scope. Upstream hero-switch attribution is unknown; hero records may
85
+ overlap within a match, so these totals cannot establish distinct match counts
86
+ or the player's overall match win rate. All-seasons coverage is limited to
87
+ records returned by the source; complete lifetime coverage is unverified.
88
+ Excluded rows also produce a metadata warning. Empty modes
85
89
  have a `None` win rate. Role mappings were observed on RivalsData on
86
90
  2026-09-30, including Deadpool's separate role IDs; generic Deadpool and unknown
87
91
  IDs are excluded rather than assigned a guessed class.
@@ -65,8 +65,14 @@ omitting the season keeps the endpoint default. `player.stats.heroes` and MCP
65
65
  `get_player_stats` support the same selector. The method also sums
66
66
  MVP/SVP counts when every included row supplies them. Win rate is calculated
67
67
  from summed wins and losses. Unknown classes and incomplete win/loss rows appear
68
- in `excluded`. Hero switching can count a single match in multiple hero records,
69
- so class totals are participation counts rather than distinct matches.
68
+ in `excluded`. The response includes `metadata` with `source`, `counts_basis`,
69
+ `win_rate_formula`, `unique_matches_verified`, `hero_switch_attribution`,
70
+ `season`, `season_scope`, and `warnings`. Numeric seasons have scope `season`,
71
+ `"all"` and `-1` normalize to season/scope `"all"`, and an omitted season has
72
+ scope `endpoint_default` with season `None`. Hero-switch attribution is unknown,
73
+ so summed hero records cannot establish unique match counts or a player's
74
+ overall match win rate. Complete lifetime coverage for all-seasons data is
75
+ unverified. Warnings flag those limitations and any excluded records.
70
76
 
71
77
  The roster at `/stats` on 2026-09-30 identifies Deadpool variants as 10571
72
78
  (tank), 10572 (DPS), and 10573 (support), Daredevil as 1055, and Angela as 1056.
@@ -69,8 +69,12 @@ It sums games, wins, losses, and available MVP/SVP counts separately
69
69
  for competitive and quickplay, with win rates calculated from summed wins and
70
70
  losses. The response has typed `classes` rows and an `excluded` list for unknown
71
71
  roles or incomplete win/loss data. MCP exposes it through `get_player_stats`
72
- with `category="classes"`. Hero switching means totals count participation,
73
- not unique matches. Role IDs and the corrected Angela/Daredevil IDs were
72
+ with `category="classes"`. Response `metadata` describes the source, formula,
73
+ season scope, and limitations. Upstream hero-switch attribution and distinct
74
+ match counts are unverified; do not derive player overall win rate from class
75
+ totals. All-seasons coverage is limited to returned records, with complete
76
+ lifetime coverage unverified. Excluded rows produce a metadata warning.
77
+ Role IDs and the corrected Angela/Daredevil IDs were
74
78
  verified against RivalsData's roster on 2026-09-30; Deadpool has separate role
75
79
  variants (10571/10572/10573), while generic 1057 remains unclassified.
76
80
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rivalsdata-api"
7
- version = "1.2.2"
7
+ version = "1.2.3"
8
8
  description = "Python client and MCP server for public Marvel Rivals stats from RivalsData"
9
9
  keywords = ["marvel-rivals", "rivalsdata", "game-stats", "api-client", "mcp"]
10
10
  readme = "README.md"
@@ -419,7 +419,9 @@ def get_player_stats(
419
419
  """Get player stats: heroes, maps, bans, or calculated classes.
420
420
 
421
421
  Classes sum hero wins/losses by tank/support/dps and game mode; these are
422
- hero participation totals, which can count a match more than once.
422
+ summed hero records, which may overlap within a match. The response metadata
423
+ explains the calculation and scope; class totals cannot establish a player's
424
+ overall match win rate. Upstream hero-switch attribution is unknown.
423
425
  Supply a season ID or "all" for combined all-seasons totals. Omitting the
424
426
  season uses the endpoint default.
425
427
  """
@@ -428,10 +428,11 @@ class ClassStatsRecord(DataModel):
428
428
 
429
429
 
430
430
  class ClassStatsResponse(DataModel):
431
- """Derived class totals and hero/mode rows excluded from calculation."""
431
+ """Derived class totals, excluded rows, and calculation metadata."""
432
432
 
433
433
  classes: list[ClassStatsRecord]
434
434
  excluded: list[DataModel]
435
+ metadata: DataModel
435
436
 
436
437
  def __init__(self, data: Mapping[str, Any] | None = None, **values: Any) -> None:
437
438
  super().__init__(data, **values)
@@ -225,8 +225,10 @@ class PlayerStats(PlayerResource):
225
225
  Supply a season ID or ``season="all"`` for combined all-seasons totals.
226
226
  Omitting ``season`` preserves the endpoint default.
227
227
  Win rate uses total wins / (wins + losses), not the average of hero
228
- percentages. Counts describe hero participation: switching heroes can
229
- cause one match to contribute to multiple hero or class records.
228
+ percentages. Counts are summed upstream hero records. The upstream
229
+ attribution rule for hero switches is unknown, so distinct match
230
+ counts cannot be established from these rows. ``metadata`` describes
231
+ the calculation and requested season scope.
230
232
  Unknown roles and incomplete win/loss rows are listed in ``excluded``.
231
233
  """
232
234
  groups = {
@@ -271,7 +273,34 @@ class PlayerStats(PlayerResource):
271
273
  total = totals["wins"] + totals["losses"]
272
274
  totals["win_rate"] = round(totals["wins"] * 100 / total) if total else None
273
275
  group[mode] = totals
274
- return ClassStatsResponse({"classes": list(groups.values()), "excluded": excluded})
276
+ all_seasons = season in ("all", -1)
277
+ warnings = [
278
+ "Hero records may overlap within a match. Class totals must not "
279
+ "be used to calculate the player's overall match win rate."
280
+ ]
281
+ if all_seasons:
282
+ warnings.append(
283
+ "All-seasons results cover the records returned by the source; "
284
+ "complete lifetime coverage is not verified."
285
+ )
286
+ if excluded:
287
+ warnings.append(
288
+ "Some hero or mode records were excluded; see excluded for details."
289
+ )
290
+ metadata = {
291
+ "source": "/player/stats/heroes",
292
+ "counts_basis": "summed_hero_records",
293
+ "win_rate_formula": "wins / (wins + losses) * 100",
294
+ "unique_matches_verified": False,
295
+ "hero_switch_attribution": "unknown",
296
+ "season": "all" if all_seasons else season,
297
+ "season_scope": "all" if all_seasons else (
298
+ "endpoint_default" if season is None else "season"
299
+ ),
300
+ "warnings": warnings,
301
+ }
302
+ return ClassStatsResponse({"classes": list(groups.values()), "excluded": excluded,
303
+ "metadata": metadata})
275
304
 
276
305
  def maps(self, *, season: int | None = None) -> list[MapRecord]:
277
306
  payload = {"season": season} if season is not None else {}
File without changes