zpdatafetch 2.3.2__tar.gz → 2.4.0__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.
Files changed (85) hide show
  1. {zpdatafetch-2.3.2/src/zpdatafetch.egg-info → zpdatafetch-2.4.0}/PKG-INFO +21 -3
  2. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/README.md +20 -2
  3. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/pyproject.toml +1 -1
  4. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/cli.py +80 -1
  5. zpdatafetch-2.4.0/src/zpdatafetch/zpleague.py +1153 -0
  6. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpleaguefetch.py +248 -47
  7. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0/src/zpdatafetch.egg-info}/PKG-INFO +21 -3
  8. zpdatafetch-2.3.2/src/zpdatafetch/zpleague.py +0 -496
  9. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/LICENSE +0 -0
  10. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/setup.cfg +0 -0
  11. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/__init__.py +0 -0
  12. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/cli.py +0 -0
  13. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/config.py +0 -0
  14. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/error_helpers.py +0 -0
  15. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/exceptions.py +0 -0
  16. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/http_client.py +0 -0
  17. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/json_helpers.py +0 -0
  18. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/logging.py +0 -0
  19. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/shared/validation.py +0 -0
  20. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/__init__.py +0 -0
  21. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/activity.py +0 -0
  22. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/auth.py +0 -0
  23. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/cli.py +0 -0
  24. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/config.py +0 -0
  25. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/followers.py +0 -0
  26. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/logging_config.py +0 -0
  27. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/profile.py +0 -0
  28. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/rideons.py +0 -0
  29. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/ridersinworld.py +0 -0
  30. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zdatafetch/worlds.py +0 -0
  31. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/__init__.py +0 -0
  32. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/async_zp.py +0 -0
  33. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/config.py +0 -0
  34. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/logging_config.py +0 -0
  35. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zp.py +0 -0
  36. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zp_obj.py +0 -0
  37. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zp_utils.py +0 -0
  38. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpcyclist.py +0 -0
  39. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpcyclistfetch.py +0 -0
  40. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpprime.py +0 -0
  41. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpprimesfetch.py +0 -0
  42. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpracefinish.py +0 -0
  43. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpracelog.py +0 -0
  44. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpraceresult.py +0 -0
  45. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpracesignup.py +0 -0
  46. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpracesprint.py +0 -0
  47. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpresultfetch.py +0 -0
  48. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpsignupfetch.py +0 -0
  49. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpsprintsfetch.py +0 -0
  50. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpteam.py +0 -0
  51. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch/zpteamfetch.py +0 -0
  52. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch.egg-info/SOURCES.txt +0 -0
  53. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch.egg-info/dependency_links.txt +0 -0
  54. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch.egg-info/entry_points.txt +0 -0
  55. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch.egg-info/requires.txt +0 -0
  56. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zpdatafetch.egg-info/top_level.txt +0 -0
  57. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/__init__.py +0 -0
  58. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/async_zr.py +0 -0
  59. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/cli.py +0 -0
  60. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/config.py +0 -0
  61. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/logging_config.py +0 -0
  62. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/rate_limiter.py +0 -0
  63. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zr.py +0 -0
  64. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zr_utils.py +0 -0
  65. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrraceresult.py +0 -0
  66. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrresultfetch.py +0 -0
  67. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrrider.py +0 -0
  68. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrriderfetch.py +0 -0
  69. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrteamfetch.py +0 -0
  70. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zrdatafetch/zrteamroster.py +0 -0
  71. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/__init__.py +0 -0
  72. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/async_zs.py +0 -0
  73. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/cli.py +0 -0
  74. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/logging_config.py +0 -0
  75. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/__init__.py +0 -0
  76. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/component.py +0 -0
  77. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/incident.py +0 -0
  78. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/maintenance.py +0 -0
  79. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/page.py +0 -0
  80. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/status.py +0 -0
  81. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/models/summary.py +0 -0
  82. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/zs.py +0 -0
  83. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/zsincidentfetch.py +0 -0
  84. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/zsmaintenancefetch.py +0 -0
  85. {zpdatafetch-2.3.2 → zpdatafetch-2.4.0}/src/zsdatafetch/zssummaryfetch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zpdatafetch
3
- Version: 2.3.2
3
+ Version: 2.4.0
4
4
  Summary: A package for fetching data from Zwiftpower and Zwiftracing.app
5
5
  Author-email: Doug Morris <doug@mhost.com>
6
6
  License-Expression: MIT
@@ -77,7 +77,7 @@ required).
77
77
  - **Primes** - Prime results for Fastest Through Segment (FTS) and First Across the Line (FAL)
78
78
  - **Sprints** - Sprint data including sprint details and positions
79
79
  - **Team data** - Team rosters and member information
80
- - **League data** - League standings and Zwift Racing Score (ZRS) information
80
+ - **League data** - League standings, events, team standings, and league metadata (name, categories, contact)
81
81
 
82
82
  ### For zrdata (Zwiftracing)
83
83
 
@@ -312,7 +312,25 @@ available classes are as follows:
312
312
  - Signup: fetch signups for a particular event by event id
313
313
  - Sprints: fetch sprints from one or more races using event id
314
314
  - Team: fetch team data by team id
315
- - League: fetch league standings by league id
315
+ - League: fetch league standings, events, team standings, team-event results and metadata by league id
316
+
317
+ **League data example:**
318
+
319
+ ```python
320
+ from zpdatafetch import ZPLeagueFetch
321
+
322
+ lf = ZPLeagueFetch()
323
+ league = lf.fetch(3379)[3379]
324
+
325
+ league.info() # ZPLeagueInfo: name, contact, categories, ...
326
+ league.events() # list[ZPLeagueEvent]: event_id, title, start_datetime
327
+ league.team_standings() # list[ZPLeagueTeamStanding]
328
+ league.team_event_results() # list[ZPLeagueTeamEventResult]
329
+ print(league.json()) # all collections as JSON (keys omitted when empty)
330
+ ```
331
+
332
+ Each source is fetched independently: a league without a standings file (e.g.
333
+ 3388) still returns its events and metadata, and vice versa.
316
334
 
317
335
  ## Zwiftracing Data (zrdata)
318
336
 
@@ -48,7 +48,7 @@ required).
48
48
  - **Primes** - Prime results for Fastest Through Segment (FTS) and First Across the Line (FAL)
49
49
  - **Sprints** - Sprint data including sprint details and positions
50
50
  - **Team data** - Team rosters and member information
51
- - **League data** - League standings and Zwift Racing Score (ZRS) information
51
+ - **League data** - League standings, events, team standings, and league metadata (name, categories, contact)
52
52
 
53
53
  ### For zrdata (Zwiftracing)
54
54
 
@@ -283,7 +283,25 @@ available classes are as follows:
283
283
  - Signup: fetch signups for a particular event by event id
284
284
  - Sprints: fetch sprints from one or more races using event id
285
285
  - Team: fetch team data by team id
286
- - League: fetch league standings by league id
286
+ - League: fetch league standings, events, team standings, team-event results and metadata by league id
287
+
288
+ **League data example:**
289
+
290
+ ```python
291
+ from zpdatafetch import ZPLeagueFetch
292
+
293
+ lf = ZPLeagueFetch()
294
+ league = lf.fetch(3379)[3379]
295
+
296
+ league.info() # ZPLeagueInfo: name, contact, categories, ...
297
+ league.events() # list[ZPLeagueEvent]: event_id, title, start_datetime
298
+ league.team_standings() # list[ZPLeagueTeamStanding]
299
+ league.team_event_results() # list[ZPLeagueTeamEventResult]
300
+ print(league.json()) # all collections as JSON (keys omitted when empty)
301
+ ```
302
+
303
+ Each source is fetched independently: a league without a standings file (e.g.
304
+ 3388) still returns its events and metadata, and vice versa.
287
305
 
288
306
  ## Zwiftracing Data (zrdata)
289
307
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "zpdatafetch"
3
- version = "2.3.2"
3
+ version = "2.4.0"
4
4
  description = "A package for fetching data from Zwiftpower and Zwiftracing.app"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -32,6 +32,35 @@ from zpdatafetch import (
32
32
  from zpdatafetch.logging_config import setup_logging
33
33
 
34
34
 
35
+ # ==============================================================================
36
+ def _league_raw_sources(obj: object) -> list[tuple[int, str, str]]:
37
+ """Return (league_id, source_label, raw_text) for a league fetch.
38
+
39
+ Empty for non-league fetches. Lets `--raw` print every fetched league
40
+ source instead of only the standings raw text.
41
+
42
+ Args:
43
+ obj: A fetched data object
44
+
45
+ Returns:
46
+ List of tuples, one per available source per league
47
+ """
48
+ if not hasattr(obj, '_events_raw'):
49
+ return []
50
+ sources = (
51
+ ('standings', getattr(obj, '_raw', {})),
52
+ ('team_standings', getattr(obj, '_team_standings_raw', {})),
53
+ ('team_event_results', getattr(obj, '_team_event_results_raw', {})),
54
+ ('events', getattr(obj, '_events_raw', {})),
55
+ )
56
+ out: list[tuple[int, str, str]] = []
57
+ for lid in getattr(obj, '_fetched', {}):
58
+ for label, raws in sources:
59
+ if isinstance(raws, dict) and lid in raws:
60
+ out.append((lid, label, raws[lid]))
61
+ return out
62
+
63
+
35
64
  # ==============================================================================
36
65
  def main() -> int | None:
37
66
  """Main entry point for the zpdatafetch CLI.
@@ -292,7 +321,12 @@ Module for fetching zwiftpower data using the Zwifpower API
292
321
 
293
322
  if args.raw:
294
323
  # Output raw response text
295
- if len(x._raw) == 1:
324
+ league_raw_sources = _league_raw_sources(x)
325
+ if league_raw_sources:
326
+ # League: print the raw text of every source that was fetched
327
+ for lid, label, raw_text in league_raw_sources:
328
+ print(f'{lid} {label}: {raw_text}')
329
+ elif len(x._raw) == 1:
296
330
  # Single ID: print just the raw string
297
331
  print(list(x._raw.values())[0])
298
332
  else:
@@ -358,6 +392,30 @@ Module for fetching zwiftpower data using the Zwifpower API
358
392
  except (TypeError, AttributeError):
359
393
  pass
360
394
 
395
+ # Nested collections on structured objects (e.g. ZPLeague)
396
+ nested: list[Any] = []
397
+ if hasattr(value, 'info'):
398
+ nested_info = getattr(value, 'info')()
399
+ if nested_info is not None:
400
+ nested.append(nested_info)
401
+ for accessor in ('team_standings', 'team_event_results', 'events'):
402
+ if hasattr(value, accessor):
403
+ nested.extend(getattr(value, accessor)())
404
+
405
+ for nested_item in nested:
406
+ if args.excluded and hasattr(nested_item, 'excluded'):
407
+ nested_excluded = nested_item.excluded()
408
+ if nested_excluded:
409
+ print(f' {nested_item!r}')
410
+ print(f' excluded: {nested_excluded}')
411
+ has_excluded = True
412
+ if args.extras and hasattr(nested_item, 'extras'):
413
+ nested_extras = nested_item.extras()
414
+ if nested_extras:
415
+ print(f' {nested_item!r}')
416
+ print(f' extras: {nested_extras}')
417
+ has_extras = True
418
+
361
419
  # Show appropriate "no data" messages for each requested flag
362
420
  if args.excluded and not has_excluded:
363
421
  print(' No excluded')
@@ -407,6 +465,27 @@ Module for fetching zwiftpower data using the Zwifpower API
407
465
  # Not a collection, print on same line
408
466
  print(f' {value!r}')
409
467
 
468
+ # Structured objects (e.g. ZPLeague) with nested collections that are
469
+ # not part of their Sequence iteration.
470
+ league_info = (
471
+ getattr(value, 'info')() if hasattr(value, 'info') else None
472
+ )
473
+ if league_info is not None:
474
+ print(f' league_info: {league_info!r}')
475
+ for label, accessor in (
476
+ ('team_standings', 'team_standings'),
477
+ ('team_event_results', 'team_event_results'),
478
+ ('events', 'events'),
479
+ ):
480
+ if not hasattr(value, accessor):
481
+ continue
482
+ nested_items = getattr(value, accessor)()
483
+ if not nested_items:
484
+ continue
485
+ print(f' {label}:')
486
+ for nested_item in nested_items:
487
+ print_collection(nested_item, indent=2)
488
+
410
489
  return None
411
490
 
412
491