<jupyter_start><jupyter_text>Using Requests to interact with the GitHub API This is a little introduction to using the [Requests](http://docs.python-requests.org/en/master/) library to interact with the [GitHub API](https://developer.github.com/v3/). The documentation for each is excellent, so the idea here is to give a few flavours of how they interact with one-another, and not to redundantly document the tools themselves. First, import some useful functionality:<jupyter_code>from pprint import pprint
from pathlib import Path

import requests<jupyter_output><empty_output><jupyter_text>Next, get hold of a [GitHub personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) with the "Read:Org" scope selected:![](PAT_creation.png)You may choose to save the token in a file called token.txt, and read it in with the code below. Alternatively, just create a variable called ```token=''```.Note: You will not be able to get the token from the GitHub interface after it has been displayed for the first time, so it is recommended to save it somewhere (like a keychain).<jupyter_code>def api_token():
    token_file = Path('token.txt')
    if not token_file.exists():
        raise IOError('Please create a token at github.com, and save it in {}'.format(token_file))

    token = token_file.read_text().strip()
    return token


token = api_token()<jupyter_output><empty_output><jupyter_text>Now that we have a personal access token, let's define the headers that will allow us to use it:<jupyter_code>headers = {'Authorization': 'token {}'.format(token),
           'Accept': 'application/vnd.github.v3+json'}
API_URL = 'https://api.github.com'<jupyter_output><empty_output><jupyter_text>Finally, we are ready. Let's find out what the "login" (username) is for this personal access token.<jupyter_code># The endpoint target.
target = '/user'

# The actual HTTP request
resp = requests.get('{}{}'.format(API_URL, target),
                    headers=headers)

# Raise an error if we didn't get a 200 return code.
resp.raise_for_status()

# Assume the response is JSON, and get hold of it.
content = resp.json()

# Print the content so that we know what a GitHub response actually looks like.
pprint(content)

# Get hold of the user's login ID
login = content['login']<jupyter_output>{'avatar_url': 'https://avatars3.githubusercontent.com/u/810663?v=4',
 'bio': 'Scientific software engineer and problem solver.',
 'blog': 'https://pelson.github.io',
 'company': None,
 'created_at': '2011-05-25T20:18:23Z',
 'email': '<EMAIL>',
 'events_url': 'https://api.github.com/users/pelson/events{/privacy}',
 'followers': 87,
 'followers_url': 'https://api.github.com/users/pelson/followers',
 'following': 23,
 'following_url': 'https://api.github.com/users/pelson/following{/other_user}',
 'gists_url': 'https://api.github.com/users/pelson/gists{/gist_id}',
 'gravatar_id': '',
 'hireable': True,
 'html_url': 'https://github.com/pelson',
 'id': 810663,
 'location': 'UK',
 'login': 'pelson',
 'name': '<NAME>',
 'organizations_url': 'https://api.github.com/users/pelson/orgs',
 'public_gists': 55,
 'public_repos': 168,
 'received_events_url': 'https://api.github.com/users/pelson/received_events',
 'repos_url': 'https://api.github.com/users/pelson/repos',
 'site_admin':[...]<jupyter_text>Now, let's look at all the repos that this user has access to:<jupyter_code>target = '/user/repos'
resp = requests.get('{}{}'.format(API_URL, target),
                    headers=headers)
resp.raise_for_status()
content = resp.json()
pprint(content[0])
pprint([repo['full_name'] for repo in content][:5])<jupyter_output>['bblay/iris_logo',
 'conda-forge/addict-feedstock',
 'conda-forge/ads-feedstock',
 'conda-forge/affine-feedstock',
 'conda-forge/agate-dbf-feedstock']<jupyter_text>Similarly, let's get hold of all the repos in the user's GitHub account:<jupyter_code>target = '/users/{}/repos'.format(login)
resp = requests.get('{}{}'.format(API_URL, target),
                    headers=headers)
resp.raise_for_status()
content = resp.json()

pprint([repo['full_name'] for repo in content][:5])<jupyter_output>['pelson/anaconda-build',
 'pelson/anaconda-list-distributions',
 'pelson/anaconda-recipes',
 'pelson/antigrain',
 'pelson/artview-feedstock']<jupyter_text>There are a number of repos starting with "a" in this user's account. Let's change the sort order by modifying the request:<jupyter_code>target = '/users/{}/repos'.format(login)

params = {'sort': 'updated'}
resp = requests.get('{}{}'.format(API_URL, target),
                    params=params,
                    headers=headers)
resp.raise_for_status()
content = resp.json()

pprint([repo['full_name'] for repo in content][:5])<jupyter_output>['pelson/intro-to-using-requests-with-github-API',
 'pelson/my-first-heroku-tornado-app',
 'pelson/example-supervisord-manager',
 'pelson/conda-rpms',
 'pelson/python-gnupg']<jupyter_text>The GitHub API is an endless trove of information. For example, one can get hold of a number of events that the authenticated user did with:<jupyter_code>target = '/users/{}/events'.format(login)

resp = requests.get('{}{}'.format(API_URL, target),
                    headers=headers)
resp.raise_for_status()
content = resp.json()

pprint({event['type'] for event in content})<jupyter_output>{'CreateEvent',
 'GollumEvent',
 'IssueCommentEvent',
 'PullRequestEvent',
 'PullRequestReviewCommentEvent',
 'PushEvent'}
{'fraction_non_alphanumeric': 0.14706959706959707, 'fraction_numerical': 0.008424908424908424, 'mean_word_length': 5.007700770077007, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 13, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '212378', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1759, 'n_words': 462, 'path': 'tutorial.ipynb', 'repo_name': 'pelson/intro-to-using-requests-with-github-API', 'size': '5477'}