Github is a repository for developers to keep their projects and code versioned.
You can create an account for free and use it as much as you want at no cost.
Some APIs are paid and a bit troublesome to set up, that’s why we are going to use the freely available Github API.
The GET resources are public, while PUT, DELETE, and POST are not.
This means the retrieval part using GET will work ok if you do exactly what I do, but if you want to change a resource, you need specific authorization and you can do it easily on your own account.
The Github API
I want you to stop and go to github.com and create your account, we are going to use it later when I show how to set up your API credentials.
If you go to https://api.github.com/
on your browser, you will see a response similar to this one, but with many more options.
{
"current_user_url": "https://api.github.com/user",
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
"authorizations_url": "https://api.github.com/authorizations",
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
"commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
"emails_url": "https://api.github.com/user/emails",
"emojis_url": "https://api.github.com/emojis",
"events_url": "https://api.github.com/events",
"feeds_url": "https://api.github.com/feeds",
"followers_url": "https://api.github.com/user/followers",
"following_url": "https://api.github.com/user/following{/target}",
"gists_url": "https://api.github.com/gists{/gist_id}",
"hub_url": "https://api.github.com/hub",
"issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
"issues_url": "https://api.github.com/issues",
"keys_url": "https://api.github.com/user/keys",
"label_search_url": "https://api.github.com/search/labels?q={query}&repository_id={repository_id}{&page,per_page}",
"notifications_url": "https://api.github.com/notifications",
"organization_url": "https://api.github.com/orgs/{org}",
"organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
"organization_teams_url": "https://api.github.com/orgs/{org}/teams",
"public_gists_url": "https://api.github.com/gists/public",
"rate_limit_url": "https://api.github.com/rate_limit",
"repository_url": "https://api.github.com/repos/{owner}/{repo}",
"repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
"current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
"starred_gists_url": "https://api.github.com/gists/starred",
"user_url": "https://api.github.com/users/{user}",
"user_organizations_url": "https://api.github.com/user/orgs",
"user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
"user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
}
This is the JSON format, which resembles a Python dictionary with the key-value pair structure.
This is a list of all the APIs that Github provides.
You can see each API has a specific URL address, so you can easily check the information of a user with https://api.github.com/users/{username}
.
My user on github is ‘renanmouraf’, so if you open https://api.github.com/users/renanmouraf
on your browser you will see a JSON similar to this (I removed some info to make it more readable ):
{
"login": "renanmouraf",
"id": 11388726,
"node_id": "MDQ6VXNlcjExMzg4NzI2",
"avatar_url": "https://avatars.githubusercontent.com/u/11388726?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/renanmouraf",
"html_url": "https://github.com/renanmouraf",
"followers_url": "https://api.github.com/users/renanmouraf/followers",
"following_url": "https://api.github.com/users/renanmouraf/following{/other_user}",
"gists_url": "https://api.github.com/users/renanmouraf/gists{/gist_id}",
"starred_url": "https://api.github.com/users/renanmouraf/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/renanmouraf/subscriptions",
"organizations_url": "https://api.github.com/users/renanmouraf/orgs",
"repos_url": "https://api.github.com/users/renanmouraf/repos",
"events_url": "https://api.github.com/users/renanmouraf/events{/privacy}",
"received_events_url": "https://api.github.com/users/renanmouraf/received_events",
"type": "User",
"site_admin": false,
"name": "Renan Moura",
"company": null,
"blog": "https://renanmf.com",
"location": null,
"email": null,
"hireable": null,
"bio": null,
"twitter_username": null,
"public_repos": 27,
"public_gists": 1,
"followers": 5,
"following": 2,
"created_at": "2015-03-09T11:15:04Z",
"updated_at": "2021-05-27T00:19:08Z"
}
So you can see you can have access to a list of my repos using https://api.github.com/users/renanmouraf/repos
as indicated by the key "repos_url".
Python and the requests module
Instead of checking my repos using the browser, let’s do it in Python.
We are going to use the json
module and the requests
module.
The requests
module doesn’t come built-in in Python, we have to install it:
pip install requests
requests
is the most used library to handle HTTP requests in Python and makes the use of APIs very simple.
Create a file "test_api.py", type the following and run it with python3 test_api.py
.
import requests
import json
response = requests.get('https://api.github.com/users/renanmouraf/repos')
print(response.status_code)
repos = response.json()
print(json.dumps(repos, indent = 4, sort_keys=True))
Here we are making a GET using requests.get()
passing the URL we want, which is my repos.
Then we print the status_code, which will be 200 if everything went alright.
Then we take the json()
with the ist of repos and use dumps()
to print it in a more readable way.
You will see that I have a bunch of repos in my github account.
Other API operations
To do the other operations, we need an API key that will allow us to create, update, and delete resources in our own Github accounts.
In fact, for most "serious" services, you can’t do anything without some API key or similar credentials. Services like Google Maps, Youtube, and Spotify have very nice APIs to play with and I recommend you to look at their documentation to check how to use them with your Python code.
To avoid the risk of Github changing their user interface, I will link to their official guide to create your own access token on Creating a personal access token. It is very simple and just a few clicks away.
Just pay attention to check the boxes to create and delete repos in order to work on the next examples like the images below suggest.
Allow operations on repos:
Delete repos:
You are going to need your username and generated token to follow the next examples. Remember to change the variable username
on this code to your own.
To create a repo, we use requests.post()
.
Replace token
with your own, you can keep the rest of the code the same.
The token information goes on the headers of the request, while the data argument takes the payload
in json format using json.dumps()
.
Payload is telling the API to create a new repo called ‘test_book’ with a description ‘A test repo’.
import requests
import json
token = '3a5f50e43ec0886fb38ffe950fd3add479567863'
repo = 'test_book'
description = 'A test repo'
payload = {'name': repo, 'description': description}
headers = {'Authorization': f'token {token}'}
response = requests.post(f'https://api.github.com/user/repos',
headers=headers, data=json.dumps(payload))
print(response.status_code)
The status code of the response will be 201 (created) if your request was successful.
When I go to ‘https://github.com/renanmouraf?tab=repositories‘, I see the new repo is created:
To delete a repo we call requests.delete()
and the headers with the access token.
Notice we don’t need a payload since the repo name goes directly on the URL after the username.
import requests
import json
username = 'renanmouraf'
token = '3a5f50e43ec0886fb38ffe950fd3add479567863'
repo = 'test_book'
headers = {'Authorization': f'token {token}'}
response = requests.delete(f'https://api.github.com/repos/{username}/{repo}',
headers=headers)
print(response.status_code)
You will see a 204 (No content) because the delete operation doesn’t return anything on success. but you can check your repositories list on Github and see that ‘test_book’ was deleted.