Some computers on the internet are servers
Others are clients (typically us)
requests
module¶requests
.>>> conda install requests
import requests
requests.get
method which calls the API's GET function.iss-now.json
endpoint tells us where the space station is at this moment.base_url = "http://api.open-notify.org/"
#get current ISS location using the iss-now.json endpoint
response = requests.get(base_url + "iss-now.json")
Response
object¶requests
module produces a Response
object containing the server's answer.Response
objectAttribute | Description |
---|---|
status_code |
Number representing status of request (200 means success, 404 means failed) |
content |
Data received from server |
url |
URL string sent to server |
headers |
Extra info on how the data was generated |
print(response.url)
print(response.status_code)
print(response.content)
print(response.headers)
http://api.open-notify.org/iss-now.json 200 b'{"message": "success", "timestamp": 1509373604, "iss_position": {"longitude": "-51.1057", "latitude": "47.1351"}}' {'Server': 'nginx/1.10.3', 'Date': 'Mon, 30 Oct 2017 14:26:44 GMT', 'Content-Type': 'application/json', 'Content-Length': '113', 'Connection': 'keep-alive', 'access-control-allow-origin': '*'}
print(type(response.content))
<class 'bytes'>
Oops. The content looks like a dictionary but it's actually a byte sequence (similar to a string).
This is because talking to APIs always happens through strings. Not very useful when working inside your code. We want to say content['iss_position']['longitude']
. So we have to convert it to a dictionary.
We can convert the response
data to a dict
using the json
module.
import json
r = response.json()
r
{'iss_position': {'latitude': '-47.7310', 'longitude': '14.0044'}, 'message': 'success', 'timestamp': 1509315256}
print(f"The space station is currently at {r['iss_position']}")
The space station is currently at {'longitude': '14.0044', 'latitude': '-47.7310'}
from IPython.display import Image
Image(url="https://media1.tenor.com/images/5f1c69725f33736abdbcbe52d059ad59/tenor.gif")
params=
keyword argument of requests.get
.iss-pass
endpoint. With Montreal's coordinates as parameters: 45.5017° N, 73.5673° Wmontreal = {'lat': 45.5017, 'lon': -73.5673 }
response = requests.get(base_url + 'iss-pass.json', params=montreal)
response.status_code
200
We could have typed up the URL manually and entered it into the browser as it appears below.
response.url
'http://api.open-notify.org/iss-pass.json?lat=45.5017&lon=-73.5673'
response.content
b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1509318078, \n "latitude": 45.5017, \n "longitude": -73.5673, \n "passes": 5\n }, \n "response": [\n {\n "duration": 499, \n "risetime": 1509355748\n }, \n {\n "duration": 636, \n "risetime": 1509361433\n }, \n {\n "duration": 623, \n "risetime": 1509367238\n }, \n {\n "duration": 615, \n "risetime": 1509373064\n }, \n {\n "duration": 639, \n "risetime": 1509378863\n }\n ]\n}\n'
r = response.json()
print(r)
{'message': 'success', 'request': {'altitude': 100, 'datetime': 1509318078, 'latitude': 45.5017, 'longitude': -73.5673, 'passes': 5}, 'response': [{'duration': 499, 'risetime': 1509355748}, {'duration': 636, 'risetime': 1509361433}, {'duration': 623, 'risetime': 1509367238}, {'duration': 615, 'risetime': 1509373064}, {'duration': 639, 'risetime': 1509378863}]}
import datetime
for p in r['response']:
#convert from UNIX time https://en.wikipedia.org/wiki/Unix_time
date = datetime.datetime.fromtimestamp(int(p['risetime']))
print(date)
2017-10-30 05:29:08 2017-10-30 07:03:53 2017-10-30 08:40:38 2017-10-30 10:17:44 2017-10-30 11:54:23
How many astronauts are in space right now?
astronauts = requests.get(base_url + "astros.json")
print(astronauts.json())
{'number': 6, 'message': 'success', 'people': [{'name': 'Sergey Ryazanskiy', 'craft': 'ISS'}, {'name': 'Randy Bresnik', 'craft': 'ISS'}, {'name': 'Paolo Nespoli', 'craft': 'ISS'}, {'name': 'Alexander Misurkin', 'craft': 'ISS'}, {'name': 'Mark Vande Hei', 'craft': 'ISS'}, {'name': 'Joe Acaba', 'craft': 'ISS'}]}
So far we've only been getting data from the server. But we can also send data for the server to store.
This is known as the POST method
Let's use the Twitter API to practice posting data.
Here are the docs for the API. Will come in handy.
auth
token to get permission. (don't worry about this part)from carlos_auth import get_auth
auth = get_auth()
auth=
keyword will take my access tokenparams=
keyword will take info about my search querybase_url = 'https://api.twitter.com/'
# search for Pizza, recent tweets, and 2 of them
search_params = {
'q': 'Pizza',
'result_type': 'recent',
'count': 2
}
search_url = f'{base_url}1.1/search/tweets.json'
search_resp = requests.get(search_url, auth=auth, params=search_params)
print(search_resp.url)
print(search_resp.status_code)
https://api.twitter.com/1.1/search/tweets.json?q=Pizza&result_type=recent&count=2 200
The search_resp
object contains a lot of info. If we want just the tweet test we go to search_resp['statuses']
which gives us a list of tweets, and for each tweet we access the text
field.
tweets = search_resp.json()
for x in tweets['statuses']:
print(x['text'] + '\n')
Do u think about me as much as I think about u? RT @lebaenesepapi: Pineapple and non-pineapple pizza eaters must put our differences aside and join forces to defeat this evil https://t.co…
requests.post()
method instead since we want to send data to the server.post_params = {'status': "Hi from COMP 364! #IAMAGOD"}
post_url = 'https://api.twitter.com/1.1/statuses/update.json'
post_tweet = requests.post(post_url, auth=auth, params=post_params)
post_tweet.status_code
200
Image(url="https://media.sticker.market/gif/sleepy-goodnight-good-night-584f425fdb58323238889c67-g.gif")