ghapi 2.0.1__tar.gz → 2.0.2__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 (29) hide show
  1. {ghapi-2.0.1/ghapi.egg-info → ghapi-2.0.2}/PKG-INFO +1 -1
  2. ghapi-2.0.2/ghapi/__init__.py +1 -0
  3. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/actions.py +7 -10
  4. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/auth.py +4 -6
  5. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/core.py +12 -15
  6. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/event.py +5 -6
  7. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/gh_spec.py +43 -6
  8. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/graphql.py +1 -4
  9. {ghapi-2.0.1 → ghapi-2.0.2/ghapi.egg-info}/PKG-INFO +1 -1
  10. ghapi-2.0.1/ghapi/__init__.py +0 -1
  11. {ghapi-2.0.1 → ghapi-2.0.2}/CONTRIBUTING.md +0 -0
  12. {ghapi-2.0.1 → ghapi-2.0.2}/LICENSE +0 -0
  13. {ghapi-2.0.1 → ghapi-2.0.2}/MANIFEST.in +0 -0
  14. {ghapi-2.0.1 → ghapi-2.0.2}/README.md +0 -0
  15. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/_modidx.py +0 -0
  16. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/all.py +0 -0
  17. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/build_lib.py +0 -0
  18. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/cli.py +0 -0
  19. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/page.py +0 -0
  20. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/py.typed +0 -0
  21. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/skill.py +0 -0
  22. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi/templates.py +0 -0
  23. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi.egg-info/SOURCES.txt +0 -0
  24. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi.egg-info/dependency_links.txt +0 -0
  25. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi.egg-info/entry_points.txt +0 -0
  26. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi.egg-info/requires.txt +0 -0
  27. {ghapi-2.0.1 → ghapi-2.0.2}/ghapi.egg-info/top_level.txt +0 -0
  28. {ghapi-2.0.1 → ghapi-2.0.2}/pyproject.toml +0 -0
  29. {ghapi-2.0.1 → ghapi-2.0.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghapi
3
- Version: 2.0.1
3
+ Version: 2.0.2
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
@@ -0,0 +1 @@
1
+ __version__ = "2.0.2"
@@ -18,7 +18,6 @@ from .templates import *
18
18
 
19
19
  import textwrap
20
20
  from contextlib import contextmanager
21
- from enum import Enum
22
21
 
23
22
  # %% ../nbs/01_actions.ipynb #fb69ba90
24
23
  # So we can run this outside of GitHub actions too, read from file if needed
@@ -26,8 +25,7 @@ for a,b in (('CONTEXT_GITHUB',context_example), ('CONTEXT_NEEDS',needs_example),
26
25
  if a not in os.environ: os.environ[a] = b
27
26
 
28
27
  contexts = 'github', 'env', 'job', 'steps', 'runner', 'secrets', 'strategy', 'matrix', 'needs'
29
- for context in contexts:
30
- globals()[f'context_{context}'] = dict2obj(loads(os.getenv(f"CONTEXT_{context.upper()}", "{}")))
28
+ for context in contexts: globals()[f'context_{context}'] = dict2obj(loads(os.getenv(f"CONTEXT_{context.upper()}", "{}")))
31
29
 
32
30
  # %% ../nbs/01_actions.ipynb #393990e1
33
31
  _all_ = ['context_github', 'context_env', 'context_job', 'context_steps', 'context_runner', 'context_secrets', 'context_strategy', 'context_matrix', 'context_needs']
@@ -41,7 +39,7 @@ def user_repo():
41
39
  return env_github.repository.split('/')
42
40
 
43
41
  # %% ../nbs/01_actions.ipynb #deb389d7
44
- Event = str_enum('Event',
42
+ Event = str_enum('Event', # chkstyle: ignore-node
45
43
  'page_build','content_reference','repository_import','create','workflow_run','delete','organization','sponsorship',
46
44
  'project_column','push','context','milestone','project_card','project','package','pull_request','repository_dispatch',
47
45
  'team_add','workflow_dispatch','member','meta','code_scanning_alert','public','needs','check_run','security_advisory',
@@ -54,8 +52,7 @@ Event = str_enum('Event',
54
52
  def _create_file(path:Path, fname:str, contents):
55
53
  if contents and not (path/fname).exists(): (path/fname).write_text(contents)
56
54
 
57
- def _replace(s:str, find, repl, i:int=0, suf:str=''):
58
- return s.replace(find, textwrap.indent(repl, ' '*i)+suf)
55
+ def _replace(s:str, find, repl, i:int=0, suf:str=''): return s.replace(find, textwrap.indent(repl, ' '*i)+suf)
59
56
 
60
57
  # %% ../nbs/01_actions.ipynb #26eb64e5
61
58
  def create_workflow_files(fname:str, workflow:str, build_script:str, prebuild:bool=False):
@@ -75,9 +72,9 @@ def fill_workflow_templates(name:str, event, run, context, script, opersys='ubun
75
72
  c = wf_tmpl
76
73
  if event=='workflow_dispatch:': event=''
77
74
  needs = ' needs: [prebuild]' if prebuild else ''
78
- for find,repl,i in (('NAME',name,0), ('EVENT',event,2), ('RUN',run,8), ('CONTEXTS',context,8),
79
- ('OPERSYS',f'[{opersys}]',0), ('NEEDS',needs,0), ('PREBUILD',pre_tmpl if prebuild else '',2)):
80
- c = _replace(c, f'${find}', str(repl), i)
75
+ repls = (('NAME',name,0), ('EVENT',event,2), ('RUN',run,8), ('CONTEXTS',context,8),
76
+ ('OPERSYS',f'[{opersys}]',0), ('NEEDS',needs,0), ('PREBUILD',pre_tmpl if prebuild else '',2))
77
+ for find,repl,i in repls: c = _replace(c, f'${find}', str(repl), i)
81
78
  create_workflow_files(name, c, script, prebuild=prebuild)
82
79
 
83
80
  # %% ../nbs/01_actions.ipynb #bc2f80a5
@@ -93,7 +90,7 @@ def_pipinst = 'pip install -Uq ghapi'
93
90
  def create_workflow(name:str, event:Event, contexts:list=None, opersys='ubuntu', prebuild=False):
94
91
  "Function to create a simple Ubuntu workflow that calls a Python `ghapi` script"
95
92
  script = "from fastcore.all import *\nfrom ghapi import *"
96
- fill_workflow_templates(name, f'{event}:', def_pipinst, env_contexts(contexts),
93
+ fill_workflow_templates(name, f'{event}:', def_pipinst, env_contexts(contexts), # chkstyle: ignore-node
97
94
  script=script, opersys=opersys, prebuild=prebuild)
98
95
 
99
96
  # %% ../nbs/01_actions.ipynb #e8482286
@@ -12,10 +12,10 @@ from fastcore.all import *
12
12
  from .core import *
13
13
 
14
14
  import webbrowser,time
15
- from urllib.parse import parse_qs,urlsplit
15
+ from urllib.parse import parse_qs
16
16
 
17
17
  # %% ../nbs/02_auth.ipynb #46620407
18
- _scopes =(
18
+ _scopes =( # chkstyle: ignore-node
19
19
  'repo','repo:status','repo_deployment','public_repo','repo:invite','security_events','admin:repo_hook','write:repo_hook',
20
20
  'read:repo_hook','admin:org','write:org','read:org','admin:public_key','write:public_key','read:public_key','admin:org_hook',
21
21
  'gist','notifications','user','read:user','user:email','user:follow','delete_repo','write:discussion','read:discussion',
@@ -61,10 +61,8 @@ def open_browser(self:GhDeviceAuth):
61
61
  @patch
62
62
  def auth(self:GhDeviceAuth)->str:
63
63
  "Return token if authentication complete, or `None` otherwise"
64
- resp = parse_qs(urlread(
65
- 'https://github.com/login/oauth/access_token',
66
- client_id=self.client_id, device_code=self.device_code,
67
- grant_type='urn:ietf:params:oauth:grant-type:device_code'))
64
+ resp = parse_qs(urlread('https://github.com/login/oauth/access_token',
65
+ client_id=self.client_id, device_code=self.device_code, grant_type='urn:ietf:params:oauth:grant-type:device_code'))
68
66
  err = nested_idx(resp, 'error', 0)
69
67
  if err == 'authorization_pending': return None
70
68
  if err: raise Exception(resp['error_description'][0])
@@ -11,7 +11,7 @@ __all__ = ['GH_HOST', 'pspec', 'img_md_pat', 'EMPTY_TREE_SHA', 'GhTransport', 'G
11
11
  # %% ../nbs/00_core.ipynb #5b5cba7b
12
12
  from fastcore.all import *
13
13
  from fastspec.spec import SpecParser
14
- from fastspec.oapi import OpenAPIClient, OpFunc, SyncOpFunc, _build_groups
14
+ from fastspec.oapi import OpenAPIClient, OpFunc, SyncOpFunc, _build_groups, UNSET
15
15
  from fastspec.transport import AsyncTransport, SyncTransport
16
16
  from .gh_spec import spec
17
17
  from fastspec.errors import APIError
@@ -19,8 +19,7 @@ from fastspec.errors import APIError
19
19
  import mimetypes,base64
20
20
  from collections import Counter
21
21
  from urllib.parse import quote
22
- from datetime import datetime, timedelta, timezone
23
- from time import sleep
22
+ from datetime import datetime
24
23
  import os, shutil, tempfile, subprocess, fnmatch, html
25
24
 
26
25
  # %% ../nbs/00_core.ipynb #ed04302a
@@ -60,8 +59,7 @@ class GhTransport(AsyncTransport):
60
59
  self.recv_hdrs = resp.headers
61
60
  if 'X-RateLimit-Remaining' in resp.headers:
62
61
  newlim = resp.headers['X-RateLimit-Remaining']
63
- if self.limit_cb is not None and newlim != self.limit_rem:
64
- self.limit_cb(int(newlim), int(resp.headers['X-RateLimit-Limit']))
62
+ if self.limit_cb is not None and newlim != self.limit_rem: self.limit_cb(int(newlim), int(resp.headers['X-RateLimit-Limit']))
65
63
  self.limit_rem = newlim
66
64
  if raw: return resp
67
65
  res = self._decode(resp)
@@ -90,7 +88,7 @@ def print_summary(method, url, kwargs):
90
88
  # %% ../nbs/00_core.ipynb #83e8a9ce
91
89
  class GhApi(OpenAPIClient):
92
90
  "GitHub API client. Endpoint groups (`issues`, `pulls`, ...) are generated per-instance from GitHub's OpenAPI metadata, so the class shows only convenience methods -- inspect a live instance, e.g. `doc(GhApi())`, to see the full API."
93
- def __init__(self, owner=None, repo=None, token=None, jwt_token=None, debug=None, limit_cb=None, gh_host=None,
91
+ def __init__(self, owner=None, repo=None, token=None, jwt_token=None, debug=None, limit_cb=None, gh_host=None, # chkstyle: ignore-node
94
92
  authenticate=True, timeout=60.0, sync=False, **kwargs):
95
93
  self.headers = { 'Accept': 'application/vnd.github.v3+json' }
96
94
  if authenticate:
@@ -215,11 +213,11 @@ async def upload_file(self:GhApi, rel, fn):
215
213
  # %% ../nbs/00_core.ipynb #3cad71a4
216
214
  @patch
217
215
  async def create_release(self:GhApi, tag_name, branch='master', name=None, body='',
218
- draft=False, prerelease=False, files=None):
216
+ draft=False, prerelease=False, files=None, make_latest=UNSET):
219
217
  "Wrapper for `GhApi.repos.create_release` which also uploads `files`"
220
218
  if name is None: name = 'v'+tag_name
221
219
  rel = await self.repos.create_release(tag_name, target_commitish=branch, name=name, body=body,
222
- draft=draft, prerelease=prerelease)
220
+ draft=draft, prerelease=prerelease, make_latest=make_latest)
223
221
  for file in listify(files): await self.upload_file(rel, file)
224
222
  return rel
225
223
 
@@ -299,8 +297,7 @@ async def create_file(self:GhApi, path, message, committer, author, content=None
299
297
  async def delete_file(self:GhApi, path, message, committer, author, sha=None, branch=None):
300
298
  if not branch: branch = (await self.repos.get())['default_branch']
301
299
  if sha is None: sha = (await self.list_files())[path].sha
302
- return await self.repos.delete_file(path, message=message, sha=sha,
303
- branch=branch, committer=committer, author=author)
300
+ return await self.repos.delete_file(path, message=message, sha=sha, branch=branch, committer=committer, author=author)
304
301
 
305
302
  # %% ../nbs/00_core.ipynb #93f6b559
306
303
  @patch
@@ -346,7 +343,7 @@ async def get_repo_contents(self:GhApi, owner, repo, branch='main',
346
343
  n_workers=16, # Max concurrent downloads
347
344
  **kwargs
348
345
  ):
349
- repo_files = await self.get_repo_files(owner, repo, **kwargs)
346
+ repo_files = await self.get_repo_files(owner, repo, branch, **kwargs)
350
347
  paths = repo_files.attrgot("path")
351
348
  return L(await parallel_async(self.get_file_content, paths, owner=owner, repo=repo, branch=branch, n_workers=n_workers))
352
349
 
@@ -379,7 +376,7 @@ async def read_issue(self:GhApi, issue_number:int):
379
376
  try: pr = await self.pulls.get(issue_number)
380
377
  except APIError: pr = None
381
378
  iss = await self.issues.get(issue_number)
382
- res = dict(title=iss.title, body=iss.body or '', is_pr=pr is not None,
379
+ res = dict(title=iss.title, body=iss.body or '', is_pr=pr is not None, # chkstyle: ignore-node
383
380
  comments=await self.issues.list_comments(issue_number))
384
381
  if pr is not None:
385
382
  res['diff'] = await self.pulls.get(issue_number, _headers={'Accept': 'application/vnd.github.v3.diff'})
@@ -395,7 +392,7 @@ async def read_issue(self:GhApi, issue_number:int):
395
392
  def _filter_diff(diff, folder='', skip_files=('_modidx.py',)):
396
393
  "Filter unified diff to only include files under `folder`, skipping `skip_files`"
397
394
  sections = re.split(r'(?=^diff --git )', diff, flags=re.MULTILINE)
398
- return ''.join(s for s in sections
395
+ return ''.join(s for s in sections # chkstyle: ignore-node
399
396
  if s.startswith(f'diff --git a/{folder}')
400
397
  and not any(f'/{f} ' in s.split('\n')[0] for f in skip_files))
401
398
 
@@ -460,7 +457,7 @@ def _parse_tmpl(name, txt):
460
457
  if not name.endswith(('.yml','.yaml')): return dict2obj(dict(name=name, raw=txt))
461
458
  import yaml
462
459
  d = yaml.safe_load(txt)
463
- secs = [dict(label=b['attributes']['label'], type=b['type'],
460
+ secs = [dict(label=b['attributes']['label'], type=b['type'], # chkstyle: ignore-node
464
461
  required=bool(nested_idx(b, 'validations', 'required')),
465
462
  options=[o['label'] if isinstance(o, dict) else o for o in b['attributes'].get('options', [])])
466
463
  for b in d.get('body', []) if b['type']!='markdown']
@@ -475,7 +472,7 @@ async def issue_template(self:GhApi):
475
472
  except APIError as e:
476
473
  if e.status_code != 404: raise
477
474
  continue
478
- return L([_parse_tmpl(f.name, base64.b64decode((await self.repos.get_content(path=f.path, **kw)).content).decode())
475
+ return L([_parse_tmpl(f.name, base64.b64decode((await self.repos.get_content(path=f.path, **kw)).content).decode()) # chkstyle: ignore-node
479
476
  for f in fs if f.name.endswith(('.md','.yml','.yaml')) and f.name != 'config.yml'])
480
477
  return L()
481
478
 
@@ -129,7 +129,7 @@ def full_type(self:GhEvent):
129
129
  _all_ = ['PageBuildEvent', 'ContentReferenceEvent', 'RepositoryImportEvent', 'CreateEvent', 'WorkflowRunEvent', 'DeleteEvent', 'OrganizationEvent', 'SponsorshipEvent', 'ProjectColumnEvent', 'PushEvent', 'ContextEvent', 'MilestoneEvent', 'ProjectCardEvent', 'ProjectEvent', 'PackageEvent', 'PullRequestEvent', 'RepositoryDispatchEvent', 'TeamAddEvent', 'WorkflowDispatchEvent', 'MemberEvent', 'MetaEvent', 'CodeScanningAlertEvent', 'PublicEvent', 'NeedsEvent', 'CheckRunEvent', 'SecurityAdvisoryEvent', 'PullRequestReviewCommentEvent', 'OrgBlockEvent', 'CommitCommentEvent', 'WatchEvent', 'MarketplacePurchaseEvent', 'StarEvent', 'InstallationRepositoriesEvent', 'CheckSuiteEvent', 'GithubAppAuthorizationEvent', 'TeamEvent', 'StatusEvent', 'RepositoryVulnerabilityAlertEvent', 'PullRequestReviewEvent', 'LabelEvent', 'InstallationEvent', 'ReleaseEvent', 'IssuesEvent', 'RepositoryEvent', 'GollumEvent', 'MembershipEvent', 'DeploymentEvent', 'DeployKeyEvent', 'IssueCommentEvent', 'PingEvent', 'DeploymentStatusEvent', 'ForkEvent', 'ScheduleEvent']
130
130
 
131
131
  # %% ../nbs/04_event.ipynb #83be1955
132
- evt_emojis = dict(
132
+ evt_emojis = dict( # chkstyle: ignore-node
133
133
  PushEvent= '⭐',
134
134
  CreateEvent= '🏭',
135
135
  IssueCommentEvent_created= '💬',
@@ -157,7 +157,7 @@ def _ref_detl(pay): return pay.ref_type + _ref(pay)
157
157
 
158
158
  def _action(self):
159
159
  pay = self.payload
160
- det = (f'issue #{pay.issue.number} on' if isinstance(self,IssuesEvent) else
160
+ det = (f'issue #{pay.issue.number} on' if isinstance(self,IssuesEvent) else # chkstyle: ignore-node
161
161
  f'PR #{pay.number} on' if isinstance(self,PullRequestEvent) else
162
162
  f'member {pay.member.login} in' if isinstance(self,MemberEvent) else
163
163
  f'review comment on PR #{pay.pull_request.number} in' if isinstance(self,PullRequestReviewCommentEvent) else
@@ -173,7 +173,7 @@ def description(self:GhEvent):
173
173
  "Description of event"
174
174
  act,pay,cls,repo = self.actor,self.payload,type(self),self.repo
175
175
  res = _action(self)
176
- return res if res else (
176
+ return res if res else ( # chkstyle: ignore-node
177
177
  f'deleted {_ref_detl(pay)} in' if isinstance(self,DeleteEvent) else
178
178
  f'created {_ref_detl(pay)} in' if isinstance(self,CreateEvent) else
179
179
  f'pushed {len(pay.commits)} commits{_ref(pay," to")} in' if isinstance(self,PushEvent) else
@@ -184,17 +184,16 @@ def description(self:GhEvent):
184
184
  remove_suffix(self.type, "Event")
185
185
  )
186
186
 
187
- #export
188
187
  @patch(as_prop=True)
189
188
  def emoji(self:GhEvent):
190
189
  "Emoji for event from `evt_emojis`"
191
190
  return evt_emojis.get(self.full_type, '❌')
192
191
 
193
192
  # %% ../nbs/04_event.ipynb #daad2a54
194
- described_evts = (PushEvent,CreateEvent,IssueCommentEvent,WatchEvent,PullRequestEvent,PullRequestReviewEvent,PullRequestReviewCommentEvent,
193
+ described_evts = (PushEvent,CreateEvent,IssueCommentEvent,WatchEvent,PullRequestEvent,PullRequestReviewEvent,PullRequestReviewCommentEvent, # chkstyle: ignore-node
195
194
  DeleteEvent,ForkEvent,IssuesEvent,ReleaseEvent,MemberEvent,CommitCommentEvent,GollumEvent,PublicEvent)
196
195
 
197
- _text_keys = dict(
196
+ _text_keys = dict( # chkstyle: ignore-node
198
197
  CreateEvent = "description",
199
198
  PullRequestEvent = "pull_request.title",
200
199
  PullRequestReviewCommentEvent = "comment.body",
@@ -6495,7 +6495,7 @@ spec = {'base_url': 'https://api.github.com',
6495
6495
  'verb': 'GET',
6496
6496
  'summary': 'List secret scanning alerts for an organization',
6497
6497
  'route_params': ['org'],
6498
- 'query_params': ['state', 'secret_type', 'exclude_secret_types', 'exclude_providers', 'providers', 'resolution', 'assignee', 'sort', 'direction', 'page', 'per_page', 'before', 'after', 'validity', 'is_publicly_leaked', 'is_multi_repo', 'hide_secret', 'is_bypassed'],
6498
+ 'query_params': ['state', 'secret_type', 'exclude_secret_types', 'exclude_providers', 'providers', 'resolution', 'assignee', 'sort', 'direction', 'page', 'per_page', 'before', 'after', 'validity', 'is_publicly_leaked', 'is_multi_repo', 'hide_secret', 'is_bypassed', 'included_metadata', 'owner_email_hash'],
6499
6499
  'required_params': ['org'],
6500
6500
  'param_types': {'org': 'str',
6501
6501
  'state': 'str',
@@ -6515,7 +6515,9 @@ spec = {'base_url': 'https://api.github.com',
6515
6515
  'is_publicly_leaked': 'bool',
6516
6516
  'is_multi_repo': 'bool',
6517
6517
  'hide_secret': 'bool',
6518
- 'is_bypassed': 'bool'},
6518
+ 'is_bypassed': 'bool',
6519
+ 'included_metadata': 'str',
6520
+ 'owner_email_hash': 'str'},
6519
6521
  'param_defaults': {'sort': 'created', 'direction': 'desc', 'page': 1, 'per_page': 30, 'is_publicly_leaked': False, 'is_multi_repo': False, 'hide_secret': False},
6520
6522
  'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6521
6523
  'state': 'Set to `open` or `resolved` to only list secret scanning alerts in a specific state.',
@@ -6538,7 +6540,11 @@ spec = {'base_url': 'https://api.github.com',
6538
6540
  'is_multi_repo': 'A boolean value representing whether or not to filter alerts by the multi-repo tag being present.',
6539
6541
  'hide_secret': 'A boolean value representing whether or not to hide literal secrets in the results.',
6540
6542
  'is_bypassed': 'A boolean value (`true` or `false`) indicating whether to filter alerts by their push protection bypass status. When set to `true`, only alerts that were created because a push protection rule was bypassed will be returned. When set to `false`, only alerts that were not caused by a push protection bypass will be '
6541
- 'returned.'},
6543
+ 'returned.',
6544
+ 'included_metadata': 'A comma-separated list of metadata fields to filter alerts by. Only alerts that have all of the specified metadata fields attached will be returned. Possible values are: `owner-email`, `owner-id`, `owner-name`, `secret-id`, `secret-name`, `secret-issued-date`, `secret-expiration-date`, `organization-name`, '
6545
+ '`organization-id`, `last-used-date`, and `has-organization-access`.',
6546
+ 'owner_email_hash': 'Filters alerts to only those whose attached `owner_email` metadata field matches the provided value. The value must be the lowercase hex-encoded SHA-256 hash of the email address to match (for example, the SHA-256 of `user@example.com`). Only alerts that have an `owner_email` metadata value whose SHA-256 hash '
6547
+ 'equals this parameter are returned.'},
6542
6548
  'docs_url': 'https://docs.github.com/rest/secret-scanning/secret-scanning#list-secret-scanning-alerts-for-an-organization'},
6543
6549
  {'group': 'secret_scanning',
6544
6550
  'name': 'list_org_pattern_configs',
@@ -11396,6 +11402,31 @@ spec = {'base_url': 'https://api.github.com',
11396
11402
  'param_types': {'owner': 'str', 'repo': 'str', 'users': 'list'},
11397
11403
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'users': 'A list of user logins to add or remove from the bypass list.'},
11398
11404
  'docs_url': 'https://docs.github.com/rest/interactions/repos#remove-users-from-the-pull-request-creation-cap-bypass-list-for-a-repository'},
11405
+ {'group': 'interactions',
11406
+ 'name': 'get_pull_request_creation_cap_for_repo',
11407
+ 'path': '/repos/{owner}/{repo}/interaction-limits/pulls/creation-cap',
11408
+ 'verb': 'GET',
11409
+ 'summary': 'Get pull request creation cap for a repository',
11410
+ 'route_params': ['owner', 'repo'],
11411
+ 'required_params': ['owner', 'repo'],
11412
+ 'param_types': {'owner': 'str', 'repo': 'str'},
11413
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.'},
11414
+ 'docs_url': 'https://docs.github.com/rest/interactions/repos#get-pull-request-creation-cap-for-a-repository'},
11415
+ {'group': 'interactions',
11416
+ 'name': 'update_pull_request_creation_cap_for_repo',
11417
+ 'path': '/repos/{owner}/{repo}/interaction-limits/pulls/creation-cap',
11418
+ 'verb': 'PATCH',
11419
+ 'summary': 'Update pull request creation cap for a repository',
11420
+ 'route_params': ['owner', 'repo'],
11421
+ 'body_params': ['enabled', 'max_open_pull_requests'],
11422
+ 'request_content_type': 'application/json',
11423
+ 'required_params': ['enabled', 'owner', 'repo'],
11424
+ 'param_types': {'owner': 'str', 'repo': 'str', 'enabled': 'bool', 'max_open_pull_requests': 'int'},
11425
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
11426
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
11427
+ 'enabled': 'Whether the pull request creation cap is enabled',
11428
+ 'max_open_pull_requests': 'The maximum number of open pull requests a user can have at one time'},
11429
+ 'docs_url': 'https://docs.github.com/rest/interactions/repos#update-pull-request-creation-cap-for-a-repository'},
11399
11430
  {'group': 'repos',
11400
11431
  'name': 'list_invitations',
11401
11432
  'path': '/repos/{owner}/{repo}/invitations',
@@ -13469,7 +13500,7 @@ spec = {'base_url': 'https://api.github.com',
13469
13500
  'verb': 'GET',
13470
13501
  'summary': 'List secret scanning alerts for a repository',
13471
13502
  'route_params': ['owner', 'repo'],
13472
- 'query_params': ['state', 'secret_type', 'exclude_secret_types', 'exclude_providers', 'providers', 'resolution', 'assignee', 'sort', 'direction', 'page', 'per_page', 'before', 'after', 'validity', 'is_publicly_leaked', 'is_multi_repo', 'hide_secret', 'is_bypassed'],
13503
+ 'query_params': ['state', 'secret_type', 'exclude_secret_types', 'exclude_providers', 'providers', 'resolution', 'assignee', 'sort', 'direction', 'page', 'per_page', 'before', 'after', 'validity', 'is_publicly_leaked', 'is_multi_repo', 'hide_secret', 'is_bypassed', 'included_metadata', 'owner_email_hash'],
13473
13504
  'required_params': ['owner', 'repo'],
13474
13505
  'param_types': {'owner': 'str',
13475
13506
  'repo': 'str',
@@ -13490,7 +13521,9 @@ spec = {'base_url': 'https://api.github.com',
13490
13521
  'is_publicly_leaked': 'bool',
13491
13522
  'is_multi_repo': 'bool',
13492
13523
  'hide_secret': 'bool',
13493
- 'is_bypassed': 'bool'},
13524
+ 'is_bypassed': 'bool',
13525
+ 'included_metadata': 'str',
13526
+ 'owner_email_hash': 'str'},
13494
13527
  'param_defaults': {'sort': 'created', 'direction': 'desc', 'page': 1, 'per_page': 30, 'is_publicly_leaked': False, 'is_multi_repo': False, 'hide_secret': False},
13495
13528
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13496
13529
  'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
@@ -13514,7 +13547,11 @@ spec = {'base_url': 'https://api.github.com',
13514
13547
  'is_multi_repo': 'A boolean value representing whether or not to filter alerts by the multi-repo tag being present.',
13515
13548
  'hide_secret': 'A boolean value representing whether or not to hide literal secrets in the results.',
13516
13549
  'is_bypassed': 'A boolean value (`true` or `false`) indicating whether to filter alerts by their push protection bypass status. When set to `true`, only alerts that were created because a push protection rule was bypassed will be returned. When set to `false`, only alerts that were not caused by a push protection bypass will be '
13517
- 'returned.'},
13550
+ 'returned.',
13551
+ 'included_metadata': 'A comma-separated list of metadata fields to filter alerts by. Only alerts that have all of the specified metadata fields attached will be returned. Possible values are: `owner-email`, `owner-id`, `owner-name`, `secret-id`, `secret-name`, `secret-issued-date`, `secret-expiration-date`, `organization-name`, '
13552
+ '`organization-id`, `last-used-date`, and `has-organization-access`.',
13553
+ 'owner_email_hash': 'Filters alerts to only those whose attached `owner_email` metadata field matches the provided value. The value must be the lowercase hex-encoded SHA-256 hash of the email address to match (for example, the SHA-256 of `user@example.com`). Only alerts that have an `owner_email` metadata value whose SHA-256 hash '
13554
+ 'equals this parameter are returned.'},
13518
13555
  'docs_url': 'https://docs.github.com/rest/secret-scanning/secret-scanning#list-secret-scanning-alerts-for-a-repository'},
13519
13556
  {'group': 'secret_scanning',
13520
13557
  'name': 'get_alert',
@@ -24,10 +24,7 @@ class GhGql:
24
24
  "Lazy-load the GraphQL client and schema"
25
25
  if self._client is None:
26
26
  if not self.token: raise ValueError("GITHUB_TOKEN not set")
27
- transport = RequestsHTTPTransport(
28
- url='https://api.github.com/graphql',
29
- headers={'Authorization': f'bearer {self.token}'}
30
- )
27
+ transport = RequestsHTTPTransport(url='https://api.github.com/graphql', headers={'Authorization': f'bearer {self.token}'})
31
28
  self._client = Client(transport=transport, fetch_schema_from_transport=True)
32
29
  self._client.execute(gql('{ __typename }')) # Trigger schema fetch
33
30
  return self._client
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghapi
3
- Version: 2.0.1
3
+ Version: 2.0.2
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
@@ -1 +0,0 @@
1
- __version__ = "2.0.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
File without changes
File without changes
File without changes
File without changes
File without changes