1: What's An API?(Working with APIs)
2016-09-15 00:00
218 查看
摘要: 2: Requests3: Type Of Requests4: Status Codes5: Hitting The Right Endpoint6: Query Parameters7: JSON Format8: Getting JSON From A Request9: Content Type10: Finding The Number Of People In Space
Here are a few times when a dataset isn't a good solution:
The data are changing quickly. An example of this is stock price data. It doesn't really make sense to regenerate a dataset and download it every minute -- this will take a lot of bandwidth, and be pretty slow.
You want a small piece of a much larger set of data. Reddit comments are one example. What if you want to just pull your own comments on reddit? It doesn't make much sense to download the entire reddit database, then filter just your own comments.
There is repeated computation involved. Spotify has an API that can tell you the genre of a piece of music. You could theoretically create your own classifier, and use it to categorize music, but you'll never have as much data as Spotify does.
In cases like the ones above, an Application Program Interface (API) is the right solution. APIs are used to dynamically query and retrieve data. They provide a language whereby a client can retrieve information quickly and effectively. Reddit, Spotify, Twitter, Facebook, and many other companies provide APIs that enable developers to access a wealth of information stored on their servers.
In this mission, we'll be querying a simple API to retrieve data about the International Space Station (ISS). Using an API will save us time and effort over doing all the computation ourselves.
APIs work much the same way, except instead of your web browser asking for a webpage, your program asks for data. This data is usually returned in
In order to get the data, we make a request to the webserver that we want to get data from. The server then replies with our data. In Python, we use the requests library to do this.
We can use a simple GET request to retrieve information from the OpenNotify API.
OpenNotify has several API endpoints. An endpoint is a server route that is used to retrieve different data from the API. For example, the
The first endpoint we'll look at on OpenNotify is the
You can see a listing of all the endpoints on OpenNotify here.
Assign the status code to the variable
# Make a get request to get the latest position of the international space station from the opennotify api.
response = requests.get("http://api.open-notify.org/iss-now.json")
status_code=response.status_code
####################################################
Assign the status code of the response to
# Enter your answer below.
response=requests.get("http://api.open-notify.org/iss-pass")
status_code=response.status_code
status_code
int (<class 'int'>)
404
response
Response (<class 'mock_requests.Response'>)
<mock_requests.Response at 0x7fda68435c18>
########################################################
Make a GET request to
Assign the status code of the response to
# Enter your answer below.
response=requests.get("http://api.open-notify.org/iss-pass.json")
status_code=response.status_code
##########################################
The ISS Pass endpoint returns when the ISS will next pass over a given location on earth. In order to compute this, we need to pass the coordinates of the location to the API. We do this by passing two parameters -- latitude and longitude.
We can do this by adding an optional keyword argument,
We can make a dictionary with these parameters, and then pass them into the function.
We can also do the same thing directly by adding the query parameters to the url, like this:
It's almost always preferable to setup the parameters as a dictionary, because
Retrieve the content of the response with
Assign the content to the variable
# Set up the parameters we want to pass to the API.
# This is the latitude and longitude of New York City.
parameters = {"lat": 40.71, "lon": -74}
# Make a get request with the parameters.
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Print the content of the response (the data the server returned)
print(response.content)
# This gets the same data as the command above
response = requests.get("http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74")
print(response.content)
parameters={"lat":37.78,"lon":-122.41}
response=requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
content=response.content
Output
b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 330, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}' b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 329, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}'
#################################################
Luckily, there's a format called JavaScript Object Notation (JSON). JSON is a way to encode data structures like lists and dictionaries to strings that ensures that they are easily readable by machines. JSON is the primary format in which data is passed back and forth to APIs.
Python has great JSON support, with the
The json library has two main methods:
Assign the resulting Python object to
# Make a list of fast food chains.
best_food_chains = ["Taco Bell", "Shake Shack", "Chipotle"]
print(type(best_food_chains))
# Import the json library
import json
# Use json.dumps to convert best_food_chains to a string.
best_food_chains_string = json.dumps(best_food_chains)
print(type(best_food_chains_string))
# Convert best_food_chains_string back into a list
print(type(json.loads(best_food_chains_string)))
# Make a dictionary
fast_food_franchise = {
"Subway": 24722,
"McDonalds": 14098,
"Starbucks": 10821,
"Pizza Hut": 7600
}
# We can also dump a dictionary to a string and load it.
fast_food_franchise_string = json.dumps(fast_food_franchise)
print(type(fast_food_franchise_string))
fast_food_franchise_2=json.loads(fast_food_franchise_string)
print(type(fast_food_franchise_2))
---------------------------------------------------------------------------
OUTPUT
best_food_chains
list (<class 'list'>)
['Taco Bell', 'Shake Shack', 'Chipotle']
best_food_chains_string
str (<class 'str'>)
'["Taco Bell", "Shake Shack", "Chipotle"]'
fast_food_franchise
dict (<class 'dict'>)
{'McDonalds': 14098, 'Pizza Hut': 7600, 'Starbucks': 10821, 'Subway': 24722}
fast_food_franchise_string
str (<class 'str'>)
'{"Starbucks": 10821, "Pizza Hut": 7600, "McDonalds": 14098, "Subway": 24722}'
fast_food_franchise_2
dict (<class 'dict'>)
{'McDonalds': 14098, 'Pizza Hut': 7600, 'Starbucks': 10821, 'Subway': 24722}
######################################################################
Assign the value to
# Make the same request we did 2 screens ago.
parameters = {"lat": 37.78, "lon": -122.41}
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Get the response data as a python object. Verify that it's a dictionary.
data = response.json()
print(type(data))
print(data)
first_pass_duration=data["response"][0]["duration"]
print(type(first_pass_duration))
print(first_pass_duration)
Output
<class 'dict'> {'response': [{'duration': 369, 'risetime': 1441456672}, {'duration': 626, 'risetime': 1441462284}, {'duration': 581, 'risetime': 1441468104}, {'duration': 482, 'risetime': 1441474000}, {'duration': 509, 'risetime': 1441479853}], 'request': {'latitude': 37.78, 'altitude': 100, 'passes': 5, 'datetime': 1441417753, 'longitude': -122.41}, 'message': 'success'} <class 'int'> 369
#####################################################################
The headers will be shown as a dictionary. Within the headers,
Assign the content type to the
# Headers is a dictionary
print(response.headers)
content_type=response.headers["content-type"]
print(type(content_type))
print(content_type)
Output
{'connection': 'keep-alive', 'via': '1.1 vegur', 'date': 'Sat, 05 Sep 2015 01:49:13 GMT', 'content-length': '520', 'content-type': 'application/json', 'server': 'gunicorn/19.3.0'} <class 'str'> application/json
##########################################################################3
Assign the result to
response=requests.get("http://api.open-notify.org/astros.json")
data=response.json()
print(type(data))
print(data)
in_space_count=data["number"]
print(type(in_space_count))
print(in_space_count)
Output
<class 'dict'> {'people': [{'craft': 'ISS', 'name': 'Gennady Padalka'}, {'craft': 'ISS', 'name': 'Mikhail Kornienko'}, {'craft': 'ISS', 'name': 'Scott Kelly'}, {'craft': 'ISS', 'name': 'Oleg Kononenko'}, {'craft': 'ISS', 'name': 'Kimiya Yui'}, {'craft': 'ISS', 'name': 'Kjell Lindgren'}, {'craft': 'ISS', 'name': 'Sergey Volkov'}, {'craft': 'ISS', 'name': 'Andreas Mogensen'}, {'craft': 'ISS', 'name': 'Aidyn Aimbetov'}], 'number': 9, 'message': 'success'} <class 'int'> 9
1: What's An API?
We've worked with datasets pretty extensively in Dataquest so far. Datasets are great, and are widely used, but there are many cases where it's impractical to use one.Here are a few times when a dataset isn't a good solution:
The data are changing quickly. An example of this is stock price data. It doesn't really make sense to regenerate a dataset and download it every minute -- this will take a lot of bandwidth, and be pretty slow.
You want a small piece of a much larger set of data. Reddit comments are one example. What if you want to just pull your own comments on reddit? It doesn't make much sense to download the entire reddit database, then filter just your own comments.
There is repeated computation involved. Spotify has an API that can tell you the genre of a piece of music. You could theoretically create your own classifier, and use it to categorize music, but you'll never have as much data as Spotify does.
In cases like the ones above, an Application Program Interface (API) is the right solution. APIs are used to dynamically query and retrieve data. They provide a language whereby a client can retrieve information quickly and effectively. Reddit, Spotify, Twitter, Facebook, and many other companies provide APIs that enable developers to access a wealth of information stored on their servers.
In this mission, we'll be querying a simple API to retrieve data about the International Space Station (ISS). Using an API will save us time and effort over doing all the computation ourselves.
2: Requests
APIs are hosted on web servers. When you type inwww.google.comin your browser's address bar, your computer is actually asking the
www.google.comserver for a webpage, which it then returns to your browser.
APIs work much the same way, except instead of your web browser asking for a webpage, your program asks for data. This data is usually returned in
jsonformat.
In order to get the data, we make a request to the webserver that we want to get data from. The server then replies with our data. In Python, we use the requests library to do this.
3: Type Of Requests
There are many different types of requests. The most commonly used one, a GET request, is used to retrieve data. We'll get into the other types in later missions.We can use a simple GET request to retrieve information from the OpenNotify API.
OpenNotify has several API endpoints. An endpoint is a server route that is used to retrieve different data from the API. For example, the
/commentsendpoint on the Reddit API might retrieve information about comments, whereas the
/usersendpoint might retrieve data about users.
The first endpoint we'll look at on OpenNotify is the
iss-now.jsonendpoint. This endpoint gets the current latitude and longitude position of the International Space Station. As you can see, retrieving this data isn't a great fit for a dataset, because it involves some calculation on the server.
You can see a listing of all the endpoints on OpenNotify here.
Instructions
You can get the status code of the response fromresponse.status_code.
Assign the status code to the variable
status_code.
# Make a get request to get the latest position of the international space station from the opennotify api.
response = requests.get("http://api.open-notify.org/iss-now.json")
status_code=response.status_code
####################################################
4: Status Codes
The request we just made had a status code of200. Status codes are returned with every request that is made to a web server. Status codes indicate information about what happened with a request. Here are some codes that are relevant to GET requests:
200-- everything went okay, and the result has been returned (if any)
301-- the server is redirecting you to a different endpoint. This can happen when a company switches domain names, or an endpoint name is changed.
401-- the server thinks you're not authenticated. This happens when you don't send the right credentials to access an API (we'll talk about this in a later mission).
400-- the server thinks you made a bad request. This can happen when you don't send along the right data, among other things.
403-- the resource you're trying to access is forbidden -- you don't have the right permissions to see it.
404-- the resource you tried to access wasn't found on the server.
Instructions
Make a GET request tohttp://api.open-notify.org/iss-pass.
Assign the status code of the response to
status_code.
# Enter your answer below.
response=requests.get("http://api.open-notify.org/iss-pass")
status_code=response.status_code
status_code
int (<class 'int'>)
404
response
Response (<class 'mock_requests.Response'>)
<mock_requests.Response at 0x7fda68435c18>
########################################################
5: Hitting The Right Endpoint
iss-passwasn't a valid endpoint, so we got a
404status code in response. We forgot to add
.jsonat the end, as the API documentation states.
Make a GET request to
http://api.open-notify.org/iss-pass.json.
Assign the status code of the response to
status_code.
# Enter your answer below.
response=requests.get("http://api.open-notify.org/iss-pass.json")
status_code=response.status_code
##########################################
6: Query Parameters
You'll see that in the last example, we got a400status code, which indicates a bad request. If you look at the documentation for the OpenNotify API, we see that the ISS Pass endpoint requires two parameters.
The ISS Pass endpoint returns when the ISS will next pass over a given location on earth. In order to compute this, we need to pass the coordinates of the location to the API. We do this by passing two parameters -- latitude and longitude.
We can do this by adding an optional keyword argument,
params, to our request. In this case, there are two parameters we need to pass:
lat-- The latitude of the location we want.
lon-- The longitude of the location we want.
We can make a dictionary with these parameters, and then pass them into the function.
We can also do the same thing directly by adding the query parameters to the url, like this:
http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74.
It's almost always preferable to setup the parameters as a dictionary, because
requeststakes care of some things that come up, like properly formatting the query parameters.
Instructions
Get a response for the latitude37.78and the longitude
-122.41(the coordinates of San Francisco).
Retrieve the content of the response with
response.content.
Assign the content to the variable
content
# Set up the parameters we want to pass to the API.
# This is the latitude and longitude of New York City.
parameters = {"lat": 40.71, "lon": -74}
# Make a get request with the parameters.
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Print the content of the response (the data the server returned)
print(response.content)
# This gets the same data as the command above
response = requests.get("http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74")
print(response.content)
parameters={"lat":37.78,"lon":-122.41}
response=requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
content=response.content
Output
b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 330, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}' b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 329, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}'
#################################################
7: JSON Format
You may have noticed that the content of the response earlier was astring. Strings are the way that we pass information back and forth to APIs, but it's hard to get the information we want out of them. How do we know how to decode the string that we get back and work with it in python?
Luckily, there's a format called JavaScript Object Notation (JSON). JSON is a way to encode data structures like lists and dictionaries to strings that ensures that they are easily readable by machines. JSON is the primary format in which data is passed back and forth to APIs.
Python has great JSON support, with the
jsonlibrary. We can both convert lists and dictionaries to JSON, and convert strings to listsand dictionaries. In the case of our ISS Pass data, it is a dictionary encoded as a string in JSON format.
The json library has two main methods:
dumps-- Takes in a Python object, and converts it to a string.
loads-- Takes a json string, and converts it to a Python object.
Instructions
Use the json functionloadsto convert
fast_food_franchise_stringinto a Python object.
Assign the resulting Python object to
fast_food_franchise_2
CODE
# Make a list of fast food chains.
best_food_chains = ["Taco Bell", "Shake Shack", "Chipotle"]
print(type(best_food_chains))
# Import the json library
import json
# Use json.dumps to convert best_food_chains to a string.
best_food_chains_string = json.dumps(best_food_chains)
print(type(best_food_chains_string))
# Convert best_food_chains_string back into a list
print(type(json.loads(best_food_chains_string)))
# Make a dictionary
fast_food_franchise = {
"Subway": 24722,
"McDonalds": 14098,
"Starbucks": 10821,
"Pizza Hut": 7600
}
# We can also dump a dictionary to a string and load it.
fast_food_franchise_string = json.dumps(fast_food_franchise)
print(type(fast_food_franchise_string))
fast_food_franchise_2=json.loads(fast_food_franchise_string)
print(type(fast_food_franchise_2))
---------------------------------------------------------------------------
OUTPUT
best_food_chains
list (<class 'list'>)
['Taco Bell', 'Shake Shack', 'Chipotle']
best_food_chains_string
str (<class 'str'>)
'["Taco Bell", "Shake Shack", "Chipotle"]'
fast_food_franchise
dict (<class 'dict'>)
{'McDonalds': 14098, 'Pizza Hut': 7600, 'Starbucks': 10821, 'Subway': 24722}
fast_food_franchise_string
str (<class 'str'>)
'{"Starbucks": 10821, "Pizza Hut": 7600, "McDonalds": 14098, "Subway": 24722}'
fast_food_franchise_2
dict (<class 'dict'>)
{'McDonalds': 14098, 'Pizza Hut': 7600, 'Starbucks': 10821, 'Subway': 24722}
######################################################################
8: Getting JSON From A Request
You can get the content of a response as a Python object by using the.json()method on the response.
Instructions
Get thedurationvalue of the first pass of the ISS over San Francisco (this is the
durationkey of the first dictionary in the
responselist).
Assign the value to
first_pass_duration.
# Make the same request we did 2 screens ago.
parameters = {"lat": 37.78, "lon": -122.41}
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Get the response data as a python object. Verify that it's a dictionary.
data = response.json()
print(type(data))
print(data)
first_pass_duration=data["response"][0]["duration"]
print(type(first_pass_duration))
print(first_pass_duration)
Output
<class 'dict'> {'response': [{'duration': 369, 'risetime': 1441456672}, {'duration': 626, 'risetime': 1441462284}, {'duration': 581, 'risetime': 1441468104}, {'duration': 482, 'risetime': 1441474000}, {'duration': 509, 'risetime': 1441479853}], 'request': {'latitude': 37.78, 'altitude': 100, 'passes': 5, 'datetime': 1441417753, 'longitude': -122.41}, 'message': 'success'} <class 'int'> 369
#####################################################################
9: Content Type
The server doesn't just send a status code and the data when it generates a response. It also sends metadata containing information on how the data was generated and how to decode it. This is stored in the response headers. We can access this with the.headersproperty of a response.
The headers will be shown as a dictionary. Within the headers,
content-typeis the most important key for now. It tells us the format of the response, and how to decode it. For the OpenNotify API, the format is json, which is why we could decode it with json earlier.
Instructions
Getcontent-typefrom
response.headers.
Assign the content type to the
content_typevariable.
# Headers is a dictionary
print(response.headers)
content_type=response.headers["content-type"]
print(type(content_type))
print(content_type)
Output
{'connection': 'keep-alive', 'via': '1.1 vegur', 'date': 'Sat, 05 Sep 2015 01:49:13 GMT', 'content-length': '520', 'content-type': 'application/json', 'server': 'gunicorn/19.3.0'} <class 'str'> application/json
##########################################################################3
10: Finding The Number Of People In Space
OpenNotify has one more API endpoint,astros.json. It tells you how many people are currently in space. The format of the responses can be found here.
Instructions
Find how many people are currently in space.Assign the result to
in_space_count.
response=requests.get("http://api.open-notify.org/astros.json")
data=response.json()
print(type(data))
print(data)
in_space_count=data["number"]
print(type(in_space_count))
print(in_space_count)
Output
<class 'dict'> {'people': [{'craft': 'ISS', 'name': 'Gennady Padalka'}, {'craft': 'ISS', 'name': 'Mikhail Kornienko'}, {'craft': 'ISS', 'name': 'Scott Kelly'}, {'craft': 'ISS', 'name': 'Oleg Kononenko'}, {'craft': 'ISS', 'name': 'Kimiya Yui'}, {'craft': 'ISS', 'name': 'Kjell Lindgren'}, {'craft': 'ISS', 'name': 'Sergey Volkov'}, {'craft': 'ISS', 'name': 'Andreas Mogensen'}, {'craft': 'ISS', 'name': 'Aidyn Aimbetov'}], 'number': 9, 'message': 'success'} <class 'int'> 9
相关文章推荐
- Working with ADO.NET Schema APIs 使用ADO.NET 模式API
- 启动AndroidStudio时报the SDK platform-tools version(xxx) is too old to check APIs cimpiled with API xxx
- The SDK platform-tools version(24.0.1) is too old to check APIs compiled with API 25
- 【Android Studio】platform-tools is too old to check APIs compiled with API 27
- Working with the ArcGIS Server ArcObjects API : ArcObjects API
- The SDK platform-tools version (20) is too old to check APIs compiled with API(x)
- The SDK platform-tools version ((21)) is too old to check APIs compiled with API 23
- the SDK platform-tools version(xxx) is too old to check APIs cimpiled with API xxx.
- Working with ADO.NET Schema APIs
- The SDK platform-tools version(24) is too old to check APIs compiled with API 25
- 1.新建项目出现包名有一道红线The SDK platform-tools version ((23)) is too old to check APIs compiled with API 20
- The SDK platform-tools version 23 is too old to check APIs compiled with API 24... ...
- The SDK platform-tools version (24.0.4) is too old to check APIs compiled with API 25
- Challenge: Working with the Reddit API
- Error: The SDK platform-tools version ((23)) is too old to check APIs compiled with API 23
- The SDK platform-tools version (24.0.4) is too old to check APIs compiled with API 25
- The SDK platform-tools version ((23)) is too old to check APIs compiled with API 26;
- QTP - 17 Working with APIs 与windows API交互