#|default_exp build_lib
#|export
from fastcore.all import *
import pprint
# from json import loads
from jsonref import loads
from collections import namedtuple
This library leverages the OpenAPI Specification to create a python client for the GitHub API. The OpenAPI specification contains metadata on all of the endpoints and how to access them properly. Using this metadata, we can construct a python client dynamically that updates automatically along with the OpenAPI Spec.
#|export
GH_OPENAPI_URL = 'https://github.com/github/rest-api-description/raw/main/descriptions/api.github.com/api.github.com.json?raw=true'
_DOC_URL = 'https://docs.github.com/'
#|hide
if 0:
s = urlread(GH_OPENAPI_URL)
js = loads(s)['paths']
sj = {o['operationId']:o for p in js.values() for o in p.values()}
j = js['/repos/{owner}/{repo}/issues/{issue_number}/labels']['post']
n = nested_idx(j, *'requestBody content application/json schema'.split())
#|export
_lu_type = dict(zip(
'NA string object array boolean integer'.split(),
map(PrettyString,'object str dict list bool int'.split())
))
def _detls(k,v):
res = [_lu_type[v.get('type', 'NA')]]
try: res.append(v['default'])
except KeyError: pass
return [k]+res
def _find_data(d):
if 'properties' in d: return d['properties']
if 'oneOf' in d:
for o in d['oneOf']:
if 'properties' in o: return o['properties']
return {}
#|export
def build_funcs(nm='ghapi/metadata.py', url=GH_OPENAPI_URL, docurl=_DOC_URL):
"Build module metadata.py from an Open API spec and optionally filter by a path `pre`"
def _get_detls(o):
data = nested_idx(o, *'requestBody content application/json schema'.split()) or {}
data = _find_data(data)
url = o['externalDocs']['url'][len(docurl):]
params = o.get('parameters',None)
qparams = [p['name'] for p in params if p['in']=='query'] if params else []
d = [_detls(*o) for o in data.items()]
preview = nested_idx(o, 'x-github','previews',0,'name') or ''
return (o['operationId'], o['summary'], url, qparams, d, preview)
js = loads(urlread(url))
_funcs = [(path, verb) + _get_detls(detls)
for path,verbs in js['paths'].items() for verb,detls in verbs.items()
if 'externalDocs' in detls]
Path(nm).write_text("funcs = " + pprint.pformat(_funcs, width=360))
#|hide
build_funcs()
This module created by build_funcs
contains a list of metadata for each endpoint, containing the path, verb, operation id, summary, documentation relative URL, and list of parameters (if any), e.g:
#|export
GhMeta = namedtuple('GhMeta', 'path verb oper_id summary doc_url params data preview'.split())
from ghapi.metadata import funcs
GhMeta(*funcs[3])
GhMeta(path='/app/hook/config', verb='get', oper_id='apps/get-webhook-config-for-app', summary='Get a webhook configuration for an app', doc_url='rest/reference/apps#get-a-webhook-configuration-for-an-app', params=[], data=[], preview='')
#|hide
from nbdev import nbdev_export
nbdev_export()
Converted 00_core.ipynb. Converted 01_actions.ipynb. Converted 02_auth.ipynb. Converted 03_page.ipynb. Converted 04_event.ipynb. Converted 10_cli.ipynb. Converted 50_fullapi.ipynb. Converted 80_tutorial_actions.ipynb. Converted 90_build_lib.ipynb. Converted Untitled.ipynb. Converted ghapi_demo.ipynb. Converted index.ipynb.