githubkit 0.11.0a2__py3-none-any.whl → 0.11.0a4__py3-none-any.whl

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 (111) hide show
  1. githubkit/compat.py +16 -2
  2. githubkit/core.py +72 -7
  3. githubkit/exception.py +24 -0
  4. githubkit/github.py +4 -2
  5. githubkit/graphql/__init__.py +13 -2
  6. githubkit/graphql/models.py +1 -0
  7. githubkit/typing.py +3 -3
  8. githubkit/utils.py +2 -17
  9. githubkit/versions/latest/__init__.py +8 -0
  10. githubkit/versions/rest.py +20 -6
  11. githubkit/versions/v2022_11_28/__init__.py +8 -0
  12. githubkit/versions/v2022_11_28/models/group_0002.py +2 -2
  13. githubkit/versions/v2022_11_28/models/group_0027.py +3 -5
  14. githubkit/versions/v2022_11_28/models/group_0041.py +1 -3
  15. githubkit/versions/v2022_11_28/models/group_0112.py +3 -2
  16. githubkit/versions/v2022_11_28/models/group_0127.py +1 -0
  17. githubkit/versions/v2022_11_28/models/group_0131.py +2 -2
  18. githubkit/versions/v2022_11_28/models/group_0169.py +1 -3
  19. githubkit/versions/v2022_11_28/models/group_0190.py +5 -4
  20. githubkit/versions/v2022_11_28/models/group_0225.py +2 -1
  21. githubkit/versions/v2022_11_28/models/group_0227.py +7 -4
  22. githubkit/versions/v2022_11_28/models/group_0228.py +2 -2
  23. githubkit/versions/v2022_11_28/models/group_0240.py +1 -3
  24. githubkit/versions/v2022_11_28/models/group_0313.py +5 -4
  25. githubkit/versions/v2022_11_28/models/group_0314.py +5 -4
  26. githubkit/versions/v2022_11_28/models/group_0315.py +4 -3
  27. githubkit/versions/v2022_11_28/models/group_0824.py +1 -3
  28. githubkit/versions/v2022_11_28/models/group_0825.py +1 -3
  29. githubkit/versions/v2022_11_28/models/group_0838.py +4 -2
  30. githubkit/versions/v2022_11_28/models/group_0841.py +3 -2
  31. githubkit/versions/v2022_11_28/models/group_0842.py +4 -2
  32. githubkit/versions/v2022_11_28/models/group_0845.py +2 -8
  33. githubkit/versions/v2022_11_28/models/group_0854.py +2 -1
  34. githubkit/versions/v2022_11_28/models/group_0855.py +3 -2
  35. githubkit/versions/v2022_11_28/models/group_0856.py +3 -2
  36. githubkit/versions/v2022_11_28/models/group_0858.py +2 -8
  37. githubkit/versions/v2022_11_28/models/group_0861.py +3 -2
  38. githubkit/versions/v2022_11_28/models/group_0863.py +3 -2
  39. githubkit/versions/v2022_11_28/models/group_0865.py +3 -2
  40. githubkit/versions/v2022_11_28/models/group_0867.py +3 -2
  41. githubkit/versions/v2022_11_28/models/group_0870.py +2 -8
  42. githubkit/versions/v2022_11_28/models/group_0887.py +3 -3
  43. githubkit/versions/v2022_11_28/models/group_0889.py +4 -2
  44. githubkit/versions/v2022_11_28/models/group_0892.py +5 -3
  45. githubkit/versions/v2022_11_28/models/group_0894.py +4 -2
  46. githubkit/versions/v2022_11_28/models/group_0913.py +3 -2
  47. githubkit/versions/v2022_11_28/models/group_0921.py +3 -2
  48. githubkit/versions/v2022_11_28/models/group_0937.py +4 -2
  49. githubkit/versions/v2022_11_28/models/group_0938.py +3 -2
  50. githubkit/versions/v2022_11_28/models/group_0939.py +4 -2
  51. githubkit/versions/v2022_11_28/models/group_0948.py +2 -8
  52. githubkit/versions/v2022_11_28/models/group_0972.py +16 -13
  53. githubkit/versions/v2022_11_28/models/group_0973.py +2 -5
  54. githubkit/versions/v2022_11_28/models/group_0974.py +2 -5
  55. githubkit/versions/v2022_11_28/models/group_0975.py +14 -17
  56. githubkit/versions/v2022_11_28/models/group_0976.py +2 -4
  57. githubkit/versions/v2022_11_28/models/group_0977.py +2 -4
  58. githubkit/versions/v2022_11_28/models/group_0982.py +8 -6
  59. githubkit/versions/v2022_11_28/models/group_0989.py +2 -8
  60. githubkit/versions/v2022_11_28/models/group_0997.py +2 -1
  61. githubkit/versions/v2022_11_28/models/group_0999.py +2 -8
  62. githubkit/versions/v2022_11_28/models/group_1004.py +4 -2
  63. githubkit/versions/v2022_11_28/models/group_1032.py +2 -1
  64. githubkit/versions/v2022_11_28/models/group_1033.py +2 -5
  65. githubkit/versions/v2022_11_28/models/group_1035.py +2 -1
  66. githubkit/versions/v2022_11_28/models/group_1036.py +2 -5
  67. githubkit/versions/v2022_11_28/models/group_1094.py +3 -7
  68. githubkit/versions/v2022_11_28/models/group_1114.py +2 -8
  69. githubkit/versions/v2022_11_28/models/group_1127.py +4 -3
  70. githubkit/versions/v2022_11_28/models/group_1134.py +3 -7
  71. githubkit/versions/v2022_11_28/rest/__init__.py +11 -1
  72. githubkit/versions/v2022_11_28/rest/actions.py +11 -1
  73. githubkit/versions/v2022_11_28/rest/activity.py +11 -1
  74. githubkit/versions/v2022_11_28/rest/apps.py +11 -1
  75. githubkit/versions/v2022_11_28/rest/billing.py +11 -1
  76. githubkit/versions/v2022_11_28/rest/checks.py +11 -1
  77. githubkit/versions/v2022_11_28/rest/classroom.py +11 -1
  78. githubkit/versions/v2022_11_28/rest/code_scanning.py +11 -1
  79. githubkit/versions/v2022_11_28/rest/codes_of_conduct.py +11 -1
  80. githubkit/versions/v2022_11_28/rest/codespaces.py +11 -1
  81. githubkit/versions/v2022_11_28/rest/copilot.py +11 -1
  82. githubkit/versions/v2022_11_28/rest/dependabot.py +11 -1
  83. githubkit/versions/v2022_11_28/rest/dependency_graph.py +11 -1
  84. githubkit/versions/v2022_11_28/rest/emojis.py +11 -1
  85. githubkit/versions/v2022_11_28/rest/gists.py +11 -1
  86. githubkit/versions/v2022_11_28/rest/git.py +11 -1
  87. githubkit/versions/v2022_11_28/rest/gitignore.py +11 -1
  88. githubkit/versions/v2022_11_28/rest/interactions.py +11 -1
  89. githubkit/versions/v2022_11_28/rest/issues.py +11 -1
  90. githubkit/versions/v2022_11_28/rest/licenses.py +11 -1
  91. githubkit/versions/v2022_11_28/rest/markdown.py +11 -1
  92. githubkit/versions/v2022_11_28/rest/meta.py +11 -1
  93. githubkit/versions/v2022_11_28/rest/migrations.py +11 -1
  94. githubkit/versions/v2022_11_28/rest/oidc.py +11 -1
  95. githubkit/versions/v2022_11_28/rest/orgs.py +11 -1
  96. githubkit/versions/v2022_11_28/rest/packages.py +11 -1
  97. githubkit/versions/v2022_11_28/rest/projects.py +11 -1
  98. githubkit/versions/v2022_11_28/rest/pulls.py +11 -1
  99. githubkit/versions/v2022_11_28/rest/rate_limit.py +11 -1
  100. githubkit/versions/v2022_11_28/rest/reactions.py +11 -1
  101. githubkit/versions/v2022_11_28/rest/repos.py +13 -1
  102. githubkit/versions/v2022_11_28/rest/search.py +11 -1
  103. githubkit/versions/v2022_11_28/rest/secret_scanning.py +11 -1
  104. githubkit/versions/v2022_11_28/rest/security_advisories.py +11 -1
  105. githubkit/versions/v2022_11_28/rest/teams.py +11 -1
  106. githubkit/versions/v2022_11_28/rest/users.py +11 -1
  107. githubkit/versions/v2022_11_28/types/group_0127.py +1 -0
  108. {githubkit-0.11.0a2.dist-info → githubkit-0.11.0a4.dist-info}/METADATA +22 -6
  109. {githubkit-0.11.0a2.dist-info → githubkit-0.11.0a4.dist-info}/RECORD +111 -109
  110. {githubkit-0.11.0a2.dist-info → githubkit-0.11.0a4.dist-info}/LICENSE +0 -0
  111. {githubkit-0.11.0a2.dist-info → githubkit-0.11.0a4.dist-info}/WHEEL +0 -0
githubkit/compat.py CHANGED
@@ -29,8 +29,9 @@ if TYPE_CHECKING:
29
29
  CVC = TypeVar("CVC", bound=CustomValidationClass)
30
30
 
31
31
 
32
- if PYDANTIC_V2:
32
+ if PYDANTIC_V2: # pragma: pydantic-v2
33
33
  from pydantic_core import CoreSchema, core_schema
34
+ from pydantic_core import to_jsonable_python as to_jsonable_python
34
35
  from pydantic import (
35
36
  BaseModel,
36
37
  ConfigDict,
@@ -80,7 +81,8 @@ if PYDANTIC_V2:
80
81
  )
81
82
  return class_
82
83
 
83
- else:
84
+ else: # pragma: pydantic-v1
85
+ from pydantic.json import pydantic_encoder
84
86
  from pydantic import Extra, BaseModel, parse_obj_as, parse_raw_as, root_validator
85
87
 
86
88
  class GitHubModel(BaseModel):
@@ -97,6 +99,18 @@ else:
97
99
  def type_validate_json(type_: Type[T], data: Any) -> T:
98
100
  return parse_raw_as(type_, data)
99
101
 
102
+ def to_jsonable_python(obj: Any) -> Any:
103
+ if isinstance(obj, dict):
104
+ return {k: to_jsonable_python(v) for k, v in obj.items()}
105
+
106
+ if isinstance(obj, (list, tuple)):
107
+ return [to_jsonable_python(item) for item in obj]
108
+
109
+ if obj is None or isinstance(obj, (int, float, str, bool)):
110
+ return obj
111
+
112
+ return pydantic_encoder(obj)
113
+
100
114
  def model_dump(model: BaseModel, by_alias: bool = True) -> Dict[str, Any]:
101
115
  return model.dict(by_alias=by_alias)
102
116
 
githubkit/core.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from types import TracebackType
2
2
  from contextvars import ContextVar
3
+ from datetime import datetime, timezone, timedelta
3
4
  from contextlib import contextmanager, asynccontextmanager
4
5
  from typing import (
5
6
  Any,
@@ -20,9 +21,8 @@ import httpx
20
21
  import hishel
21
22
 
22
23
  from .response import Response
23
- from .utils import obj_to_jsonable
24
+ from .compat import to_jsonable_python
24
25
  from .config import Config, get_config
25
- from .exception import RequestError, RequestFailed, RequestTimeout
26
26
  from .auth import BaseAuthStrategy, TokenAuthStrategy, UnauthAuthStrategy
27
27
  from .typing import (
28
28
  URLTypes,
@@ -32,6 +32,13 @@ from .typing import (
32
32
  RequestFiles,
33
33
  QueryParamTypes,
34
34
  )
35
+ from .exception import (
36
+ RequestError,
37
+ RequestFailed,
38
+ RequestTimeout,
39
+ PrimaryRateLimitExceeded,
40
+ SecondaryRateLimitExceeded,
41
+ )
35
42
 
36
43
  T = TypeVar("T")
37
44
  A = TypeVar("A", bound="BaseAuthStrategy")
@@ -265,7 +272,7 @@ class GitHubCore(Generic[A]):
265
272
  content=content,
266
273
  data=data,
267
274
  files=files,
268
- json=obj_to_jsonable(json),
275
+ json=to_jsonable_python(json),
269
276
  headers=headers,
270
277
  cookies=cookies,
271
278
  )
@@ -297,7 +304,7 @@ class GitHubCore(Generic[A]):
297
304
  content=content,
298
305
  data=data,
299
306
  files=files,
300
- json=obj_to_jsonable(json),
307
+ json=to_jsonable_python(json),
301
308
  headers=headers,
302
309
  cookies=cookies,
303
310
  )
@@ -316,15 +323,73 @@ class GitHubCore(Generic[A]):
316
323
  if response.is_error:
317
324
  error_models = error_models or {}
318
325
  status_code = str(response.status_code)
326
+
319
327
  error_model = error_models.get(
320
328
  status_code,
321
329
  error_models.get(
322
330
  f"{status_code[:-2]}XX", error_models.get("default", Any)
323
331
  ),
324
332
  )
325
- rep = Response(response, error_model)
326
- raise RequestFailed(rep)
327
- return Response(response, response_model)
333
+ resp = Response(response, error_model)
334
+ else:
335
+ resp = Response(response, response_model)
336
+
337
+ # only check rate limit when response is 403 or 429
338
+ if response.status_code in (403, 429):
339
+ self._check_rate_limit(resp)
340
+
341
+ if response.is_error:
342
+ raise RequestFailed(resp)
343
+ return resp
344
+
345
+ # check rate limit
346
+ def _check_rate_limit(self, response: Response) -> None:
347
+ # check rate limit exceeded
348
+ # https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api#exceeding-the-rate-limit
349
+ # https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api#exceeding-the-rate-limit
350
+ # https://github.com/octokit/plugin-throttling.js/blob/135a0f556752a6c4c0ed3b2798bb58e228cd179a/src/index.ts#L134-L179
351
+
352
+ # Secondary rate limits
353
+ # the `retry-after` response header is present
354
+ if "retry-after" in response.headers:
355
+ raise SecondaryRateLimitExceeded(
356
+ response, self._extract_retry_after(response)
357
+ )
358
+
359
+ if (
360
+ "x-ratelimit-remaining" in response.headers
361
+ and response.headers["x-ratelimit-remaining"] == "0"
362
+ ):
363
+ retry_after = self._extract_retry_after(response)
364
+
365
+ try:
366
+ error = response.json()
367
+ except Exception:
368
+ error = None
369
+
370
+ # Secondary rate limits
371
+ # error message indicates that you exceeded a secondary rate limit
372
+ if (
373
+ isinstance(error, dict)
374
+ and "message" in error
375
+ and "secondary rate" in error["message"]
376
+ ):
377
+ raise SecondaryRateLimitExceeded(response, retry_after)
378
+
379
+ # Primary rate limits
380
+ raise PrimaryRateLimitExceeded(response, retry_after)
381
+
382
+ def _extract_retry_after(self, response: Response) -> timedelta:
383
+ if "retry-after" in response.headers:
384
+ return timedelta(seconds=int(response.headers["retry-after"]))
385
+ elif "x-ratelimit-reset" in response.headers:
386
+ retry_after = datetime.fromtimestamp(
387
+ int(response.headers["x-ratelimit-reset"]), tz=timezone.utc
388
+ ) - datetime.now(tz=timezone.utc)
389
+ return max(retry_after, timedelta())
390
+ else:
391
+ # wait for at least one minute before retrying
392
+ return timedelta(seconds=60)
328
393
 
329
394
  # sync request and check
330
395
  def request(
githubkit/exception.py CHANGED
@@ -1,3 +1,4 @@
1
+ from datetime import timedelta
1
2
  from typing import TYPE_CHECKING
2
3
 
3
4
  import httpx
@@ -50,6 +51,29 @@ class RequestFailed(GitHubException):
50
51
  )
51
52
 
52
53
 
54
+ class RateLimitExceeded(RequestFailed):
55
+ """API request failed with rate limit exceeded"""
56
+
57
+ def __init__(self, response: "Response", retry_after: timedelta):
58
+ super().__init__(response)
59
+ self.retry_after = retry_after
60
+
61
+ def __repr__(self) -> str:
62
+ return (
63
+ f"{self.__class__.__name__}(method={self.request.method}, "
64
+ f"url={self.request.url}, status_code={self.response.status_code}, "
65
+ f"retry_after={self.retry_after})"
66
+ )
67
+
68
+
69
+ class PrimaryRateLimitExceeded(RateLimitExceeded):
70
+ """API request failed with primary rate limit exceeded"""
71
+
72
+
73
+ class SecondaryRateLimitExceeded(RateLimitExceeded):
74
+ """API request failed with secondary rate limit exceeded"""
75
+
76
+
53
77
  class GraphQLFailed(GitHubException):
54
78
  """GraphQL request with errors in response"""
55
79
 
githubkit/github.py CHANGED
@@ -142,7 +142,8 @@ class GitHub(GitHubCore[A]):
142
142
  json = build_graphql_request(query, variables)
143
143
 
144
144
  return parse_graphql_response(
145
- self.request("POST", "/graphql", json=json, response_model=GraphQLResponse)
145
+ self,
146
+ self.request("POST", "/graphql", json=json, response_model=GraphQLResponse),
146
147
  )
147
148
 
148
149
  async def async_graphql(
@@ -151,9 +152,10 @@ class GitHub(GitHubCore[A]):
151
152
  json = build_graphql_request(query, variables)
152
153
 
153
154
  return parse_graphql_response(
155
+ self,
154
156
  await self.arequest(
155
157
  "POST", "/graphql", json=json, response_model=GraphQLResponse
156
- )
158
+ ),
157
159
  )
158
160
 
159
161
  # rest pagination
@@ -1,12 +1,13 @@
1
1
  from typing import TYPE_CHECKING, Any, Dict, Optional, cast
2
2
 
3
- from githubkit.exception import GraphQLFailed
3
+ from githubkit.exception import GraphQLFailed, PrimaryRateLimitExceeded
4
4
 
5
5
  from .models import GraphQLError as GraphQLError
6
6
  from .models import SourceLocation as SourceLocation
7
7
  from .models import GraphQLResponse as GraphQLResponse
8
8
 
9
9
  if TYPE_CHECKING:
10
+ from githubkit.core import GitHubCore
10
11
  from githubkit.response import Response
11
12
 
12
13
 
@@ -19,8 +20,18 @@ def build_graphql_request(
19
20
  return json
20
21
 
21
22
 
22
- def parse_graphql_response(response: "Response[GraphQLResponse]") -> Dict[str, Any]:
23
+ def parse_graphql_response(
24
+ github: "GitHubCore", response: "Response[GraphQLResponse]"
25
+ ) -> Dict[str, Any]:
23
26
  response_data = response.parsed_data
24
27
  if response_data.errors:
28
+ # check rate limit exceeded
29
+ # https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api#exceeding-the-rate-limit
30
+ # x-ratelimit-remaining may not be 0, ignore it
31
+ # https://github.com/octokit/plugin-throttling.js/pull/636
32
+ if any(error.type == "RATE_LIMITED" for error in response_data.errors):
33
+ raise PrimaryRateLimitExceeded(
34
+ response, github._extract_retry_after(response)
35
+ )
25
36
  raise GraphQLFailed(response_data)
26
37
  return cast(Dict[str, Any], response_data.data)
@@ -9,6 +9,7 @@ class SourceLocation(GitHubModel):
9
9
 
10
10
 
11
11
  class GraphQLError(GitHubModel):
12
+ type: str # https://github.com/octokit/graphql.js/pull/314
12
13
  message: str
13
14
  locations: Optional[List[SourceLocation]] = None
14
15
  path: Optional[List[Union[int, str]]] = None
githubkit/typing.py CHANGED
@@ -45,7 +45,7 @@ FileTypes: TypeAlias = Union[
45
45
  ]
46
46
  RequestFiles: TypeAlias = Union[Dict[str, FileTypes], List[Tuple[str, FileTypes]]]
47
47
 
48
- if PYDANTIC_V2:
48
+ if PYDANTIC_V2: # pragma: pydantic-v2
49
49
  from pydantic import AfterValidator
50
50
  from pydantic_core import PydanticCustomError
51
51
 
@@ -59,9 +59,9 @@ if PYDANTIC_V2:
59
59
  AfterValidator(_validate_unique_list),
60
60
  Field(json_schema_extra={"uniqueItems": True}),
61
61
  ]
62
- else:
62
+ else: # pragma: pydantic-v1
63
63
  UniqueList: TypeAlias = Annotated[List[H], Field(unique_items=True)] # type: ignore
64
64
 
65
65
  # if the property is not required, we allow it to have the value null.
66
66
  # See https://github.com/yanyongyu/githubkit/issues/47
67
- Missing: TypeAlias = Annotated[Union[Literal[UNSET], T, None], Field(default=UNSET)]
67
+ Missing: TypeAlias = Union[Literal[UNSET], T, None]
githubkit/utils.py CHANGED
@@ -3,11 +3,10 @@ from enum import Enum
3
3
  from typing import Any, Dict, Type, Generic, Literal, TypeVar, final
4
4
 
5
5
  from pydantic import BaseModel
6
- from pydantic_core import to_jsonable_python
7
6
 
8
7
  from .compat import PYDANTIC_V2, custom_validation, type_validate_python
9
8
 
10
- if PYDANTIC_V2:
9
+ if PYDANTIC_V2: # pragma: pydantic-v2
11
10
  from pydantic_core import core_schema
12
11
  from pydantic import GetCoreSchemaHandler
13
12
 
@@ -69,20 +68,6 @@ def is_async(obj: Any) -> bool:
69
68
  return inspect.iscoroutinefunction(func_)
70
69
 
71
70
 
72
- # FIXME: remove pydantic-core dependency
73
- def obj_to_jsonable(obj: Any) -> Any:
74
- if isinstance(obj, dict):
75
- return {k: obj_to_jsonable(v) for k, v in obj.items()}
76
-
77
- if isinstance(obj, (list, tuple)):
78
- return [obj_to_jsonable(item) for item in obj]
79
-
80
- if obj is None or isinstance(obj, (int, float, str, bool)):
81
- return obj
82
-
83
- return to_jsonable_python(obj)
84
-
85
-
86
71
  class TaggedUnion(Generic[T]):
87
72
  __slots__ = ("type_", "discriminator", "tag")
88
73
 
@@ -94,7 +79,7 @@ class TaggedUnion(Generic[T]):
94
79
  def _validate(self, value: Any) -> T:
95
80
  return type_validate_python(self.type_, value)
96
81
 
97
- if PYDANTIC_V2:
82
+ if PYDANTIC_V2: # pragma: pydantic-v2
98
83
 
99
84
  def __get_pydantic_core_schema__(
100
85
  self, _source_type: Any, _handler: "GetCoreSchemaHandler"
@@ -0,0 +1,8 @@
1
+ """DO NOT EDIT THIS FILE!
2
+
3
+ This file is automatically @generated by githubkit using the follow command:
4
+
5
+ python -m codegen && isort . && black .
6
+
7
+ See https://github.com/github/rest-api-description for more information.
8
+ """
@@ -8,6 +8,7 @@ See https://github.com/github/rest-api-description for more information.
8
8
  """
9
9
 
10
10
  import importlib
11
+ from weakref import WeakKeyDictionary, ref
11
12
  from typing import TYPE_CHECKING, Any, Dict, Literal, overload
12
13
 
13
14
  from . import VERSIONS, VERSION_TYPE, LATEST_VERSION
@@ -27,7 +28,9 @@ else:
27
28
 
28
29
 
29
30
  class RestVersionSwitcher(_VersionProxy):
30
- _cached_namespaces: Dict[VERSION_TYPE, Any] = {}
31
+ _cached_namespaces: "WeakKeyDictionary[GitHubCore, Dict[VERSION_TYPE, Any]]" = (
32
+ WeakKeyDictionary()
33
+ )
31
34
 
32
35
  if not TYPE_CHECKING:
33
36
 
@@ -40,7 +43,16 @@ class RestVersionSwitcher(_VersionProxy):
40
43
  return getattr(namespace, name)
41
44
 
42
45
  def __init__(self, github: "GitHubCore"):
43
- self._github = github
46
+ self._github_ref = ref(github)
47
+
48
+ @property
49
+ def _github(self) -> "GitHubCore":
50
+ if g := self._github_ref():
51
+ return g
52
+ raise RuntimeError(
53
+ "GitHub client has already been collected. "
54
+ "Do not use the namespace after the client has been collected."
55
+ )
44
56
 
45
57
  @overload
46
58
  def __call__(self, version: Literal["2022-11-28"]) -> "V20221128RestNamespace":
@@ -51,9 +63,11 @@ class RestVersionSwitcher(_VersionProxy):
51
63
  ...
52
64
 
53
65
  def __call__(self, version: VERSION_TYPE = LATEST_VERSION) -> Any:
54
- if version in self._cached_namespaces:
55
- return self._cached_namespaces[version]
66
+ g = self._github
67
+ cache = self._cached_namespaces.setdefault(g, {})
68
+ if version in cache:
69
+ return cache[version]
56
70
  module = importlib.import_module(f".{VERSIONS[version]}.rest", __package__)
57
- namespace = module.RestNamespace(self._github)
58
- self._cached_namespaces[version] = namespace
71
+ namespace = module.RestNamespace(g)
72
+ cache[version] = namespace
59
73
  return namespace
@@ -0,0 +1,8 @@
1
+ """DO NOT EDIT THIS FILE!
2
+
3
+ This file is automatically @generated by githubkit using the follow command:
4
+
5
+ python -m codegen && isort . && black .
6
+
7
+ See https://github.com/github/rest-api-description for more information.
8
+ """
@@ -56,8 +56,8 @@ class GlobalAdvisory(GitHubModel):
56
56
  repository_advisory_url: Union[str, None] = Field(
57
57
  description="The API URL for the repository advisory."
58
58
  )
59
- summary: Annotated[str, Field(max_length=1024)] = Field(
60
- description="A short summary of the advisory."
59
+ summary: str = Field(
60
+ max_length=1024, description="A short summary of the advisory."
61
61
  )
62
62
  description: Union[Annotated[str, Field(max_length=65535)], None] = Field(
63
63
  description="A detailed description of what the advisory entails."
@@ -33,8 +33,8 @@ class DependabotAlertSecurityAdvisory(GitHubModel):
33
33
  cve_id: Union[str, None] = Field(
34
34
  description="The unique CVE ID assigned to the advisory."
35
35
  )
36
- summary: Annotated[str, Field(max_length=1024)] = Field(
37
- description="A short, plain text summary of the advisory."
36
+ summary: str = Field(
37
+ max_length=1024, description="A short, plain text summary of the advisory."
38
38
  )
39
39
  description: str = Field(
40
40
  description="A long-form Markdown-supported description of the advisory."
@@ -74,9 +74,7 @@ class DependabotAlertSecurityAdvisoryPropCvss(GitHubModel):
74
74
  Details for the advisory pertaining to the Common Vulnerability Scoring System.
75
75
  """
76
76
 
77
- score: Annotated[float, Field(le=10.0)] = Field(
78
- description="The overall CVSS score of the advisory."
79
- )
77
+ score: float = Field(le=10.0, description="The overall CVSS score of the advisory.")
80
78
  vector_string: Union[str, None] = Field(
81
79
  description="The full CVSS vector string for the advisory."
82
80
  )
@@ -32,9 +32,7 @@ class GistComment(GitHubModel):
32
32
  id: int = Field()
33
33
  node_id: str = Field()
34
34
  url: str = Field()
35
- body: Annotated[str, Field(max_length=65535)] = Field(
36
- description="The comment text."
37
- )
35
+ body: str = Field(max_length=65535, description="The comment text.")
38
36
  user: Union[None, SimpleUser] = Field()
39
37
  created_at: datetime = Field()
40
38
  updated_at: datetime = Field()
@@ -29,8 +29,9 @@ class RepositoryRulePullRequestPropParameters(GitHubModel):
29
29
  require_last_push_approval: bool = Field(
30
30
  description="Whether the most recent reviewable push must be approved by someone other than the person who pushed it."
31
31
  )
32
- required_approving_review_count: Annotated[int, Field(le=10.0)] = Field(
33
- description="The number of approving reviews that are required before a pull request can be merged."
32
+ required_approving_review_count: int = Field(
33
+ le=10.0,
34
+ description="The number of approving reviews that are required before a pull request can be merged.",
34
35
  )
35
36
  required_review_thread_resolution: bool = Field(
36
37
  description="All conversations on code must be resolved before a pull request can be merged."
@@ -78,6 +78,7 @@ class RepositoryRuleset(GitHubModel):
78
78
  RepositoryRulesetConditions,
79
79
  OrgRulesetConditionsOneof0,
80
80
  OrgRulesetConditionsOneof1,
81
+ None,
81
82
  ]
82
83
  ] = Field(default=UNSET)
83
84
  rules: Missing[
@@ -37,8 +37,8 @@ class RepositoryAdvisory(GitHubModel):
37
37
  )
38
38
  url: str = Field(description="The API URL for the advisory.")
39
39
  html_url: str = Field(description="The URL for the advisory.")
40
- summary: Annotated[str, Field(max_length=1024)] = Field(
41
- description="A short summary of the advisory."
40
+ summary: str = Field(
41
+ max_length=1024, description="A short summary of the advisory."
42
42
  )
43
43
  description: Union[Annotated[str, Field(max_length=65535)], None] = Field(
44
44
  description="A detailed description of what the advisory entails."
@@ -44,9 +44,7 @@ class ProtectedBranchPullRequestReview(GitHubModel):
44
44
  )
45
45
  dismiss_stale_reviews: bool = Field()
46
46
  require_code_owner_reviews: bool = Field()
47
- required_approving_review_count: Missing[Annotated[int, Field(le=6.0)]] = Field(
48
- default=UNSET
49
- )
47
+ required_approving_review_count: Missing[int] = Field(le=6.0, default=UNSET)
50
48
  require_last_push_approval: Missing[bool] = Field(
51
49
  default=UNSET,
52
50
  description="Whether the most recent push must be approved by someone other than the person who pushed it.",
@@ -29,10 +29,11 @@ class CodeScanningAnalysis(GitHubModel):
29
29
  ref: str = Field(
30
30
  description="The Git reference, formatted as `refs/pull/<number>/merge`, `refs/pull/<number>/head`,\n`refs/heads/<branch name>` or simply `<branch name>`."
31
31
  )
32
- commit_sha: Annotated[
33
- str, Field(min_length=40, max_length=40, pattern="^[0-9a-fA-F]+$")
34
- ] = Field(
35
- description="The SHA of the commit to which the analysis you are uploading relates."
32
+ commit_sha: str = Field(
33
+ min_length=40,
34
+ max_length=40,
35
+ pattern="^[0-9a-fA-F]+$",
36
+ description="The SHA of the commit to which the analysis you are uploading relates.",
36
37
  )
37
38
  analysis_key: str = Field(
38
39
  description="Identifies the configuration under which the analysis was executed. For example, in GitHub Actions this includes the workflow filename and job name."
@@ -25,7 +25,8 @@ from .group_0224 import Metadata
25
25
  class Dependency(GitHubModel):
26
26
  """Dependency"""
27
27
 
28
- package_url: Missing[Annotated[str, Field(pattern="^pkg")]] = Field(
28
+ package_url: Missing[str] = Field(
29
+ pattern="^pkg",
29
30
  default=UNSET,
30
31
  description="Package-url (PURL) of dependency. See https://github.com/package-url/purl-spec for more details.",
31
32
  )
@@ -32,11 +32,14 @@ class Snapshot(GitHubModel):
32
32
  description="The version of the repository snapshot submission."
33
33
  )
34
34
  job: SnapshotPropJob = Field()
35
- sha: Annotated[str, Field(min_length=40, max_length=40)] = Field(
36
- description="The commit SHA associated with this dependency snapshot. Maximum length: 40 characters."
35
+ sha: str = Field(
36
+ min_length=40,
37
+ max_length=40,
38
+ description="The commit SHA associated with this dependency snapshot. Maximum length: 40 characters.",
37
39
  )
38
- ref: Annotated[str, Field(pattern="^refs/")] = Field(
39
- description="The repository branch that triggered this snapshot."
40
+ ref: str = Field(
41
+ pattern="^refs/",
42
+ description="The repository branch that triggered this snapshot.",
40
43
  )
41
44
  detector: SnapshotPropDetector = Field(
42
45
  description="A description of the detector used."
@@ -37,8 +37,8 @@ class DeploymentStatus(GitHubModel):
37
37
  "error", "failure", "inactive", "pending", "success", "queued", "in_progress"
38
38
  ] = Field(description="The state of the status.")
39
39
  creator: Union[None, SimpleUser] = Field()
40
- description: Annotated[str, Field(max_length=140)] = Field(
41
- default="", description="A short description of the status."
40
+ description: str = Field(
41
+ max_length=140, default="", description="A short description of the status."
42
42
  )
43
43
  environment: Missing[str] = Field(
44
44
  default=UNSET,
@@ -33,9 +33,7 @@ class GitRefPropObject(GitHubModel):
33
33
  """GitRefPropObject"""
34
34
 
35
35
  type: str = Field()
36
- sha: Annotated[str, Field(min_length=40, max_length=40)] = Field(
37
- description="SHA for the reference"
38
- )
36
+ sha: str = Field(min_length=40, max_length=40, description="SHA for the reference")
39
37
  url: str = Field()
40
38
 
41
39
 
@@ -23,11 +23,12 @@ from githubkit.compat import GitHubModel, model_rebuild
23
23
  class RepositoryAdvisoryCreate(GitHubModel):
24
24
  """RepositoryAdvisoryCreate"""
25
25
 
26
- summary: Annotated[str, Field(max_length=1024)] = Field(
27
- description="A short summary of the advisory."
26
+ summary: str = Field(
27
+ max_length=1024, description="A short summary of the advisory."
28
28
  )
29
- description: Annotated[str, Field(max_length=65535)] = Field(
30
- description="A detailed description of what the advisory impacts."
29
+ description: str = Field(
30
+ max_length=65535,
31
+ description="A detailed description of what the advisory impacts.",
31
32
  )
32
33
  cve_id: Missing[Union[str, None]] = Field(
33
34
  default=UNSET, description="The Common Vulnerabilities and Exposures (CVE) ID."
@@ -23,11 +23,12 @@ from githubkit.compat import GitHubModel, model_rebuild
23
23
  class PrivateVulnerabilityReportCreate(GitHubModel):
24
24
  """PrivateVulnerabilityReportCreate"""
25
25
 
26
- summary: Annotated[str, Field(max_length=1024)] = Field(
27
- description="A short summary of the advisory."
26
+ summary: str = Field(
27
+ max_length=1024, description="A short summary of the advisory."
28
28
  )
29
- description: Annotated[str, Field(max_length=65535)] = Field(
30
- description="A detailed description of what the advisory impacts."
29
+ description: str = Field(
30
+ max_length=65535,
31
+ description="A detailed description of what the advisory impacts.",
31
32
  )
32
33
  vulnerabilities: Missing[
33
34
  Union[List[PrivateVulnerabilityReportCreatePropVulnerabilitiesItems], None]
@@ -23,10 +23,11 @@ from githubkit.compat import GitHubModel, model_rebuild
23
23
  class RepositoryAdvisoryUpdate(GitHubModel):
24
24
  """RepositoryAdvisoryUpdate"""
25
25
 
26
- summary: Missing[Annotated[str, Field(max_length=1024)]] = Field(
27
- default=UNSET, description="A short summary of the advisory."
26
+ summary: Missing[str] = Field(
27
+ max_length=1024, default=UNSET, description="A short summary of the advisory."
28
28
  )
29
- description: Missing[Annotated[str, Field(max_length=65535)]] = Field(
29
+ description: Missing[str] = Field(
30
+ max_length=65535,
30
31
  default=UNSET,
31
32
  description="A detailed description of what the advisory impacts.",
32
33
  )
@@ -20,9 +20,7 @@ from githubkit.compat import GitHubModel, model_rebuild
20
20
  class GistsGistIdCommentsPostBody(GitHubModel):
21
21
  """GistsGistIdCommentsPostBody"""
22
22
 
23
- body: Annotated[str, Field(max_length=65535)] = Field(
24
- description="The comment text."
25
- )
23
+ body: str = Field(max_length=65535, description="The comment text.")
26
24
 
27
25
 
28
26
  model_rebuild(GistsGistIdCommentsPostBody)
@@ -20,9 +20,7 @@ from githubkit.compat import GitHubModel, model_rebuild
20
20
  class GistsGistIdCommentsCommentIdPatchBody(GitHubModel):
21
21
  """GistsGistIdCommentsCommentIdPatchBody"""
22
22
 
23
- body: Annotated[str, Field(max_length=65535)] = Field(
24
- description="The comment text."
25
- )
23
+ body: str = Field(max_length=65535, description="The comment text.")
26
24
 
27
25
 
28
26
  model_rebuild(GistsGistIdCommentsCommentIdPatchBody)