python-xbox 0.1.0rc4__tar.gz → 0.1.1__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 (65) hide show
  1. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/.gitignore +2 -0
  2. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/PKG-INFO +32 -32
  3. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/README.md +27 -26
  4. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/pyproject.toml +18 -10
  5. python_xbox-0.1.1/src/pythonxbox/__init__.py +4 -0
  6. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/client.py +2 -3
  7. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/account/__init__.py +4 -2
  8. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/achievements/__init__.py +11 -9
  9. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/baseprovider.py +0 -1
  10. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/catalog/__init__.py +4 -4
  11. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/catalog/models.py +4 -4
  12. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/cqs/__init__.py +6 -4
  13. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/gameclips/__init__.py +21 -11
  14. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/lists/__init__.py +9 -4
  15. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/mediahub/__init__.py +5 -3
  16. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/message/__init__.py +16 -9
  17. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/people/__init__.py +12 -11
  18. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/presence/__init__.py +14 -6
  19. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/presence/models.py +4 -3
  20. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/profile/__init__.py +7 -5
  21. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/profile/models.py +2 -2
  22. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/ratelimitedprovider.py +6 -6
  23. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/screenshots/__init__.py +21 -11
  24. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/smartglass/__init__.py +8 -8
  25. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/smartglass/models.py +9 -9
  26. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/titlehub/__init__.py +4 -3
  27. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/titlehub/models.py +2 -2
  28. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/usersearch/__init__.py +4 -2
  29. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/userstats/__init__.py +13 -9
  30. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/userstats/models.py +5 -5
  31. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/authentication/manager.py +19 -23
  32. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/authentication/models.py +3 -2
  33. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/authentication/xal.py +13 -13
  34. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/exceptions.py +3 -1
  35. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/filetimes.py +2 -3
  36. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/models.py +6 -14
  37. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/ratelimits/__init__.py +12 -15
  38. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/ratelimits/models.py +1 -0
  39. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/request_signer.py +12 -11
  40. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/change_gamertag.py +4 -2
  41. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/xal.py +1 -2
  42. python_xbox-0.1.0rc4/src/pythonxbox/__init__.py +0 -4
  43. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/LICENSE +0 -0
  44. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/__init__.py +0 -0
  45. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/language.py +0 -0
  46. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/__init__.py +0 -0
  47. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/account/models.py +0 -0
  48. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/achievements/models.py +0 -0
  49. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/catalog/const.py +0 -0
  50. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/cqs/models.py +0 -0
  51. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/gameclips/models.py +0 -0
  52. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/lists/models.py +0 -0
  53. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/mediahub/models.py +0 -0
  54. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/message/models.py +0 -0
  55. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/people/models.py +0 -0
  56. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/screenshots/models.py +0 -0
  57. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/api/provider/usersearch/models.py +0 -0
  58. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/authentication/__init__.py +0 -0
  59. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/__init__.py +0 -0
  60. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/common/signed_session.py +0 -0
  61. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/py.typed +0 -0
  62. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/__init__.py +0 -0
  63. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/authenticate.py +0 -0
  64. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/friends.py +0 -0
  65. {python_xbox-0.1.0rc4 → python_xbox-0.1.1}/src/pythonxbox/scripts/search.py +0 -0
@@ -74,3 +74,5 @@ target/
74
74
  # Node
75
75
  node_modules
76
76
 
77
+ # mkdocs site
78
+ site/
@@ -1,9 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-xbox
3
- Version: 0.1.0rc4
3
+ Version: 0.1.1
4
4
  Summary: A library to authenticate with Xbox Network and use their API
5
5
  Project-URL: Source, https://github.com/tr4nt0r/python-xbox
6
- Author: OpenXbox
7
6
  Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>
8
7
  License-Expression: MIT
9
8
  License-File: LICENSE
@@ -19,22 +18,23 @@ Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Programming Language :: Python :: 3.14
20
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
20
  Requires-Python: >=3.11
22
- Requires-Dist: ecdsa
23
- Requires-Dist: httpx
24
- Requires-Dist: ms-cv
25
- Requires-Dist: pydantic==2.*
21
+ Requires-Dist: ecdsa>=0.19
22
+ Requires-Dist: httpx>=0.25.1
23
+ Requires-Dist: ms-cv>=0.1.1
24
+ Requires-Dist: pydantic>=2.12
26
25
  Provides-Extra: cli
27
26
  Requires-Dist: platformdirs>=4.5.0; extra == 'cli'
28
27
  Description-Content-Type: text/markdown
29
28
 
30
- # Xbox-WebAPI
29
+ # python-xbox
31
30
 
32
- [![PyPi - latest](https://img.shields.io/pypi/v/xbox-webapi.svg)](https://pypi.python.org/pypi/xbox-webapi/)
33
- [![Documentation status](https://readthedocs.org/projects/xbox-webapi-python/badge/?version=latest)](http://xbox-webapi-python.readthedocs.io/en/latest/?badge=latest)
34
- [![Build status](https://img.shields.io/github/actions/workflow/status/OpenXbox/xbox-webapi-python/build.yml?branch=master)](https://github.com/OpenXbox/xbox-webapi-python/actions?query=workflow%3Abuild)
35
- [![Discord chat channel](https://img.shields.io/badge/discord-OpenXbox-blue.svg)](https://openxbox.org/discord)
31
+ [![PyPi - latest](https://img.shields.io/pypi/v/python-xbox.svg)](https://pypi.python.org/pypi/python-xbox/)
32
+ [![Build](https://github.com/tr4nt0r/python-xbox/actions/workflows/build.yml/badge.svg)](https://github.com/tr4nt0r/python-xbox/actions/workflows/build.yml)
33
+ ![PyPI - Downloads](https://img.shields.io/pypi/dm/python-xbox?style=flat&label=pypi%20downloads)
34
+ [!["Buy Me A Coffee"](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://www.buymeacoffee.com/tr4nt0r)
35
+ [![GitHub Sponsor](https://img.shields.io/badge/GitHub-Sponsor-blue?logo=github)](https://github.com/sponsors/tr4nt0r)
36
36
 
37
- Xbox-WebAPI is a python library to authenticate with Xbox Live via your Microsoft Account and provides Xbox related Web-API.
37
+ python-xbox is a python library to authenticate with Xbox Network via your Microsoft Account and provides Xbox related Web-API.
38
38
 
39
39
  Authentication is supported via OAuth2.
40
40
 
@@ -48,21 +48,22 @@ Authentication is supported via OAuth2.
48
48
 
49
49
  ## Dependencies
50
50
 
51
- - Python >= 3.8
51
+ - Python >= 3.11
52
52
 
53
53
  ## How to use
54
54
 
55
- Install
55
+ ### Install
56
56
 
57
- ```text
58
- pip install xbox-webapi
57
+ ```bash
58
+ pip install python-xbox
59
59
  ```
60
60
 
61
- Authentication
61
+ ### Authentication
62
62
 
63
- **Note: You must use non child account (> 18 years old)**
63
+ > [!NOTE]
64
+ > You must use non child account (> 18 years old)
64
65
 
65
- Token save location: If tokenfile is not provided via cmdline, fallback of `<appdirs.user_data_dir>/tokens.json` is used as save-location
66
+ Token save location: If tokenfile is not provided via cmdline, fallback of `<platformdirs.user_data_dir>/tokens.json` is used as save-location
66
67
 
67
68
  Specifically:
68
69
 
@@ -72,32 +73,32 @@ Mac OSX: `/Users/<username>/Library/Application Support/xbox/tokens.json`
72
73
 
73
74
  Linux: `/home/<username>/.local/share/xbox`
74
75
 
75
- For more information, see: <https://pypi.org/project/appdirs> and module: `xbox.webapi.scripts.constants`
76
+ For more information, see: <https://pypi.org/project/platformdirs> and module: `python-xbox.scripts.constants`
76
77
 
77
- ```
78
+ ```bash
78
79
  xbox-authenticate --client-id <client-id> --client-secret <client-secret>
79
80
  ```
80
81
 
81
82
  Example: Search Xbox Live via cmdline tool
82
83
 
83
- ```text
84
+ ```bash
84
85
  # Search Xbox One Catalog
85
86
  xbox-searchlive "Some game title"
86
87
  ```
87
88
 
88
89
  API usage
89
90
 
90
- ```py
91
+ ```python
91
92
  import asyncio
92
93
  import sys
93
94
 
94
95
  from httpx import HTTPStatusError
95
96
 
96
- from xbox.webapi.api.client import XboxLiveClient
97
- from xbox.webapi.authentication.manager import AuthenticationManager
98
- from xbox.webapi.authentication.models import OAuth2TokenResponse
99
- from xbox.webapi.common.signed_session import SignedSession
100
- from xbox.webapi.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
97
+ from pythonxbox.api.client import XboxLiveClient
98
+ from pythonxbox.authentication.manager import AuthenticationManager
99
+ from pythonxbox.authentication.models import OAuth2TokenResponse
100
+ from pythonxbox.common.signed_session import SignedSession
101
+ from pythonxbox.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
101
102
 
102
103
  """
103
104
  This uses the global default client identification by OpenXbox
@@ -109,7 +110,7 @@ client_secret = CLIENT_SECRET
109
110
  tokens_file = TOKENS_FILE
110
111
 
111
112
  """
112
- For doing authentication, see xbox/webapi/scripts/authenticate.py
113
+ For doing authentication, see pythonxbox/scripts/authenticate.py
113
114
  """
114
115
 
115
116
 
@@ -123,7 +124,7 @@ async def async_main():
123
124
 
124
125
  """
125
126
  Read in tokens that you received from the `xbox-authenticate`-script previously
126
- See `xbox/webapi/scripts/authenticate.py`
127
+ See `pythonxbox/scripts/authenticate.py`
127
128
  """
128
129
  try:
129
130
  with open(tokens_file) as f:
@@ -201,8 +202,7 @@ asyncio.run(async_main())
201
202
 
202
203
  ## Credits
203
204
 
204
- This package uses parts of [Cookiecutter](https://github.com/audreyr/cookiecutter)
205
- and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.
205
+ This library is derived from [xbox-webapi](https://github.com/OpenXbox/xbox-webapi-python) library from the [OpenXbox](https://github.com/openxbox) project
206
206
  The authentication code is based on [joealcorn/xbox](https://github.com/joealcorn/xbox)
207
207
 
208
208
  Informations on endpoints gathered from:
@@ -1,11 +1,12 @@
1
- # Xbox-WebAPI
1
+ # python-xbox
2
2
 
3
- [![PyPi - latest](https://img.shields.io/pypi/v/xbox-webapi.svg)](https://pypi.python.org/pypi/xbox-webapi/)
4
- [![Documentation status](https://readthedocs.org/projects/xbox-webapi-python/badge/?version=latest)](http://xbox-webapi-python.readthedocs.io/en/latest/?badge=latest)
5
- [![Build status](https://img.shields.io/github/actions/workflow/status/OpenXbox/xbox-webapi-python/build.yml?branch=master)](https://github.com/OpenXbox/xbox-webapi-python/actions?query=workflow%3Abuild)
6
- [![Discord chat channel](https://img.shields.io/badge/discord-OpenXbox-blue.svg)](https://openxbox.org/discord)
3
+ [![PyPi - latest](https://img.shields.io/pypi/v/python-xbox.svg)](https://pypi.python.org/pypi/python-xbox/)
4
+ [![Build](https://github.com/tr4nt0r/python-xbox/actions/workflows/build.yml/badge.svg)](https://github.com/tr4nt0r/python-xbox/actions/workflows/build.yml)
5
+ ![PyPI - Downloads](https://img.shields.io/pypi/dm/python-xbox?style=flat&label=pypi%20downloads)
6
+ [!["Buy Me A Coffee"](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://www.buymeacoffee.com/tr4nt0r)
7
+ [![GitHub Sponsor](https://img.shields.io/badge/GitHub-Sponsor-blue?logo=github)](https://github.com/sponsors/tr4nt0r)
7
8
 
8
- Xbox-WebAPI is a python library to authenticate with Xbox Live via your Microsoft Account and provides Xbox related Web-API.
9
+ python-xbox is a python library to authenticate with Xbox Network via your Microsoft Account and provides Xbox related Web-API.
9
10
 
10
11
  Authentication is supported via OAuth2.
11
12
 
@@ -19,21 +20,22 @@ Authentication is supported via OAuth2.
19
20
 
20
21
  ## Dependencies
21
22
 
22
- - Python >= 3.8
23
+ - Python >= 3.11
23
24
 
24
25
  ## How to use
25
26
 
26
- Install
27
+ ### Install
27
28
 
28
- ```text
29
- pip install xbox-webapi
29
+ ```bash
30
+ pip install python-xbox
30
31
  ```
31
32
 
32
- Authentication
33
+ ### Authentication
33
34
 
34
- **Note: You must use non child account (> 18 years old)**
35
+ > [!NOTE]
36
+ > You must use non child account (> 18 years old)
35
37
 
36
- Token save location: If tokenfile is not provided via cmdline, fallback of `<appdirs.user_data_dir>/tokens.json` is used as save-location
38
+ Token save location: If tokenfile is not provided via cmdline, fallback of `<platformdirs.user_data_dir>/tokens.json` is used as save-location
37
39
 
38
40
  Specifically:
39
41
 
@@ -43,32 +45,32 @@ Mac OSX: `/Users/<username>/Library/Application Support/xbox/tokens.json`
43
45
 
44
46
  Linux: `/home/<username>/.local/share/xbox`
45
47
 
46
- For more information, see: <https://pypi.org/project/appdirs> and module: `xbox.webapi.scripts.constants`
48
+ For more information, see: <https://pypi.org/project/platformdirs> and module: `python-xbox.scripts.constants`
47
49
 
48
- ```
50
+ ```bash
49
51
  xbox-authenticate --client-id <client-id> --client-secret <client-secret>
50
52
  ```
51
53
 
52
54
  Example: Search Xbox Live via cmdline tool
53
55
 
54
- ```text
56
+ ```bash
55
57
  # Search Xbox One Catalog
56
58
  xbox-searchlive "Some game title"
57
59
  ```
58
60
 
59
61
  API usage
60
62
 
61
- ```py
63
+ ```python
62
64
  import asyncio
63
65
  import sys
64
66
 
65
67
  from httpx import HTTPStatusError
66
68
 
67
- from xbox.webapi.api.client import XboxLiveClient
68
- from xbox.webapi.authentication.manager import AuthenticationManager
69
- from xbox.webapi.authentication.models import OAuth2TokenResponse
70
- from xbox.webapi.common.signed_session import SignedSession
71
- from xbox.webapi.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
69
+ from pythonxbox.api.client import XboxLiveClient
70
+ from pythonxbox.authentication.manager import AuthenticationManager
71
+ from pythonxbox.authentication.models import OAuth2TokenResponse
72
+ from pythonxbox.common.signed_session import SignedSession
73
+ from pythonxbox.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
72
74
 
73
75
  """
74
76
  This uses the global default client identification by OpenXbox
@@ -80,7 +82,7 @@ client_secret = CLIENT_SECRET
80
82
  tokens_file = TOKENS_FILE
81
83
 
82
84
  """
83
- For doing authentication, see xbox/webapi/scripts/authenticate.py
85
+ For doing authentication, see pythonxbox/scripts/authenticate.py
84
86
  """
85
87
 
86
88
 
@@ -94,7 +96,7 @@ async def async_main():
94
96
 
95
97
  """
96
98
  Read in tokens that you received from the `xbox-authenticate`-script previously
97
- See `xbox/webapi/scripts/authenticate.py`
99
+ See `pythonxbox/scripts/authenticate.py`
98
100
  """
99
101
  try:
100
102
  with open(tokens_file) as f:
@@ -172,8 +174,7 @@ asyncio.run(async_main())
172
174
 
173
175
  ## Credits
174
176
 
175
- This package uses parts of [Cookiecutter](https://github.com/audreyr/cookiecutter)
176
- and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.
177
+ This library is derived from [xbox-webapi](https://github.com/OpenXbox/xbox-webapi-python) library from the [OpenXbox](https://github.com/openxbox) project
177
178
  The authentication code is based on [joealcorn/xbox](https://github.com/joealcorn/xbox)
178
179
 
179
180
  Informations on endpoints gathered from:
@@ -3,13 +3,12 @@ name = "python-xbox"
3
3
  description = "A library to authenticate with Xbox Network and use their API"
4
4
  authors = [
5
5
  {name = "Manfred Dennerlein Rodelo", email = "manfred@dennerlein.name"},
6
- {name = "OpenXbox"},
7
6
  ]
8
7
  dependencies = [
9
- "ecdsa",
10
- "httpx",
11
- "ms_cv",
12
- "pydantic==2.*",
8
+ "ecdsa>=0.19",
9
+ "httpx>=0.25.1",
10
+ "ms_cv>=0.1.1",
11
+ "pydantic>=2.12",
13
12
  ]
14
13
  requires-python = ">=3.11"
15
14
  readme = "README.md"
@@ -49,14 +48,14 @@ line-length = 88
49
48
  target-version = "py311"
50
49
 
51
50
  [tool.ruff.lint]
52
- select = ["E4", "E7", "E9", "F", "UP", "S", "ANN"]
51
+ select = ["E4", "E7", "E9", "F", "UP", "S", "ANN", "C4", "I", "RUF", "SIM", "PLR", "ERA", "RET", "B", "A"]
53
52
  # select = ["ALL"]
54
- ignore = ["ANN003", "ANN401"]
53
+ ignore = ["ANN003", "ANN401", "D", "COM"]
55
54
 
56
55
 
57
56
  [tool.ruff.lint.per-file-ignores]
58
57
  "**/scripts/*" = ["UP", "S104"]
59
- "tests/*" = ["S101"]
58
+ "tests/*" = ["S101", "PLR2004"]
60
59
  "src/pythonxbox/authentication/xal.py" = ["S101"]
61
60
 
62
61
  [tool.ruff.lint.isort]
@@ -88,7 +87,7 @@ dependencies = [
88
87
  "ecdsa==0.19.1",
89
88
  "httpx==0.28.1",
90
89
  "ms_cv==0.1.1",
91
- "pydantic==2.12.3",
90
+ "pydantic==2.12.4",
92
91
  "pytest==8.4.2",
93
92
  "pytest-asyncio==1.2.0",
94
93
  "pytest-cov==7.0.0",
@@ -116,10 +115,19 @@ python = ["3.14", "3.13", "3.12", "3.11"]
116
115
 
117
116
  [tool.hatch.envs.hatch-static-analysis]
118
117
  dependencies = [
119
- "ruff==0.14.2",
118
+ "ruff==0.14.4",
120
119
  ]
121
120
  config-path = "none"
122
121
 
122
+ [tool.hatch.envs.docs]
123
+ dependencies = [
124
+ "mkdocs-material==9.6.23",
125
+ "mkdocstrings[python]==0.30.1",
126
+ ]
127
+ [tool.hatch.envs.docs.scripts]
128
+ serve = "mkdocs serve"
129
+ build = "mkdocs build"
130
+
123
131
  [build-system]
124
132
  requires = ["hatchling", "hatch-regex-commit"]
125
133
  build-backend = "hatchling.build"
@@ -0,0 +1,4 @@
1
+ """Top-level package for python-xbox."""
2
+
3
+ __author__ = """tr4nt0r"""
4
+ __version__ = "0.1.1"
@@ -84,10 +84,9 @@ class Session:
84
84
  data = data or {}
85
85
  data.update(extra_data)
86
86
 
87
- if rate_limits:
87
+ if rate_limits and rate_limits.is_exceeded():
88
88
  # Check if rate limits have been exceeded for this endpoint
89
- if rate_limits.is_exceeded():
90
- raise RateLimitExceededException("Rate limit exceeded", rate_limits)
89
+ raise RateLimitExceededException("Rate limit exceeded", rate_limits)
91
90
 
92
91
  response = await self._auth_mgr.session.request(
93
92
  method, url, **kwargs, headers=headers, params=params, data=data
@@ -1,3 +1,5 @@
1
+ from typing import ClassVar
2
+
1
3
  from pythonxbox.api.provider.account.models import (
2
4
  ChangeGamertagResult,
3
5
  ClaimGamertagResult,
@@ -9,8 +11,8 @@ class AccountProvider(BaseProvider):
9
11
  BASE_URL_USER_MGT = "https://user.mgt.xboxlive.com"
10
12
  BASE_URL_ACCOUNT = "https://accounts.xboxlive.com"
11
13
 
12
- HEADERS_USER_MGT = {"x-xbl-contract-version": "1"}
13
- HEADERS_ACCOUNT = {"x-xbl-contract-version": "2"}
14
+ HEADERS_USER_MGT: ClassVar = {"x-xbl-contract-version": "1"}
15
+ HEADERS_ACCOUNT: ClassVar = {"x-xbl-contract-version": "2"}
14
16
 
15
17
  async def claim_gamertag(
16
18
  self, xuid: str, gamertag: str, **kwargs
@@ -4,6 +4,8 @@ Achievements
4
4
  Get Xbox 360 and Xbox One Achievement data
5
5
  """
6
6
 
7
+ from typing import ClassVar
8
+
7
9
  from pythonxbox.api.provider.achievements.models import (
8
10
  Achievement360ProgressResponse,
9
11
  Achievement360Response,
@@ -15,10 +17,10 @@ from pythonxbox.api.provider.ratelimitedprovider import RateLimitedProvider
15
17
 
16
18
  class AchievementsProvider(RateLimitedProvider):
17
19
  ACHIEVEMENTS_URL = "https://achievements.xboxlive.com"
18
- HEADERS_GAME_360_PROGRESS = {"x-xbl-contract-version": "1"}
19
- HEADERS_GAME_PROGRESS = {"x-xbl-contract-version": "2"}
20
+ HEADERS_GAME_360_PROGRESS: ClassVar = {"x-xbl-contract-version": "1"}
21
+ HEADERS_GAME_PROGRESS: ClassVar = {"x-xbl-contract-version": "2"}
20
22
 
21
- RATE_LIMITS = {"burst": 100, "sustain": 300}
23
+ RATE_LIMITS: ClassVar = {"burst": 100, "sustain": 300}
22
24
 
23
25
  async def get_achievements_detail_item(
24
26
  self, xuid: str, service_config_id: str, achievement_id: str, **kwargs
@@ -42,7 +44,7 @@ class AchievementsProvider(RateLimitedProvider):
42
44
  **kwargs,
43
45
  )
44
46
  resp.raise_for_status()
45
- return AchievementResponse(**resp.json())
47
+ return AchievementResponse.model_validate_json(resp.text)
46
48
 
47
49
  async def get_achievements_xbox360_all(
48
50
  self, xuid: str, title_id: str, **kwargs
@@ -67,7 +69,7 @@ class AchievementsProvider(RateLimitedProvider):
67
69
  **kwargs,
68
70
  )
69
71
  resp.raise_for_status()
70
- return Achievement360Response(**resp.json())
72
+ return Achievement360Response.model_validate_json(resp.text)
71
73
 
72
74
  async def get_achievements_xbox360_earned(
73
75
  self, xuid: str, title_id: str, **kwargs
@@ -92,7 +94,7 @@ class AchievementsProvider(RateLimitedProvider):
92
94
  **kwargs,
93
95
  )
94
96
  resp.raise_for_status()
95
- return Achievement360Response(**resp.json())
97
+ return Achievement360Response.model_validate_json(resp.text)
96
98
 
97
99
  async def get_achievements_xbox360_recent_progress_and_info(
98
100
  self, xuid: str, **kwargs
@@ -114,7 +116,7 @@ class AchievementsProvider(RateLimitedProvider):
114
116
  **kwargs,
115
117
  )
116
118
  resp.raise_for_status()
117
- return Achievement360ProgressResponse(**resp.json())
119
+ return Achievement360ProgressResponse.model_validate_json(resp.text)
118
120
 
119
121
  async def get_achievements_xboxone_gameprogress(
120
122
  self, xuid: str, title_id: str, **kwargs
@@ -139,7 +141,7 @@ class AchievementsProvider(RateLimitedProvider):
139
141
  **kwargs,
140
142
  )
141
143
  resp.raise_for_status()
142
- return AchievementResponse(**resp.json())
144
+ return AchievementResponse.model_validate_json(resp.text)
143
145
 
144
146
  async def get_achievements_xboxone_recent_progress_and_info(
145
147
  self, xuid: str, **kwargs
@@ -161,4 +163,4 @@ class AchievementsProvider(RateLimitedProvider):
161
163
  **kwargs,
162
164
  )
163
165
  resp.raise_for_status()
164
- return RecentProgressResponse(**resp.json())
166
+ return RecentProgressResponse.model_validate_json(resp.text)
@@ -6,7 +6,6 @@ Subclassed by every *real* provider
6
6
 
7
7
  from typing import TYPE_CHECKING
8
8
 
9
-
10
9
  if TYPE_CHECKING:
11
10
  from pythonxbox.api.client import XboxLiveClient
12
11
 
@@ -36,11 +36,11 @@ class CatalogProvider(BaseProvider):
36
36
  url, params=params, include_auth=False, **kwargs
37
37
  )
38
38
  resp.raise_for_status()
39
- return CatalogResponse(**resp.json())
39
+ return CatalogResponse.model_validate_json(resp.text)
40
40
 
41
41
  async def get_product_from_alternate_id(
42
42
  self,
43
- id: str,
43
+ id: str, # noqa: A002
44
44
  id_type: AlternateIdType,
45
45
  fields: FieldsTemplate = FieldsTemplate.DETAILS,
46
46
  top: int = 25,
@@ -60,7 +60,7 @@ class CatalogProvider(BaseProvider):
60
60
  url, params=params, include_auth=False, **kwargs
61
61
  )
62
62
  resp.raise_for_status()
63
- return CatalogResponse(**resp.json())
63
+ return CatalogResponse.model_validate_json(resp.text)
64
64
 
65
65
  async def product_search(
66
66
  self,
@@ -83,4 +83,4 @@ class CatalogProvider(BaseProvider):
83
83
  url, params=params, include_auth=False, **kwargs
84
84
  )
85
85
  resp.raise_for_status()
86
- return CatalogSearchResponse(**resp.json())
86
+ return CatalogSearchResponse.model_validate_json(resp.text)
@@ -1,5 +1,5 @@
1
1
  from datetime import datetime
2
- from enum import Enum
2
+ from enum import StrEnum
3
3
  from typing import Any
4
4
 
5
5
  from pydantic import Field, field_validator
@@ -7,18 +7,18 @@ from pydantic import Field, field_validator
7
7
  from pythonxbox.common.models import PascalCaseModel
8
8
 
9
9
 
10
- class AlternateIdType(str, Enum):
10
+ class AlternateIdType(StrEnum):
11
11
  LEGACY_XBOX_PRODUCT_ID = "LegacyXboxProductId"
12
12
  XBOX_TITLE_ID = "XboxTitleId"
13
13
  PACKAGE_FAMILY_NAME = "PackageFamilyName"
14
14
 
15
15
 
16
- class FieldsTemplate(str, Enum):
16
+ class FieldsTemplate(StrEnum):
17
17
  BROWSE = "browse"
18
18
  DETAILS = "details"
19
19
 
20
20
 
21
- class PlatformType(str, Enum):
21
+ class PlatformType(StrEnum):
22
22
  XBOX = "windows.xbox"
23
23
  DESKTOP = "windows.desktop"
24
24
 
@@ -5,6 +5,8 @@ Used for download stump (TV Streaming) data
5
5
  (RemoteTVInput ServiceChannel on Smartglass)
6
6
  """
7
7
 
8
+ from typing import ClassVar
9
+
8
10
  from pythonxbox.api.provider.baseprovider import BaseProvider
9
11
  from pythonxbox.api.provider.cqs.models import (
10
12
  CqsChannelListResponse,
@@ -14,7 +16,7 @@ from pythonxbox.api.provider.cqs.models import (
14
16
 
15
17
  class CQSProvider(BaseProvider):
16
18
  CQS_URL = "https://cqs.xboxlive.com"
17
- HEADERS_CQS = {
19
+ HEADERS_CQS: ClassVar = {
18
20
  "Cache-Control": "no-cache",
19
21
  "Accept": "application/json",
20
22
  "Pragma": "no-cache",
@@ -44,9 +46,9 @@ class CQSProvider(BaseProvider):
44
46
  url, params=params, headers=self.HEADERS_CQS, **kwargs
45
47
  )
46
48
  resp.raise_for_status()
47
- return CqsChannelListResponse(**resp.json())
49
+ return CqsChannelListResponse.model_validate_json(resp.text)
48
50
 
49
- async def get_schedule(
51
+ async def get_schedule( # noqa: PLR0913
50
52
  self,
51
53
  locale_info: str,
52
54
  headend_id: str,
@@ -82,4 +84,4 @@ class CQSProvider(BaseProvider):
82
84
  url, params=params, headers=self.HEADERS_CQS, **kwargs
83
85
  )
84
86
  resp.raise_for_status()
85
- return CqsScheduleResponse(**resp.json())
87
+ return CqsScheduleResponse.model_validate_json(resp.text)
@@ -2,13 +2,15 @@
2
2
  Gameclips - Get gameclip info
3
3
  """
4
4
 
5
+ from typing import ClassVar
6
+
5
7
  from pythonxbox.api.provider.baseprovider import BaseProvider
6
8
  from pythonxbox.api.provider.gameclips.models import GameclipsResponse
7
9
 
8
10
 
9
11
  class GameclipProvider(BaseProvider):
10
12
  GAMECLIPS_METADATA_URL = "https://gameclipsmetadata.xboxlive.com"
11
- HEADERS_GAMECLIPS_METADATA = {"x-xbl-contract-version": "1"}
13
+ HEADERS_GAMECLIPS_METADATA: ClassVar = {"x-xbl-contract-version": "1"}
12
14
 
13
15
  async def get_recent_community_clips_by_title_id(
14
16
  self, title_id: str, **kwargs
@@ -28,10 +30,14 @@ class GameclipProvider(BaseProvider):
28
30
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
29
31
  )
30
32
  resp.raise_for_status()
31
- return GameclipsResponse(**resp.json())
33
+ return GameclipsResponse.model_validate_json(resp.text)
32
34
 
33
35
  async def get_recent_own_clips(
34
- self, title_id: str = None, skip_items: int = 0, max_items: int = 25, **kwargs
36
+ self,
37
+ title_id: str | None = None,
38
+ skip_items: int = 0,
39
+ max_items: int = 25,
40
+ **kwargs,
35
41
  ) -> GameclipsResponse:
36
42
  """
37
43
  Get own recent clips, optionally filter for title Id
@@ -54,12 +60,12 @@ class GameclipProvider(BaseProvider):
54
60
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
55
61
  )
56
62
  resp.raise_for_status()
57
- return GameclipsResponse(**resp.json())
63
+ return GameclipsResponse.model_validate_json(resp.text)
58
64
 
59
65
  async def get_recent_clips_by_xuid(
60
66
  self,
61
67
  xuid: str,
62
- title_id: str = None,
68
+ title_id: str | None = None,
63
69
  skip_items: int = 0,
64
70
  max_items: int = 25,
65
71
  **kwargs,
@@ -86,7 +92,7 @@ class GameclipProvider(BaseProvider):
86
92
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
87
93
  )
88
94
  resp.raise_for_status()
89
- return GameclipsResponse(**resp.json())
95
+ return GameclipsResponse.model_validate_json(resp.text)
90
96
 
91
97
  async def get_saved_community_clips_by_title_id(
92
98
  self, title_id: str, **kwargs
@@ -106,10 +112,14 @@ class GameclipProvider(BaseProvider):
106
112
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
107
113
  )
108
114
  resp.raise_for_status()
109
- return GameclipsResponse(**resp.json())
115
+ return GameclipsResponse.model_validate_json(resp.text)
110
116
 
111
117
  async def get_saved_own_clips(
112
- self, title_id: str = None, skip_items: int = 0, max_items: int = 25, **kwargs
118
+ self,
119
+ title_id: str | None = None,
120
+ skip_items: int = 0,
121
+ max_items: int = 25,
122
+ **kwargs,
113
123
  ) -> GameclipsResponse:
114
124
  """
115
125
  Get own saved clips, optionally filter for title Id an
@@ -132,12 +142,12 @@ class GameclipProvider(BaseProvider):
132
142
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
133
143
  )
134
144
  resp.raise_for_status()
135
- return GameclipsResponse(**resp.json())
145
+ return GameclipsResponse.model_validate_json(resp.text)
136
146
 
137
147
  async def get_saved_clips_by_xuid(
138
148
  self,
139
149
  xuid: str,
140
- title_id: str = None,
150
+ title_id: str | None = None,
141
151
  skip_items: int = 0,
142
152
  max_items: int = 25,
143
153
  **kwargs,
@@ -164,4 +174,4 @@ class GameclipProvider(BaseProvider):
164
174
  url, params=params, headers=self.HEADERS_GAMECLIPS_METADATA, **kwargs
165
175
  )
166
176
  resp.raise_for_status()
167
- return GameclipsResponse(**resp.json())
177
+ return GameclipsResponse.model_validate_json(resp.text)