<jupyter_start><jupyter_text>We looked at a basic API in the last mission. That API didn't require authentication, but most do. Imagine that you're using the reddit API to pull a list of your private messages. It would be a huge privacy breach for reddit to give that information to anyone, so requiring authentication makes sense.APIs also use authentication to perform rate limiting. Developers typically use APIs to build interesting applications or services. In order to ensure that it remains available and responsive for all users, an API will prevent you from making too many requests in too short a time. We call this restriction rate limiting. It ensures that one user can't overload the API server by making too many requests too fast.In this mission, we'll explore the GitHub API and use it to pull some interesting data on repositories and users. GitHub has user accounts (https://github.com/torvalds), repositories that contain code (https://github.com/torvalds/linux), and organizations that companies can create (https://github.com/dataquestio).Take a look at the documentation for the [GitHub API](https://developer.github.com/v3/), and specifically the [authentication](https://developer.github.com/v3/authentication) section To authenticate with the GitHub API, we'll need to use an access token. An access token is a credential we can generate on GitHub's website. The token is a string that the API can read and associate with your account.Using a token is preferable to a username and password for a few reasons:Typically, you'll be accessing an API from a script. If you put your username and password in the script and someone manages to get their hands on it, they can take over your account. In contrast, you can revoke an access token to cancel an unauthorized person's access if there's a security breach.Access tokens can have scopes and specific permissions. For instance, you can make a token that has permission to write to your GitHub repositories and make new ones. Or, you can make a token that can only read from your repositories. Using read-access-only tokens in potentially insecure or shared scripts gives you more control over security.You'll need to pass your token to the GitHub API through an Authorization header. Just like the server sends headers in response to our request, we can send the server headers when we make a request. Headers contain metadata about the request. We can use Python's requests library to make a dictionary of headers, and then pass it into our request.We need to include the word token in the Authorization header, followed by our access token - the one given has been revoked and won't work outside of the DQ platform<jupyter_code>import requests

# Create a dictionary of headers containing our Authorization header.
# This token has been revoked so it won't work outside of the Dataquest platform
headers = {"Authorization": "token <PASSWORD>"}

# Make a GET request to the GitHub API with our headers.
# This API endpoint will give us details about Vik Paruchuri.
response = requests.get("https://api.github.com/users/VikParuchuri", headers=headers)

# Print the content of the response.  As you can see, this token corresponds to the account of <NAME>.
print(response.json())
response = requests.get("https://api.github.com/users/VikParuchuri/orgs", headers=headers)
orgs = response.json()<jupyter_output>{'message': 'Bad credentials', 'documentation_url': 'https://developer.github.com/v3'}<jupyter_text>Endpoints and objects<jupyter_code># We've loaded headers in.
response = requests.get("https://api.github.com/users/torvalds", headers=headers)
torvalds = response.json()<jupyter_output><empty_output><jupyter_text>Other objects<jupyter_code>response = requests.get("https://api.github.com/repos/octocat/Hello-World", headers=headers)
hello_world = response.json()
print(hello_world)<jupyter_output>{'message': 'Bad credentials', 'documentation_url': 'https://developer.github.com/v3'}<jupyter_text>Pagination - too many results<jupyter_code>params = {"per_page": 50, "page": 1}
response = requests.get("https://api.github.com/users/VikParuchuri/starred", headers=headers, params=params)
page1_repos = response.json()
params = {"per_page": 50, "page": 2}
response = requests.get("https://api.github.com/users/VikParuchuri/starred", headers=headers, params=params)
page2_repos = response.json()<jupyter_output><empty_output><jupyter_text>User-level endpoints<jupyter_code>response = requests.get("https://api.github.com/user", headers=headers)
user = response.json()<jupyter_output><empty_output><jupyter_text>POST requests<jupyter_code># Create the data we'll pass into the API endpoint.  
# While this endpoint only requires the "name" key, there are other optional keys.
payload = {"name": "test"}

# We need to pass in our authentication headers!
response = requests.post("https://api.github.com/user/repos", json=payload, headers=headers)
print(response.status_code)
payload = {"name": "learning-about-apis"}
response = requests.post("https://api.github.com/user/repos", json=payload, headers=headers)
status = response.status_code<jupyter_output>401<jupyter_text>PUT / PATCH<jupyter_code>payload = {"description": "The best repository ever!", "name": "test"}
response = requests.patch("https://api.github.com/repos/VikParuchuri/test", json=payload, headers=headers)
print(response.status_code)
payload = {"description": "Learning about requests!", "name": "learning-about-apis"}
response = requests.patch("https://api.github.com/repos/VikParuchuri/learning-about-apis", json=payload, headers=headers)
status = response.status_code<jupyter_output>401<jupyter_text>DELETE<jupyter_code>response = requests.delete("https://api.github.com/repos/VikParuchuri/test", headers=headers)
print(response.status_code)
response = requests.delete("https://api.github.com/repos/VikParuchuri/learning-about-apis", headers=headers)
status = response.status_code<jupyter_output>401
{'fraction_non_alphanumeric': 0.09583053127101547, 'fraction_numerical': 0.0035305985205110963, 'mean_word_length': 5.822247706422019, 'pattern_counts': {'":': 11, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 20, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '593734', 'license': 'Apache-2.0', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1588, 'n_words': 632, 'path': '4.4 Working with APIs/Intermediate APIs.ipynb', 'repo_name': 'orspain/Dataquest', 'size': '5985'}