您的位置:首页 > 其它

1: What's An API?(Working with APIs)

2016-09-15 00:00 169 查看
摘要: 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

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 in
www.google.com
in your browser's address bar, your computer is actually asking the
www.google.com
server 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
json
format.

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
/comments
endpoint on the Reddit API might retrieve information about comments, whereas the
/users
endpoint might retrieve data about users.

The first endpoint we'll look at on OpenNotify is the
iss-now.json
endpoint. 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 from
response.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 of
200
. 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 to
http://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-pass
wasn't a valid endpoint, so we got a
404
status code in response. We forgot to add
.json
at 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 a
400
status 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
requests
takes care of some things that come up, like properly formatting the query parameters.

Instructions

Get a response for the latitude
37.78
and 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 a
string
. 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
json
library. 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 function
loads
to convert
fast_food_franchise_string
into 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 the
duration
value of the first pass of the ISS over San Francisco (this is the
duration
key of the first dictionary in the
response
list).

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
.headers
property of a response.

The headers will be shown as a dictionary. Within the headers,
content-type
is 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

Get
content-type
from
response.headers
.

Assign the content type to the
content_type
variable.

# 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: