github-rest-api 0.40.0__tar.gz → 0.41.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/PKG-INFO +2 -1
- github_rest_api-0.41.0/github_rest_api/__init__.py +11 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/github.py +147 -25
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/pyproject.toml +2 -1
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/tests/test_github.py +11 -1
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/uv.lock +103 -0
- github_rest_api-0.40.0/.claude/settings.json +0 -9
- github_rest_api-0.40.0/github_rest_api/__init__.py +0 -5
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.devcontainer/devcontainer.json +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.github/workflows/create_pr_to_main.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.github/workflows/lint.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.github/workflows/release.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.github/workflows/remove_branch.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.github/workflows/test.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/.gitignore +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/GEMINI.md +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/README.md +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/__init__.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/__init__.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/benchmark.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/profiling.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/utils.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/container/__init__.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/container/build_container_images.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/container/config_container.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/container/update_version_containerfile.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/__init__.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/add_github_repo.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/create_pull_request.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/release_on_github.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/remove_branch.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/create_pr_dev_to_main.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/create_pr_to_dev.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/create_pr_to_main.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/python/lint.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/python/test.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/workflows/remove_branch.yaml +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/utils.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/utils.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/memory/MEMORY.md +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/memory/feedback_test_runner.md +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/tests/__init__.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/tests/test_build_container_images.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/tests/test_release_on_github.py +0 -0
- {github_rest_api-0.40.0 → github_rest_api-0.41.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github-rest-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41.0
|
|
4
4
|
Summary: Simple wrapper of GitHub REST APIs.
|
|
5
5
|
Author-email: Ben Du <longendu@yahoo.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
10
10
|
Requires-Python: <4,>=3.12
|
|
11
11
|
Requires-Dist: dulwich>=0.25.1
|
|
12
12
|
Requires-Dist: psutil>=5.9.4
|
|
13
|
+
Requires-Dist: pynacl>=1.5
|
|
13
14
|
Requires-Dist: pyyaml>=6
|
|
14
15
|
Requires-Dist: requests>=2.28.2
|
|
15
16
|
Requires-Dist: tenacity>=9.1.4
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
"""Simple wrapper of GitHub REST APIs."""
|
|
2
2
|
|
|
3
3
|
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from base64 import b64encode
|
|
5
|
+
from collections.abc import Sequence
|
|
4
6
|
from enum import StrEnum
|
|
5
7
|
from typing import Any, Callable
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
import requests
|
|
10
|
+
from nacl import encoding, public
|
|
11
|
+
|
|
12
|
+
URL_API = "https://api.github.com"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _encrypt_secret(public_key: str, value: str) -> str:
|
|
16
|
+
"""Encrypt a secret value using a LibSodium sealed box.
|
|
17
|
+
:param public_key: The base64-encoded public key to encrypt against.
|
|
18
|
+
:param value: The plaintext secret value to encrypt.
|
|
19
|
+
"""
|
|
20
|
+
pkey = public.PublicKey(public_key.encode(), encoding.Base64Encoder)
|
|
21
|
+
encrypted = public.SealedBox(pkey).encrypt(value.encode())
|
|
22
|
+
return b64encode(encrypted).decode()
|
|
8
23
|
|
|
9
24
|
|
|
10
25
|
def build_http_headers(token: str) -> dict[str, str]:
|
|
@@ -36,6 +51,12 @@ class GitHub:
|
|
|
36
51
|
def _get(
|
|
37
52
|
self, url: str, raise_for_status: bool = True, **kwargs
|
|
38
53
|
) -> requests.Response:
|
|
54
|
+
"""Send a GET request to a GitHub REST API endpoint.
|
|
55
|
+
:param url: The endpoint URL to request.
|
|
56
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
57
|
+
:param kwargs: Additional keyword arguments (e.g. `params`) forwarded
|
|
58
|
+
to `requests.get`.
|
|
59
|
+
"""
|
|
39
60
|
resp = requests.get(
|
|
40
61
|
url=url,
|
|
41
62
|
headers=self._headers,
|
|
@@ -49,6 +70,13 @@ class GitHub:
|
|
|
49
70
|
def _post(
|
|
50
71
|
self, url: str, headers=None, raise_for_status: bool = True, **kwargs
|
|
51
72
|
) -> requests.Response:
|
|
73
|
+
"""Send a POST request to a GitHub REST API endpoint.
|
|
74
|
+
:param url: The endpoint URL to request.
|
|
75
|
+
:param headers: Request headers; defaults to the standard auth headers.
|
|
76
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
77
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
78
|
+
to `requests.post`.
|
|
79
|
+
"""
|
|
52
80
|
if headers is None:
|
|
53
81
|
headers = self._headers
|
|
54
82
|
resp = requests.post(
|
|
@@ -67,17 +95,32 @@ class GitHub:
|
|
|
67
95
|
resp.raise_for_status()
|
|
68
96
|
return resp
|
|
69
97
|
|
|
70
|
-
def _put(
|
|
98
|
+
def _put(
|
|
99
|
+
self, url: str, raise_for_status: bool = True, **kwargs
|
|
100
|
+
) -> requests.Response:
|
|
101
|
+
"""Send a PUT request to a GitHub REST API endpoint.
|
|
102
|
+
:param url: The endpoint URL to request.
|
|
103
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
104
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
105
|
+
to `requests.put`.
|
|
106
|
+
"""
|
|
71
107
|
resp = requests.put(
|
|
72
108
|
url=url,
|
|
73
109
|
headers=self._headers,
|
|
74
110
|
timeout=10,
|
|
111
|
+
**kwargs,
|
|
75
112
|
)
|
|
76
113
|
if raise_for_status:
|
|
77
114
|
resp.raise_for_status()
|
|
78
115
|
return resp
|
|
79
116
|
|
|
80
117
|
def _patch(self, url, raise_for_status: bool = True, **kwargs) -> requests.Response:
|
|
118
|
+
"""Send a PATCH request to a GitHub REST API endpoint.
|
|
119
|
+
:param url: The endpoint URL to request.
|
|
120
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
121
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
122
|
+
to `requests.patch`.
|
|
123
|
+
"""
|
|
81
124
|
resp = requests.patch(
|
|
82
125
|
url=url,
|
|
83
126
|
headers=self._headers,
|
|
@@ -118,8 +161,7 @@ class Repository(GitHub):
|
|
|
118
161
|
"""
|
|
119
162
|
super().__init__(token)
|
|
120
163
|
self._repo = repo
|
|
121
|
-
self.
|
|
122
|
-
self._url_repo = f"{self._url}/{repo}"
|
|
164
|
+
self._url_repo = f"{URL_API}/repos/{repo}"
|
|
123
165
|
self._url_tags = f"{self._url_repo}/tags"
|
|
124
166
|
self._url_transfer = f"{self._url_repo}/transfer"
|
|
125
167
|
self._url_pull = f"{self._url_repo}/pulls"
|
|
@@ -127,6 +169,7 @@ class Repository(GitHub):
|
|
|
127
169
|
self._url_refs = f"{self._url_repo}/git/refs"
|
|
128
170
|
self._url_issues = f"{self._url_repo}/issues"
|
|
129
171
|
self._url_releases = f"{self._url_repo}/releases"
|
|
172
|
+
self._url_secrets = f"{self._url_repo}/actions/secrets"
|
|
130
173
|
|
|
131
174
|
def get_releases(self, n: int = 0) -> list[dict[str, Any]]:
|
|
132
175
|
"""List releases in this repository."""
|
|
@@ -157,8 +200,6 @@ class Repository(GitHub):
|
|
|
157
200
|
For more details, please refer to
|
|
158
201
|
https://docs.github.com/en/rest/releases/releases#create-a-release.
|
|
159
202
|
"""
|
|
160
|
-
if not isinstance(json, dict):
|
|
161
|
-
raise ValueError("A dict value is required for `json`.")
|
|
162
203
|
return self._post(
|
|
163
204
|
url=self._url_releases,
|
|
164
205
|
json=json,
|
|
@@ -171,7 +212,9 @@ class Repository(GitHub):
|
|
|
171
212
|
path = Path(path)
|
|
172
213
|
with path.open(mode="rb") as fin:
|
|
173
214
|
return self._post(
|
|
174
|
-
url=f"{self._url_releases.replace('api', 'uploads', 1)}/{
|
|
215
|
+
url=f"{self._url_releases.replace('api', 'uploads', 1)}/{
|
|
216
|
+
release
|
|
217
|
+
}/assets",
|
|
175
218
|
params={
|
|
176
219
|
"name": name,
|
|
177
220
|
},
|
|
@@ -193,8 +236,6 @@ class Repository(GitHub):
|
|
|
193
236
|
about the pull request to be created.
|
|
194
237
|
It's passed to the json parameter of requests.post.
|
|
195
238
|
"""
|
|
196
|
-
if not isinstance(json, dict):
|
|
197
|
-
raise ValueError("A dict value is required for `json`.")
|
|
198
239
|
if not ("head" in json and "base" in json):
|
|
199
240
|
raise ValueError("The data dict must contains keys head and base!")
|
|
200
241
|
# return an existing PR
|
|
@@ -217,8 +258,6 @@ class Repository(GitHub):
|
|
|
217
258
|
"""Merge a pull request in this repository.
|
|
218
259
|
:param pr_number: The number of the pull quest to be merged.
|
|
219
260
|
"""
|
|
220
|
-
if not isinstance(pr_number, int):
|
|
221
|
-
raise ValueError("An integer value is required for `pr_number`.")
|
|
222
261
|
return self._put(
|
|
223
262
|
url=f"{self._url_pull}/{pr_number}/merge",
|
|
224
263
|
).json()
|
|
@@ -228,10 +267,6 @@ class Repository(GitHub):
|
|
|
228
267
|
:param update: The branch to update.
|
|
229
268
|
:param upstream: The upstream branch.
|
|
230
269
|
"""
|
|
231
|
-
if not isinstance(update, str):
|
|
232
|
-
raise ValueError("A string value is required for `update`.")
|
|
233
|
-
if not isinstance(upstream, str):
|
|
234
|
-
raise ValueError("A string value is required for `upstream`.")
|
|
235
270
|
pr = self.create_pull_request(
|
|
236
271
|
{
|
|
237
272
|
"base": update,
|
|
@@ -250,8 +285,6 @@ class Repository(GitHub):
|
|
|
250
285
|
|
|
251
286
|
:param pr_number: The number of the pull request.
|
|
252
287
|
"""
|
|
253
|
-
if not isinstance(pr_number, int):
|
|
254
|
-
raise ValueError("An integer value is required for `pr_number`.")
|
|
255
288
|
return self._extract_all(url=f"{self._url_pull}/{pr_number}/files", n=n)
|
|
256
289
|
|
|
257
290
|
def get_branches(self, n: int = 0) -> list[dict[str, Any]]:
|
|
@@ -272,8 +305,6 @@ class Repository(GitHub):
|
|
|
272
305
|
"""Delete a reference from this repository.
|
|
273
306
|
:param ref: The reference to delete from this repository.
|
|
274
307
|
"""
|
|
275
|
-
if not isinstance(ref, str):
|
|
276
|
-
raise ValueError("A string value is required for `ref`.")
|
|
277
308
|
return self._delete(
|
|
278
309
|
url=f"{self._url_refs}/{ref}",
|
|
279
310
|
)
|
|
@@ -284,6 +315,36 @@ class Repository(GitHub):
|
|
|
284
315
|
"""
|
|
285
316
|
return self.delete_ref(ref=f"heads/{branch}")
|
|
286
317
|
|
|
318
|
+
def delete_secret(self, name: str) -> requests.Response:
|
|
319
|
+
"""Delete a secret from this repository.
|
|
320
|
+
:param name: The name of the secret to delete.
|
|
321
|
+
"""
|
|
322
|
+
return self._delete(
|
|
323
|
+
url=f"{self._url_secrets}/{name}",
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def get_secret_public_key(self) -> dict[str, Any]:
|
|
327
|
+
"""Get the public key for encrypting secrets in this repository."""
|
|
328
|
+
return self._get(url=f"{self._url_secrets}/public-key").json()
|
|
329
|
+
|
|
330
|
+
def create_or_update_secret(
|
|
331
|
+
self, name: str, value: str, public_key: dict[str, Any]
|
|
332
|
+
) -> requests.Response:
|
|
333
|
+
"""Create or update a secret in this repository.
|
|
334
|
+
:param name: The name of the secret.
|
|
335
|
+
:param value: The plaintext value of the secret.
|
|
336
|
+
:param public_key: A public key (as returned by `get_secret_public_key`)
|
|
337
|
+
to encrypt the secret with. Fetch it once and reuse it to avoid a
|
|
338
|
+
redundant request when creating or updating multiple secrets.
|
|
339
|
+
"""
|
|
340
|
+
return self._put(
|
|
341
|
+
url=f"{self._url_secrets}/{name}",
|
|
342
|
+
json={
|
|
343
|
+
"encrypted_value": _encrypt_secret(public_key["key"], value),
|
|
344
|
+
"key_id": public_key["key_id"],
|
|
345
|
+
},
|
|
346
|
+
)
|
|
347
|
+
|
|
287
348
|
def pr_has_change(
|
|
288
349
|
self, pr_number: int, pred: Callable[[str], bool] = lambda _: True
|
|
289
350
|
) -> bool:
|
|
@@ -313,10 +374,6 @@ class Repository(GitHub):
|
|
|
313
374
|
:param issue_number: The number of the issue.
|
|
314
375
|
:param body: Body text of the new comment.
|
|
315
376
|
"""
|
|
316
|
-
if not isinstance(issue_number, int):
|
|
317
|
-
raise ValueError("An integer value is required for `issue_number`.")
|
|
318
|
-
if not isinstance(body, str):
|
|
319
|
-
raise ValueError("A string message is required for `body`.")
|
|
320
377
|
return self._post(
|
|
321
378
|
url=f"{self._url_issues}/{issue_number}/comments",
|
|
322
379
|
json={"body": body},
|
|
@@ -344,6 +401,12 @@ class RepositoryType(StrEnum):
|
|
|
344
401
|
PRIVATE = "private"
|
|
345
402
|
|
|
346
403
|
|
|
404
|
+
class SecretVisibility(StrEnum):
|
|
405
|
+
ALL = "all"
|
|
406
|
+
PRIVATE = "private"
|
|
407
|
+
SELECTED = "selected"
|
|
408
|
+
|
|
409
|
+
|
|
347
410
|
class Owner(GitHub, metaclass=ABCMeta):
|
|
348
411
|
"""An abstract owner class representing an organization or user."""
|
|
349
412
|
|
|
@@ -354,6 +417,7 @@ class Owner(GitHub, metaclass=ABCMeta):
|
|
|
354
417
|
"""
|
|
355
418
|
super().__init__(token)
|
|
356
419
|
self._owner = owner
|
|
420
|
+
self._url_owner = ""
|
|
357
421
|
self._url_repos = ""
|
|
358
422
|
self._url_create_repo = ""
|
|
359
423
|
|
|
@@ -376,6 +440,14 @@ class Owner(GitHub, metaclass=ABCMeta):
|
|
|
376
440
|
def create_repository(
|
|
377
441
|
self, name: str, description: str = "", private: bool = True, **kwargs
|
|
378
442
|
) -> dict[str, Any]:
|
|
443
|
+
"""Create a repository for this owner.
|
|
444
|
+
:param name: The name of the repository.
|
|
445
|
+
:param description: A short description of the repository.
|
|
446
|
+
:param private: Whether the repository is private.
|
|
447
|
+
:param kwargs: Additional keyword arguments forwarded to `_post`
|
|
448
|
+
(e.g. `params` or `raise_for_status`). Note `json` is already set
|
|
449
|
+
from the other parameters and must not be passed here.
|
|
450
|
+
"""
|
|
379
451
|
data = {
|
|
380
452
|
"name": name,
|
|
381
453
|
"description": description,
|
|
@@ -400,8 +472,9 @@ class User(Owner):
|
|
|
400
472
|
self._set_urls()
|
|
401
473
|
|
|
402
474
|
def _set_urls(self) -> None:
|
|
403
|
-
self.
|
|
404
|
-
self.
|
|
475
|
+
self._url_owner = f"{URL_API}/users/{self._owner}"
|
|
476
|
+
self._url_repos = f"{self._url_owner}/repos"
|
|
477
|
+
self._url_create_repo = f"{URL_API}/user/repos"
|
|
405
478
|
|
|
406
479
|
|
|
407
480
|
class Organization(Owner):
|
|
@@ -416,5 +489,54 @@ class Organization(Owner):
|
|
|
416
489
|
self._set_urls()
|
|
417
490
|
|
|
418
491
|
def _set_urls(self) -> None:
|
|
419
|
-
self.
|
|
492
|
+
self._url_owner = f"{URL_API}/orgs/{self._owner}"
|
|
493
|
+
self._url_repos = f"{self._url_owner}/repos"
|
|
420
494
|
self._url_create_repo = self._url_repos
|
|
495
|
+
self._url_secrets = f"{self._url_owner}/actions/secrets"
|
|
496
|
+
|
|
497
|
+
def delete_secret(self, name: str) -> requests.Response:
|
|
498
|
+
"""Delete an organization secret.
|
|
499
|
+
:param name: The name of the secret to delete.
|
|
500
|
+
"""
|
|
501
|
+
return self._delete(
|
|
502
|
+
url=f"{self._url_secrets}/{name}",
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
def get_secret_public_key(self) -> dict[str, Any]:
|
|
506
|
+
"""Get the public key for encrypting secrets in this organization."""
|
|
507
|
+
return self._get(url=f"{self._url_secrets}/public-key").json()
|
|
508
|
+
|
|
509
|
+
def create_or_update_secret(
|
|
510
|
+
self,
|
|
511
|
+
name: str,
|
|
512
|
+
value: str,
|
|
513
|
+
public_key: dict[str, Any],
|
|
514
|
+
visibility: SecretVisibility = SecretVisibility.ALL,
|
|
515
|
+
selected_repository_ids: Sequence[int] = (),
|
|
516
|
+
) -> requests.Response:
|
|
517
|
+
"""Create or update an organization secret.
|
|
518
|
+
:param name: The name of the secret.
|
|
519
|
+
:param value: The plaintext value of the secret.
|
|
520
|
+
:param public_key: A public key (as returned by `get_secret_public_key`)
|
|
521
|
+
to encrypt the secret with. Fetch it once and reuse it to avoid a
|
|
522
|
+
redundant request when creating or updating multiple secrets.
|
|
523
|
+
:param visibility: Which repositories can access the secret
|
|
524
|
+
(all, private, or selected).
|
|
525
|
+
:param selected_repository_ids: Repository IDs that can access the secret
|
|
526
|
+
when visibility is `selected`.
|
|
527
|
+
"""
|
|
528
|
+
if selected_repository_ids and visibility != SecretVisibility.SELECTED:
|
|
529
|
+
raise ValueError(
|
|
530
|
+
"`selected_repository_ids` can only be provided when `visibility` is 'selected'."
|
|
531
|
+
)
|
|
532
|
+
json: dict[str, Any] = {
|
|
533
|
+
"encrypted_value": _encrypt_secret(public_key["key"], value),
|
|
534
|
+
"key_id": public_key["key_id"],
|
|
535
|
+
"visibility": visibility,
|
|
536
|
+
}
|
|
537
|
+
if selected_repository_ids:
|
|
538
|
+
json["selected_repository_ids"] = list(selected_repository_ids)
|
|
539
|
+
return self._put(
|
|
540
|
+
url=f"{self._url_secrets}/{name}",
|
|
541
|
+
json=json,
|
|
542
|
+
)
|
|
@@ -4,7 +4,7 @@ requires = [ "hatchling" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "github-rest-api"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.41.0"
|
|
8
8
|
description = "Simple wrapper of GitHub REST APIs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [ { name = "Ben Du", email = "longendu@yahoo.com" } ]
|
|
@@ -18,6 +18,7 @@ classifiers = [
|
|
|
18
18
|
dependencies = [
|
|
19
19
|
"dulwich>=0.25.1",
|
|
20
20
|
"psutil>=5.9.4",
|
|
21
|
+
"pynacl>=1.5",
|
|
21
22
|
"pyyaml>=6",
|
|
22
23
|
"requests>=2.28.2",
|
|
23
24
|
"tenacity>=9.1.4",
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from
|
|
2
|
+
from base64 import b64decode
|
|
3
|
+
from nacl import encoding, public
|
|
4
|
+
from github_rest_api.github import User, Organization, Repository, _encrypt_secret
|
|
3
5
|
|
|
4
6
|
TOKEN = os.environ.get("GITHUB_TOKEN", "")
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
def test_encrypt_secret_roundtrip():
|
|
10
|
+
private_key = public.PrivateKey.generate()
|
|
11
|
+
public_key = private_key.public_key.encode(encoding.Base64Encoder).decode()
|
|
12
|
+
encrypted = _encrypt_secret(public_key, "s3cret-value")
|
|
13
|
+
decrypted = public.SealedBox(private_key).decrypt(b64decode(encrypted))
|
|
14
|
+
assert decrypted == b"s3cret-value"
|
|
15
|
+
|
|
16
|
+
|
|
7
17
|
def test_user_get_repositories():
|
|
8
18
|
user = User(TOKEN, "dclong")
|
|
9
19
|
repos = user.get_repositories()
|
|
@@ -11,6 +11,63 @@ wheels = [
|
|
|
11
11
|
{ url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" },
|
|
12
12
|
]
|
|
13
13
|
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "cffi"
|
|
16
|
+
version = "2.0.0"
|
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
|
20
|
+
]
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
|
|
24
|
+
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
|
|
25
|
+
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
|
|
26
|
+
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
|
|
27
|
+
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
|
|
28
|
+
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
|
|
29
|
+
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
|
|
30
|
+
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
|
|
31
|
+
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
|
|
32
|
+
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
|
|
33
|
+
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
|
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
|
|
35
|
+
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
|
|
36
|
+
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
|
|
37
|
+
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
|
|
38
|
+
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
|
|
39
|
+
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
|
|
40
|
+
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
|
|
41
|
+
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
|
|
42
|
+
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
|
|
43
|
+
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
|
|
44
|
+
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
|
|
45
|
+
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
|
|
46
|
+
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
|
|
47
|
+
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
|
|
48
|
+
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
|
|
49
|
+
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
|
|
50
|
+
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
|
|
51
|
+
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
|
|
52
|
+
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
|
|
53
|
+
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
|
|
54
|
+
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
|
|
56
|
+
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
|
|
57
|
+
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
|
|
58
|
+
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
|
|
59
|
+
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
|
|
60
|
+
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
|
|
61
|
+
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
|
|
64
|
+
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
|
|
66
|
+
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
|
|
67
|
+
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
|
|
68
|
+
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
|
|
69
|
+
]
|
|
70
|
+
|
|
14
71
|
[[package]]
|
|
15
72
|
name = "charset-normalizer"
|
|
16
73
|
version = "3.4.7"
|
|
@@ -171,6 +228,7 @@ source = { editable = "." }
|
|
|
171
228
|
dependencies = [
|
|
172
229
|
{ name = "dulwich" },
|
|
173
230
|
{ name = "psutil" },
|
|
231
|
+
{ name = "pynacl" },
|
|
174
232
|
{ name = "pyyaml" },
|
|
175
233
|
{ name = "requests" },
|
|
176
234
|
{ name = "tenacity" },
|
|
@@ -191,6 +249,7 @@ dev = [
|
|
|
191
249
|
requires-dist = [
|
|
192
250
|
{ name = "dulwich", specifier = ">=0.25.1" },
|
|
193
251
|
{ name = "psutil", specifier = ">=5.9.4" },
|
|
252
|
+
{ name = "pynacl", specifier = ">=1.5" },
|
|
194
253
|
{ name = "pyyaml", specifier = ">=6" },
|
|
195
254
|
{ name = "requests", specifier = ">=2.28.2" },
|
|
196
255
|
{ name = "tenacity", specifier = ">=9.1.4" },
|
|
@@ -280,6 +339,15 @@ wheels = [
|
|
|
280
339
|
{ url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
|
|
281
340
|
]
|
|
282
341
|
|
|
342
|
+
[[package]]
|
|
343
|
+
name = "pycparser"
|
|
344
|
+
version = "3.0"
|
|
345
|
+
source = { registry = "https://pypi.org/simple" }
|
|
346
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
|
|
347
|
+
wheels = [
|
|
348
|
+
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
|
|
349
|
+
]
|
|
350
|
+
|
|
283
351
|
[[package]]
|
|
284
352
|
name = "pygments"
|
|
285
353
|
version = "2.20.0"
|
|
@@ -289,6 +357,41 @@ wheels = [
|
|
|
289
357
|
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
|
290
358
|
]
|
|
291
359
|
|
|
360
|
+
[[package]]
|
|
361
|
+
name = "pynacl"
|
|
362
|
+
version = "1.6.2"
|
|
363
|
+
source = { registry = "https://pypi.org/simple" }
|
|
364
|
+
dependencies = [
|
|
365
|
+
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
366
|
+
]
|
|
367
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d9/9a/4019b524b03a13438637b11538c82781a5eda427394380381af8f04f467a/pynacl-1.6.2.tar.gz", hash = "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c", size = 3511692, upload-time = "2026-01-01T17:48:10.851Z" }
|
|
368
|
+
wheels = [
|
|
369
|
+
{ url = "https://files.pythonhosted.org/packages/4b/79/0e3c34dc3c4671f67d251c07aa8eb100916f250ee470df230b0ab89551b4/pynacl-1.6.2-cp314-cp314t-macosx_10_10_universal2.whl", hash = "sha256:622d7b07cc5c02c666795792931b50c91f3ce3c2649762efb1ef0d5684c81594", size = 390064, upload-time = "2026-01-01T17:31:57.264Z" },
|
|
370
|
+
{ url = "https://files.pythonhosted.org/packages/eb/1c/23a26e931736e13b16483795c8a6b2f641bf6a3d5238c22b070a5112722c/pynacl-1.6.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d071c6a9a4c94d79eb665db4ce5cedc537faf74f2355e4d502591d850d3913c0", size = 809370, upload-time = "2026-01-01T17:31:59.198Z" },
|
|
371
|
+
{ url = "https://files.pythonhosted.org/packages/87/74/8d4b718f8a22aea9e8dcc8b95deb76d4aae380e2f5b570cc70b5fd0a852d/pynacl-1.6.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe9847ca47d287af41e82be1dd5e23023d3c31a951da134121ab02e42ac218c9", size = 1408304, upload-time = "2026-01-01T17:32:01.162Z" },
|
|
372
|
+
{ url = "https://files.pythonhosted.org/packages/fd/73/be4fdd3a6a87fe8a4553380c2b47fbd1f7f58292eb820902f5c8ac7de7b0/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04316d1fc625d860b6c162fff704eb8426b1a8bcd3abacea11142cbd99a6b574", size = 844871, upload-time = "2026-01-01T17:32:02.824Z" },
|
|
373
|
+
{ url = "https://files.pythonhosted.org/packages/55/ad/6efc57ab75ee4422e96b5f2697d51bbcf6cdcc091e66310df91fbdc144a8/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44081faff368d6c5553ccf55322ef2819abb40e25afaec7e740f159f74813634", size = 1446356, upload-time = "2026-01-01T17:32:04.452Z" },
|
|
374
|
+
{ url = "https://files.pythonhosted.org/packages/78/b7/928ee9c4779caa0a915844311ab9fb5f99585621c5d6e4574538a17dca07/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:a9f9932d8d2811ce1a8ffa79dcbdf3970e7355b5c8eb0c1a881a57e7f7d96e88", size = 826814, upload-time = "2026-01-01T17:32:06.078Z" },
|
|
375
|
+
{ url = "https://files.pythonhosted.org/packages/f7/a9/1bdba746a2be20f8809fee75c10e3159d75864ef69c6b0dd168fc60e485d/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:bc4a36b28dd72fb4845e5d8f9760610588a96d5a51f01d84d8c6ff9849968c14", size = 1411742, upload-time = "2026-01-01T17:32:07.651Z" },
|
|
376
|
+
{ url = "https://files.pythonhosted.org/packages/f3/2f/5e7ea8d85f9f3ea5b6b87db1d8388daa3587eed181bdeb0306816fdbbe79/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bffb6d0f6becacb6526f8f42adfb5efb26337056ee0831fb9a7044d1a964444", size = 801714, upload-time = "2026-01-01T17:32:09.558Z" },
|
|
377
|
+
{ url = "https://files.pythonhosted.org/packages/06/ea/43fe2f7eab5f200e40fb10d305bf6f87ea31b3bbc83443eac37cd34a9e1e/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fef529ef3ee487ad8113d287a593fa26f48ee3620d92ecc6f1d09ea38e0709b", size = 1372257, upload-time = "2026-01-01T17:32:11.026Z" },
|
|
378
|
+
{ url = "https://files.pythonhosted.org/packages/4d/54/c9ea116412788629b1347e415f72195c25eb2f3809b2d3e7b25f5c79f13a/pynacl-1.6.2-cp314-cp314t-win32.whl", hash = "sha256:a84bf1c20339d06dc0c85d9aea9637a24f718f375d861b2668b2f9f96fa51145", size = 231319, upload-time = "2026-01-01T17:32:12.46Z" },
|
|
379
|
+
{ url = "https://files.pythonhosted.org/packages/ce/04/64e9d76646abac2dccf904fccba352a86e7d172647557f35b9fe2a5ee4a1/pynacl-1.6.2-cp314-cp314t-win_amd64.whl", hash = "sha256:320ef68a41c87547c91a8b58903c9caa641ab01e8512ce291085b5fe2fcb7590", size = 244044, upload-time = "2026-01-01T17:32:13.781Z" },
|
|
380
|
+
{ url = "https://files.pythonhosted.org/packages/33/33/7873dc161c6a06f43cda13dec67b6fe152cb2f982581151956fa5e5cdb47/pynacl-1.6.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d29bfe37e20e015a7d8b23cfc8bd6aa7909c92a1b8f41ee416bbb3e79ef182b2", size = 188740, upload-time = "2026-01-01T17:32:15.083Z" },
|
|
381
|
+
{ url = "https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465", size = 388458, upload-time = "2026-01-01T17:32:16.829Z" },
|
|
382
|
+
{ url = "https://files.pythonhosted.org/packages/1e/b4/e927e0653ba63b02a4ca5b4d852a8d1d678afbf69b3dbf9c4d0785ac905c/pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0", size = 800020, upload-time = "2026-01-01T17:32:18.34Z" },
|
|
383
|
+
{ url = "https://files.pythonhosted.org/packages/7f/81/d60984052df5c97b1d24365bc1e30024379b42c4edcd79d2436b1b9806f2/pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4", size = 1399174, upload-time = "2026-01-01T17:32:20.239Z" },
|
|
384
|
+
{ url = "https://files.pythonhosted.org/packages/68/f7/322f2f9915c4ef27d140101dd0ed26b479f7e6f5f183590fd32dfc48c4d3/pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87", size = 835085, upload-time = "2026-01-01T17:32:22.24Z" },
|
|
385
|
+
{ url = "https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c", size = 1437614, upload-time = "2026-01-01T17:32:23.766Z" },
|
|
386
|
+
{ url = "https://files.pythonhosted.org/packages/c4/58/fc6e649762b029315325ace1a8c6be66125e42f67416d3dbd47b69563d61/pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130", size = 818251, upload-time = "2026-01-01T17:32:25.69Z" },
|
|
387
|
+
{ url = "https://files.pythonhosted.org/packages/c9/a8/b917096b1accc9acd878819a49d3d84875731a41eb665f6ebc826b1af99e/pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6", size = 1402859, upload-time = "2026-01-01T17:32:27.215Z" },
|
|
388
|
+
{ url = "https://files.pythonhosted.org/packages/85/42/fe60b5f4473e12c72f977548e4028156f4d340b884c635ec6b063fe7e9a5/pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e", size = 791926, upload-time = "2026-01-01T17:32:29.314Z" },
|
|
389
|
+
{ url = "https://files.pythonhosted.org/packages/fa/f9/e40e318c604259301cc091a2a63f237d9e7b424c4851cafaea4ea7c4834e/pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577", size = 1363101, upload-time = "2026-01-01T17:32:31.263Z" },
|
|
390
|
+
{ url = "https://files.pythonhosted.org/packages/48/47/e761c254f410c023a469284a9bc210933e18588ca87706ae93002c05114c/pynacl-1.6.2-cp38-abi3-win32.whl", hash = "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa", size = 227421, upload-time = "2026-01-01T17:32:33.076Z" },
|
|
391
|
+
{ url = "https://files.pythonhosted.org/packages/41/ad/334600e8cacc7d86587fe5f565480fde569dfb487389c8e1be56ac21d8ac/pynacl-1.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0", size = 239754, upload-time = "2026-01-01T17:32:34.557Z" },
|
|
392
|
+
{ url = "https://files.pythonhosted.org/packages/29/7d/5945b5af29534641820d3bd7b00962abbbdfee84ec7e19f0d5b3175f9a31/pynacl-1.6.2-cp38-abi3-win_arm64.whl", hash = "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c", size = 184801, upload-time = "2026-01-01T17:32:36.309Z" },
|
|
393
|
+
]
|
|
394
|
+
|
|
292
395
|
[[package]]
|
|
293
396
|
name = "pyproject-fmt"
|
|
294
397
|
version = "2.21.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/benchmark.py
RENAMED
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/profiling.py
RENAMED
|
File without changes
|
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/container/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/__init__.py
RENAMED
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/add_github_repo.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_rest_api-0.40.0 → github_rest_api-0.41.0}/github_rest_api/scripts/github/remove_branch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|