vlrdevapi 2.0.1__tar.gz → 2.1.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.
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/CHANGELOG.md +34 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/PKG-INFO +1 -1
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/pyproject.toml +1 -1
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/__init__.py +1 -1
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/info/parser.py +2 -3
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/list/models.py +10 -2
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/namespace.py +6 -2
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/stages/parser.py +4 -6
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/teams/__init__.py +2 -1
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/teams/models.py +22 -1
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/teams/namespace.py +4 -2
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/teams/parser.py +30 -3
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/datetime.py +20 -11
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/timezone.py +9 -2
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/uv.lock +241 -229
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.gitattributes +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.github/workflows/docs-check.yml +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.github/workflows/publish.yml +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.github/workflows/test.yml +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.gitignore +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.python-version +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/.readthedocs.yaml +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/CODE_OF_CONDUCT.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/CONTRIBUTING.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/LICENCE +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/README.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/SECURITY.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/SUPPORT.md +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/scripts/check_mdx_examples.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/scripts/download_fixtures.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/__init__.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_base.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_cache.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_client.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/_common.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/info/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/info/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/info/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/info/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/list/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/list/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/list/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/list/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/matches/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/matches/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/matches/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/matches/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/matches/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/stages/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/stages/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/stages/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/stages/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/standings/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/standings/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/standings/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/standings/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/standings/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_event/teams/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/common.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/completed/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/completed/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/completed/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/completed/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/completed/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/live/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/live/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/live/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/live/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/live/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/upcoming/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/upcoming/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/upcoming/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/upcoming/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_matches/upcoming/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/_common_parsing.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/agents/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/agents/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/agents/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/agents/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/agents/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/info/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/info/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/info/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/info/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/info/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/matches/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/matches/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/matches/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/matches/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/matches/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/profile/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/profile/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/profile/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/profile/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/profile/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/teams/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/teams/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/teams/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/teams/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_player/teams/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/economy/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/economy/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/economy/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/economy/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/economy/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/info/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/info/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/info/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/info/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/info/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/match_namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/match_namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/performance/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/performance/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/performance/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/performance/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/performance/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/players/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/players/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/players/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/players/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/players/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/rounds/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/rounds/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/rounds/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/rounds/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/rounds/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/vods/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/vods/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/vods/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/vods/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_series/vods/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/completed_matches/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/completed_matches/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/completed_matches/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/completed_matches/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/completed_matches/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/info/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/info/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/info/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/info/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/info/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/placements/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/placements/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/placements/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/placements/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/placements/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/roster/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/roster/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/roster/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/roster/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/roster/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/stats/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/stats/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/stats/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/stats/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/stats/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/transactions/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/transactions/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/transactions/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/transactions/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/transactions/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/upcoming_matches/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/upcoming_matches/models.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/upcoming_matches/namespace.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/upcoming_matches/namespace.pyi +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_team/upcoming_matches/parser.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_utils/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_utils/pagination.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_utils/paths.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_utils/team_enrichment.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/_utils/team_parsing.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/__init__.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/countries.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/mappings.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/commons/prizes.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/exceptions.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/fetcher.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/py.typed +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/src/vlrdevapi/validators.py +0 -0
- {vlrdevapi-2.0.1 → vlrdevapi-2.1.0}/wrangler.jsonc +0 -0
|
@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Events list dates without a year** — `event.list()` dates are rendered
|
|
13
|
+
on vlr.gg without a year (e.g. `"Jul 9 – Aug 23"`). These now use a
|
|
14
|
+
sentinel year of `2019` instead of the current year. Any parsed date with
|
|
15
|
+
`year < 2020` means the source omitted the year, so guard with
|
|
16
|
+
`event.start_date.year < 2020` before relying on it.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Python 3.13/3.15 date parsing deprecation** — `datetime.strptime` emits
|
|
21
|
+
a `DeprecationWarning` when parsing a day-of-month without a year (and will
|
|
22
|
+
change behavior in Python 3.15). All such parses now supply an explicit
|
|
23
|
+
year derived from context (reference date, page-header year, or the
|
|
24
|
+
sentinel above).
|
|
25
|
+
|
|
26
|
+
## [2.1.0] - 2026-08-07
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Event teams player rosters** — `event.teams()` now includes a `players`
|
|
31
|
+
list on each `Team`, containing each player's `name` and `id` parsed from
|
|
32
|
+
the event page. The `players` field is always present and defaults to `[]`
|
|
33
|
+
when roster data is unavailable. A new `TeamPlayer` model was added and exposed
|
|
34
|
+
from the `_event.teams` submodule.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **Documentation** — event teams reference updated with the new `players`
|
|
39
|
+
field, a `TeamPlayer` fields table, and a roster iteration example.
|
|
40
|
+
|
|
8
41
|
## [2.0.1] - 2026-07-29
|
|
9
42
|
|
|
10
43
|
### Fixed
|
|
@@ -92,5 +125,6 @@ The API surface, module structure, and type system are all new.
|
|
|
92
125
|
- `aiohttp` and `asyncio` dependencies.
|
|
93
126
|
- v1.x match/event/team parsing modules.
|
|
94
127
|
|
|
128
|
+
[2.1.0]: https://github.com/Vanshbordia/vlrdevapi/compare/v2.0.1...v2.1.0
|
|
95
129
|
[2.0.1]: https://github.com/Vanshbordia/vlrdevapi/compare/v2.0.0...v2.0.1
|
|
96
130
|
[2.0.0]: https://github.com/Vanshbordia/vlrdevapi/compare/v1.6.2...v2.0.0
|
|
@@ -288,10 +288,9 @@ def _parse_partial_date(text: str, reference_end: date) -> date | None:
|
|
|
288
288
|
if full_attempt is not None:
|
|
289
289
|
return full_attempt
|
|
290
290
|
|
|
291
|
-
for fmt in ("%b %d", "%B %d"):
|
|
291
|
+
for fmt in ("%b %d %Y", "%B %d %Y"):
|
|
292
292
|
try:
|
|
293
|
-
|
|
294
|
-
return dt.replace(year=reference_end.year).date()
|
|
293
|
+
return datetime.strptime(f"{text} {reference_end.year}", fmt).date()
|
|
295
294
|
except ValueError:
|
|
296
295
|
continue
|
|
297
296
|
|
|
@@ -22,8 +22,16 @@ class EventListItem(BaseModel):
|
|
|
22
22
|
default="upcoming", description="Event status",
|
|
23
23
|
)
|
|
24
24
|
prize: EventPrize | None = Field(default=None, description="Prize information")
|
|
25
|
-
start_date: date | None = Field(
|
|
26
|
-
|
|
25
|
+
start_date: date | None = Field(
|
|
26
|
+
default=None,
|
|
27
|
+
description="Event start date. Year is 2019 when the listing omitted it "
|
|
28
|
+
"(year < 2020 means the year is not present).",
|
|
29
|
+
)
|
|
30
|
+
end_date: date | None = Field(
|
|
31
|
+
default=None,
|
|
32
|
+
description="Event end date. Year is 2019 when the listing omitted it "
|
|
33
|
+
"(year < 2020 means the year is not present).",
|
|
34
|
+
)
|
|
27
35
|
region: str = Field(default="", description="Country or region name from flag")
|
|
28
36
|
image_url: str = Field(default="", description="URL to the event thumbnail image")
|
|
29
37
|
url: str = Field(default="", description="Full URL to the event page on vlr.gg")
|
|
@@ -99,8 +99,10 @@ class EventMatchNamespace:
|
|
|
99
99
|
If ``None``, returns teams for all stages.
|
|
100
100
|
|
|
101
101
|
Returns:
|
|
102
|
-
EventTeams: Teams grouped by stage, with team ``name``, ``
|
|
103
|
-
``
|
|
102
|
+
EventTeams: Teams grouped by stage, with team ``name``, ``id``,
|
|
103
|
+
optional ``note``, and a ``players`` list (each with ``name``
|
|
104
|
+
and ``id``). ``players`` is always present and may be an empty
|
|
105
|
+
list when roster data is unavailable.
|
|
104
106
|
|
|
105
107
|
Raises:
|
|
106
108
|
NotFoundError: If the event page does not exist (HTTP 404).
|
|
@@ -241,6 +243,8 @@ class EventNamespace:
|
|
|
241
243
|
Returns:
|
|
242
244
|
An ``EventTeamsNamespace`` instance. Call with an ``event_id``
|
|
243
245
|
and optional ``stage`` to return an ``EventTeams`` model.
|
|
246
|
+
Each ``Team`` includes a ``players`` roster list that is always
|
|
247
|
+
present and may be empty when roster data is unavailable.
|
|
244
248
|
|
|
245
249
|
"""
|
|
246
250
|
return self._teams
|
|
@@ -189,10 +189,9 @@ def _parse_subnav_single_date(text: str, year: int | None) -> date | None:
|
|
|
189
189
|
return None
|
|
190
190
|
|
|
191
191
|
if year is not None:
|
|
192
|
-
for fmt in ("%b %d", "%B %d"):
|
|
192
|
+
for fmt in ("%b %d %Y", "%B %d %Y"):
|
|
193
193
|
try:
|
|
194
|
-
|
|
195
|
-
return dt.replace(year=year).date()
|
|
194
|
+
return datetime.strptime(f"{text} {year}", fmt).date()
|
|
196
195
|
except ValueError:
|
|
197
196
|
continue
|
|
198
197
|
|
|
@@ -220,10 +219,9 @@ def _parse_subnav_partial_date(text: str, year: int) -> date | None:
|
|
|
220
219
|
if full is not None:
|
|
221
220
|
return full
|
|
222
221
|
|
|
223
|
-
for fmt in ("%b %d", "%B %d"):
|
|
222
|
+
for fmt in ("%b %d %Y", "%B %d %Y"):
|
|
224
223
|
try:
|
|
225
|
-
|
|
226
|
-
return dt.replace(year=year).date()
|
|
224
|
+
return datetime.strptime(f"{text} {year}", fmt).date()
|
|
227
225
|
except ValueError:
|
|
228
226
|
continue
|
|
229
227
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from vlrdevapi._event.teams.models import EventStageTeams, EventTeams
|
|
1
|
+
from vlrdevapi._event.teams.models import EventStageTeams, EventTeams, TeamPlayer
|
|
2
2
|
from vlrdevapi._event.teams.namespace import EventTeamsNamespace
|
|
3
3
|
|
|
4
4
|
__all__ = [
|
|
5
5
|
"EventStageTeams",
|
|
6
6
|
"EventTeams",
|
|
7
|
+
"TeamPlayer",
|
|
7
8
|
"EventTeamsNamespace",
|
|
8
9
|
]
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
from pydantic import BaseModel, ConfigDict, Field
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
class TeamPlayer(BaseModel):
|
|
5
|
+
"""Player information for a team at an event."""
|
|
6
|
+
|
|
7
|
+
model_config = ConfigDict(
|
|
8
|
+
json_schema_extra={"description": "Player information for a team at an event."},
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
id: int = Field(
|
|
12
|
+
default=0,
|
|
13
|
+
description="Player identifier from vlr.gg (e.g., 1311)",
|
|
14
|
+
)
|
|
15
|
+
name: str = Field(
|
|
16
|
+
default="",
|
|
17
|
+
description="Player in-game name (e.g., 'Melser')",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
4
21
|
class Team(BaseModel):
|
|
5
22
|
"""Team information for an event from vlr.gg."""
|
|
6
23
|
|
|
@@ -20,6 +37,10 @@ class Team(BaseModel):
|
|
|
20
37
|
default=None,
|
|
21
38
|
description="Optional note (e.g., 'Partner Team')",
|
|
22
39
|
)
|
|
40
|
+
players: list[TeamPlayer] = Field(
|
|
41
|
+
default_factory=list,
|
|
42
|
+
description="List of players on the team (name and id). Always present; empty when roster data is unavailable.",
|
|
43
|
+
)
|
|
23
44
|
|
|
24
45
|
|
|
25
46
|
class EventStageTeams(BaseModel):
|
|
@@ -60,4 +81,4 @@ class EventTeams(BaseModel):
|
|
|
60
81
|
return iter(self.stages)
|
|
61
82
|
|
|
62
83
|
def __getitem__(self, index):
|
|
63
|
-
return self.stages[index]
|
|
84
|
+
return self.stages[index]
|
|
@@ -43,8 +43,10 @@ class EventTeamsNamespace:
|
|
|
43
43
|
stage: Optional stage name or path to filter by (e.g. 'playoffs').
|
|
44
44
|
|
|
45
45
|
Returns:
|
|
46
|
-
EventTeams: Teams grouped by stage, with team ``name``, ``
|
|
47
|
-
``
|
|
46
|
+
EventTeams: Teams grouped by stage, with team ``name``, ``id``,
|
|
47
|
+
optional ``note``, and a ``players`` list (each with ``name``
|
|
48
|
+
and ``id``). ``players`` is always present and may be an empty
|
|
49
|
+
list when roster data is unavailable.
|
|
48
50
|
|
|
49
51
|
Raises:
|
|
50
52
|
ValidationError: If ``event_id`` is not a valid positive integer.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
1
|
from selectolax.parser import HTMLParser, Node
|
|
3
2
|
|
|
4
|
-
from vlrdevapi._event.teams.models import Team
|
|
3
|
+
from vlrdevapi._event.teams.models import Team, TeamPlayer
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
def parse_subnav(html: HTMLParser) -> list[tuple[str, str]]:
|
|
@@ -70,4 +69,32 @@ def _parse_team_card(card: Node) -> Team | None:
|
|
|
70
69
|
note_el = card.css_first(".event-team-note")
|
|
71
70
|
note = note_el.text(strip=True) if note_el else None
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
players = _parse_players(card)
|
|
73
|
+
|
|
74
|
+
return Team(name=name, id=team_id, note=note, players=players)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _parse_players(card: Node) -> list[TeamPlayer]:
|
|
78
|
+
"""Parse the players listed on a team card."""
|
|
79
|
+
players = []
|
|
80
|
+
for item in card.css(".event-team-players-item"):
|
|
81
|
+
player = _parse_player_item(item)
|
|
82
|
+
if player:
|
|
83
|
+
players.append(player)
|
|
84
|
+
return players
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _parse_player_item(item: Node) -> TeamPlayer | None:
|
|
88
|
+
"""Parse a single player anchor (e.g. /player/1311/melser)."""
|
|
89
|
+
href = item.attributes.get("href", "")
|
|
90
|
+
if not href or "/player/" not in href:
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
id_str = href.split("/player/")[1].split("/")[0]
|
|
95
|
+
player_id = int(id_str)
|
|
96
|
+
except (ValueError, IndexError):
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
name = item.text(strip=True)
|
|
100
|
+
return TeamPlayer(id=player_id, name=name)
|
|
@@ -5,6 +5,12 @@ from zoneinfo import ZoneInfo
|
|
|
5
5
|
|
|
6
6
|
UTC = UTC
|
|
7
7
|
|
|
8
|
+
# Sentinel year used when a vlr.gg page omits the year from a date
|
|
9
|
+
# (e.g. ``"Sep 14"``). Any parsed date with ``year < 2020`` means the
|
|
10
|
+
# source did not specify a year; Valorant launched in 2020, so no real
|
|
11
|
+
# data can carry the sentinel year 2019.
|
|
12
|
+
_UNKNOWN_YEAR = 2019
|
|
13
|
+
|
|
8
14
|
# Fallback when no ``source_tz`` is provided. Prefer passing an explicit
|
|
9
15
|
# timezone from :class:`~vlrdevapi._client.VLRClient` (``source_tz`` or
|
|
10
16
|
# ``auto_detect_tz=True``).
|
|
@@ -108,7 +114,9 @@ def parse_vlr_date_range(text: str) -> tuple[date | None, date | None]:
|
|
|
108
114
|
|
|
109
115
|
Supports en-dash, em-dash, and hyphen as separators. If the right side is
|
|
110
116
|
``"TBD"``, the end date is ``None``. If no separator is found, the same
|
|
111
|
-
date is returned for both start and end.
|
|
117
|
+
date is returned for both start and end. When a side has no year, the
|
|
118
|
+
sentinel year :data:`_UNKNOWN_YEAR` (2019) is used; a parsed date with
|
|
119
|
+
``year < 2020`` means the source omitted the year.
|
|
112
120
|
|
|
113
121
|
Args:
|
|
114
122
|
text: The date range string to parse.
|
|
@@ -154,7 +162,10 @@ def _parse_list_date(text: str) -> date | None:
|
|
|
154
162
|
"""Parse a date string from list/match pages.
|
|
155
163
|
|
|
156
164
|
Tries formats with year (``%b %d, %Y``, etc.) first, then formats
|
|
157
|
-
without year
|
|
165
|
+
without year. When the year is absent, the sentinel year
|
|
166
|
+
:data:`_UNKNOWN_YEAR` (2019) is used to signal that the source did not
|
|
167
|
+
specify a year (any parsed date with ``year < 2020`` means the year is
|
|
168
|
+
unknown).
|
|
158
169
|
|
|
159
170
|
Args:
|
|
160
171
|
text: The date string to parse.
|
|
@@ -176,12 +187,11 @@ def _parse_list_date(text: str) -> date | None:
|
|
|
176
187
|
except ValueError:
|
|
177
188
|
continue
|
|
178
189
|
|
|
179
|
-
# Try formats without year,
|
|
180
|
-
|
|
181
|
-
for fmt in ("%b %d", "%B %d"):
|
|
190
|
+
# Try formats without year; the source omits the year, so use the
|
|
191
|
+
# sentinel year to signal that it is unknown.
|
|
192
|
+
for fmt in ("%b %d %Y", "%B %d %Y"):
|
|
182
193
|
try:
|
|
183
|
-
|
|
184
|
-
return dt.replace(year=current_year).date()
|
|
194
|
+
return datetime.strptime(f"{text} {_UNKNOWN_YEAR}", fmt).date()
|
|
185
195
|
except ValueError:
|
|
186
196
|
continue
|
|
187
197
|
|
|
@@ -207,12 +217,11 @@ def _parse_list_partial_date(text: str, reference: date) -> date | None:
|
|
|
207
217
|
if not text:
|
|
208
218
|
return None
|
|
209
219
|
full = _parse_list_date(text)
|
|
210
|
-
if full is not None:
|
|
220
|
+
if full is not None and full.year != _UNKNOWN_YEAR:
|
|
211
221
|
return full
|
|
212
|
-
for fmt in ("%b %d", "%B %d"):
|
|
222
|
+
for fmt in ("%b %d %Y", "%B %d %Y"):
|
|
213
223
|
try:
|
|
214
|
-
|
|
215
|
-
return dt.replace(year=reference.year).date()
|
|
224
|
+
return datetime.strptime(f"{text} {reference.year}", fmt).date()
|
|
216
225
|
except ValueError:
|
|
217
226
|
continue
|
|
218
227
|
return None
|
|
@@ -242,7 +242,7 @@ def _detect_from_offset(
|
|
|
242
242
|
except ValueError:
|
|
243
243
|
return None
|
|
244
244
|
|
|
245
|
-
date_formats = ("%A, %B %d
|
|
245
|
+
date_formats = ("%A, %B %d, %Y", "%B %d, %Y", "%b %d, %Y")
|
|
246
246
|
local_date = None
|
|
247
247
|
for fmt in date_formats:
|
|
248
248
|
try:
|
|
@@ -251,7 +251,14 @@ def _detect_from_offset(
|
|
|
251
251
|
except ValueError:
|
|
252
252
|
continue
|
|
253
253
|
if local_date is None:
|
|
254
|
-
|
|
254
|
+
try:
|
|
255
|
+
# Weekday-only format with no year; the reference timestamp
|
|
256
|
+
# provides the canonical year.
|
|
257
|
+
local_date = datetime.strptime(
|
|
258
|
+
f"{displayed_date.strip()} {canonical.year}", "%A, %B %d %Y"
|
|
259
|
+
).date()
|
|
260
|
+
except ValueError:
|
|
261
|
+
local_date = canonical.date()
|
|
255
262
|
else:
|
|
256
263
|
local_date = local_date.replace(year=canonical.year)
|
|
257
264
|
|