ghapi 1.1.0__tar.gz → 2.0.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.
- {ghapi-1.1.0 → ghapi-2.0.0}/MANIFEST.in +0 -1
- {ghapi-1.1.0/ghapi.egg-info → ghapi-2.0.0}/PKG-INFO +71 -19
- {ghapi-1.1.0 → ghapi-2.0.0}/README.md +67 -15
- ghapi-2.0.0/ghapi/__init__.py +1 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/_modidx.py +17 -25
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/actions.py +4 -4
- ghapi-2.0.0/ghapi/build_lib.py +20 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/cli.py +7 -6
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/core.py +174 -181
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/event.py +14 -13
- ghapi-2.0.0/ghapi/gh_spec.py +16361 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/page.py +25 -13
- ghapi-2.0.0/ghapi/skill.py +70 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/templates.py +6 -6
- {ghapi-1.1.0 → ghapi-2.0.0/ghapi.egg-info}/PKG-INFO +71 -19
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi.egg-info/SOURCES.txt +1 -2
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi.egg-info/requires.txt +2 -2
- {ghapi-1.1.0 → ghapi-2.0.0}/pyproject.toml +3 -3
- ghapi-1.1.0/ghapi/__init__.py +0 -1
- ghapi-1.1.0/ghapi/_nbdev.py +0 -91
- ghapi-1.1.0/ghapi/build_lib.py +0 -59
- ghapi-1.1.0/ghapi/metadata.py +0 -1946
- ghapi-1.1.0/ghapi/skill.py +0 -68
- {ghapi-1.1.0 → ghapi-2.0.0}/CONTRIBUTING.md +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/LICENSE +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/all.py +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/auth.py +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/graphql.py +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi/py.typed +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi.egg-info/dependency_links.txt +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi.egg-info/entry_points.txt +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/ghapi.egg-info/top_level.txt +0 -0
- {ghapi-1.1.0 → ghapi-2.0.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghapi
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A python client for the GitHub API
|
|
5
5
|
Author-email: Jeremy Howard <info@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -12,13 +12,13 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: fastcore>=1.
|
|
18
|
+
Requires-Dist: fastcore>=1.14.3
|
|
19
|
+
Requires-Dist: fastspec>=0.1.0
|
|
19
20
|
Provides-Extra: dev
|
|
20
21
|
Requires-Dist: fastgit; extra == "dev"
|
|
21
|
-
Requires-Dist: jsonref; extra == "dev"
|
|
22
22
|
Requires-Dist: matplotlib; extra == "dev"
|
|
23
23
|
Requires-Dist: nbclassic; extra == "dev"
|
|
24
24
|
Requires-Dist: nbdev; extra == "dev"
|
|
@@ -31,6 +31,15 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
33
33
|
|
|
34
|
+
> **ghapi v2 (July 2026) is now async by default.** Every API call is
|
|
35
|
+
> now awaited: `res = await api.repos.get()`. Top-level `await` works
|
|
36
|
+
> directly in Jupyter and modern REPLs; in scripts, use
|
|
37
|
+
> [`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run).
|
|
38
|
+
> For sync code (which should be largely compatible with v1), use
|
|
39
|
+
> `GhApi(sync=True)`. See the [Sync
|
|
40
|
+
> usage](https://ghapi.fast.ai/core.html#sync-usage) section of the docs
|
|
41
|
+
> for details. To stay on the old version, pin `ghapi<2`.
|
|
42
|
+
|
|
34
43
|
[`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) provides 100%
|
|
35
44
|
always-updated coverage of the entire [GitHub
|
|
36
45
|
API](https://docs.github.com/rest). Because we automatically convert the
|
|
@@ -38,7 +47,8 @@ API](https://docs.github.com/rest). Because we automatically convert the
|
|
|
38
47
|
spec](https://docs.github.com/rest/overview/openapi-description) to a
|
|
39
48
|
Pythonic API, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) is always
|
|
40
49
|
up to date with the latest changes to GitHub APIs. Furthermore, because
|
|
41
|
-
this is all
|
|
50
|
+
this is all built dynamically from a compact pre-parsed copy of the
|
|
51
|
+
spec, the package stays small and is always up to date.
|
|
42
52
|
|
|
43
53
|
Using [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi), you can automate
|
|
44
54
|
nearly anything that you can do through the GitHub web interface or
|
|
@@ -67,8 +77,7 @@ or from the command line. An overview of each is provided below.
|
|
|
67
77
|
|
|
68
78
|
## Installation
|
|
69
79
|
|
|
70
|
-
To install, run
|
|
71
|
-
`conda install -c fastai ghapi`.
|
|
80
|
+
To install, run `pip install ghapi`.
|
|
72
81
|
|
|
73
82
|
## How to use - Python
|
|
74
83
|
|
|
@@ -88,12 +97,17 @@ viewer.
|
|
|
88
97
|
|
|
89
98
|
All of the documentation is available directly as Jupyter Notebooks, for
|
|
90
99
|
instance the current page you’re reading is available as a notebook
|
|
91
|
-
[here](https://github.com/
|
|
92
|
-
any page as an interactive notebook in Google Colab, click the
|
|
93
|
-
badge at the top of the page.
|
|
100
|
+
[here](https://github.com/AnswerDotAI/ghapi/blob/main/nbs/index.ipynb).
|
|
101
|
+
To open any page as an interactive notebook in Google Colab, click the
|
|
102
|
+
*Colab* badge at the top of the page.
|
|
94
103
|
|
|
95
104
|
To access the GitHub API, first create a
|
|
96
|
-
[`GhApi`](https://ghapi.fast.ai/core.html#ghapi) object
|
|
105
|
+
[`GhApi`](https://ghapi.fast.ai/core.html#ghapi) object. Note that as of
|
|
106
|
+
v2, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) is async: every
|
|
107
|
+
endpoint call is `await`ed. In Jupyter and modern Python REPLs top-level
|
|
108
|
+
`await` just works, as shown below; in scripts, wrap your code in a
|
|
109
|
+
function run with
|
|
110
|
+
[`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run).
|
|
97
111
|
|
|
98
112
|
``` python
|
|
99
113
|
from ghapi.all import GhApi
|
|
@@ -108,21 +122,32 @@ functionality provided by the API by displaying the object:
|
|
|
108
122
|
api
|
|
109
123
|
```
|
|
110
124
|
|
|
125
|
+
<div class="prose" markdown="1">
|
|
126
|
+
|
|
111
127
|
- [actions](https://docs.github.com/rest/reference/actions)
|
|
112
128
|
- [activity](https://docs.github.com/rest/reference/activity)
|
|
129
|
+
- [agent_tasks](https://docs.github.com/rest/reference/agent-tasks)
|
|
130
|
+
- [agents](https://docs.github.com/rest/reference/agents)
|
|
113
131
|
- [api_insights](https://docs.github.com/rest/reference/api-insights)
|
|
114
132
|
- [apps](https://docs.github.com/rest/reference/apps)
|
|
115
133
|
- [billing](https://docs.github.com/rest/reference/billing)
|
|
134
|
+
- [campaigns](https://docs.github.com/rest/reference/campaigns)
|
|
116
135
|
- [checks](https://docs.github.com/rest/reference/checks)
|
|
117
136
|
- [classroom](https://docs.github.com/rest/reference/classroom)
|
|
137
|
+
- [code_quality](https://docs.github.com/rest/reference/code-quality)
|
|
118
138
|
- [code_scanning](https://docs.github.com/rest/reference/code-scanning)
|
|
119
139
|
- [code_security](https://docs.github.com/rest/reference/code-security)
|
|
120
140
|
- [codes_of_conduct](https://docs.github.com/rest/reference/codes-of-conduct)
|
|
121
141
|
- [codespaces](https://docs.github.com/rest/reference/codespaces)
|
|
122
142
|
- [copilot](https://docs.github.com/rest/reference/copilot)
|
|
143
|
+
- [copilot_spaces](https://docs.github.com/rest/reference/copilot-spaces)
|
|
144
|
+
- [credentials](https://docs.github.com/rest/reference/credentials)
|
|
123
145
|
- [dependabot](https://docs.github.com/rest/reference/dependabot)
|
|
124
146
|
- [dependency_graph](https://docs.github.com/rest/reference/dependency-graph)
|
|
125
147
|
- [emojis](https://docs.github.com/rest/reference/emojis)
|
|
148
|
+
- [enterprise_team_memberships](https://docs.github.com/rest/reference/enterprise-team-memberships)
|
|
149
|
+
- [enterprise_team_organizations](https://docs.github.com/rest/reference/enterprise-team-organizations)
|
|
150
|
+
- [enterprise_teams](https://docs.github.com/rest/reference/enterprise-teams)
|
|
126
151
|
- [gists](https://docs.github.com/rest/reference/gists)
|
|
127
152
|
- [git](https://docs.github.com/rest/reference/git)
|
|
128
153
|
- [gitignore](https://docs.github.com/rest/reference/gitignore)
|
|
@@ -148,6 +173,8 @@ api
|
|
|
148
173
|
- [teams](https://docs.github.com/rest/reference/teams)
|
|
149
174
|
- [users](https://docs.github.com/rest/reference/users)
|
|
150
175
|
|
|
176
|
+
</div>
|
|
177
|
+
|
|
151
178
|
Then we can explore the endpoints provided by the API in each group,
|
|
152
179
|
e.g. for the `git` group:
|
|
153
180
|
|
|
@@ -155,6 +182,8 @@ e.g. for the `git` group:
|
|
|
155
182
|
api.git
|
|
156
183
|
```
|
|
157
184
|
|
|
185
|
+
<div class="prose" markdown="1">
|
|
186
|
+
|
|
158
187
|
- [git.create_blob](https://docs.github.com/rest/git/blobs#create-a-blob)(owner,
|
|
159
188
|
repo, content, encoding): *Create a blob*
|
|
160
189
|
- [git.get_blob](https://docs.github.com/rest/git/blobs#get-a-blob)(owner,
|
|
@@ -183,24 +212,41 @@ api.git
|
|
|
183
212
|
- [git.get_tree](https://docs.github.com/rest/git/trees#get-a-tree)(owner,
|
|
184
213
|
repo, tree_sha, recursive): *Get a tree*
|
|
185
214
|
|
|
215
|
+
</div>
|
|
216
|
+
|
|
186
217
|
Here’s how to learn about an endpoint you want to use, e.g.:
|
|
187
218
|
|
|
188
219
|
``` python
|
|
189
220
|
api.git.get_ref
|
|
190
221
|
```
|
|
191
222
|
|
|
192
|
-
|
|
193
|
-
|
|
223
|
+
<div class="prose" markdown="1">
|
|
224
|
+
|
|
225
|
+
Get a reference
|
|
226
|
+
|
|
227
|
+
Docs: https://docs.github.com/rest/git/refs#get-a-reference
|
|
228
|
+
|
|
229
|
+
Parameters: - owner (str, required): The account owner of the
|
|
230
|
+
repository. The name is not case sensitive. - repo (str, required): The
|
|
231
|
+
name of the repository without the `.git` extension. The name is not
|
|
232
|
+
case sensitive. - ref (str, required): The Git reference. For more
|
|
233
|
+
information, see “[Git
|
|
234
|
+
References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)”
|
|
235
|
+
in the Git documentation.
|
|
236
|
+
|
|
237
|
+
</div>
|
|
194
238
|
|
|
195
239
|
In Jupyter Notebook full tab completion, parameter lists, etc are
|
|
196
240
|
provided for all endpoints. Endpoints are called as standard Python
|
|
197
241
|
methods:
|
|
198
242
|
|
|
199
243
|
``` python
|
|
200
|
-
api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
244
|
+
await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
201
245
|
```
|
|
202
246
|
|
|
203
|
-
|
|
247
|
+
<div class="prose" markdown="1">
|
|
248
|
+
|
|
249
|
+
``` python
|
|
204
250
|
{ 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
|
|
205
251
|
'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
|
|
206
252
|
'type': 'commit',
|
|
@@ -209,6 +255,8 @@ api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
|
209
255
|
'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
|
|
210
256
|
```
|
|
211
257
|
|
|
258
|
+
</div>
|
|
259
|
+
|
|
212
260
|
To use [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) to access
|
|
213
261
|
authenticated operations (other than when running through GitHub
|
|
214
262
|
Actions), you will need a GitHub [personal access
|
|
@@ -243,10 +291,12 @@ api = GhApi(owner='fastai', repo='fastcore', token=github_token)
|
|
|
243
291
|
We can now repeat the previous method, but only need to pass `ref`:
|
|
244
292
|
|
|
245
293
|
``` python
|
|
246
|
-
api.git.get_ref('heads/master')
|
|
294
|
+
await api.git.get_ref('heads/master')
|
|
247
295
|
```
|
|
248
296
|
|
|
249
|
-
|
|
297
|
+
<div class="prose" markdown="1">
|
|
298
|
+
|
|
299
|
+
``` python
|
|
250
300
|
{ 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
|
|
251
301
|
'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
|
|
252
302
|
'type': 'commit',
|
|
@@ -255,17 +305,19 @@ api.git.get_ref('heads/master')
|
|
|
255
305
|
'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
|
|
256
306
|
```
|
|
257
307
|
|
|
308
|
+
</div>
|
|
309
|
+
|
|
258
310
|
Now that we’ve provided our token, we can use authenticated endpoints
|
|
259
311
|
such as creating an issue:
|
|
260
312
|
|
|
261
313
|
``` python
|
|
262
|
-
issue = api.issues.create("Remember to check out GhApi!")
|
|
314
|
+
issue = await api.issues.create("Remember to check out GhApi!")
|
|
263
315
|
```
|
|
264
316
|
|
|
265
317
|
Since we’ve now checked out GhApi, let’s close this issue. 😎
|
|
266
318
|
|
|
267
319
|
``` python
|
|
268
|
-
api.issues.update(issue.number, state='closed')
|
|
320
|
+
await api.issues.update(issue.number, state='closed')
|
|
269
321
|
```
|
|
270
322
|
|
|
271
323
|
## How to use - command line
|
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
5
5
|
|
|
6
|
+
> **ghapi v2 (July 2026) is now async by default.** Every API call is
|
|
7
|
+
> now awaited: `res = await api.repos.get()`. Top-level `await` works
|
|
8
|
+
> directly in Jupyter and modern REPLs; in scripts, use
|
|
9
|
+
> [`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run).
|
|
10
|
+
> For sync code (which should be largely compatible with v1), use
|
|
11
|
+
> `GhApi(sync=True)`. See the [Sync
|
|
12
|
+
> usage](https://ghapi.fast.ai/core.html#sync-usage) section of the docs
|
|
13
|
+
> for details. To stay on the old version, pin `ghapi<2`.
|
|
14
|
+
|
|
6
15
|
[`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) provides 100%
|
|
7
16
|
always-updated coverage of the entire [GitHub
|
|
8
17
|
API](https://docs.github.com/rest). Because we automatically convert the
|
|
@@ -10,7 +19,8 @@ API](https://docs.github.com/rest). Because we automatically convert the
|
|
|
10
19
|
spec](https://docs.github.com/rest/overview/openapi-description) to a
|
|
11
20
|
Pythonic API, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) is always
|
|
12
21
|
up to date with the latest changes to GitHub APIs. Furthermore, because
|
|
13
|
-
this is all
|
|
22
|
+
this is all built dynamically from a compact pre-parsed copy of the
|
|
23
|
+
spec, the package stays small and is always up to date.
|
|
14
24
|
|
|
15
25
|
Using [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi), you can automate
|
|
16
26
|
nearly anything that you can do through the GitHub web interface or
|
|
@@ -39,8 +49,7 @@ or from the command line. An overview of each is provided below.
|
|
|
39
49
|
|
|
40
50
|
## Installation
|
|
41
51
|
|
|
42
|
-
To install, run
|
|
43
|
-
`conda install -c fastai ghapi`.
|
|
52
|
+
To install, run `pip install ghapi`.
|
|
44
53
|
|
|
45
54
|
## How to use - Python
|
|
46
55
|
|
|
@@ -60,12 +69,17 @@ viewer.
|
|
|
60
69
|
|
|
61
70
|
All of the documentation is available directly as Jupyter Notebooks, for
|
|
62
71
|
instance the current page you’re reading is available as a notebook
|
|
63
|
-
[here](https://github.com/
|
|
64
|
-
any page as an interactive notebook in Google Colab, click the
|
|
65
|
-
badge at the top of the page.
|
|
72
|
+
[here](https://github.com/AnswerDotAI/ghapi/blob/main/nbs/index.ipynb).
|
|
73
|
+
To open any page as an interactive notebook in Google Colab, click the
|
|
74
|
+
*Colab* badge at the top of the page.
|
|
66
75
|
|
|
67
76
|
To access the GitHub API, first create a
|
|
68
|
-
[`GhApi`](https://ghapi.fast.ai/core.html#ghapi) object
|
|
77
|
+
[`GhApi`](https://ghapi.fast.ai/core.html#ghapi) object. Note that as of
|
|
78
|
+
v2, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) is async: every
|
|
79
|
+
endpoint call is `await`ed. In Jupyter and modern Python REPLs top-level
|
|
80
|
+
`await` just works, as shown below; in scripts, wrap your code in a
|
|
81
|
+
function run with
|
|
82
|
+
[`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run).
|
|
69
83
|
|
|
70
84
|
``` python
|
|
71
85
|
from ghapi.all import GhApi
|
|
@@ -80,21 +94,32 @@ functionality provided by the API by displaying the object:
|
|
|
80
94
|
api
|
|
81
95
|
```
|
|
82
96
|
|
|
97
|
+
<div class="prose" markdown="1">
|
|
98
|
+
|
|
83
99
|
- [actions](https://docs.github.com/rest/reference/actions)
|
|
84
100
|
- [activity](https://docs.github.com/rest/reference/activity)
|
|
101
|
+
- [agent_tasks](https://docs.github.com/rest/reference/agent-tasks)
|
|
102
|
+
- [agents](https://docs.github.com/rest/reference/agents)
|
|
85
103
|
- [api_insights](https://docs.github.com/rest/reference/api-insights)
|
|
86
104
|
- [apps](https://docs.github.com/rest/reference/apps)
|
|
87
105
|
- [billing](https://docs.github.com/rest/reference/billing)
|
|
106
|
+
- [campaigns](https://docs.github.com/rest/reference/campaigns)
|
|
88
107
|
- [checks](https://docs.github.com/rest/reference/checks)
|
|
89
108
|
- [classroom](https://docs.github.com/rest/reference/classroom)
|
|
109
|
+
- [code_quality](https://docs.github.com/rest/reference/code-quality)
|
|
90
110
|
- [code_scanning](https://docs.github.com/rest/reference/code-scanning)
|
|
91
111
|
- [code_security](https://docs.github.com/rest/reference/code-security)
|
|
92
112
|
- [codes_of_conduct](https://docs.github.com/rest/reference/codes-of-conduct)
|
|
93
113
|
- [codespaces](https://docs.github.com/rest/reference/codespaces)
|
|
94
114
|
- [copilot](https://docs.github.com/rest/reference/copilot)
|
|
115
|
+
- [copilot_spaces](https://docs.github.com/rest/reference/copilot-spaces)
|
|
116
|
+
- [credentials](https://docs.github.com/rest/reference/credentials)
|
|
95
117
|
- [dependabot](https://docs.github.com/rest/reference/dependabot)
|
|
96
118
|
- [dependency_graph](https://docs.github.com/rest/reference/dependency-graph)
|
|
97
119
|
- [emojis](https://docs.github.com/rest/reference/emojis)
|
|
120
|
+
- [enterprise_team_memberships](https://docs.github.com/rest/reference/enterprise-team-memberships)
|
|
121
|
+
- [enterprise_team_organizations](https://docs.github.com/rest/reference/enterprise-team-organizations)
|
|
122
|
+
- [enterprise_teams](https://docs.github.com/rest/reference/enterprise-teams)
|
|
98
123
|
- [gists](https://docs.github.com/rest/reference/gists)
|
|
99
124
|
- [git](https://docs.github.com/rest/reference/git)
|
|
100
125
|
- [gitignore](https://docs.github.com/rest/reference/gitignore)
|
|
@@ -120,6 +145,8 @@ api
|
|
|
120
145
|
- [teams](https://docs.github.com/rest/reference/teams)
|
|
121
146
|
- [users](https://docs.github.com/rest/reference/users)
|
|
122
147
|
|
|
148
|
+
</div>
|
|
149
|
+
|
|
123
150
|
Then we can explore the endpoints provided by the API in each group,
|
|
124
151
|
e.g. for the `git` group:
|
|
125
152
|
|
|
@@ -127,6 +154,8 @@ e.g. for the `git` group:
|
|
|
127
154
|
api.git
|
|
128
155
|
```
|
|
129
156
|
|
|
157
|
+
<div class="prose" markdown="1">
|
|
158
|
+
|
|
130
159
|
- [git.create_blob](https://docs.github.com/rest/git/blobs#create-a-blob)(owner,
|
|
131
160
|
repo, content, encoding): *Create a blob*
|
|
132
161
|
- [git.get_blob](https://docs.github.com/rest/git/blobs#get-a-blob)(owner,
|
|
@@ -155,24 +184,41 @@ api.git
|
|
|
155
184
|
- [git.get_tree](https://docs.github.com/rest/git/trees#get-a-tree)(owner,
|
|
156
185
|
repo, tree_sha, recursive): *Get a tree*
|
|
157
186
|
|
|
187
|
+
</div>
|
|
188
|
+
|
|
158
189
|
Here’s how to learn about an endpoint you want to use, e.g.:
|
|
159
190
|
|
|
160
191
|
``` python
|
|
161
192
|
api.git.get_ref
|
|
162
193
|
```
|
|
163
194
|
|
|
164
|
-
|
|
165
|
-
|
|
195
|
+
<div class="prose" markdown="1">
|
|
196
|
+
|
|
197
|
+
Get a reference
|
|
198
|
+
|
|
199
|
+
Docs: https://docs.github.com/rest/git/refs#get-a-reference
|
|
200
|
+
|
|
201
|
+
Parameters: - owner (str, required): The account owner of the
|
|
202
|
+
repository. The name is not case sensitive. - repo (str, required): The
|
|
203
|
+
name of the repository without the `.git` extension. The name is not
|
|
204
|
+
case sensitive. - ref (str, required): The Git reference. For more
|
|
205
|
+
information, see “[Git
|
|
206
|
+
References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)”
|
|
207
|
+
in the Git documentation.
|
|
208
|
+
|
|
209
|
+
</div>
|
|
166
210
|
|
|
167
211
|
In Jupyter Notebook full tab completion, parameter lists, etc are
|
|
168
212
|
provided for all endpoints. Endpoints are called as standard Python
|
|
169
213
|
methods:
|
|
170
214
|
|
|
171
215
|
``` python
|
|
172
|
-
api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
216
|
+
await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
173
217
|
```
|
|
174
218
|
|
|
175
|
-
|
|
219
|
+
<div class="prose" markdown="1">
|
|
220
|
+
|
|
221
|
+
``` python
|
|
176
222
|
{ 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
|
|
177
223
|
'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
|
|
178
224
|
'type': 'commit',
|
|
@@ -181,6 +227,8 @@ api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
|
|
|
181
227
|
'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
|
|
182
228
|
```
|
|
183
229
|
|
|
230
|
+
</div>
|
|
231
|
+
|
|
184
232
|
To use [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) to access
|
|
185
233
|
authenticated operations (other than when running through GitHub
|
|
186
234
|
Actions), you will need a GitHub [personal access
|
|
@@ -215,10 +263,12 @@ api = GhApi(owner='fastai', repo='fastcore', token=github_token)
|
|
|
215
263
|
We can now repeat the previous method, but only need to pass `ref`:
|
|
216
264
|
|
|
217
265
|
``` python
|
|
218
|
-
api.git.get_ref('heads/master')
|
|
266
|
+
await api.git.get_ref('heads/master')
|
|
219
267
|
```
|
|
220
268
|
|
|
221
|
-
|
|
269
|
+
<div class="prose" markdown="1">
|
|
270
|
+
|
|
271
|
+
``` python
|
|
222
272
|
{ 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
|
|
223
273
|
'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
|
|
224
274
|
'type': 'commit',
|
|
@@ -227,17 +277,19 @@ api.git.get_ref('heads/master')
|
|
|
227
277
|
'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
|
|
228
278
|
```
|
|
229
279
|
|
|
280
|
+
</div>
|
|
281
|
+
|
|
230
282
|
Now that we’ve provided our token, we can use authenticated endpoints
|
|
231
283
|
such as creating an issue:
|
|
232
284
|
|
|
233
285
|
``` python
|
|
234
|
-
issue = api.issues.create("Remember to check out GhApi!")
|
|
286
|
+
issue = await api.issues.create("Remember to check out GhApi!")
|
|
235
287
|
```
|
|
236
288
|
|
|
237
289
|
Since we’ve now checked out GhApi, let’s close this issue. 😎
|
|
238
290
|
|
|
239
291
|
``` python
|
|
240
|
-
api.issues.update(issue.number, state='closed')
|
|
292
|
+
await api.issues.update(issue.number, state='closed')
|
|
241
293
|
```
|
|
242
294
|
|
|
243
295
|
## How to use - command line
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.0"
|
|
@@ -32,9 +32,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
32
32
|
'ghapi.auth.GhDeviceAuth.wait': ('auth.html#ghdeviceauth.wait', 'ghapi/auth.py'),
|
|
33
33
|
'ghapi.auth.github_auth_device': ('auth.html#github_auth_device', 'ghapi/auth.py'),
|
|
34
34
|
'ghapi.auth.scope_str': ('auth.html#scope_str', 'ghapi/auth.py')},
|
|
35
|
-
'ghapi.build_lib': {
|
|
36
|
-
'ghapi.build_lib._find_data': ('build_lib.html#_find_data', 'ghapi/build_lib.py'),
|
|
37
|
-
'ghapi.build_lib.build_funcs': ('build_lib.html#build_funcs', 'ghapi/build_lib.py')},
|
|
35
|
+
'ghapi.build_lib': {'ghapi.build_lib.build_spec': ('build_lib.html#build_spec', 'ghapi/build_lib.py')},
|
|
38
36
|
'ghapi.cli': { 'ghapi.cli._api': ('cli.html#_api', 'ghapi/cli.py'),
|
|
39
37
|
'ghapi.cli._call_api': ('cli.html#_call_api', 'ghapi/cli.py'),
|
|
40
38
|
'ghapi.cli._ghapi': ('cli.html#_ghapi', 'ghapi/cli.py'),
|
|
@@ -46,8 +44,6 @@ d = { 'settings': { 'branch': 'main',
|
|
|
46
44
|
'ghapi.cli.ghraw': ('cli.html#ghraw', 'ghapi/cli.py')},
|
|
47
45
|
'ghapi.core': { 'ghapi.core.GhApi': ('core.html#ghapi', 'ghapi/core.py'),
|
|
48
46
|
'ghapi.core.GhApi.__call__': ('core.html#ghapi.__call__', 'ghapi/core.py'),
|
|
49
|
-
'ghapi.core.GhApi.__dir__': ('core.html#ghapi.__dir__', 'ghapi/core.py'),
|
|
50
|
-
'ghapi.core.GhApi.__getattr__': ('core.html#ghapi.__getattr__', 'ghapi/core.py'),
|
|
51
47
|
'ghapi.core.GhApi.__getitem__': ('core.html#ghapi.__getitem__', 'ghapi/core.py'),
|
|
52
48
|
'ghapi.core.GhApi.__init__': ('core.html#ghapi.__init__', 'ghapi/core.py'),
|
|
53
49
|
'ghapi.core.GhApi._get_repo_files': ('core.html#ghapi._get_repo_files', 'ghapi/core.py'),
|
|
@@ -58,53 +54,48 @@ d = { 'settings': { 'branch': 'main',
|
|
|
58
54
|
'ghapi.core.GhApi.create_gist': ('core.html#ghapi.create_gist', 'ghapi/core.py'),
|
|
59
55
|
'ghapi.core.GhApi.create_or_update_file': ('core.html#ghapi.create_or_update_file', 'ghapi/core.py'),
|
|
60
56
|
'ghapi.core.GhApi.create_release': ('core.html#ghapi.create_release', 'ghapi/core.py'),
|
|
57
|
+
'ghapi.core.GhApi.debug': ('core.html#ghapi.debug', 'ghapi/core.py'),
|
|
61
58
|
'ghapi.core.GhApi.delete_branch': ('core.html#ghapi.delete_branch', 'ghapi/core.py'),
|
|
62
59
|
'ghapi.core.GhApi.delete_file': ('core.html#ghapi.delete_file', 'ghapi/core.py'),
|
|
63
60
|
'ghapi.core.GhApi.delete_release': ('core.html#ghapi.delete_release', 'ghapi/core.py'),
|
|
64
61
|
'ghapi.core.GhApi.delete_tag': ('core.html#ghapi.delete_tag', 'ghapi/core.py'),
|
|
65
62
|
'ghapi.core.GhApi.enable_pages': ('core.html#ghapi.enable_pages', 'ghapi/core.py'),
|
|
66
|
-
'ghapi.core.GhApi.full_docs': ('core.html#ghapi.full_docs', 'ghapi/core.py'),
|
|
67
63
|
'ghapi.core.GhApi.get_branch': ('core.html#ghapi.get_branch', 'ghapi/core.py'),
|
|
68
64
|
'ghapi.core.GhApi.get_content': ('core.html#ghapi.get_content', 'ghapi/core.py'),
|
|
69
65
|
'ghapi.core.GhApi.get_file_content': ('core.html#ghapi.get_file_content', 'ghapi/core.py'),
|
|
70
66
|
'ghapi.core.GhApi.get_repo_contents': ('core.html#ghapi.get_repo_contents', 'ghapi/core.py'),
|
|
71
67
|
'ghapi.core.GhApi.get_repo_files': ('core.html#ghapi.get_repo_files', 'ghapi/core.py'),
|
|
72
68
|
'ghapi.core.GhApi.gist_file': ('core.html#ghapi.gist_file', 'ghapi/core.py'),
|
|
69
|
+
'ghapi.core.GhApi.limit_rem': ('core.html#ghapi.limit_rem', 'ghapi/core.py'),
|
|
73
70
|
'ghapi.core.GhApi.list_branches': ('core.html#ghapi.list_branches', 'ghapi/core.py'),
|
|
74
71
|
'ghapi.core.GhApi.list_files': ('core.html#ghapi.list_files', 'ghapi/core.py'),
|
|
75
72
|
'ghapi.core.GhApi.list_tags': ('core.html#ghapi.list_tags', 'ghapi/core.py'),
|
|
76
73
|
'ghapi.core.GhApi.load_gist': ('core.html#ghapi.load_gist', 'ghapi/core.py'),
|
|
77
74
|
'ghapi.core.GhApi.pr_status': ('core.html#ghapi.pr_status', 'ghapi/core.py'),
|
|
78
75
|
'ghapi.core.GhApi.read_issue': ('core.html#ghapi.read_issue', 'ghapi/core.py'),
|
|
76
|
+
'ghapi.core.GhApi.recv_hdrs': ('core.html#ghapi.recv_hdrs', 'ghapi/core.py'),
|
|
79
77
|
'ghapi.core.GhApi.update_contents': ('core.html#ghapi.update_contents', 'ghapi/core.py'),
|
|
80
78
|
'ghapi.core.GhApi.update_gist': ('core.html#ghapi.update_gist', 'ghapi/core.py'),
|
|
81
79
|
'ghapi.core.GhApi.upload_file': ('core.html#ghapi.upload_file', 'ghapi/core.py'),
|
|
80
|
+
'ghapi.core.GhSyncTransport': ('core.html#ghsynctransport', 'ghapi/core.py'),
|
|
81
|
+
'ghapi.core.GhSyncTransport.request': ('core.html#ghsynctransport.request', 'ghapi/core.py'),
|
|
82
|
+
'ghapi.core.GhTransport': ('core.html#ghtransport', 'ghapi/core.py'),
|
|
83
|
+
'ghapi.core.GhTransport.__init__': ('core.html#ghtransport.__init__', 'ghapi/core.py'),
|
|
84
|
+
'ghapi.core.GhTransport._decode': ('core.html#ghtransport._decode', 'ghapi/core.py'),
|
|
85
|
+
'ghapi.core.GhTransport._post': ('core.html#ghtransport._post', 'ghapi/core.py'),
|
|
86
|
+
'ghapi.core.GhTransport._pre': ('core.html#ghtransport._pre', 'ghapi/core.py'),
|
|
87
|
+
'ghapi.core.GhTransport.request': ('core.html#ghtransport.request', 'ghapi/core.py'),
|
|
82
88
|
'ghapi.core._CheckStatus': ('core.html#_checkstatus', 'ghapi/core.py'),
|
|
83
89
|
'ghapi.core._CheckStatus._repr_markdown_': ('core.html#_checkstatus._repr_markdown_', 'ghapi/core.py'),
|
|
84
|
-
'ghapi.core._GhObj': ('core.html#_ghobj', 'ghapi/core.py'),
|
|
85
|
-
'ghapi.core._GhVerb': ('core.html#_ghverb', 'ghapi/core.py'),
|
|
86
|
-
'ghapi.core._GhVerb.__call__': ('core.html#_ghverb.__call__', 'ghapi/core.py'),
|
|
87
|
-
'ghapi.core._GhVerb.__init__': ('core.html#_ghverb.__init__', 'ghapi/core.py'),
|
|
88
|
-
'ghapi.core._GhVerb.__signature__': ('core.html#_ghverb.__signature__', 'ghapi/core.py'),
|
|
89
|
-
'ghapi.core._GhVerb.__str__': ('core.html#_ghverb.__str__', 'ghapi/core.py'),
|
|
90
|
-
'ghapi.core._GhVerb._repr_markdown_': ('core.html#_ghverb._repr_markdown_', 'ghapi/core.py'),
|
|
91
|
-
'ghapi.core._GhVerb.doc_url': ('core.html#_ghverb.doc_url', 'ghapi/core.py'),
|
|
92
|
-
'ghapi.core._GhVerbGroup': ('core.html#_ghverbgroup', 'ghapi/core.py'),
|
|
93
|
-
'ghapi.core._GhVerbGroup.__init__': ('core.html#_ghverbgroup.__init__', 'ghapi/core.py'),
|
|
94
|
-
'ghapi.core._GhVerbGroup.__str__': ('core.html#_ghverbgroup.__str__', 'ghapi/core.py'),
|
|
95
|
-
'ghapi.core._GhVerbGroup._repr_markdown_': ('core.html#_ghverbgroup._repr_markdown_', 'ghapi/core.py'),
|
|
96
90
|
'ghapi.core._IssueInfo': ('core.html#_issueinfo', 'ghapi/core.py'),
|
|
97
91
|
'ghapi.core._IssueInfo._repr_markdown_': ('core.html#_issueinfo._repr_markdown_', 'ghapi/core.py'),
|
|
98
92
|
'ghapi.core._filter_diff': ('core.html#_filter_diff', 'ghapi/core.py'),
|
|
99
93
|
'ghapi.core._find_matches': ('core.html#_find_matches', 'ghapi/core.py'),
|
|
100
94
|
'ghapi.core._fmt_replies': ('core.html#_fmt_replies', 'ghapi/core.py'),
|
|
101
95
|
'ghapi.core._include': ('core.html#_include', 'ghapi/core.py'),
|
|
102
|
-
'ghapi.core._mk_param': ('core.html#_mk_param', 'ghapi/core.py'),
|
|
103
|
-
'ghapi.core._mk_sig': ('core.html#_mk_sig', 'ghapi/core.py'),
|
|
104
|
-
'ghapi.core._mk_sig_detls': ('core.html#_mk_sig_detls', 'ghapi/core.py'),
|
|
105
|
-
'ghapi.core._preview_hdr': ('core.html#_preview_hdr', 'ghapi/core.py'),
|
|
106
96
|
'ghapi.core._reduce_ctx': ('core.html#_reduce_ctx', 'ghapi/core.py'),
|
|
107
97
|
'ghapi.core._run_subp': ('core.html#_run_subp', 'ghapi/core.py'),
|
|
98
|
+
'ghapi.core.call_gh': ('core.html#call_gh', 'ghapi/core.py'),
|
|
108
99
|
'ghapi.core.date2gh': ('core.html#date2gh', 'ghapi/core.py'),
|
|
109
100
|
'ghapi.core.gh2date': ('core.html#gh2date', 'ghapi/core.py'),
|
|
110
101
|
'ghapi.core.print_summary': ('core.html#print_summary', 'ghapi/core.py'),
|
|
@@ -126,6 +117,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
126
117
|
'ghapi.event._want_evt': ('event.html#_want_evt', 'ghapi/event.py'),
|
|
127
118
|
'ghapi.event.load_sample_events': ('event.html#load_sample_events', 'ghapi/event.py'),
|
|
128
119
|
'ghapi.event.save_sample_events': ('event.html#save_sample_events', 'ghapi/event.py')},
|
|
120
|
+
'ghapi.gh_spec': {},
|
|
129
121
|
'ghapi.graphql': { 'ghapi.graphql.GhGql': ('graphql.html#ghgql', 'ghapi/graphql.py'),
|
|
130
122
|
'ghapi.graphql.GhGql.__call__': ('graphql.html#ghgql.__call__', 'ghapi/graphql.py'),
|
|
131
123
|
'ghapi.graphql.GhGql.__init__': ('graphql.html#ghgql.__init__', 'ghapi/graphql.py'),
|
|
@@ -139,16 +131,16 @@ d = { 'settings': { 'branch': 'main',
|
|
|
139
131
|
'ghapi.graphql.list_queries': ('graphql.html#list_queries', 'ghapi/graphql.py'),
|
|
140
132
|
'ghapi.graphql.query_args': ('graphql.html#query_args', 'ghapi/graphql.py'),
|
|
141
133
|
'ghapi.graphql.type_fields': ('graphql.html#type_fields', 'ghapi/graphql.py')},
|
|
142
|
-
'ghapi.metadata': {},
|
|
143
134
|
'ghapi.page': { 'ghapi.page.GhApi.last_page': ('page.html#ghapi.last_page', 'ghapi/page.py'),
|
|
144
135
|
'ghapi.page._Scanner': ('page.html#_scanner', 'ghapi/page.py'),
|
|
145
136
|
'ghapi.page._Scanner.__getitem__': ('page.html#_scanner.__getitem__', 'ghapi/page.py'),
|
|
146
137
|
'ghapi.page._Scanner.__init__': ('page.html#_scanner.__init__', 'ghapi/page.py'),
|
|
147
138
|
'ghapi.page._Scanner.scan': ('page.html#_scanner.scan', 'ghapi/page.py'),
|
|
148
|
-
'ghapi.page._call_page': ('page.html#_call_page', 'ghapi/page.py'),
|
|
149
139
|
'ghapi.page._parse_link_hdr': ('page.html#_parse_link_hdr', 'ghapi/page.py'),
|
|
150
140
|
'ghapi.page.paged': ('page.html#paged', 'ghapi/page.py'),
|
|
151
141
|
'ghapi.page.pages': ('page.html#pages', 'ghapi/page.py'),
|
|
152
|
-
'ghapi.page.parse_link_hdr': ('page.html#parse_link_hdr', 'ghapi/page.py')
|
|
142
|
+
'ghapi.page.parse_link_hdr': ('page.html#parse_link_hdr', 'ghapi/page.py'),
|
|
143
|
+
'ghapi.page.sync_paged': ('page.html#sync_paged', 'ghapi/page.py'),
|
|
144
|
+
'ghapi.page.sync_pages': ('page.html#sync_pages', 'ghapi/page.py')},
|
|
153
145
|
'ghapi.skill': {},
|
|
154
146
|
'ghapi.templates': {}}}
|
|
@@ -74,7 +74,7 @@ def fill_workflow_templates(name:str, event, run, context, script, opersys='ubun
|
|
|
74
74
|
"Function to create a simple Ubuntu workflow that calls a Python `ghapi` script"
|
|
75
75
|
c = wf_tmpl
|
|
76
76
|
if event=='workflow_dispatch:': event=''
|
|
77
|
-
needs = ' needs: [prebuild]' if prebuild else
|
|
77
|
+
needs = ' needs: [prebuild]' if prebuild else ''
|
|
78
78
|
for find,repl,i in (('NAME',name,0), ('EVENT',event,2), ('RUN',run,8), ('CONTEXTS',context,8),
|
|
79
79
|
('OPERSYS',f'[{opersys}]',0), ('NEEDS',needs,0), ('PREBUILD',pre_tmpl if prebuild else '',2)):
|
|
80
80
|
c = _replace(c, f'${find}', str(repl), i)
|
|
@@ -153,11 +153,11 @@ def actions_mask(value):
|
|
|
153
153
|
print(f"::add-mask::{value}")
|
|
154
154
|
|
|
155
155
|
# %% ../nbs/01_actions.ipynb #8682ff46
|
|
156
|
-
def set_git_user(api=None):
|
|
156
|
+
async def set_git_user(api=None):
|
|
157
157
|
"Set git user name/email to authenticated user (if `api`) or GitHub Actions bot (otherwise)"
|
|
158
158
|
if api:
|
|
159
|
-
user = api.users.get_authenticated().name
|
|
160
|
-
email = first(api.users.list_emails_for_authenticated(), attrgetter('primary')).email
|
|
159
|
+
user = (await api.users.get_authenticated()).name
|
|
160
|
+
email = first(await api.users.list_emails_for_authenticated(), attrgetter('primary')).email
|
|
161
161
|
else:
|
|
162
162
|
user = 'github-actions[bot]'
|
|
163
163
|
email = 'github-actions[bot]@users.noreply.github.com'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Docs: https://ghapi.fast.ai/build_lib.html.md"""
|
|
2
|
+
|
|
3
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/90_build_lib.ipynb.
|
|
4
|
+
|
|
5
|
+
# %% auto #0
|
|
6
|
+
__all__ = ['GH_OPENAPI_URL', 'build_spec']
|
|
7
|
+
|
|
8
|
+
# %% ../nbs/90_build_lib.ipynb #cdbcf258
|
|
9
|
+
from fastcore.all import *
|
|
10
|
+
from fastspec.spec import SpecParser
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
|
|
14
|
+
# %% ../nbs/90_build_lib.ipynb #c215ed8d
|
|
15
|
+
GH_OPENAPI_URL = 'https://github.com/github/rest-api-description/raw/main/descriptions/api.github.com/api.github.com.json?raw=true'
|
|
16
|
+
|
|
17
|
+
# %% ../nbs/90_build_lib.ipynb #cf7204d9
|
|
18
|
+
def build_spec(nm='ghapi/gh_spec.py', url=GH_OPENAPI_URL):
|
|
19
|
+
"Regenerate the compact spec module `gh_spec.py` from GitHub's OpenAPI description."
|
|
20
|
+
SpecParser.from_openapi(dict2obj(json.loads(urlread(url)))).save(nm)
|
|
@@ -9,9 +9,10 @@ __all__ = ['ghapi', 'ghpath', 'ghraw', 'completion_ghapi']
|
|
|
9
9
|
|
|
10
10
|
# %% ../nbs/10_cli.ipynb #e10a0628
|
|
11
11
|
from fastcore.all import *
|
|
12
|
-
import ghapi.core as gh,inspect
|
|
13
12
|
from .core import *
|
|
14
|
-
from
|
|
13
|
+
from fastspec.oapi import OpFunc
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
15
16
|
|
|
16
17
|
# %% ../nbs/10_cli.ipynb #44ebb54f
|
|
17
18
|
def _parse_args(a):
|
|
@@ -43,7 +44,7 @@ def _call_api(f):
|
|
|
43
44
|
cmd,api,pos,kw = _api()
|
|
44
45
|
if not pos: return print(f"Usage: `{cmd}` operation <params>")
|
|
45
46
|
call = f(pos, api)
|
|
46
|
-
return call if kw.get('help', None) else call(*pos, **kw)
|
|
47
|
+
return call if kw.get('help', None) else asyncio.run(call(*pos, **kw))
|
|
47
48
|
|
|
48
49
|
# %% ../nbs/10_cli.ipynb #55f9002f
|
|
49
50
|
def _ghapi(arg, api):
|
|
@@ -54,8 +55,8 @@ def _ghapi(arg, api):
|
|
|
54
55
|
def ghapi():
|
|
55
56
|
"Python backend for the `ghapi` command, which calls an endpoint by operation name"
|
|
56
57
|
res = _call_api(_ghapi)
|
|
57
|
-
if isinstance(res,
|
|
58
|
-
elif res: print(
|
|
58
|
+
if isinstance(res, OpFunc): print(repr(res))
|
|
59
|
+
elif res is not None: print(res)
|
|
59
60
|
|
|
60
61
|
# %% ../nbs/10_cli.ipynb #524623ba
|
|
61
62
|
def _ghpath(arg, api): return api[arg.pop(0),arg.pop(0)]
|
|
@@ -70,7 +71,7 @@ def ghraw():
|
|
|
70
71
|
"Python backend for the `ghraw` command, which calls a fully-specified endpoint"
|
|
71
72
|
cmd,api,pos,kw = _api()
|
|
72
73
|
if not pos: return print(f"Usage: `{cmd}` operation <params>")
|
|
73
|
-
print(api(*pos, **kw))
|
|
74
|
+
print(asyncio.run(api(*pos, **kw)))
|
|
74
75
|
|
|
75
76
|
# %% ../nbs/10_cli.ipynb #21033494
|
|
76
77
|
_TAB_COMPLETION="""
|