requests¶Most APIs require users to identify themselves, and have limits on the volume and frequency of requests each user can make, in order to:
This typically requires users to register, upon which they're provided with credentials, typically in the form of a unique id and an accompanying key or secret.
We'll be using the Spotify API throughout the tutorial. In order to use it, you'll need a Spotify account.
Follow CREATE AN APP from the Dashboard, then copy your Client ID and Client Secret to somewhere handy.

In addition to the id and secret we've just gathered, Spotify requires us to authenticate prior to requesting data.
There are several options available; we'll be using the Client Credentials Flow. This will give us access to masses of data about the contents of the Spotify catalogue, but without access to personalized information such as user playlists.
We'll send the id and secretto the API using a POST request, and be sent an access_token in the response.
access_token¶The documentation tells us that we'll need to:
POST request to https://accounts.spotify.com/api/token'grant_type': 'client_credentials' in the request body'Authorization' : 'Basic [base64 encoded client_id:client_secret]' in the headerFortunately, the requests.post() and HTTPBasicAuth functions will simplify this for us.
First of all, fork the repl. Next, create a new file called .env, and then enter your credentials in the format shown in .env.example.
.env files aren't shared when a fork of a repl is made; they allow you to store values you don't want to sharemain.py will be executed when you hit Run. If all is well, you should see a dictionary printed in the console at the bottom.
!!! warning "Access Token"
**Take a copy of your `access_token`** from your repl's console; you'll need it later to get data from the API.
Tokens are **valid for one hour**, so come back to your fork of the repl to generate another one if needed later on.
import requests
from requests.auth import HTTPBasicAuth
import os
client_id = os.getenv("CLIENT_ID")
client_secret = os.getenv("CLIENT_SECRET")
requests and os packages, and the HTTPBasicAuth submodule.getenv() method to collect our credentials from the .env fileWe can use the Python help() function to see the docstring for requests.post():
help(requests.post)
Help on function post in module requests.api:
post(url, data=None, json=None, **kwargs)
Sends a POST request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
url = 'https://accounts.spotify.com/api/token'
data = {'grant_type': 'client_credentials'}
auth=HTTPBasicAuth(client_id, client_secret)
url is the one given by the API documentationdata is the parameter:value pair required to be in the bodyauth is an optional keyword argumentHTTPBasicAuth method has done the required encoding and formatting of the credentials for usPOST request¶response = requests.post(url, data=data, auth=auth)
response.ok
we used the .post() method of requests with the arguments we had defined, assigning the returned object to response
the .ok attribute of the Response object is True, meaning that the response was successful
response.json()
{'access_token': 'BQA5XobojGmQ22qGfcf1XSX1xTJD6pH6oeltC5HtX5fML8ps_uDp1U74ybc5M45CmmRf8DX8FAFjOivOae4',
'token_type': 'Bearer',
'expires_in': 3600,
'scope': ''}
.json() method of the response object returned by the API converts the included JSON object into a Python dictionarykey:value pairs include the access_token we need; highlight and right-click it to copy (usual shortcuts don't work in the console)expires_in value - this is the time in seconds (i.e. one hour) that the token will remain usable forresponse.status_code
200
The .status_code attribute indicates whether the request was successful, and if not, what went wrong.
200 is good news, as is anything in the 200s 400s typcially indicate an issue with your code or parameters500s indicate something is malfunctioning on the serverJSON (JavaScript Object Notation) is the most popular data format used by web APIs.
Fortunately for Python programmers, it is fairly straightforward to map JSON to equivalent Python data structures, data types and values (and as shown above, modules which can do this for us).
key:value pairs inside { braces }[ brackets ]The JSON values true, false and null are equivalent to the Python values True, False and None respectively.