ghapi 2.0.5__tar.gz → 2.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {ghapi-2.0.5/ghapi.egg-info → ghapi-2.0.7}/PKG-INFO +44 -29
  2. {ghapi-2.0.5 → ghapi-2.0.7}/README.md +40 -26
  3. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/__init__.py +2 -1
  4. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/_modidx.py +23 -13
  5. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/build_lib.py +10 -2
  6. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/core.py +137 -8
  7. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/gh_spec.py +375 -37
  8. ghapi-2.0.7/ghapi/gql_spec.py +1815 -0
  9. ghapi-2.0.7/ghapi/graphql.py +39 -0
  10. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/skill.py +19 -13
  11. {ghapi-2.0.5 → ghapi-2.0.7/ghapi.egg-info}/PKG-INFO +44 -29
  12. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi.egg-info/SOURCES.txt +1 -0
  13. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi.egg-info/requires.txt +5 -2
  14. {ghapi-2.0.5 → ghapi-2.0.7}/pyproject.toml +1 -1
  15. ghapi-2.0.5/ghapi/graphql.py +0 -74
  16. {ghapi-2.0.5 → ghapi-2.0.7}/CONTRIBUTING.md +0 -0
  17. {ghapi-2.0.5 → ghapi-2.0.7}/LICENSE +0 -0
  18. {ghapi-2.0.5 → ghapi-2.0.7}/MANIFEST.in +0 -0
  19. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/actions.py +0 -0
  20. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/all.py +0 -0
  21. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/auth.py +0 -0
  22. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/cli.py +0 -0
  23. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/event.py +0 -0
  24. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/page.py +0 -0
  25. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/py.typed +0 -0
  26. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi/templates.py +0 -0
  27. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi.egg-info/dependency_links.txt +0 -0
  28. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi.egg-info/entry_points.txt +0 -0
  29. {ghapi-2.0.5 → ghapi-2.0.7}/ghapi.egg-info/top_level.txt +0 -0
  30. {ghapi-2.0.5 → ghapi-2.0.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghapi
3
- Version: 2.0.5
3
+ Version: 2.0.7
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
@@ -15,8 +15,9 @@ Classifier: Programming Language :: Python :: 3 :: Only
15
15
  Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: fastcore>=2.1.16
19
- Requires-Dist: fastspec>=0.1.2
18
+ Requires-Dist: fastcore>=2.2.6
19
+ Requires-Dist: fastspec>=0.1.7
20
+ Requires-Dist: tomli; python_version < "3.11"
20
21
  Provides-Extra: dev
21
22
  Requires-Dist: fastgit; extra == "dev"
22
23
  Requires-Dist: matplotlib; extra == "dev"
@@ -69,6 +70,9 @@ To access the GitHub API, first create a [`GhApi`](https://ghapi.fast.ai/core.ht
69
70
 
70
71
  ``` python
71
72
  from ghapi.all import GhApi
73
+ ```
74
+
75
+ ``` python
72
76
  api = GhApi()
73
77
  ```
74
78
 
@@ -78,8 +82,6 @@ Every part of the API includes documentation directly in the `api` object itself
78
82
  api
79
83
  ```
80
84
 
81
- <div class="prose" markdown="1">
82
-
83
85
  - [actions](https://docs.github.com/rest/reference/actions)
84
86
  - [activity](https://docs.github.com/rest/reference/activity)
85
87
  - [agent_tasks](https://docs.github.com/rest/reference/agent-tasks)
@@ -119,6 +121,7 @@ api
119
121
  - [packages](https://docs.github.com/rest/reference/packages)
120
122
  - [private_registries](https://docs.github.com/rest/reference/private-registries)
121
123
  - [projects](https://docs.github.com/rest/reference/projects)
124
+ - [pull_request_stacks](https://docs.github.com/rest/reference/pull-request-stacks)
122
125
  - [pulls](https://docs.github.com/rest/reference/pulls)
123
126
  - [rate_limit](https://docs.github.com/rest/reference/rate-limit)
124
127
  - [reactions](https://docs.github.com/rest/reference/reactions)
@@ -129,16 +132,12 @@ api
129
132
  - [teams](https://docs.github.com/rest/reference/teams)
130
133
  - [users](https://docs.github.com/rest/reference/users)
131
134
 
132
- </div>
133
-
134
135
  Then we can explore the endpoints provided by the API in each group, e.g. for the `git` group:
135
136
 
136
137
  ``` python
137
138
  api.git
138
139
  ```
139
140
 
140
- <div class="prose" markdown="1">
141
-
142
141
  - [git.create_blob](https://docs.github.com/rest/git/blobs#create-a-blob)(owner, repo, content, encoding): *Create a blob*
143
142
  - [git.get_blob](https://docs.github.com/rest/git/blobs#get-a-blob)(owner, repo, file_sha): *Get a blob*
144
143
  - [git.create_commit](https://docs.github.com/rest/git/commits#create-a-commit)(owner, repo, message, tree, parents, author, committer, signature): *Create a commit*
@@ -153,16 +152,12 @@ api.git
153
152
  - [git.create_tree](https://docs.github.com/rest/git/trees#create-a-tree)(owner, repo, tree, base_tree): *Create a tree*
154
153
  - [git.get_tree](https://docs.github.com/rest/git/trees#get-a-tree)(owner, repo, tree_sha, recursive): *Get a tree*
155
154
 
156
- </div>
157
-
158
155
  Here’s how to learn about an endpoint you want to use, e.g.:
159
156
 
160
157
  ``` python
161
158
  api.git.get_ref
162
159
  ```
163
160
 
164
- <div class="prose" markdown="1">
165
-
166
161
  Get a reference
167
162
 
168
163
  Docs: https://docs.github.com/rest/git/refs#get-a-reference
@@ -172,16 +167,12 @@ Parameters:
172
167
  - repo (str, required): The name of the repository without the `.git` extension. The name is not case sensitive.
173
168
  - ref (str, required): The Git reference. For more information, see “[Git References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)” in the Git documentation.
174
169
 
175
- </div>
176
-
177
- In Jupyter Notebook full tab completion, parameter lists, etc are provided for all endpoints. Endpoints are called as standard Python methods:
170
+ Jupyter provides full tab completion and parameter lists for every endpoint. Endpoints are called as standard Python methods:
178
171
 
179
172
  ``` python
180
173
  await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
181
174
  ```
182
175
 
183
- <div class="prose" markdown="1">
184
-
185
176
  ``` python
186
177
  { 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
187
178
  'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
@@ -191,17 +182,13 @@ await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
191
182
  'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
192
183
  ```
193
184
 
194
- </div>
195
-
196
- To use [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) to access authenticated operations (other than when running through GitHub Actions), you will need a GitHub [personal access token](https://docs.github.com/github/authenticating-to-github/creating-a-personal-access-token), which is a secret code used to access your account. If you don’t have one, [click here](https://github.com/settings/tokens/new) to create one. You’ll be asked to enter a name – choose anything you like, for instance “*ghapi*”. You’ll also be asked to choose “scopes”; this limits what you’ll be able to do with the API using this token. If you’re not sure, click “*repo*” “*gist*”, “*notifications*”, and “*workflow*”. Then click “Generate Token” at the bottom of the screen, and copy the token (the long string of letters and numbers shown). You can easily do that by clicking the little clipboard icon next to the token.
197
-
198
- Rather than pasting that token into every script, it’s easiest to save it as an environment variable. If you save it as `$GITHUB_TOKEN` then it will be most convenient, so add this to the end of your `.bashrc` or `.zshrc` file:
185
+ To use authenticated operations (other than when running through GitHub Actions), you will need a GitHub [personal access token](https://docs.github.com/github/authenticating-to-github/creating-a-personal-access-token). If you don’t have one, [click here](https://github.com/settings/tokens/new) to create it, choosing the scopes you need (“repo”, “gist”, “notifications”, and “workflow” cover most uses). Save it as an environment variable named `GITHUB_TOKEN`, e.g. by adding this to your `.bashrc` or `.zshrc`:
199
186
 
200
187
  export GITHUB_TOKEN=xxx
201
188
 
202
- …replacing the `xxx` with the token you just copied. (Don’t forget to `source` that file after you change it.), pass a \[GitHub token\].
189
+ [`GhApi`](https://ghapi.fast.ai/core.html#ghapi) uses that variable automatically, or you can pass `token=` explicitly.
203
190
 
204
- As well as your `token`, you can also pass any parameters you want auto-inserted into relevant methods, such as `owner` and `repo`:
191
+ As well as `token`, you can pass any parameters you want auto-inserted into relevant methods, such as `owner` and `repo`:
205
192
 
206
193
  ``` python
207
194
  api = GhApi(owner='fastai', repo='fastcore', token=github_token)
@@ -213,8 +200,6 @@ We can now repeat the previous method, but only need to pass `ref`:
213
200
  await api.git.get_ref('heads/master')
214
201
  ```
215
202
 
216
- <div class="prose" markdown="1">
217
-
218
203
  ``` python
219
204
  { 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
220
205
  'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
@@ -224,8 +209,6 @@ await api.git.get_ref('heads/master')
224
209
  'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
225
210
  ```
226
211
 
227
- </div>
228
-
229
212
  Now that we’ve provided our token, we can use authenticated endpoints such as creating an issue:
230
213
 
231
214
  ``` python
@@ -238,6 +221,38 @@ Since we’ve now checked out GhApi, let’s close this issue. 😎
238
221
  await api.issues.update(issue.number, state='closed')
239
222
  ```
240
223
 
224
+ ## Beyond the endpoints
225
+
226
+ [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) also layers task-level conveniences over the generated endpoints – see the [GhApi details](https://ghapi.fast.ai/core.html) page for the full set. Highlights: [`paged`](https://ghapi.fast.ai/page.html#paged)/[`pages`](https://ghapi.fast.ai/page.html#pages) iterate any list endpoint; [`read_issue`](https://ghapi.fast.ai/core.html#read_issue)/[`read_pr`](https://ghapi.fast.ai/core.html#read_pr) gather a whole issue or PR (body, comments, diff, reviews) in one call; [`dep_graph`](https://ghapi.fast.ai/core.html#dep_graph)/[`dep_order`](https://ghapi.fast.ai/core.html#dep_order) sort an ecosystem’s repos dependency-first; plus helpers for gists, releases, branches, and repo files. For CI, [`check_status`](https://ghapi.fast.ai/core.html#check_status) combines commit statuses and check runs into one verdict, and [`failed_step_log`](https://ghapi.fast.ai/core.html#failed_step_log) drills into why a run went red:
227
+
228
+ ``` python
229
+ api = GhApi(owner='AnswerDotAI', repo='ghapi', token=github_token)
230
+ await api.check_status('main')
231
+ ```
232
+
233
+ **failure**
234
+
235
+ - 93199230629 update-pip-graph: success (46s)
236
+ - 93199227080 deploy: failure (22s)
237
+
238
+ ## GraphQL
239
+
240
+ When a read fans out across many repos, the [GraphQL client](https://ghapi.fast.ai/graphql.html) fetches it in a single `batch` call – issued as parallel chunked requests under the hood, at a fraction of the rate-limit cost of per-repo REST calls. Build schema-checked query fragments by attribute chaining, then `batch` them: here, the head commit of several repos at once. The same page covers interactive schema discovery, cursor pagination, raw queries, and more:
241
+
242
+ ``` python
243
+ from ghapi.graphql import GhGql
244
+ ```
245
+
246
+ ``` python
247
+ gql = GhGql()
248
+ await gql.batch(*[gql.repository(owner='AnswerDotAI', name=n).defaultBranchRef.target.oid
249
+ for n in ('fastcore', 'fasthtml', 'ghapi')])
250
+ ```
251
+
252
+ ['25c4f3228ccac3c5a63da71b5eaa4be3c428f602',
253
+ 'e5d967ae627c63035e296e6f319f220e278327e7',
254
+ 'ad07893daac86de6693bc9bb57ae7216c1b347d0']
255
+
241
256
  ## How to use - command line
242
257
 
243
258
  You can use [`GhApi`](https://ghapi.fast.ai/core.html#ghapi) via the command line, and can access nearly everything in the [GitHub API](https://docs.github.com/rest). We provide an overview here of one of the command line programs, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) – see the full CLI docs page for details on all the programs available.
@@ -40,6 +40,9 @@ To access the GitHub API, first create a [`GhApi`](https://ghapi.fast.ai/core.ht
40
40
 
41
41
  ``` python
42
42
  from ghapi.all import GhApi
43
+ ```
44
+
45
+ ``` python
43
46
  api = GhApi()
44
47
  ```
45
48
 
@@ -49,8 +52,6 @@ Every part of the API includes documentation directly in the `api` object itself
49
52
  api
50
53
  ```
51
54
 
52
- <div class="prose" markdown="1">
53
-
54
55
  - [actions](https://docs.github.com/rest/reference/actions)
55
56
  - [activity](https://docs.github.com/rest/reference/activity)
56
57
  - [agent_tasks](https://docs.github.com/rest/reference/agent-tasks)
@@ -90,6 +91,7 @@ api
90
91
  - [packages](https://docs.github.com/rest/reference/packages)
91
92
  - [private_registries](https://docs.github.com/rest/reference/private-registries)
92
93
  - [projects](https://docs.github.com/rest/reference/projects)
94
+ - [pull_request_stacks](https://docs.github.com/rest/reference/pull-request-stacks)
93
95
  - [pulls](https://docs.github.com/rest/reference/pulls)
94
96
  - [rate_limit](https://docs.github.com/rest/reference/rate-limit)
95
97
  - [reactions](https://docs.github.com/rest/reference/reactions)
@@ -100,16 +102,12 @@ api
100
102
  - [teams](https://docs.github.com/rest/reference/teams)
101
103
  - [users](https://docs.github.com/rest/reference/users)
102
104
 
103
- </div>
104
-
105
105
  Then we can explore the endpoints provided by the API in each group, e.g. for the `git` group:
106
106
 
107
107
  ``` python
108
108
  api.git
109
109
  ```
110
110
 
111
- <div class="prose" markdown="1">
112
-
113
111
  - [git.create_blob](https://docs.github.com/rest/git/blobs#create-a-blob)(owner, repo, content, encoding): *Create a blob*
114
112
  - [git.get_blob](https://docs.github.com/rest/git/blobs#get-a-blob)(owner, repo, file_sha): *Get a blob*
115
113
  - [git.create_commit](https://docs.github.com/rest/git/commits#create-a-commit)(owner, repo, message, tree, parents, author, committer, signature): *Create a commit*
@@ -124,16 +122,12 @@ api.git
124
122
  - [git.create_tree](https://docs.github.com/rest/git/trees#create-a-tree)(owner, repo, tree, base_tree): *Create a tree*
125
123
  - [git.get_tree](https://docs.github.com/rest/git/trees#get-a-tree)(owner, repo, tree_sha, recursive): *Get a tree*
126
124
 
127
- </div>
128
-
129
125
  Here’s how to learn about an endpoint you want to use, e.g.:
130
126
 
131
127
  ``` python
132
128
  api.git.get_ref
133
129
  ```
134
130
 
135
- <div class="prose" markdown="1">
136
-
137
131
  Get a reference
138
132
 
139
133
  Docs: https://docs.github.com/rest/git/refs#get-a-reference
@@ -143,16 +137,12 @@ Parameters:
143
137
  - repo (str, required): The name of the repository without the `.git` extension. The name is not case sensitive.
144
138
  - ref (str, required): The Git reference. For more information, see “[Git References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)” in the Git documentation.
145
139
 
146
- </div>
147
-
148
- In Jupyter Notebook full tab completion, parameter lists, etc are provided for all endpoints. Endpoints are called as standard Python methods:
140
+ Jupyter provides full tab completion and parameter lists for every endpoint. Endpoints are called as standard Python methods:
149
141
 
150
142
  ``` python
151
143
  await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
152
144
  ```
153
145
 
154
- <div class="prose" markdown="1">
155
-
156
146
  ``` python
157
147
  { 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
158
148
  'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
@@ -162,17 +152,13 @@ await api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')
162
152
  'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
163
153
  ```
164
154
 
165
- </div>
166
-
167
- To use [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) to access authenticated operations (other than when running through GitHub Actions), you will need a GitHub [personal access token](https://docs.github.com/github/authenticating-to-github/creating-a-personal-access-token), which is a secret code used to access your account. If you don’t have one, [click here](https://github.com/settings/tokens/new) to create one. You’ll be asked to enter a name – choose anything you like, for instance “*ghapi*”. You’ll also be asked to choose “scopes”; this limits what you’ll be able to do with the API using this token. If you’re not sure, click “*repo*” “*gist*”, “*notifications*”, and “*workflow*”. Then click “Generate Token” at the bottom of the screen, and copy the token (the long string of letters and numbers shown). You can easily do that by clicking the little clipboard icon next to the token.
168
-
169
- Rather than pasting that token into every script, it’s easiest to save it as an environment variable. If you save it as `$GITHUB_TOKEN` then it will be most convenient, so add this to the end of your `.bashrc` or `.zshrc` file:
155
+ To use authenticated operations (other than when running through GitHub Actions), you will need a GitHub [personal access token](https://docs.github.com/github/authenticating-to-github/creating-a-personal-access-token). If you don’t have one, [click here](https://github.com/settings/tokens/new) to create it, choosing the scopes you need (“repo”, “gist”, “notifications”, and “workflow” cover most uses). Save it as an environment variable named `GITHUB_TOKEN`, e.g. by adding this to your `.bashrc` or `.zshrc`:
170
156
 
171
157
  export GITHUB_TOKEN=xxx
172
158
 
173
- …replacing the `xxx` with the token you just copied. (Don’t forget to `source` that file after you change it.), pass a \[GitHub token\].
159
+ [`GhApi`](https://ghapi.fast.ai/core.html#ghapi) uses that variable automatically, or you can pass `token=` explicitly.
174
160
 
175
- As well as your `token`, you can also pass any parameters you want auto-inserted into relevant methods, such as `owner` and `repo`:
161
+ As well as `token`, you can pass any parameters you want auto-inserted into relevant methods, such as `owner` and `repo`:
176
162
 
177
163
  ``` python
178
164
  api = GhApi(owner='fastai', repo='fastcore', token=github_token)
@@ -184,8 +170,6 @@ We can now repeat the previous method, but only need to pass `ref`:
184
170
  await api.git.get_ref('heads/master')
185
171
  ```
186
172
 
187
- <div class="prose" markdown="1">
188
-
189
173
  ``` python
190
174
  { 'node_id': 'MDM6UmVmMjI1NDYwNTk5OnJlZnMvaGVhZHMvbWFzdGVy',
191
175
  'object': { 'sha': 'c0608379fe60014534c8dffe2e381138e8160f53',
@@ -195,8 +179,6 @@ await api.git.get_ref('heads/master')
195
179
  'url': 'https://api.github.com/repos/AnswerDotAI/fastcore/git/refs/heads/master'}
196
180
  ```
197
181
 
198
- </div>
199
-
200
182
  Now that we’ve provided our token, we can use authenticated endpoints such as creating an issue:
201
183
 
202
184
  ``` python
@@ -209,6 +191,38 @@ Since we’ve now checked out GhApi, let’s close this issue. 😎
209
191
  await api.issues.update(issue.number, state='closed')
210
192
  ```
211
193
 
194
+ ## Beyond the endpoints
195
+
196
+ [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) also layers task-level conveniences over the generated endpoints – see the [GhApi details](https://ghapi.fast.ai/core.html) page for the full set. Highlights: [`paged`](https://ghapi.fast.ai/page.html#paged)/[`pages`](https://ghapi.fast.ai/page.html#pages) iterate any list endpoint; [`read_issue`](https://ghapi.fast.ai/core.html#read_issue)/[`read_pr`](https://ghapi.fast.ai/core.html#read_pr) gather a whole issue or PR (body, comments, diff, reviews) in one call; [`dep_graph`](https://ghapi.fast.ai/core.html#dep_graph)/[`dep_order`](https://ghapi.fast.ai/core.html#dep_order) sort an ecosystem’s repos dependency-first; plus helpers for gists, releases, branches, and repo files. For CI, [`check_status`](https://ghapi.fast.ai/core.html#check_status) combines commit statuses and check runs into one verdict, and [`failed_step_log`](https://ghapi.fast.ai/core.html#failed_step_log) drills into why a run went red:
197
+
198
+ ``` python
199
+ api = GhApi(owner='AnswerDotAI', repo='ghapi', token=github_token)
200
+ await api.check_status('main')
201
+ ```
202
+
203
+ **failure**
204
+
205
+ - 93199230629 update-pip-graph: success (46s)
206
+ - 93199227080 deploy: failure (22s)
207
+
208
+ ## GraphQL
209
+
210
+ When a read fans out across many repos, the [GraphQL client](https://ghapi.fast.ai/graphql.html) fetches it in a single `batch` call – issued as parallel chunked requests under the hood, at a fraction of the rate-limit cost of per-repo REST calls. Build schema-checked query fragments by attribute chaining, then `batch` them: here, the head commit of several repos at once. The same page covers interactive schema discovery, cursor pagination, raw queries, and more:
211
+
212
+ ``` python
213
+ from ghapi.graphql import GhGql
214
+ ```
215
+
216
+ ``` python
217
+ gql = GhGql()
218
+ await gql.batch(*[gql.repository(owner='AnswerDotAI', name=n).defaultBranchRef.target.oid
219
+ for n in ('fastcore', 'fasthtml', 'ghapi')])
220
+ ```
221
+
222
+ ['25c4f3228ccac3c5a63da71b5eaa4be3c428f602',
223
+ 'e5d967ae627c63035e296e6f319f220e278327e7',
224
+ 'ad07893daac86de6693bc9bb57ae7216c1b347d0']
225
+
212
226
  ## How to use - command line
213
227
 
214
228
  You can use [`GhApi`](https://ghapi.fast.ai/core.html#ghapi) via the command line, and can access nearly everything in the [GitHub API](https://docs.github.com/rest). We provide an overview here of one of the command line programs, [`ghapi`](https://ghapi.fast.ai/cli.html#ghapi) – see the full CLI docs page for details on all the programs available.
@@ -2,6 +2,7 @@
2
2
 
3
3
  Modules:
4
4
 
5
+ - `ghapi.graphql`: Query GitHub's GraphQL API: schema-aware chained queries, one-request batching, and raw GraphQL
5
6
  - `ghapi.skill`: GitHub REST API access via `GhApi`, plus local git operations via `fastgit.Git`. Use this for day-to-day GitHub work: reading/creating issues and PRs, checking CI status, managing releases/branches/gists, and repo-local git operations -- all from Python, no shelling out to `gh`/`git` needed."""
6
7
 
7
- __version__ = "2.0.5"
8
+ __version__ = "2.0.7"
@@ -32,7 +32,8 @@ 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': {'ghapi.build_lib.build_spec': ('build_lib.html#build_spec', 'ghapi/build_lib.py')},
35
+ 'ghapi.build_lib': { 'ghapi.build_lib.build_gql_spec': ('build_lib.html#build_gql_spec', 'ghapi/build_lib.py'),
36
+ 'ghapi.build_lib.build_spec': ('build_lib.html#build_spec', 'ghapi/build_lib.py')},
36
37
  'ghapi.cli': { 'ghapi.cli._api': ('cli.html#_api', 'ghapi/cli.py'),
37
38
  'ghapi.cli._call_api': ('cli.html#_call_api', 'ghapi/cli.py'),
38
39
  'ghapi.cli._ghapi': ('cli.html#_ghapi', 'ghapi/cli.py'),
@@ -42,7 +43,11 @@ d = { 'settings': { 'branch': 'main',
42
43
  'ghapi.cli.ghapi': ('cli.html#ghapi', 'ghapi/cli.py'),
43
44
  'ghapi.cli.ghpath': ('cli.html#ghpath', 'ghapi/cli.py'),
44
45
  'ghapi.cli.ghraw': ('cli.html#ghraw', 'ghapi/cli.py')},
45
- 'ghapi.core': { 'ghapi.core.GhApi': ('core.html#ghapi', 'ghapi/core.py'),
46
+ 'ghapi.core': { 'ghapi.core.CheckRun': ('core.html#checkrun', 'ghapi/core.py'),
47
+ 'ghapi.core.CheckRun.__repr__': ('core.html#checkrun.__repr__', 'ghapi/core.py'),
48
+ 'ghapi.core.CommitStatus': ('core.html#commitstatus', 'ghapi/core.py'),
49
+ 'ghapi.core.CommitStatus.__repr__': ('core.html#commitstatus.__repr__', 'ghapi/core.py'),
50
+ 'ghapi.core.GhApi': ('core.html#ghapi', 'ghapi/core.py'),
46
51
  'ghapi.core.GhApi.__call__': ('core.html#ghapi.__call__', 'ghapi/core.py'),
47
52
  'ghapi.core.GhApi.__getitem__': ('core.html#ghapi.__getitem__', 'ghapi/core.py'),
48
53
  'ghapi.core.GhApi.__init__': ('core.html#ghapi.__init__', 'ghapi/core.py'),
@@ -59,6 +64,8 @@ d = { 'settings': { 'branch': 'main',
59
64
  'ghapi.core.GhApi.recv_hdrs': ('core.html#ghapi.recv_hdrs', 'ghapi/core.py'),
60
65
  'ghapi.core.GhApi.update_gist': ('core.html#ghapi.update_gist', 'ghapi/core.py'),
61
66
  'ghapi.core.GhApi.upload_file': ('core.html#ghapi.upload_file', 'ghapi/core.py'),
67
+ 'ghapi.core.GhRows': ('core.html#ghrows', 'ghapi/core.py'),
68
+ 'ghapi.core.GhRows.__repr__': ('core.html#ghrows.__repr__', 'ghapi/core.py'),
62
69
  'ghapi.core.GhSyncTransport': ('core.html#ghsynctransport', 'ghapi/core.py'),
63
70
  'ghapi.core.GhSyncTransport.request': ('core.html#ghsynctransport.request', 'ghapi/core.py'),
64
71
  'ghapi.core.GhTransport': ('core.html#ghtransport', 'ghapi/core.py'),
@@ -72,14 +79,19 @@ d = { 'settings': { 'branch': 'main',
72
79
  'ghapi.core._IssueInfo': ('core.html#_issueinfo', 'ghapi/core.py'),
73
80
  'ghapi.core._IssueInfo._repr_markdown_': ('core.html#_issueinfo._repr_markdown_', 'ghapi/core.py'),
74
81
  'ghapi.core._LiveDefaults': ('core.html#_livedefaults', 'ghapi/core.py'),
82
+ 'ghapi.core._LiveDefaults.__contains__': ('core.html#_livedefaults.__contains__', 'ghapi/core.py'),
83
+ 'ghapi.core._LiveDefaults.get': ('core.html#_livedefaults.get', 'ghapi/core.py'),
75
84
  'ghapi.core._LiveDefaults.items': ('core.html#_livedefaults.items', 'ghapi/core.py'),
85
+ 'ghapi.core._dur': ('core.html#_dur', 'ghapi/core.py'),
76
86
  'ghapi.core._filter_diff': ('core.html#_filter_diff', 'ghapi/core.py'),
77
87
  'ghapi.core._find_matches': ('core.html#_find_matches', 'ghapi/core.py'),
78
88
  'ghapi.core._fmt_replies': ('core.html#_fmt_replies', 'ghapi/core.py'),
79
89
  'ghapi.core._include': ('core.html#_include', 'ghapi/core.py'),
90
+ 'ghapi.core._listed': ('core.html#_listed', 'ghapi/core.py'),
80
91
  'ghapi.core._parse_tmpl': ('core.html#_parse_tmpl', 'ghapi/core.py'),
81
92
  'ghapi.core._reduce_ctx': ('core.html#_reduce_ctx', 'ghapi/core.py'),
82
93
  'ghapi.core._run_subp': ('core.html#_run_subp', 'ghapi/core.py'),
94
+ 'ghapi.core._transdeps': ('core.html#_transdeps', 'ghapi/core.py'),
83
95
  'ghapi.core.call_gh': ('core.html#call_gh', 'ghapi/core.py'),
84
96
  'ghapi.core.check_status': ('core.html#check_status', 'ghapi/core.py'),
85
97
  'ghapi.core.commit_tree': ('core.html#commit_tree', 'ghapi/core.py'),
@@ -92,7 +104,13 @@ d = { 'settings': { 'branch': 'main',
92
104
  'ghapi.core.delete_file': ('core.html#delete_file', 'ghapi/core.py'),
93
105
  'ghapi.core.delete_release': ('core.html#delete_release', 'ghapi/core.py'),
94
106
  'ghapi.core.delete_tag': ('core.html#delete_tag', 'ghapi/core.py'),
107
+ 'ghapi.core.dep_closure': ('core.html#dep_closure', 'ghapi/core.py'),
108
+ 'ghapi.core.dep_dependents': ('core.html#dep_dependents', 'ghapi/core.py'),
109
+ 'ghapi.core.dep_graph': ('core.html#dep_graph', 'ghapi/core.py'),
110
+ 'ghapi.core.dep_key': ('core.html#dep_key', 'ghapi/core.py'),
111
+ 'ghapi.core.dep_order': ('core.html#dep_order', 'ghapi/core.py'),
95
112
  'ghapi.core.enable_pages': ('core.html#enable_pages', 'ghapi/core.py'),
113
+ 'ghapi.core.failed_step_log': ('core.html#failed_step_log', 'ghapi/core.py'),
96
114
  'ghapi.core.get_branch': ('core.html#get_branch', 'ghapi/core.py'),
97
115
  'ghapi.core.get_content': ('core.html#get_content', 'ghapi/core.py'),
98
116
  'ghapi.core.gh2date': ('core.html#gh2date', 'ghapi/core.py'),
@@ -102,6 +120,7 @@ d = { 'settings': { 'branch': 'main',
102
120
  'ghapi.core.list_branches': ('core.html#list_branches', 'ghapi/core.py'),
103
121
  'ghapi.core.list_files': ('core.html#list_files', 'ghapi/core.py'),
104
122
  'ghapi.core.list_tags': ('core.html#list_tags', 'ghapi/core.py'),
123
+ 'ghapi.core.local_dep_graph': ('core.html#local_dep_graph', 'ghapi/core.py'),
105
124
  'ghapi.core.pr_file_diff': ('core.html#pr_file_diff', 'ghapi/core.py'),
106
125
  'ghapi.core.pr_status': ('core.html#pr_status', 'ghapi/core.py'),
107
126
  'ghapi.core.print_summary': ('core.html#print_summary', 'ghapi/core.py'),
@@ -126,19 +145,10 @@ d = { 'settings': { 'branch': 'main',
126
145
  'ghapi.event.load_sample_events': ('event.html#load_sample_events', 'ghapi/event.py'),
127
146
  'ghapi.event.save_sample_events': ('event.html#save_sample_events', 'ghapi/event.py')},
128
147
  'ghapi.gh_spec': {},
148
+ 'ghapi.gql_spec': {},
129
149
  'ghapi.graphql': { 'ghapi.graphql.GhGql': ('graphql.html#ghgql', 'ghapi/graphql.py'),
130
- 'ghapi.graphql.GhGql.__call__': ('graphql.html#ghgql.__call__', 'ghapi/graphql.py'),
131
150
  'ghapi.graphql.GhGql.__init__': ('graphql.html#ghgql.__init__', 'ghapi/graphql.py'),
132
- 'ghapi.graphql.GhGql.client': ('graphql.html#ghgql.client', 'ghapi/graphql.py'),
133
- 'ghapi.graphql.GhGql.list_queries': ('graphql.html#ghgql.list_queries', 'ghapi/graphql.py'),
134
- 'ghapi.graphql.GhGql.query_args': ('graphql.html#ghgql.query_args', 'ghapi/graphql.py'),
135
- 'ghapi.graphql.GhGql.schema': ('graphql.html#ghgql.schema', 'ghapi/graphql.py'),
136
- 'ghapi.graphql.GhGql.type_fields': ('graphql.html#ghgql.type_fields', 'ghapi/graphql.py'),
137
- 'ghapi.graphql._get_client': ('graphql.html#_get_client', 'ghapi/graphql.py'),
138
- 'ghapi.graphql.gh_query': ('graphql.html#gh_query', 'ghapi/graphql.py'),
139
- 'ghapi.graphql.list_queries': ('graphql.html#list_queries', 'ghapi/graphql.py'),
140
- 'ghapi.graphql.query_args': ('graphql.html#query_args', 'ghapi/graphql.py'),
141
- 'ghapi.graphql.type_fields': ('graphql.html#type_fields', 'ghapi/graphql.py')},
151
+ 'ghapi.graphql.GhGql.repo': ('graphql.html#ghgql.repo', 'ghapi/graphql.py')},
142
152
  'ghapi.page': { 'ghapi.page.GhApi.last_page': ('page.html#ghapi.last_page', 'ghapi/page.py'),
143
153
  'ghapi.page._Scanner': ('page.html#_scanner', 'ghapi/page.py'),
144
154
  'ghapi.page._Scanner.__getitem__': ('page.html#_scanner.__getitem__', 'ghapi/page.py'),
@@ -3,13 +3,14 @@
3
3
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/90_build_lib.ipynb.
4
4
 
5
5
  # %% auto #0
6
- __all__ = ['GH_OPENAPI_URL', 'build_spec']
6
+ __all__ = ['GH_OPENAPI_URL', 'build_spec', 'build_gql_spec']
7
7
 
8
8
  # %% ../nbs/90_build_lib.ipynb #cdbcf258
9
9
  from fastcore.all import *
10
10
  from fastspec.spec import SpecParser
11
+ from fastspec.gql import GqlSpec, INTROSPECT
11
12
 
12
- import json
13
+ import json, httpx
13
14
 
14
15
  # %% ../nbs/90_build_lib.ipynb #c215ed8d
15
16
  GH_OPENAPI_URL = 'https://github.com/github/rest-api-description/raw/main/descriptions/api.github.com/api.github.com.json?raw=true'
@@ -18,3 +19,10 @@ GH_OPENAPI_URL = 'https://github.com/github/rest-api-description/raw/main/descri
18
19
  def build_spec(nm='ghapi/gh_spec.py', url=GH_OPENAPI_URL):
19
20
  "Regenerate the compact spec module `gh_spec.py` from GitHub's OpenAPI description."
20
21
  SpecParser.from_openapi(dict2obj(json.loads(urlread(url)))).save(nm)
22
+
23
+ # %% ../nbs/90_build_lib.ipynb #9aef0afb
24
+ def build_gql_spec(nm='ghapi/gql_spec.py', url='https://api.github.com/graphql'):
25
+ "Regenerate the distilled GraphQL schema tables shipped as `ghapi.gql_spec`."
26
+ r = httpx.post(url, json=dict(query=INTROSPECT), headers=dict(Authorization=f'bearer {os.environ["GITHUB_TOKEN"]}'), timeout=60)
27
+ r.raise_for_status()
28
+ GqlSpec.from_introspection(r.json()).save(nm)