gitcode-api 1.1.3__tar.gz → 1.2.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.
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/PKG-INFO +18 -25
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/README.md +17 -24
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/__main__.py +2 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/_base_client.py +12 -4
- gitcode_api-1.2.1/gitcode_api/_base_resource.py +60 -0
- gitcode_api-1.2.1/gitcode_api/_cli_banner.py +31 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/_client.py +2 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/_models.py +7 -0
- gitcode_api-1.2.1/gitcode_api/cli.py +368 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/_shared.py +3 -2
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/collaboration.py +4 -4
- gitcode_api-1.2.1/gitcode_api/version.txt +1 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/PKG-INFO +18 -25
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/SOURCES.txt +2 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/pyproject.toml +12 -1
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_cli.py +72 -4
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_client.py +8 -14
- gitcode_api-1.1.3/gitcode_api/cli.py +0 -255
- gitcode_api-1.1.3/gitcode_api/version.txt +0 -1
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/LICENSE +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/__init__.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/_exceptions.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/__init__.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/account.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/misc.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api/resources/repositories.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/dependency_links.txt +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/entry_points.txt +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/requires.txt +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/gitcode_api.egg-info/top_level.txt +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/setup.cfg +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_base_client.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_models.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_resources_account.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_resources_collaboration.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_resources_misc.py +0 -0
- {gitcode_api-1.1.3 → gitcode_api-1.2.1}/tests/test_resources_repositories.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitcode-api
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Easy to use Python SDK for the GitCode REST API, community-maintained.
|
|
5
5
|
Author-email: Hugo Huang <hugo@hugohuang.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -29,7 +29,7 @@ Dynamic: license-file
|
|
|
29
29
|
|
|
30
30
|
[](https://pypi.org/project/gitcode-api) [](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API) [](https://pepy.tech/projects/gitcode-api)
|
|
31
31
|
|
|
32
|
-
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
32
|
+
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
33
33
|
|
|
34
34
|
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests.
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ Dynamic: license-file
|
|
|
37
37
|
|
|
38
38
|
- Community project for developers who want a practical GitCode Python library.
|
|
39
39
|
- Sync and async clients with a consistent API surface.
|
|
40
|
-
- Resource
|
|
40
|
+
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
41
41
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
42
42
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
43
43
|
|
|
@@ -120,7 +120,7 @@ asyncio.run(main())
|
|
|
120
120
|
|
|
121
121
|
### Context managers
|
|
122
122
|
|
|
123
|
-
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in.
|
|
123
|
+
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in. `close()` also clears the LRU cache used by each resource group's `method_signature(...)` helper (see the [Available Resources](#available-resources) section).
|
|
124
124
|
|
|
125
125
|
```python
|
|
126
126
|
from gitcode_api import GitCode
|
|
@@ -151,16 +151,13 @@ from gitcode_api import GitCode
|
|
|
151
151
|
|
|
152
152
|
client = GitCode(owner="SushiNinja", repo="GitCode-API")
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
print(pull.number)
|
|
162
|
-
finally:
|
|
163
|
-
client.close()
|
|
154
|
+
pull = client.pulls.create(
|
|
155
|
+
title="Add feature",
|
|
156
|
+
head="feature-branch",
|
|
157
|
+
base="main",
|
|
158
|
+
body="Implements the new flow.",
|
|
159
|
+
)
|
|
160
|
+
print(pull.number)
|
|
164
161
|
```
|
|
165
162
|
|
|
166
163
|
Get the authenticated user:
|
|
@@ -170,11 +167,8 @@ from gitcode_api import GitCode
|
|
|
170
167
|
|
|
171
168
|
client = GitCode()
|
|
172
169
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
print(user.login)
|
|
176
|
-
finally:
|
|
177
|
-
client.close()
|
|
170
|
+
user = client.users.me()
|
|
171
|
+
print(user.login)
|
|
178
172
|
```
|
|
179
173
|
|
|
180
174
|
Search repositories:
|
|
@@ -184,12 +178,9 @@ from gitcode_api import GitCode
|
|
|
184
178
|
|
|
185
179
|
client = GitCode()
|
|
186
180
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
print(repo.full_name)
|
|
191
|
-
finally:
|
|
192
|
-
client.close()
|
|
181
|
+
repos = client.search.repositories(q="sdk language:python", per_page=10)
|
|
182
|
+
for repo in repos:
|
|
183
|
+
print(repo.full_name)
|
|
193
184
|
```
|
|
194
185
|
|
|
195
186
|
## Available Resources
|
|
@@ -203,6 +194,8 @@ Both `GitCode` and `AsyncGitCode` expose:
|
|
|
203
194
|
- `releases`, `tags`, and `webhooks`
|
|
204
195
|
- `users`, `orgs`, `search`, and `oauth`
|
|
205
196
|
|
|
197
|
+
Every resource group inherits a cached `methods` property from the shared resource base: a `tuple` of public callable names in stable SDK order (underscore-segment sort key, not plain A–Z on the full identifier). Private names and the introspection helpers `methods` and `method_signature` are omitted. For example, `client.pulls.methods` helps with discovery or tooling without reading the full manual list. For one method’s parameters and return type, call `client.pulls.method_signature("list_issues")` (a cached string from `inspect.signature`, with `gitcode_api._models.` stripped from annotations).
|
|
198
|
+
|
|
206
199
|
## Examples
|
|
207
200
|
|
|
208
201
|
Runnable examples live in `examples/`:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/gitcode-api) [](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API) [](https://pepy.tech/projects/gitcode-api)
|
|
4
4
|
|
|
5
|
-
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
5
|
+
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
6
6
|
|
|
7
7
|
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests.
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
- Community project for developers who want a practical GitCode Python library.
|
|
12
12
|
- Sync and async clients with a consistent API surface.
|
|
13
|
-
- Resource
|
|
13
|
+
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
14
14
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
15
15
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
16
16
|
|
|
@@ -93,7 +93,7 @@ asyncio.run(main())
|
|
|
93
93
|
|
|
94
94
|
### Context managers
|
|
95
95
|
|
|
96
|
-
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in.
|
|
96
|
+
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in. `close()` also clears the LRU cache used by each resource group's `method_signature(...)` helper (see the [Available Resources](#available-resources) section).
|
|
97
97
|
|
|
98
98
|
```python
|
|
99
99
|
from gitcode_api import GitCode
|
|
@@ -124,16 +124,13 @@ from gitcode_api import GitCode
|
|
|
124
124
|
|
|
125
125
|
client = GitCode(owner="SushiNinja", repo="GitCode-API")
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
print(pull.number)
|
|
135
|
-
finally:
|
|
136
|
-
client.close()
|
|
127
|
+
pull = client.pulls.create(
|
|
128
|
+
title="Add feature",
|
|
129
|
+
head="feature-branch",
|
|
130
|
+
base="main",
|
|
131
|
+
body="Implements the new flow.",
|
|
132
|
+
)
|
|
133
|
+
print(pull.number)
|
|
137
134
|
```
|
|
138
135
|
|
|
139
136
|
Get the authenticated user:
|
|
@@ -143,11 +140,8 @@ from gitcode_api import GitCode
|
|
|
143
140
|
|
|
144
141
|
client = GitCode()
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
print(user.login)
|
|
149
|
-
finally:
|
|
150
|
-
client.close()
|
|
143
|
+
user = client.users.me()
|
|
144
|
+
print(user.login)
|
|
151
145
|
```
|
|
152
146
|
|
|
153
147
|
Search repositories:
|
|
@@ -157,12 +151,9 @@ from gitcode_api import GitCode
|
|
|
157
151
|
|
|
158
152
|
client = GitCode()
|
|
159
153
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
print(repo.full_name)
|
|
164
|
-
finally:
|
|
165
|
-
client.close()
|
|
154
|
+
repos = client.search.repositories(q="sdk language:python", per_page=10)
|
|
155
|
+
for repo in repos:
|
|
156
|
+
print(repo.full_name)
|
|
166
157
|
```
|
|
167
158
|
|
|
168
159
|
## Available Resources
|
|
@@ -176,6 +167,8 @@ Both `GitCode` and `AsyncGitCode` expose:
|
|
|
176
167
|
- `releases`, `tags`, and `webhooks`
|
|
177
168
|
- `users`, `orgs`, `search`, and `oauth`
|
|
178
169
|
|
|
170
|
+
Every resource group inherits a cached `methods` property from the shared resource base: a `tuple` of public callable names in stable SDK order (underscore-segment sort key, not plain A–Z on the full identifier). Private names and the introspection helpers `methods` and `method_signature` are omitted. For example, `client.pulls.methods` helps with discovery or tooling without reading the full manual list. For one method’s parameters and return type, call `client.pulls.method_signature("list_issues")` (a cached string from `inspect.signature`, with `gitcode_api._models.` stripped from annotations).
|
|
171
|
+
|
|
179
172
|
## Examples
|
|
180
173
|
|
|
181
174
|
Runnable examples live in `examples/`:
|
|
@@ -10,6 +10,7 @@ from urllib.parse import quote
|
|
|
10
10
|
|
|
11
11
|
import httpx
|
|
12
12
|
|
|
13
|
+
from ._base_resource import BaseResource
|
|
13
14
|
from ._exceptions import GitCodeConfigurationError, GitCodeHTTPStatusError
|
|
14
15
|
|
|
15
16
|
DEFAULT_BASE_URL = "https://api.gitcode.com/api/v5"
|
|
@@ -181,6 +182,13 @@ class BaseGitCodeClient:
|
|
|
181
182
|
except ValueError:
|
|
182
183
|
return response.text
|
|
183
184
|
|
|
185
|
+
def _close_resources(self) -> None:
|
|
186
|
+
"""Release resource group caches to allow for garbage collection."""
|
|
187
|
+
for attr in dir(self):
|
|
188
|
+
resource = getattr(self, attr)
|
|
189
|
+
if isinstance(resource, BaseResource):
|
|
190
|
+
resource.method_signature.cache_clear()
|
|
191
|
+
|
|
184
192
|
|
|
185
193
|
class SyncAPIClient(BaseGitCodeClient):
|
|
186
194
|
"""Low-level synchronous HTTP transport used by resource classes.
|
|
@@ -207,7 +215,6 @@ class SyncAPIClient(BaseGitCodeClient):
|
|
|
207
215
|
) -> None:
|
|
208
216
|
"""Create or reuse an ``httpx.Client`` for synchronous requests."""
|
|
209
217
|
super().__init__(api_key=api_key, owner=owner, repo=repo, base_url=base_url, timeout=timeout, decrypt=decrypt)
|
|
210
|
-
self._owns_client = http_client is None
|
|
211
218
|
self._client = http_client or httpx.Client(timeout=self.timeout)
|
|
212
219
|
|
|
213
220
|
def request(
|
|
@@ -244,7 +251,8 @@ class SyncAPIClient(BaseGitCodeClient):
|
|
|
244
251
|
return self._parse_response(response, raw=raw)
|
|
245
252
|
|
|
246
253
|
def close(self) -> None:
|
|
247
|
-
"""Close the underlying HTTP client."""
|
|
254
|
+
"""Close the underlying HTTP client and clear cache for garbage collection."""
|
|
255
|
+
self._close_resources()
|
|
248
256
|
self._client.close()
|
|
249
257
|
|
|
250
258
|
def __enter__(self) -> "SyncAPIClient":
|
|
@@ -281,7 +289,6 @@ class AsyncAPIClient(BaseGitCodeClient):
|
|
|
281
289
|
) -> None:
|
|
282
290
|
"""Create or reuse an ``httpx.AsyncClient`` for asynchronous requests."""
|
|
283
291
|
super().__init__(api_key=api_key, owner=owner, repo=repo, base_url=base_url, timeout=timeout, decrypt=decrypt)
|
|
284
|
-
self._owns_client = http_client is None
|
|
285
292
|
self._client = http_client or httpx.AsyncClient(timeout=self.timeout)
|
|
286
293
|
|
|
287
294
|
async def request(
|
|
@@ -318,7 +325,8 @@ class AsyncAPIClient(BaseGitCodeClient):
|
|
|
318
325
|
return self._parse_response(response, raw=raw)
|
|
319
326
|
|
|
320
327
|
async def close(self) -> None:
|
|
321
|
-
"""Close the underlying async HTTP client."""
|
|
328
|
+
"""Close the underlying async HTTP client and clear cache for garbage collection."""
|
|
329
|
+
self._close_resources()
|
|
322
330
|
await self._client.aclose()
|
|
323
331
|
|
|
324
332
|
async def __aenter__(self) -> "AsyncAPIClient":
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Resource base classe for the GitCode SDK."""
|
|
2
|
+
|
|
3
|
+
from functools import cached_property, lru_cache
|
|
4
|
+
|
|
5
|
+
_UTILITY_METHODS = {"methods", "method_signature"}
|
|
6
|
+
_DATA_MODEL_PATH = "gitcode_api._models."
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseResource:
|
|
10
|
+
"""Resource group base class."""
|
|
11
|
+
|
|
12
|
+
def __del__(self) -> None:
|
|
13
|
+
"""Attempt to clear the lru cache."""
|
|
14
|
+
self.method_signature.cache_clear()
|
|
15
|
+
|
|
16
|
+
@cached_property
|
|
17
|
+
def methods(self) -> tuple[str, ...]:
|
|
18
|
+
"""Public callable names on this resource group in stable SDK order.
|
|
19
|
+
|
|
20
|
+
Ordering uses :func:`sorted` with a key derived from each name's
|
|
21
|
+
underscore-separated segments (for example two-part names are ordered
|
|
22
|
+
as if ``second_first``). This is not plain lexicographic order on the
|
|
23
|
+
full method string. Excludes ``methods``, names starting with ``_``,
|
|
24
|
+
and non-callables. The result is cached on first access.
|
|
25
|
+
|
|
26
|
+
:returns: Tuple of method names in that order.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def _is_valid_func(name: str):
|
|
30
|
+
return not (name.startswith("_") or name in _UTILITY_METHODS) and callable(getattr(self, name))
|
|
31
|
+
|
|
32
|
+
def _sort_helper(method_name: str):
|
|
33
|
+
name_parts = method_name.split("_")
|
|
34
|
+
num_part = len(name_parts)
|
|
35
|
+
if num_part == 2:
|
|
36
|
+
return f"{name_parts[1]}_{name_parts[0]}"
|
|
37
|
+
if num_part == 3:
|
|
38
|
+
return f"{{{name_parts[0]}_"
|
|
39
|
+
return "_" + method_name
|
|
40
|
+
|
|
41
|
+
return tuple(
|
|
42
|
+
sorted(
|
|
43
|
+
(func for func in dir(self) if _is_valid_func(func)),
|
|
44
|
+
key=_sort_helper,
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
@lru_cache(maxsize=50)
|
|
49
|
+
def method_signature(self, method_name: str) -> str:
|
|
50
|
+
"""Return signature for a method in this resource group, result is cached.
|
|
51
|
+
|
|
52
|
+
For example ``client.pulls.method_signature("list_issues")`` would return:
|
|
53
|
+
list_issues(*, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None) -> List[Issue]
|
|
54
|
+
|
|
55
|
+
:param method_name: Attribute name of a callable on this resource.
|
|
56
|
+
:returns: Formatted signature.
|
|
57
|
+
"""
|
|
58
|
+
import inspect
|
|
59
|
+
|
|
60
|
+
return method_name + str(inspect.signature(getattr(self, method_name))).replace(_DATA_MODEL_PATH, "")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""ASCII art banner for command-line interface."""
|
|
2
|
+
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
# ANSI Colour Codes
|
|
7
|
+
CREDBG = "\033[41m"
|
|
8
|
+
CRED = "\033[91m"
|
|
9
|
+
CBLU = "\033[94m"
|
|
10
|
+
CCYN = "\033[96m"
|
|
11
|
+
CGRN = "\033[92m"
|
|
12
|
+
CYEL = "\033[41m"
|
|
13
|
+
CEND = "\033[0m"
|
|
14
|
+
|
|
15
|
+
# ASCII Art Banner
|
|
16
|
+
BANNER = r"""
|
|
17
|
+
_____ _ _ _____ _ _____ _____
|
|
18
|
+
/ ____(_) | / ____| | | /\ | __ \_ _|
|
|
19
|
+
| | __ _| |_| | ___ __| | ___ / \ | |__) || |
|
|
20
|
+
| | |_ | | __| | / _ \ / _` |/ _ \ / /\ \ | ___/ | |
|
|
21
|
+
| |__| | | |_| |___| (_) | (_| | __/ / ____ \| | _| |_
|
|
22
|
+
\_____|_|\__|\_____\___/ \__,_|\___| /_/ \_\_| |_____|
|
|
23
|
+
""".strip("\n")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@lru_cache(maxsize=1)
|
|
27
|
+
def format_default_welcome(version: str) -> str:
|
|
28
|
+
"""Colored banner and version line for the no-arguments launcher (plain if not a TTY)."""
|
|
29
|
+
if sys.stdout.isatty():
|
|
30
|
+
return f"{CRED}{BANNER}{CEND}\n{CBLU} Ver. {version}{CEND}\n\n"
|
|
31
|
+
return f"{BANNER}\n Ver. {version}\n\n"
|
|
@@ -144,6 +144,7 @@ class GitCode(SyncAPIClient):
|
|
|
144
144
|
self.oauth = OAuthResource(self)
|
|
145
145
|
|
|
146
146
|
def __enter__(self) -> "GitCode":
|
|
147
|
+
"""Enter synchronous context and return this client."""
|
|
147
148
|
return self
|
|
148
149
|
|
|
149
150
|
|
|
@@ -246,4 +247,5 @@ class AsyncGitCode(AsyncAPIClient):
|
|
|
246
247
|
self.oauth = AsyncOAuthResource(self)
|
|
247
248
|
|
|
248
249
|
async def __aenter__(self) -> "AsyncGitCode":
|
|
250
|
+
"""Enter asynchronous context and return this client."""
|
|
249
251
|
return self
|
|
@@ -73,6 +73,7 @@ class APIObject(Mapping[str, Any]):
|
|
|
73
73
|
data: MutableMapping[str, Any] = field(init=False, repr=False)
|
|
74
74
|
|
|
75
75
|
def __init__(self, data: Mapping[str, Any]):
|
|
76
|
+
"""Initialize from API response data."""
|
|
76
77
|
payload = dict(data)
|
|
77
78
|
object.__setattr__(self, "data", payload)
|
|
78
79
|
type_hints = get_type_hints(self.__class__)
|
|
@@ -95,24 +96,30 @@ class APIObject(Mapping[str, Any]):
|
|
|
95
96
|
object.__setattr__(self, model_field.name, value)
|
|
96
97
|
|
|
97
98
|
def __getitem__(self, key: str) -> Any:
|
|
99
|
+
"""Return the value for ``key`` from the backing mapping."""
|
|
98
100
|
return _wrap_value(self.data[key])
|
|
99
101
|
|
|
100
102
|
def __iter__(self) -> Iterator[str]:
|
|
103
|
+
"""Iterate keys of the backing mapping."""
|
|
101
104
|
return iter(self.data)
|
|
102
105
|
|
|
103
106
|
def __len__(self) -> int:
|
|
107
|
+
"""Return the number of keys in the backing mapping."""
|
|
104
108
|
return len(self.data)
|
|
105
109
|
|
|
106
110
|
def __getattr__(self, name: str) -> Any:
|
|
111
|
+
"""Resolve unknown attributes from the backing mapping."""
|
|
107
112
|
try:
|
|
108
113
|
return _wrap_value(self.data[name])
|
|
109
114
|
except KeyError as exc:
|
|
110
115
|
raise AttributeError(name) from exc
|
|
111
116
|
|
|
112
117
|
def get(self, key: str, default: Any = None) -> Any:
|
|
118
|
+
"""Return the value for ``key``, or ``default`` if missing."""
|
|
113
119
|
return _wrap_value(self.data.get(key, default))
|
|
114
120
|
|
|
115
121
|
def to_dict(self) -> Dict[str, Any]:
|
|
122
|
+
"""Return a shallow copy of the backing mapping."""
|
|
116
123
|
return dict(self.data)
|
|
117
124
|
|
|
118
125
|
|