In [1]:
from github3 import (login, GitHub)
from github_settings import (username, password, token)
from itertools import islice
#gh = login(username, password=password)
gh = login(token=token)
# set up an anonymous user to see what can be done without authn
anon = GitHub()
#user = gh.user('rdhyee-GITenberg')
user = gh.user()
# <User [sigmavirus24:Ian Cordasco]>
print(user.name)
# Ian Cordasco
print(user.login)
# sigmavirus24
print(user.followers)
# 4
for f in gh.iter_followers():
print(str(f))
kennethreitz = gh.user('kennethreitz')
# <User [kennethreitz:Kenneth Reitz]>
print(kennethreitz.name)
print(kennethreitz.login)
print(kennethreitz.followers)
# let's grab just a subset of the followers
followers = [str(f) for f in islice(gh.iter_followers('kennethreitz'), 100)]
In [2]:
# let's use a token instead
# create a gist https://github3py.readthedocs.org/en/master/examples/gist.html#creating-a-gist-after-authenticating
files = {
'spam.txt' : {
'content': 'What... is the air-speed velocity of an unladen swallow?'
}
}
gist = gh.create_gist('Answer this to cross the bridge', files, public=False)
# gist == <Gist [gist-id]>
print(gist.html_url)
In [3]:
# delete gist?
gist.delete()
Out[3]:
In [ ]:
# need to login with username, password
In [44]:
gh = login(username, password)
def authorization_description_already_exists(e):
"""
Given an exception e when trying to create a token, is the exception the result of a duplicate description
"""
if (e.code == 422 and
e.message == u'Validation Failed' and
(u'already_exists', u'description') in [(error['code'], error['field']) for error in e.errors]):
return True
else:
return False
try:
token = gh.authorize(username, password, scopes=('public_repo'), note='test token 2016.03.17')
except Exception as e:
if authorization_description_already_exists(e):
print ("duplicate key description")
else:
raise e
In [22]:
gh.authorization?
In [23]:
for auth in gh.iter_authorizations():
print (auth.id, auth.name)
Goal: can we read off list of files from a given release
Example: https://github.com/GITenberg/Adventures-of-Huckleberry-Finn_76/releases/tag/0.0.50
Since we're currently using github3.py/repo.py at 0.9.3, which doesn't have Repository.release_from_tag
, we borrow Repository.release_from_tag in v 1.0.0a4
In [ ]:
# adapted from
# https://github.com/sigmavirus24/github3.py/blob/38de787e465bffc63da73d23dc51f50d86dc903d/github3/repos/repo.py#L1781-L1793
from github3.repos.release import Release
def release_from_tag(repo, tag_name):
"""Get a release by tag name.
release_from_tag() returns a release with specified tag
while release() returns a release with specified release id
:param str tag_name: (required) name of tag
:returns: :class:`Release <github3.repos.release.Release>`
"""
url = repo._build_url('releases', 'tags', tag_name,
base_url=repo._api)
json = repo._json(repo._get(url), 200)
return Release(json, repo) if json else None
In [ ]:
from itertools import islice
# instantiate repo
(repo_owner, repo_name) = ('GITenberg', 'Adventures-of-Huckleberry-Finn_76')
repo = gh.repository(repo_owner, repo_name)
repo_anon = anon.repository(repo_owner, repo_name)
# can use either authenticated repo, or anonymous access repo_anon
# loop through releases
for (i, release) in enumerate(islice(repo_anon.iter_releases(),3)):
print (i, release.id, release.tag_name)
print "\n"
for (i, release) in enumerate(islice(repo.iter_releases(),3)):
print (i, release.id, release.tag_name)
In [ ]:
release = release_from_tag(repo, '0.0.50')
(release.id, release.tag_name)
for asset in release.iter_assets():
# pick out some of the attributes of Asset
# https://github.com/sigmavirus24/github3.py/blob/0.9.3/github3/repos/release.py#L145-L164
print (asset.id, asset.name, asset.content_type, asset.download_url, asset.download_count)
In [ ]:
# a function which given a repo and tag, returns which of epub, pdf, mobi are available
from github3 import (login, GitHub)
from github3.repos.release import Release
# a token can generated at https://github.com/settings/tokens -- no private access needed
from github_settings import GITHUB_PUBLIC_TOKEN
# release_from_tag adapted from
# https://github.com/sigmavirus24/github3.py/blob/38de787e465bffc63da73d23dc51f50d86dc903d/github3/repos/repo.py#L1781-L1793
def release_from_tag(repo, tag_name):
"""Get a release by tag name.
release_from_tag() returns a release with specified tag
while release() returns a release with specified release id
:param str tag_name: (required) name of tag
:returns: :class:`Release <github3.repos.release.Release>`
"""
url = repo._build_url('releases', 'tags', tag_name,
base_url=repo._api)
json = repo._json(repo._get(url), 200)
return Release(json, repo) if json else None
def ebooks_in_github_release(repo_owner, repo_name, tag, token=None):
"""
returns a list of (book_type, book_name) for a given GitHub release (specified by
owner, name, tag). token is a GitHub authorization token -- useful for accessing
higher rate limit in the GitHub API
"""
# epub, mobi, pdf, html, text
# map mimetype to file extension
EBOOK_FORMATS = {'application/epub+zip':'epub',
'application/x-mobipocket-ebook': 'mobi',
'application/pdf': 'pdf',
'text/plain': 'text',
'text/html':'html'}
if token is not None:
gh = login(token=token)
else:
# anonymous access
gh = GitHub()
repo = gh.repository(repo_owner, repo_name)
release = release_from_tag(repo, tag)
return [(EBOOK_FORMATS.get(asset.content_type), asset.name)
for asset in release.iter_assets()
if EBOOK_FORMATS.get(asset.content_type) is not None]
# test out ebooks_in_github_release
(repo_owner, repo_name) = ('GITenberg', 'Adventures-of-Huckleberry-Finn_76')
ebooks_in_github_release(repo_owner, repo_name, '0.0.50', token=GITHUB_PUBLIC_TOKEN)
In [ ]:
# https://github.com/GITenberg/Adventures-of-Huckleberry-Finn_76/raw/master/metadata.yaml
from urlparse import urlparse
url = "https://github.com/GITenberg/Adventures-of-Huckleberry-Finn_76/raw/master/metadata.yaml"
url_path = urlparse(url).path.split("/")
(repo_owner, repo_name) = (url_path[1], url_path[2])
(repo_owner, repo_name)
In [ ]:
master_branch = repo.branch('master')
master_branch.commit.sha
master_tree = repo.tree(master_branch.commit.sha)
for hash_ in master_tree.tree:
print (hash_.path, hash_.type)
In [ ]:
def asciidoc_in_repo_root(repo, branch ='master'):
"""return list of asciidocs in the root of repo"""
repo_branch = repo.branch(branch)
tree = repo.tree(repo_branch.commit.sha)
return [hash_.path
for hash_ in tree.tree
if hash_.path.endswith('.asciidoc')]
asciidoc_in_repo_root(repo)
In [ ]:
try:
repo_data = {
'name': 'TEST REPO',
'description': 'can I create a repo using github3.py?',
'homepage': '',
'private': False,
'has_issues': True,
'has_wiki': True
}
if repo_data.get('name'):
r = gh.create_repo(repo_data.pop('name'), **repo_data)
if r:
print("Created {0} successfully.".format(r.name))
except Exception as e:
print (e)
Now that I have an empty repo, how to do the equivalent of the following?
echo "# TEST-REPO" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/rdhyee-GITenberg/TEST-REPO.git
git push -u origin master
In [ ]:
# once we have a repo, we can instantiate it
repo = gh.repository('rdhyee-GITenberg', 'TEST-REPO')
repo
python - How to create a commit and push into repo with GitHub API v3? - Stack Overflow
But there is a File CRUD API: repo.create_file() in github3.py/repo.py at 0.9.3
In [ ]:
# now have r -- a repo
# let's read off key parameters
# latest commit
# borrow code from https://github.com/sigmavirus24/github3.py/blob/d3552f77778c5f570cdd7efa5c80c0b88b8d9ad7/tests/integration/test_repos_repo.py#L239
data = {
'path': 'README.md',
'message': 'first pass',
'content': b'Hello world',
'branch': 'master'
}
created_file = repo.create_file(**data)
created_file
In [ ]:
# create a tag?
import arrow
commit = created_file['commit']
commit.sha
user = gh.user()
tag_data = {
'tag': '0.0.1',
'message': 'tag 0.0.1',
'sha': commit.sha,
'obj_type': 'commit',
'tagger': {
'name': user.name,
'email': user.email,
'date': arrow.utcnow().isoformat()
},
'lightweight': False
}
tag = repo.create_tag(**tag_data)
tag
In [ ]:
# get list of current tags
list(repo.iter_tags())
In [ ]:
# directory_contents (in v 1+)
# [github3.py/test_repos_repo.py at d3552f77778c5f570cdd7efa5c80c0b88b8d9ad7 · sigmavirus24/github3.py](https://github.com/sigmavirus24/github3.py/blob/d3552f77778c5f570cdd7efa5c80c0b88b8d9ad7/tests/integration/test_repos_repo.py#L475-L486)
#
repo.contents("")
In [ ]:
# grab content
content = repo.contents("README.md", ref='master')
In [ ]:
new_content = content.decoded.decode('utf-8') + u"\n" + u"line 2"
data = {
'message': 'second pass',
'content': new_content.encode('utf-8'),
}
commit = content.update(**data)
commit
In [ ]:
# tag again
tag_data = {
'tag': '0.0.2',
'message': 'tag 0.0.2',
'sha': commit.sha,
'obj_type': 'commit',
'tagger': {
'name': user.name,
'email': user.email,
'date': arrow.utcnow().isoformat()
},
'lightweight': False
}
tag = repo.create_tag(**tag_data)
tag
In [ ]: