Python API Lesson

Woman programmer writing plan on white board about APIs

API access with Python can be incredibly useful and fun. Also as so many Python related things, it’s very practical. In this tutorial we will learn how to access some cool APIs.

Used Where?

  • To reuse the code
  • To extend an already existing function
  • To override standard operators
  • To create an entity with its own logic
  • To make logic more suitable for the use case or the intended audience
  • To create a core logic and take advantage of inheritance based on that

Let’s dive right into it.

1) JSON

Most APIs you’ll encounter will be in json format. It’s just awesomely structured and very convenient so no wonder why engineers decide to implement it to every API out there. That also means you should have an understanding of it if you’d like to deal communicate with APIs but don’t worry it’s rather simple.

2) Requests

Another module we’ll use is Python’s requests library. It’ll make it super smooth to get requests and access web this way.

3) API

Finally you also need an API. We will share some really cool ones and there are tons of others out there in the inter webs.

Estimated Time

30 mins

Difficulty

Advanced

Functions

requests.get

Skill Level

requests.get, .text, json.loads, json.dumps

Course Provider

Provided by HolyPython.com

Most APIs you’ll encounter will be in json format. It’s just awesomely structured and very convenient so no wonder why engineers decide to implement it to every API out there. That also means you should have an understanding of it if you’d like to deal communicate with APIs but don’t worry it’s rather simple.

Example 1: International Space Station (ISS) Data

open-notify.org has an awesome API that shares some basic International Space Station data. 

http://api.open-notify.org is the address for the free API service and you can find the source code at github link here: https://github.com/open-notify/Open-Notify-API.

When you click on their API Server webpage, it shows a clear documentation explaining the format to access API data.

We’ll start with importing the 2 libraries we’ll need: requests and json.

import requests
import json

From the documentation, here are the links we can use to access API.

a) ISS Location Now

f = "http://api.open-notify.org/iss-now.json"
data = requests.get(f)

Okay, that’s basically it. Can you believe that? Your data is already inside variable named: data.

data.text

You need to print your data as data.text though. Otherwise data is a request object and it will tell you the status code of your HTTP operation. (In this case 200 means everything is OK.) You can read more about HTTP Status Codes and Errors here.

print(data)

<Response [200]>

print(data.text)

“{“timestamp”: 1573291044, “iss_position”: {“latitude”: “50.0040”, “longitude”: “-115.5382”}, “message”: “success”}”

json.loads() & json.dumps()

json.loads()

loads will convert your string into dictionary.

tt = json.loads(data.text)
print(tt)

{“timestamp”: 1573291044, “iss_position”: {“latitude”: “50.0040”, “longitude”: “-115.5382”}, “message”: “success”}

print (tt["timestamp"])

1573291044

print (tt["iss_position"])

{“latitude”: “50.0040”, “longitude”: “-115.5382”}

print (tt["iss_position"]["latitude"])

50.0040

print (tt["iss_position"]["longitude"])

-115.5382

Thanks to json.loads() we were able to use dictionary format and call values with their keys. Now let’s see what can be done with json.dumps()

json.dumps()

dumps will convert your dictionary into string. One trick is using the “indent=” argument you can make your string look pretty to the eyes of the reader.

pp = json.dumps(tt, indent=3)

Output:

{
   "timestamp": 1573294107,
   "iss_position": {
      "latitude": "-51.2585",
      "longitude": "79.9957"
   },
   "message": "success"
}

Humans In Space

People in Space feature of this API will tell you the astronauts that are currently in space at the time of your query.

f = r"http://api.open-notify.org/astros.json"
data2 = requests.get(f)
print(data2.text)

Output:

{"people": [{"name": "Christina Koch", "craft": "ISS"}, {"name": "Alexander Skvortsov", "craft": "ISS"}, {"name": "Luca Parmitano", "craft": "ISS"}, {"name": "Andrew Morgan", "craft": "ISS"}, {"name": "Oleg Skripochka", "craft": "ISS"}, {"name": "Jessica Meir", "craft": "ISS"}], "number": 6, "message": "success"}

Let’s convert our string data2.text into dictionary and then loop through each item under key: “people”. Turns out there are 6, representing the names of each astronauts in the space as of the time this tutorial is being written. (November 9, 2019)

tt = json.loads(data2.text)
for i in tt["people"]:
print(i)

Output:

{'name': 'Christina Koch', 'craft': 'ISS'}
{'name': 'Alexander Skvortsov', 'craft': 'ISS'}
{'name': 'Luca Parmitano', 'craft': 'ISS'}
{'name': 'Andrew Morgan', 'craft': 'ISS'}
{'name': 'Oleg Skripochka', 'craft': 'ISS'}
{'name': 'Jessica Meir', 'craft': 'ISS'}

How about just the names:

tt = json.loads(data2.text)
for i in tt["people"]:
print(i["name"])

Output:

Christina Koch
Alexander Skvortsov
Luca Parmitano
Andrew Morgan
Oleg Skripochka
Jessica Meir

Space Station Passing Times

Finally ISS Pass Times will tell you how much time need to pass before ISS passes over the specific coordinates you provide. Let’s look at when ISS will pass over Brooklyn Bridge, NYC next.

f = r"http://api.open-notify.org/iss-pass.json?lat=40.705911&lon=-73.996692"
data3 = requests.get(f)
tt = json.loads(data.text)
pp = json.dumps(tt, indent=3)
print(pp)

Output:

{
     "message": "success",
     "request": {
          "altitude": 100,
          "datetime": 1573297192,
          "latitude": 40.705911,
          "longitude": -73.996692,
          "passes": 5
     },
     "response": [
          {
               "duration": 307,
               "risetime": 1573351566
          },
          {
               "duration": 639,
               "risetime": 1573357156
          },
          {
               "duration": 633,
               "risetime": 1573362968
          },
          {
               "duration": 567,
               "risetime": 1573368856
          }
     ]
}

It takes latitude and longitude as input and it will give pass time duration in seconds and risetime in unix timestamp as output. You can see the output body has 2 sections: request and response.

By using this data you can think of a more presentable and beautiful output as below:

ISS Data Output Example

0 mins

To orbit the earth

0

Speed in kmh

0 kms

Altitude

Params

Most APIs you’ll encounter will be in json format. It’s just awesomely structured and very convenient so no wonder why engineers decide to implement it to every API out there. That also means you should have an understanding of it if you’d like to deal communicate with APIs but don’t worry it’s rather simple.

Documentation

One thing you should keep in mind that different APIs have different formatting so you will need to spend a moment checking out the Documentation of the API you’re interested in. Luckily they almost always have very clear and explanatory Documentation pages.

Example 2: DataMuse

DataMuse is a word query API that will give you words based on a wide range of constraints on meaning, spelling, sound, and vocabulary.

Here are some of the query parameters:

ml: Means like constraint
sl: Sounds like constraint 
sp: Spelled like constraint 
rel_[code]: Related word constraints

import requests

From the documentation on DataMuse website, here are the links we can use to access API.


parameter = {"sl" : "plethora"}
f = "https://api.datamuse.com/words?"

data1 = requests.get(f, params=parameter)

In this case we are making use of params which is helpful mainly for 2 things:

  1. You can conveniently change your query by changing your parameter.
  2. You can create automated processes more efficiently.

And the example will request:

  1. Words that sound like plethora 

There is one more thing you should take into account. data1 variable in the example above contains a “request object” now and if you print it you will get a request code signifying the outcome of request action as a code (200: successful, 404: error etc.) 

This can be useful indeed, however, if you want to see the content of your request object you need to print it with adding .text to it. See below:

print(data)

Output:

<Response [200]>

print(data.text)

Output: (partial data)

[{“word”:”plethora”,”score”:100,”numSyllables”:3},{“word”:”plethra”,”score”:100,”numSyllables”:2},{“word”:”pleather”,”score”:90,”numSyllables”:2},{“word”:”plethoras”,”score”:90,”numSyllables”:3},{“word”:”play through”,”score”:90,”numSyllables”:2},{“word”:”plethoric”,”score”:87,”numSyllables”:3},{“word”:”pleura”,”score”:85,”numSyllables”:2},{“word”:”plura”,”score”:85,”numSyllables”:2},{“word”:”blether”,”score”:83,”numSyllables”:2},{“word”:”pleasuring”,”score”:78,”numSyllables”:3},{“word”:”blathered”,”score”:78,”numSyllables”:2},{“word”:”eleuthera”,”score”:78,”numSyllables”:4},{“word”:”blathers”,”score”:78,”numSyllables”:2},{“word”:”plumber”,”score”:77,”numSyllables”:2},{“word”:”plummer”,”score”:77,”numSyllables”:2},{“word”:”plucker”,”score”:77,”numSyllables”:2},{“word”:”plumbers”,”score”:77,”numSyllables”:2},{“word”:”pother”,”score”:77,”numSyllables”:2},{“word”:”blithering”,”score”:77,”numSyllables”:3},{“word”:”pluckers”,”score”:77,”numSyllables”:2},{“word”:”pythia”,”score”:77,”numSyllables”:3},{“word”:”pira”,”score”:77,”numSyllables”:2},{“word”:”pyrrha”,”score”:77,”numSyllables”:2},{“word”:”piera”,”score”:77,”numSyllables”:2},{“word”:”pothers”,”score”:77,”numSyllables”:2},{“word”:”pathia”,”score”:77,”numSyllables”:3},{“word”:”players”,”score”:75,”numSyllables”:2},{“word”:”perry”,”score”:75,”numSyllables”:2},{“word”:”platter”,”score”:75,”numSyllables”:2},{“word”:”playa”,”score”:75,”numSyllables”:2},{“word”:”plaza”,”score”:75,”numSyllables”:2}……..

TIPS AND ADVANCED CONCEPTS

Tips

  • You may want to make use of params, it’s simple and can be very useful when you have more complex queries.

Advanced Concepts (optional)

  • Python’s requests library has its own .textand .jsonmethod.
  • It’s used, because data out there on the internet is in UTF-8 format. (This is usually all you have to know as nearly 95% of all data on the internet is UTF-8 and probably higher percentage for data most people encounter.)
  • Python on the other hand always uses Unicode format. So, what .text method does is, it decodes data into Python’s string.
  • Just remember, we decode into Python’s Unicode format because data out there uses UTF-8 encoding. This part can be hard to remember unless the wording is right.
  • Additionally you can import json library and use it’s json.loads and json.dumps for similar purposes.

If you’d like to see a refresher on JSON and Web Requests method of strings you can click here and here.

SUMMARY

  • json: library to handle json format
  • requests: library to make web requests.
  • documentation: Text needed to understand how specific API functions
  • params: An argument that can be passed to requests.get. Defines parameters of an API request
  • .text: method needed to read a request object as text
  • json.loads(): json method to convert text to dictionary
  • json.dumps(): json method to convert dictionary to text

Thank you for checking out this lessons about Json format in Python.

Please share if you found it useful.