HTTP Requests
HTTP defines a set of request methods to indicate the desired action to be performed for a given resource.
To reach out on the network and retrieve some data (resource) we need to execute an HTTP request. There are a few commonly used HTTP methods that are standard for accessing, adding, or modifying data with APIs.
These are:
- GET
- POST
- PATCH
- DELETE
Ideally, the verbs correspond to the action that you take on the resource (we'll talk about why I used the word ideally in the next section):
- GET method retrieves something from a resource
- POST requests add an entity to a resource
- PATCH modifies an existing entity
- DELETE requests remove a resource
When developers build an API they define API routes. These are URLs on the server that process the HTTP request arguments and return data based on those arguments (or an error).
Each route has an accepted HTTP method that you must use. For example, I might have a profile picture on my API at https://api.example.com/picture/me
. To get that image to display in a web application you would have to use a GET request.
RESTful APIs
I use words like ideally and typically when I talk about APIs because it's not a law that developers implement them a certain way.
Most of the APIs I use are RESTful APIs. That means that they implement an architecture pattern called REST, and it stands for Representational State Transfer. However, one of the benefits of APIs, HTTP methods, REST, etc. is that they are not constrained by programming language. Therefore, a RESTful API built with Python does not have to be accessed with Python.
With different languages, frameworks, and technologies building REST APIs it's inevitable that there will be variations in how they are accessed. Some APIs use POST methods to do the work of PATCH and DELETE. Other APIs only use GET methods and handle the rest of the process in the code.
You have to read the documentation of the API before knowing how it's used.
requests
There are different libraries used by programming languages to access APIs. It's difficult to claim that one is better than the other because sending an HTTP request is a simple thing to do.
However, the one I choose to use in Python is the requests library. It's popular, so you'll see it used in tutorials and documentation examples.
In this example, I'm going to assume that you already have downloaded the library using PIP and that it's available in your environment.
Google's Elevation API
In this example, we are going to access data from Google's Elevation API.
The Elevation API provides a simple interface to query locations on the earth for elevation data.
Google has good documentation. At the same time, Google has a lot of words in it's documentation. The first thing I do when scrolling through data for an API is to try and find the data object that is returned (to see if it's the data that I want). Then, I look for a code sample.
It doesn't really matter what language the code sample uses, because the components are the same:
- URL
- HTTP method
- arguments
I find the return object:
{
"results" : [
{
"elevation" : 1608.637939453125,
"location" : {
"lat" : 39.73915360,
"lng" : -104.98470340
},
"resolution" : 4.771975994110107
}
],
"status" : "OK"
}
It will return elevation data given a latitude and longitude coordinate in JSON format. Perfect!
Next, I find some sample code:
https://maps.googleapis.com/maps/api/elevation/json?locations=39.7391536,-104.9847034&key=YOUR_API_KEY
In this example, the same code was just a URL. That's because the arguments are passed in via query parameters at the end of the URL. Therefore, I have the URL, arguments, and assume that I need to use a GET request.
API Keys
API keys are used to manage who can access an API and how many times they can call the API. It's standard these days for all APIs to require an API key: even if they are free.
The URL in the previous section takes an API key has the last argument (YOUR_API_KEY
).
API keys, generally, need to be kept secret. Google doesn't follow this approach. They advise you to restrict your API key by IP address, domain, etc. This API key is used in a way that makes it 'public', but I still like to keep it hidden in my source code.
The steps to get an API key from Google are beyond the scope of this article. You'll need to follow the steps using this link.
Call the Elevation API
I am using Python's IDLE in this example. Therefore, when you see >>>
in the code, it means that the code was entered in the Python Shell.
First, import the requests
module.
>>> import requests
Then, define the variables that we are going to use in the API call.
>>> API_KEY = "your api key"
>>> BASE_URL = "https://maps.googleapis.com/maps/api"
>>> lat = 46.804123
>>> long = -121.658627
Next, call the API and save the response in the variable res
.
>>> res = requests.get(f'{BASE_URL}/elevation/json?locations={lat},{long}&key={API_KEY}')
Check the status code to see if the request was successful.
>>> res.status_code
# 200
Before converting the response to JSON, we can view the value as text.
>>> res.text
# '{\n "error_message" : "You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started",\n "results" : [],\n "status" : "REQUEST_DENIED"\n}\n'
Uh oh, looks like we got an error.
It is easier to work with this data if we convert it to JSON.
>>> res_json = res.json()
>>> res_json
# {'error_message': 'You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started', 'results': [], 'status': 'REQUEST_DENIED'}
>>> res_json['error_message']
# 'You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started'
The truth is, the first time I used the API it returned the data I wanted. Now, it wants me to pay for it. I hope you got the data!
If not, you may need to go through the process of:
- Setting up a billing account
- Enabling the API and the billing account
However, if you jump through all of Google's API hoops, you will eventually get a JSON response that looks like:
>>> res_json
# {'results': [{'elevation': 1292.1767578125, 'location': {'lat': 46.804123, 'lng': -121.658627}, 'resolution': 4.771975994110107}], 'status': 'OK'}
Congratulations if you made it this far! You have successfully called an API using Python.