python-xbox 0.1.0rc3__tar.gz → 0.1.0rc4__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 (64) hide show
  1. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/LICENSE +2 -1
  2. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/PKG-INFO +5 -3
  3. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/pyproject.toml +7 -4
  4. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/__init__.py +1 -1
  5. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/client.py +2 -2
  6. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/language.py +7 -1
  7. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/account/__init__.py +4 -2
  8. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/achievements/__init__.py +6 -6
  9. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/baseprovider.py +7 -1
  10. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/catalog/models.py +1 -1
  11. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/presence/__init__.py +1 -1
  12. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/ratelimitedprovider.py +6 -2
  13. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/smartglass/__init__.py +5 -1
  14. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/titlehub/__init__.py +5 -1
  15. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/authentication/manager.py +1 -1
  16. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/authentication/models.py +1 -1
  17. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/authentication/xal.py +2 -2
  18. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/exceptions.py +5 -3
  19. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/models.py +3 -3
  20. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/ratelimits/__init__.py +5 -5
  21. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/request_signer.py +8 -6
  22. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/signed_session.py +10 -4
  23. python_xbox-0.1.0rc4/src/pythonxbox/py.typed +0 -0
  24. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/authenticate.py +4 -4
  25. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/change_gamertag.py +2 -2
  26. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/friends.py +2 -2
  27. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/search.py +2 -2
  28. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/xal.py +3 -3
  29. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/.gitignore +0 -0
  30. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/README.md +0 -0
  31. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/__init__.py +0 -0
  32. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/__init__.py +0 -0
  33. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/account/models.py +0 -0
  34. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/achievements/models.py +0 -0
  35. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/catalog/__init__.py +0 -0
  36. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/catalog/const.py +0 -0
  37. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/cqs/__init__.py +0 -0
  38. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/cqs/models.py +0 -0
  39. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/gameclips/__init__.py +0 -0
  40. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/gameclips/models.py +0 -0
  41. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/lists/__init__.py +0 -0
  42. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/lists/models.py +0 -0
  43. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/mediahub/__init__.py +0 -0
  44. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/mediahub/models.py +0 -0
  45. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/message/__init__.py +0 -0
  46. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/message/models.py +0 -0
  47. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/people/__init__.py +0 -0
  48. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/people/models.py +0 -0
  49. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/presence/models.py +0 -0
  50. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/profile/__init__.py +0 -0
  51. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/profile/models.py +0 -0
  52. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/screenshots/__init__.py +0 -0
  53. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/screenshots/models.py +0 -0
  54. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/smartglass/models.py +0 -0
  55. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/titlehub/models.py +0 -0
  56. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/usersearch/__init__.py +0 -0
  57. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/usersearch/models.py +0 -0
  58. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/userstats/__init__.py +0 -0
  59. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/api/provider/userstats/models.py +0 -0
  60. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/authentication/__init__.py +0 -0
  61. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/__init__.py +0 -0
  62. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/filetimes.py +0 -0
  63. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/common/ratelimits/models.py +0 -0
  64. {python_xbox-0.1.0rc3 → python_xbox-0.1.0rc4}/src/pythonxbox/scripts/__init__.py +0 -0
@@ -1,4 +1,5 @@
1
- Copyright (c) 2020 OpenXbox
1
+ Copyright (c) 2025 Manfred Dennerlein Rodelo
2
+ Copyright (c) 2020 - 2025 OpenXbox
2
3
 
3
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
5
  of this software and associated documentation files (the "Software"), to deal
@@ -1,15 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-xbox
3
- Version: 0.1.0rc3
3
+ Version: 0.1.0rc4
4
4
  Summary: A library to authenticate with Xbox Network and use their API
5
- Project-URL: Homepage, https://github.com/tr4nt0r/python-xbox
5
+ Project-URL: Source, https://github.com/tr4nt0r/python-xbox
6
6
  Author: OpenXbox
7
+ Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>
7
8
  License-Expression: MIT
8
9
  License-File: LICENSE
9
10
  Keywords: xbox one live api
10
- Classifier: Development Status :: 4 - Beta
11
+ Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Intended Audience :: Developers
12
13
  Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
13
15
  Classifier: Programming Language :: Python :: 3
14
16
  Classifier: Programming Language :: Python :: 3.11
15
17
  Classifier: Programming Language :: Python :: 3.12
@@ -2,6 +2,7 @@
2
2
  name = "python-xbox"
3
3
  description = "A library to authenticate with Xbox Network and use their API"
4
4
  authors = [
5
+ {name = "Manfred Dennerlein Rodelo", email = "manfred@dennerlein.name"},
5
6
  {name = "OpenXbox"},
6
7
  ]
7
8
  dependencies = [
@@ -15,7 +16,7 @@ readme = "README.md"
15
16
  license = "MIT"
16
17
  keywords = ["xbox one live api"]
17
18
  classifiers = [
18
- "Development Status :: 4 - Beta",
19
+ "Development Status :: 5 - Production/Stable",
19
20
  "Intended Audience :: Developers",
20
21
  "License :: OSI Approved :: MIT License",
21
22
  "Programming Language :: Python :: 3",
@@ -23,12 +24,13 @@ classifiers = [
23
24
  "Programming Language :: Python :: 3.12",
24
25
  "Programming Language :: Python :: 3.13",
25
26
  "Programming Language :: Python :: 3.14",
27
+ "Operating System :: OS Independent",
26
28
  "Topic :: Software Development :: Libraries :: Python Modules",
27
29
  ]
28
30
  dynamic = ["version"]
29
31
 
30
32
  [project.urls]
31
- Homepage = "https://github.com/tr4nt0r/python-xbox"
33
+ Source = "https://github.com/tr4nt0r/python-xbox"
32
34
 
33
35
  [project.optional-dependencies]
34
36
  cli = [
@@ -47,8 +49,9 @@ line-length = 88
47
49
  target-version = "py311"
48
50
 
49
51
  [tool.ruff.lint]
50
- select = ["E4", "E7", "E9", "F", "UP", "S"]
51
- ignore = []
52
+ select = ["E4", "E7", "E9", "F", "UP", "S", "ANN"]
53
+ # select = ["ALL"]
54
+ ignore = ["ANN003", "ANN401"]
52
55
 
53
56
 
54
57
  [tool.ruff.lint.per-file-ignores]
@@ -1,4 +1,4 @@
1
1
  """Top-level package for xbox-webapi-python."""
2
2
 
3
3
  __author__ = """OpenXbox"""
4
- __version__ = "0.1.0rc3"
4
+ __version__ = "0.1.0rc4"
@@ -36,7 +36,7 @@ log = logging.getLogger("xbox.api")
36
36
 
37
37
 
38
38
  class Session:
39
- def __init__(self, auth_mgr: AuthenticationManager):
39
+ def __init__(self, auth_mgr: AuthenticationManager) -> None:
40
40
  self._auth_mgr = auth_mgr
41
41
  self._cv = CorrelationVector()
42
42
 
@@ -125,7 +125,7 @@ class XboxLiveClient:
125
125
  self,
126
126
  auth_mgr: AuthenticationManager,
127
127
  language: XboxLiveLanguage = DefaultXboxLiveLanguages.United_States,
128
- ):
128
+ ) -> None:
129
129
  self._auth_mgr = auth_mgr
130
130
  self.session = Session(auth_mgr)
131
131
  self._language = language
@@ -4,7 +4,13 @@ Language definitions
4
4
 
5
5
 
6
6
  class XboxLiveLanguage:
7
- def __init__(self, name, short_id, identifier, locale):
7
+ def __init__(
8
+ self,
9
+ name: str,
10
+ short_id: str,
11
+ identifier: str,
12
+ locale: str,
13
+ ) -> None:
8
14
  """
9
15
  Initialize a new instance of :class:`XboxLiveLanguage`
10
16
 
@@ -12,7 +12,9 @@ class AccountProvider(BaseProvider):
12
12
  HEADERS_USER_MGT = {"x-xbl-contract-version": "1"}
13
13
  HEADERS_ACCOUNT = {"x-xbl-contract-version": "2"}
14
14
 
15
- async def claim_gamertag(self, xuid, gamertag, **kwargs) -> ClaimGamertagResult:
15
+ async def claim_gamertag(
16
+ self, xuid: str, gamertag: str, **kwargs
17
+ ) -> ClaimGamertagResult:
16
18
  """
17
19
  Claim gamertag
18
20
 
@@ -40,7 +42,7 @@ class AccountProvider(BaseProvider):
40
42
  resp.raise_for_status()
41
43
 
42
44
  async def change_gamertag(
43
- self, xuid, gamertag, preview=False, **kwargs
45
+ self, xuid: str, gamertag: str, preview: bool = False, **kwargs
44
46
  ) -> ChangeGamertagResult:
45
47
  """
46
48
  Change your gamertag.
@@ -21,7 +21,7 @@ class AchievementsProvider(RateLimitedProvider):
21
21
  RATE_LIMITS = {"burst": 100, "sustain": 300}
22
22
 
23
23
  async def get_achievements_detail_item(
24
- self, xuid, service_config_id, achievement_id, **kwargs
24
+ self, xuid: str, service_config_id: str, achievement_id: str, **kwargs
25
25
  ) -> AchievementResponse:
26
26
  """
27
27
  Get achievement detail for specific item
@@ -45,7 +45,7 @@ class AchievementsProvider(RateLimitedProvider):
45
45
  return AchievementResponse(**resp.json())
46
46
 
47
47
  async def get_achievements_xbox360_all(
48
- self, xuid, title_id, **kwargs
48
+ self, xuid: str, title_id: str, **kwargs
49
49
  ) -> Achievement360Response:
50
50
  """
51
51
  Get all achievements for specific X360 title Id
@@ -70,7 +70,7 @@ class AchievementsProvider(RateLimitedProvider):
70
70
  return Achievement360Response(**resp.json())
71
71
 
72
72
  async def get_achievements_xbox360_earned(
73
- self, xuid, title_id, **kwargs
73
+ self, xuid: str, title_id: str, **kwargs
74
74
  ) -> Achievement360Response:
75
75
  """
76
76
  Get earned achievements for specific X360 title id
@@ -95,7 +95,7 @@ class AchievementsProvider(RateLimitedProvider):
95
95
  return Achievement360Response(**resp.json())
96
96
 
97
97
  async def get_achievements_xbox360_recent_progress_and_info(
98
- self, xuid, **kwargs
98
+ self, xuid: str, **kwargs
99
99
  ) -> Achievement360ProgressResponse:
100
100
  """
101
101
  Get recent achievement progress and information
@@ -117,7 +117,7 @@ class AchievementsProvider(RateLimitedProvider):
117
117
  return Achievement360ProgressResponse(**resp.json())
118
118
 
119
119
  async def get_achievements_xboxone_gameprogress(
120
- self, xuid, title_id, **kwargs
120
+ self, xuid: str, title_id: str, **kwargs
121
121
  ) -> AchievementResponse:
122
122
  """
123
123
  Get gameprogress for Xbox One title
@@ -142,7 +142,7 @@ class AchievementsProvider(RateLimitedProvider):
142
142
  return AchievementResponse(**resp.json())
143
143
 
144
144
  async def get_achievements_xboxone_recent_progress_and_info(
145
- self, xuid, **kwargs
145
+ self, xuid: str, **kwargs
146
146
  ) -> RecentProgressResponse:
147
147
  """
148
148
  Get recent achievement progress and information
@@ -4,9 +4,15 @@ BaseProvider
4
4
  Subclassed by every *real* provider
5
5
  """
6
6
 
7
+ from typing import TYPE_CHECKING
8
+
9
+
10
+ if TYPE_CHECKING:
11
+ from pythonxbox.api.client import XboxLiveClient
12
+
7
13
 
8
14
  class BaseProvider:
9
- def __init__(self, client):
15
+ def __init__(self, client: "XboxLiveClient") -> None:
10
16
  """
11
17
  Initialize an the BaseProvider
12
18
 
@@ -250,7 +250,7 @@ class SkuProperties(PascalCaseModel):
250
250
  is_bundle: bool
251
251
 
252
252
  @field_validator("last_update_date", mode="before", check_fields=True)
253
- def validator(x):
253
+ def validator(x: "SkuProperties") -> "SkuProperties":
254
254
  return x or None
255
255
 
256
256
 
@@ -17,7 +17,7 @@ class PresenceProvider(BaseProvider):
17
17
 
18
18
  async def get_presence(
19
19
  self,
20
- xuid,
20
+ xuid: str,
21
21
  presence_level: PresenceLevel = PresenceLevel.USER,
22
22
  **kwargs,
23
23
  ) -> PresenceItem:
@@ -4,17 +4,21 @@ RateLimitedProvider
4
4
  Subclassed by providers with rate limit support
5
5
  """
6
6
 
7
+ from typing import TYPE_CHECKING
7
8
  from pythonxbox.api.provider.baseprovider import BaseProvider
8
9
  from pythonxbox.common.exceptions import XboxException
9
10
  from pythonxbox.common.ratelimits import CombinedRateLimit
10
11
  from pythonxbox.common.ratelimits.models import LimitType, ParsedRateLimit, TimePeriod
11
12
 
13
+ if TYPE_CHECKING:
14
+ from pythonxbox.api.client import XboxLiveClient
15
+
12
16
 
13
17
  class RateLimitedProvider(BaseProvider):
14
18
  # dict -> Dict (typing.dict) https://stackoverflow.com/a/63460173
15
19
  RATE_LIMITS: dict[str, int | dict[str, int]]
16
20
 
17
- def __init__(self, client):
21
+ def __init__(self, client: "XboxLiveClient") -> None:
18
22
  """
19
23
  Initialize Baseclass
20
24
 
@@ -39,7 +43,7 @@ class RateLimitedProvider(BaseProvider):
39
43
  "RateLimitedProvider as parent class but RATE_LIMITS not set!"
40
44
  )
41
45
 
42
- def __handle_rate_limit_setup(self):
46
+ def __handle_rate_limit_setup(self) -> None:
43
47
  # Retrieve burst and sustain from the dict
44
48
  burst_key = self.RATE_LIMITS["burst"]
45
49
  sustain_key = self.RATE_LIMITS["sustain"]
@@ -2,6 +2,7 @@
2
2
  SmartGlass - Control Registered Devices
3
3
  """
4
4
 
5
+ from typing import TYPE_CHECKING
5
6
  from uuid import uuid4
6
7
 
7
8
  from httpx import Response
@@ -19,6 +20,9 @@ from pythonxbox.api.provider.smartglass.models import (
19
20
  VolumeDirection,
20
21
  )
21
22
 
23
+ if TYPE_CHECKING:
24
+ from pythonxbox.api.client import XboxLiveClient
25
+
22
26
 
23
27
  class SmartglassProvider(BaseProvider):
24
28
  SG_URL = "https://xccs.xboxlive.com"
@@ -27,7 +31,7 @@ class SmartglassProvider(BaseProvider):
27
31
  "skillplatform": "RemoteManagement",
28
32
  }
29
33
 
30
- def __init__(self, client):
34
+ def __init__(self, client: "XboxLiveClient") -> None:
31
35
  """
32
36
  Initialize Baseclass, create smartglass session id
33
37
 
@@ -2,15 +2,19 @@
2
2
  Titlehub - Get Title history and info
3
3
  """
4
4
 
5
+ from typing import TYPE_CHECKING
5
6
  from pythonxbox.api.provider.baseprovider import BaseProvider
6
7
  from pythonxbox.api.provider.titlehub.models import TitleFields, TitleHubResponse
7
8
 
9
+ if TYPE_CHECKING:
10
+ from pythonxbox.api.client import XboxLiveClient
11
+
8
12
 
9
13
  class TitlehubProvider(BaseProvider):
10
14
  TITLEHUB_URL = "https://titlehub.xboxlive.com"
11
15
  SEPARATOR = ","
12
16
 
13
- def __init__(self, client):
17
+ def __init__(self, client: "XboxLiveClient") -> None:
14
18
  """
15
19
  Initialize Baseclass, set 'Accept-Language' header from client instance
16
20
 
@@ -29,7 +29,7 @@ class AuthenticationManager:
29
29
  client_secret: str,
30
30
  redirect_uri: str,
31
31
  scopes: list[str] | None = None,
32
- ):
32
+ ) -> None:
33
33
  if not isinstance(client_session, (SignedSession, httpx.AsyncClient)):
34
34
  raise DeprecationWarning(
35
35
  """Xbox WebAPI changed to use SignedSession (wrapped httpx.AsyncClient).
@@ -8,7 +8,7 @@ from pydantic.dataclasses import dataclass
8
8
  from pythonxbox.common.models import PascalCaseModel
9
9
 
10
10
 
11
- def utc_now():
11
+ def utc_now() -> datetime:
12
12
  return datetime.now(UTC)
13
13
 
14
14
 
@@ -81,7 +81,7 @@ class XALManager:
81
81
  device_id: uuid.UUID,
82
82
  app_params: XalAppParameters,
83
83
  client_params: XalClientParameters,
84
- ):
84
+ ) -> None:
85
85
  self.session = session
86
86
  self.device_id = device_id
87
87
  self.app_params = app_params
@@ -89,7 +89,7 @@ class XALManager:
89
89
  self.cv = CorrelationVector()
90
90
 
91
91
  @staticmethod
92
- def _get_random_bytes(length) -> bytes:
92
+ def _get_random_bytes(length: int) -> bytes:
93
93
  return os.urandom(length)
94
94
 
95
95
  @staticmethod
@@ -2,7 +2,9 @@
2
2
  Special Exception subclasses
3
3
  """
4
4
 
5
+ from typing import Any
5
6
  from pythonxbox.common.ratelimits import RateLimit
7
+ from httpx import Response
6
8
 
7
9
 
8
10
  class XboxException(Exception):
@@ -18,7 +20,7 @@ class AuthenticationException(XboxException):
18
20
 
19
21
 
20
22
  class TwoFactorAuthRequired(XboxException):
21
- def __init__(self, message, server_data):
23
+ def __init__(self, message: str, server_data: dict[str, Any]) -> None:
22
24
  """
23
25
  Raised when 2FA is required
24
26
 
@@ -31,7 +33,7 @@ class TwoFactorAuthRequired(XboxException):
31
33
 
32
34
 
33
35
  class InvalidRequest(XboxException):
34
- def __init__(self, message, response):
36
+ def __init__(self, message: str, response: Response) -> None:
35
37
  """
36
38
  Raised when something is wrong with the request
37
39
 
@@ -51,7 +53,7 @@ class NotFoundException(XboxException):
51
53
 
52
54
 
53
55
  class RateLimitExceededException(XboxException):
54
- def __init__(self, message, rate_limit: RateLimit):
56
+ def __init__(self, message: str, rate_limit: RateLimit) -> None:
55
57
  self.message = message
56
58
  self.rate_limit = rate_limit
57
59
  self.try_again_in = rate_limit.get_reset_after()
@@ -3,16 +3,16 @@
3
3
  from pydantic import ConfigDict, BaseModel
4
4
 
5
5
 
6
- def to_pascal(string):
6
+ def to_pascal(string: str) -> str:
7
7
  return "".join(word.capitalize() for word in string.split("_"))
8
8
 
9
9
 
10
- def to_camel(string):
10
+ def to_camel(string: str) -> str:
11
11
  words = string.split("_")
12
12
  return words[0] + "".join(word.capitalize() for word in words[1:])
13
13
 
14
14
 
15
- def to_lower(string):
15
+ def to_lower(string: str) -> str:
16
16
  return string.replace("_", "")
17
17
 
18
18
 
@@ -59,7 +59,7 @@ class SingleRateLimit(RateLimit):
59
59
  This class is mainly used by the CombinedRateLimit class.
60
60
  """
61
61
 
62
- def __init__(self, time_period: TimePeriod, type: LimitType, limit: int):
62
+ def __init__(self, time_period: TimePeriod, type: LimitType, limit: int) -> None:
63
63
  self.__time_period = time_period
64
64
  self.__type = type
65
65
  self.__limit = limit
@@ -122,14 +122,14 @@ class SingleRateLimit(RateLimit):
122
122
  return IncrementResult(counter=self.__counter, exceeded=self.__exceeded)
123
123
 
124
124
  # Should be called after every inc of the counter
125
- def __check_if_exceeded(self):
125
+ def __check_if_exceeded(self) -> None:
126
126
  if not self.__exceeded:
127
127
  if self.__counter >= self.__limit:
128
128
  self.__exceeded = True
129
129
  # reset-after is now dependent on the time since the first request of this cycle.
130
130
  # self.__set_reset_after()
131
131
 
132
- def __reset_counter_if_required(self):
132
+ def __reset_counter_if_required(self) -> None:
133
133
  # Check to make sure reset_after is not None
134
134
  # - This is the case if this function is called before the counter
135
135
  # is incremented after a reset / new instantiation
@@ -139,7 +139,7 @@ class SingleRateLimit(RateLimit):
139
139
  self.__counter = 0
140
140
  self.__reset_after = None
141
141
 
142
- def __set_reset_after(self):
142
+ def __set_reset_after(self) -> None:
143
143
  self.__reset_after = datetime.now() + timedelta(
144
144
  seconds=self.get_time_period().value
145
145
  )
@@ -151,7 +151,7 @@ class CombinedRateLimit(RateLimit):
151
151
 
152
152
  """
153
153
 
154
- def __init__(self, *parsed_limits: ParsedRateLimit, type: LimitType):
154
+ def __init__(self, *parsed_limits: ParsedRateLimit, type: LimitType) -> None:
155
155
  # *parsed_limits is a tuple
156
156
 
157
157
  # Create a SingleRateLimit instance for each limit
@@ -20,10 +20,12 @@ DEFAULT_SIGNING_POLICY = SignaturePolicy(
20
20
 
21
21
 
22
22
  class RequestSigner:
23
- def __init__(self, signing_key=None, signing_policy=None):
24
- self.signing_key: SigningKey = signing_key or SigningKey.generate(
25
- curve=NIST256p
26
- )
23
+ def __init__(
24
+ self,
25
+ signing_key: SigningKey | None = None,
26
+ signing_policy: SignaturePolicy | None = None,
27
+ ) -> None:
28
+ self.signing_key = signing_key or SigningKey.generate(curve=NIST256p)
27
29
  self.signing_policy = signing_policy or DEFAULT_SIGNING_POLICY
28
30
 
29
31
  pk_point = self.signing_key.verifying_key.pubkey.point
@@ -44,7 +46,7 @@ class RequestSigner:
44
46
  return SigningKey.from_pem(signing_key)
45
47
 
46
48
  @classmethod
47
- def from_pem(cls, pem_string: str):
49
+ def from_pem(cls, pem_string: str) -> SigningKey:
48
50
  request_signer = RequestSigner.import_signing_key(pem_string)
49
51
  return cls(request_signer)
50
52
 
@@ -184,5 +186,5 @@ class RequestSigner:
184
186
  return encoded
185
187
 
186
188
  @staticmethod
187
- def __encode_ec_coord(coord) -> str:
189
+ def __encode_ec_coord(coord: int) -> str:
188
190
  return RequestSigner.__base64_escaped(coord.to_bytes(32, "big"))
@@ -3,20 +3,26 @@ Signed Session
3
3
  A wrapper around httpx' AsyncClient which transparently calculates the "Signature" header.
4
4
  """
5
5
 
6
+ from ssl import SSLContext
7
+
6
8
  import httpx
9
+ from httpx import Response
7
10
 
8
- from ssl import SSLContext
9
11
  from pythonxbox.common.request_signer import RequestSigner
10
12
 
11
13
 
12
14
  class SignedSession(httpx.AsyncClient):
13
- def __init__(self, request_signer=None, ssl_context: SSLContext = None):
15
+ def __init__(
16
+ self,
17
+ request_signer: RequestSigner | None = None,
18
+ ssl_context: SSLContext | None = None,
19
+ ) -> None:
14
20
  super().__init__(verify=ssl_context if ssl_context is not None else True)
15
21
 
16
22
  self.request_signer = request_signer or RequestSigner()
17
23
 
18
24
  @classmethod
19
- def from_pem_signing_key(cls, pem_string: str):
25
+ def from_pem_signing_key(cls, pem_string: str) -> "SignedSession":
20
26
  request_signer = RequestSigner.from_pem(pem_string)
21
27
  return cls(request_signer)
22
28
 
@@ -45,7 +51,7 @@ class SignedSession(httpx.AsyncClient):
45
51
  prepared = self._prepare_signed_request(request)
46
52
  return await self.send(prepared)
47
53
 
48
- async def send_signed(self, method: str, url: str, **kwargs):
54
+ async def send_signed(self, method: str, url: str, **kwargs) -> Response:
49
55
  """
50
56
  Shorthand for creating request + prepare signed + send
51
57
  """
File without changes
@@ -25,7 +25,7 @@ class AuthCallbackRequestHandler(http.server.BaseHTTPRequestHandler):
25
25
  Handles the auth callback that's received when Windows Live auth flow completed
26
26
  """
27
27
 
28
- def do_GET(self):
28
+ def do_GET(self) -> None:
29
29
  try:
30
30
  url_path = self.requestline.split(" ")[1]
31
31
  query_params = parse_qs(urlparse(url_path).query)
@@ -73,7 +73,7 @@ class AuthCallbackRequestHandler(http.server.BaseHTTPRequestHandler):
73
73
 
74
74
  async def do_auth(
75
75
  client_id: str, client_secret: str, redirect_uri: str, token_filepath: str
76
- ):
76
+ ) -> None:
77
77
  async with SignedSession() as session:
78
78
  auth_mgr = AuthenticationManager(
79
79
  session, client_id, client_secret, redirect_uri
@@ -99,7 +99,7 @@ async def do_auth(
99
99
  f.write(auth_mgr.oauth.model_dump_json())
100
100
 
101
101
 
102
- async def async_main():
102
+ async def async_main() -> None:
103
103
  parser = argparse.ArgumentParser(description="Authenticate with XBL")
104
104
  parser.add_argument(
105
105
  "--tokens",
@@ -151,7 +151,7 @@ async def async_main():
151
151
  )
152
152
 
153
153
 
154
- def main():
154
+ def main() -> None:
155
155
  asyncio.run(async_main())
156
156
 
157
157
 
@@ -20,7 +20,7 @@ from pythonxbox.common.signed_session import SignedSession
20
20
  from pythonxbox.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
21
21
 
22
22
 
23
- async def async_main():
23
+ async def async_main() -> None:
24
24
  parser = argparse.ArgumentParser(description="Change your gamertag")
25
25
  parser.add_argument(
26
26
  "--tokens",
@@ -103,7 +103,7 @@ async def async_main():
103
103
  print("Gamertag successfully changed to %s" % args.gamertag)
104
104
 
105
105
 
106
- def main():
106
+ def main() -> None:
107
107
  asyncio.run(async_main())
108
108
 
109
109
 
@@ -17,7 +17,7 @@ from pythonxbox.common.signed_session import SignedSession
17
17
  from pythonxbox.scripts import CLIENT_ID, CLIENT_SECRET, TOKENS_FILE
18
18
 
19
19
 
20
- async def async_main():
20
+ async def async_main() -> None:
21
21
  parser = argparse.ArgumentParser(description="Change your gamertag")
22
22
  parser.add_argument(
23
23
  "--tokens",
@@ -72,7 +72,7 @@ async def async_main():
72
72
  pprint(resp.dict())
73
73
 
74
74
 
75
- def main():
75
+ def main() -> None:
76
76
  asyncio.run(async_main())
77
77
 
78
78
 
@@ -14,7 +14,7 @@ from pythonxbox.authentication.manager import AuthenticationManager
14
14
  from pythonxbox.common.signed_session import SignedSession
15
15
 
16
16
 
17
- async def async_main():
17
+ async def async_main() -> None:
18
18
  parser = argparse.ArgumentParser(description="Search for Content on XBL")
19
19
  parser.add_argument("search_query", help="Name to search for")
20
20
 
@@ -35,7 +35,7 @@ async def async_main():
35
35
  pprint(resp.dict())
36
36
 
37
37
 
38
- def main():
38
+ def main() -> None:
39
39
  asyncio.run(async_main())
40
40
 
41
41
 
@@ -50,7 +50,7 @@ def user_prompt_authentication(auth_url: str) -> str:
50
50
  return redirect_url
51
51
 
52
52
 
53
- async def do_auth(device_id: uuid.UUID, token_filepath: str):
53
+ async def do_auth(device_id: uuid.UUID, token_filepath: str) -> None:
54
54
  async with SignedSession() as session:
55
55
  app_params = APP_PARAMS_GAMEPASS_BETA
56
56
  client_params = CLIENT_PARAMS_ANDROID
@@ -85,7 +85,7 @@ async def do_auth(device_id: uuid.UUID, token_filepath: str):
85
85
  json.dump(store, f, default=pydantic_encoder)
86
86
 
87
87
 
88
- async def async_main():
88
+ async def async_main() -> None:
89
89
  parser = argparse.ArgumentParser(description="Authenticate with XBL via XAL")
90
90
  parser.add_argument(
91
91
  "--tokens",
@@ -105,7 +105,7 @@ async def async_main():
105
105
  await do_auth(args.device_id, args.tokens)
106
106
 
107
107
 
108
- def main():
108
+ def main() -> None:
109
109
  asyncio.run(async_main())
110
110
 
111
111
 
File without changes