Welcome to day 40
of your 100 days
of Python challenge.
Today,
we'll build a mini weather API using flask and rest principles.
You learn how to create handle and serve restful endpoints
that deliver weather data in JSON format.
This project will also cover basic A P routing error handling and query parameters.
So
let's look at what you learned today first. What are Rest
APIS? Now we've used some of it but we actually did not know what we were doing.
So this is where we will learn it,
setting up a flask rest API
next, defining API routes and endpoints,
returning
JSON
responses.
And finally day 40 project which is a mini weather API.
So let's get started
and let's look at what are rest
APIS
rest which stands for representational state transfer
is an architecture style for building
APIS.
Now rest
APIS
use HTTP methods
to interact with resources.
There are four different types of methods that are basic which are get
which retrieve data
we have post which adds new data,
we have put
which updates existing data and we have delete which removes data.
Now why build
APIS first for data access APIS
enable sharing data across applications. Scalability
apis
can scale to handle many requests
and finally, flexibility,
clients can request only the data they need.
So that brings us to setting up a flask rest API
Now for that,
we need to install some required packages which include flask and flask restful.
So you already have flask. I'm gonna open my terminal here or command prompt
and you can go ahead and say pip
install
flask,
you should have that Flask
restful. This is another one which is new, which we'll be using this time
and it's gonna download if I don't have anything as it says,
it's already has
a flask,
but I didn't have Flask restful and it installed that successfully right here.
So I'm going to clear this out so that will install all the required packages. Next.
Let's go ahead and create a basic flask. API example. I'm gonna go here,
create a new file, save this as a dot py.
And here first, I'm gonna say from Flask, import Flask and
jsonify Flask. You know what it is.
Jsonify is
something that converts Python dictionaries into
Json responses. And that's why I am importing
jsonify here.
Next,
I'm gonna create the app by
saying Flask underscore underscore name underscore underscore
and then let's create a root endpoint.
Now, this is something similar to creating the drought. I must say a
dot Drought slash,
create a function home
and here instead of returning text or HTML or template
I'm gonna say return
jsonify
and I'm gonna give a dictionary of message.
Welcome to Mini
Weather
API. So this will return back. So if I call this API,
which I call the URL slash, it will give me a JSON
data instead of HTML or anything.
So it's nothing but instead of getting text or HTML, I'm getting
JSON in this particular case. Finally, to run the application,
if name equal to main, I'll say a
run debug equal to two. Now, if I run this application on my, so I'm gonna go here,
make sure I'm in the right folder.
And here I can say Python
app dot py,
it's running on this particular URL. I opened this URL in my Chrome browser here.
And if you see when I call this URL, it's saying I can say
message,
welcome to Mini
Weather
API. It looks like a json data that I got
JSON data again looks like dictionary. So it says message, welcome to mini
Weather
API. So this is a
basic API that you built and this is your first API
that you built and is available to users to use.
Now at that particular URL.
Next, let's talk about defining
API routes and endpoints.
So first structure your A P endpoints like for example, we'll have for weather,
we'll have
weather where we get weather details for a default city. Then we can have
weather with a city name which gets weather for a specific city.
Let's look at an example weather data. So what I'm gonna do is I'm going to create here
an example just to show you here,
weather data for New York is temperature is 22.
Condition is sunny London temperature is 15 condition
is cloudy Tokyo temperature is 28 condition is
clear.
Now, I don't know how we get this data,
but this is what we get and this is what we can reply back again if I copy this
and add it here
to my
dataset,
save it.
Go back to my browser, refresh it.
You have the weather data based for London, New York and Tokyo coming from the A P A.
There you go.
Now let's go ahead and implement this entire application here.
So I'm going to delete everything here and start with importing flask,
jsonify and request from flask.
Next, I'm gonna say app equal to flask name.
Then I'm gonna create some mock weather data that we just had where
I'm gonna create a weather data variable with weather of New York temperature.
22 condition is sunny.
London temperature is 15. Condition is cloudy.
Tokyo temperature is 28 and condition is clear. Close this
let's create a root and point
A
dot RF
function equal to return
jsonify
message. Welcome to many weather A P
that we just created.
Next. Let's get weather for all the cities. Now, if you
call a route slash weather
with the method of the type get,
this is the get API that I'm calling because I'm requesting some data.
This will call this function, get all weather
and it will return,
jsonify the weather data. It will
jsonify this weather data and return back
and this will look something like this.
Next,
I'm gonna say get weather for a specific city for this. I'm gonna create a
dot route weather
and in Angular brackets, city. This will be depending on what user selects either
New York, London or Tokyo or the URL, whatever it is based on these cities,
I'm gonna say get weather by city,
city equals city dot lower. Now, if you say capital London, Lon capital N
capital Tokyo,
I want to convert everything into lower case and I will
say city and whether it I'm gonna check if the city
key exists in the weather data. Is it either New York, London or Tokyo?
Then I'm gonna say return
jsonify city
weather data for that city. So I'm gonna just return this particular data back
next. If it doesn't exist, then I'm gonna say error city not found
and then finally run the app by saying name equal domain
A
dot
Run debug equal to two. So this is my entire code for this
API Now, if I want to run this code, I can just go here, save it,
go back. It's already
restarted. I'm gonna open my browser
and here first
it goes to the basic route here it says
welcome message is welcome to mini weather app.
Now, if I want to get weather for all of them, I can just slash
weather and I get weather for all the three cities.
If I say weather slash
London, if you see I'm putting capital L for London,
it will give me London because I convert it into lower case right here.
So if I say
Tokyo,
it will give me Tokyo weather again. New York will give me New York weather.
Perfect. So that kind of gets me the data out from here.
So this brings us to returning
JSON responses, which we just saw of getting
JSON responses back on our, depending on the URL that we call, but depending on which
URL you call, you'll get that data back.
So now let's go ahead to the next section which is
day 40 project mini
Weather
API
here. We will have multiple endpoints like weather and weather city.
We'll have proper
Json responses and we'll have error handling for invalid cities.
So I have already created this app dot
py here.
Let's go ahead
and just to add some more functionality. Let's add an additional city.
So I'm gonna go ahead here
and add
Sydney to my
list of cities. So this will give me better data for four different cities.
I have my basic route here.
I'm gonna call it, I mean it's already called mini weather API. So that's perfect.
This will give me weather for all the cities, that's perfect.
And for a particular city, if you specify any of the city,
I get weather for that particular city by saying get weather by city,
it will give, I think I
got rid of my city equal to,
let's make sure we put that back city equal to
city dot
lower.
So that converts whatever the user passes the city name into lowercase.
And I have that
data back if or else there's an error.
Now,
I also want to give users the functionality to add new weather data for a new city.
So for that,
I'm gonna go ahead and here
create
add, let me just move all this to the top.
And here I'm gonna specify
that I want to add
new
weather
data.
So this will happen through post like all the
things that we did request that we did will get
this time. I want to create a route which is app
route. And in this particular case, we will call the same URL
weather.
But
the method that will be called
in this particular case
is post.
So what happens is when you make a post request,
this will be called when you make a get request for the same URL, this will be called.
So that's how these methods work.
So here I'm gonna say add underscore
city underscore weather
as the function.
And inside here, I'm gonna say data equal to
request
dot
JSON. So this is the data that is provided to me
and
Json and then I'm gonna say city
equal to which city is this? Let's say city dot get
from the one that user has passed.
I'm getting
the name of the city
and I'm converting into lower case because all my city names are lower case.
Next, I want to get the temperature for that city
that will be data dot
get
and I am looking for
temperature.
Next, I need
condition
like is it cloudy? Is it sunny data dot get?
And I'll specify
condition
perfect. So I have all the three parameters that I need.
And here next, I'm gonna check if not city if user did not pass anything or not
temperature
or not
condition because I need all these three parameters. If not, then I'm gonna return
saying
jsonify
and here
I'll pass
ed
saying
missing city
temperature
or conditions.
So one of these things is missing,
please provide me the right data and I'll say this is an error of the type 400.
So every time you call a particular URL, it will give you a status quo.
So for example, if I inspect here
and if I look at
my network
and move this a little bit below
and when I call this, you'll probably see that called Tokyo. But here
it mentioned again, let me run it again. Tokyo is the status is 200. But what if I enter
something like this?
It says 404 because this city is not found and that's what 404 is. And if I give some
other URL again, not found
and this is 404. So in this particular case,
I'm saying the error is of the type 404 because 40 400
because that city is you have some error in your system.
Next, I'm gonna say weather underscore data
for the city, which means
for the city that user pass, that means the data is available.
So I'm gonna set
the temperature
is equal to temperature
and
condition.
So this will run when everything is successful, pretty much
condition.
And then I'll return here
jsonify. In
this particular case, I will give a message
to the user
seeing F of F string,
whether for
city, whatever city user pass
added success
fully.
And this time, I'll say this is of the type
201 which means it was all successful and I was able to add that data.
Next. Let's go ahead and I think I already wrote the code to run the app.
I'm gonna close this here.
Save it.
Go back
here and see that it's running. OK? Perfect.
So this time instead of using Chrome,
what I'm gonna do is I'm gonna use something called as postman.
So you can download Postman from postman.com. This helps you test
API S so I already have it installed and I have an account so you can go ahead and sign in
and download this UI
based on which computer you have. If I have Mac, I'm gonna say,
depending on Apple chip or mac chip, I can download it.
I'm gonna download this for here and once it's downloaded, I can open it
and just call the API S that are available. My URL S are right.
Where is it URL here? This is the API endpoint
that I have and I have slash whether is where I can get all the information.
So again, once postman is installed or downloaded,
I'm gonna open it and it looks something like this.
It says unlock postman with an account.
I have an account, but I'm not gonna log in right now.
But what I'm gonna do is I'm just gonna go ahead close this
and here
I'm going to say I'm gonna create a new US, I'm gonna close
everything here,
whatever is open and here I can just give that URL that I have,
which was let's go back to my terminal.
This was the URL. If I just run this
and you'll see, it says welcome to mini
weather
repair because I got I'm passing that
uh data.
Then I call slash what if I call slash weather here and go ahead and say slash weather,
run it.
We
get the weather for London, New York, Sydney and Tokyo again,
if I say weather for a particular city.
So in this case, let's get weather for Sydney,
send it and there you go. We get
Sydney. Now if I want to add now you see it says get here, I'm making a get call.
But if I do post and in this case,
I am gonna say slash weather because that's the post URL here, right?
Post this thing.
And I am going to pass a weather for a particular city so I can just
pick this year
if you see the things that it needs.
If you check here, I said data dot request JSON
data dot get city temperature and conditions.
So it needs all these three different parameters. So I'm going to go here,
select body
and I'll say raw, but I'm passing
JSON
data here. I'm just gonna
do this
temperature
condition.
Oops, let's not
do any mistake. Let's increase the size. I think it's too big
for this. I hope it's visible to you.
And here I'm going to say city
is
Atlanta
when the weather is 22 and it's a rainy
send,
it's gonna say weather for Atlanta added successfully, which means
I'm gonna set here, get weather for Atlanta send and I'll get
the weather for Atlanta that is available or else I can call
weather for the all of them.
And I'll see Atlanta, London, New York, Sydney and Tokyo.
So Atlanta go weather got added here and that happened because we added,
we call this add new weather data uh
functionality to our application.
So we were able to create dynamic endpoints here handle multiple routes.
We did error handling, we validate city names and input data. We got
JSON responses proper A P response formatting.
We did some extensibility where we easily add more data points and
bonus challenge for today is
add a put
to update existing city weather, try that
add delete to remove a city from the weather data
and finally try to implement API authentication example,
using API case if you know what I'm talking about, if not, that's ok,
we'll be covering that in future.
So if you have any questions or had any
issues implementing these or understanding any of these,
let me know in the messages and I'll get back to you.