In the previous part we have seen how bottle works and some other magic that bottle can do for us. In this part we will create our weather web app Weave. This part will be more challenging when compared to other parts because you will learn a lot after completing this part and will be satisfied using bottle.
If you have come here without seeing the previous parts then the pre-requisite for understanding this part is a little knowledge of python requests module, bottle framework and obviously python.
Okay folks fasten your seat belts and get ready for take off ;).
As you all know as we will be creating our weather app using API's from IPInfoDB and OpenWeatherMap first go create an account on both the sites: OpenWeather Members Signup and IPInfo Create Free Account.
At this point please make a note that I will represent my API key as '#####' and you should replace it with the corresponding API key that you have got from the website after signing up.
We will start our programming by using the IPInfoDB API.
Okay visit the following url:
http://api.ipinfodb.com/v3/ip-city/?key=#####&ip=4.4.4.4
You will find something like this:
Of course ip address will change but to use this API we need to create it in a usable data format. We will create a reusable script. Open a new script ctrl+n and then type the following:
I have saved this file as ip.py in my working directory. We are doing this in order to convert the data that we get from the server to dictionary format or the python usable format.
Lets see what is happening in the code.
First I have imported the requests module
Then we have created a function with an optional parameter of
Next we are creating a dictionary so that we can use it in our data request.
In the next line we are sending a request to get the value and storing the value in variable
As you can see that the data is empty and useless. But if we will host the same web app on server then we will get the real ip address of the user or client.
To address this issue we will assume some value for our variable; so,
Thus the changed code will be something like this:
Next we will start using templates. Now in your working directory create folders like this:
Now the static files will be as follows:
ip.tpl
static/css/style.css
Correspondingly we will modify our python web app app.py as follows:
Start the server and when you visit http://localhost:8080/myip then you should see something like this:
Now we will use combine both the weather data and the ip data in our website. Now go ahead save the following as weather_ip.tpl:
static/css/style.css
app.py:
Please sit aside, take some time and try to understand each and everything in the above code, I have written it in a very simple way. This is the major step to complete this part.
The only thing I would like to explain in the above code is the routing or the url. In the previous parts we have used something like this:
This is to tell the server that if the user visits either 'http://localhost:8080/something' or 'http://localhost:8080/something/' then show the same thing. But in the previous app.py code we have only used
Now start the server and visit the following url:
http://localhost:8080/, you should see something like this:
I think now you are looking for the next section on how to make the webapp look like that of weave. But according to me it would be better if I give this to you are a homework/practice. But I will give you some hints on how I made the web app.
If you have come here without seeing the previous parts then the pre-requisite for understanding this part is a little knowledge of python requests module, bottle framework and obviously python.
Okay folks fasten your seat belts and get ready for take off ;).
As you all know as we will be creating our weather app using API's from IPInfoDB and OpenWeatherMap first go create an account on both the sites: OpenWeather Members Signup and IPInfo Create Free Account.
At this point please make a note that I will represent my API key as '#####' and you should replace it with the corresponding API key that you have got from the website after signing up.
We will start our programming by using the IPInfoDB API.
Okay visit the following url:
http://api.ipinfodb.com/v3/ip-city/?key=#####&ip=4.4.4.4
You will find something like this:
IPInfoDB API result |
import requests def ipinfo(ipaddress=None): """ This function will return the data related to the ip address """ payload = {'key':'#####','ip':ipaddress} r = requests.get('http://api.ipinfodb.com/v3/ip-city/',params=payload) ipinfo = r.text ip_list = ipinfo.strip().split(';') ip_dict = {} ip_dict['status'] = ip_list[0] ip_dict['ip'] = ip_list[2] ip_dict['country_code'] = ip_list[3] ip_dict['country'] = ip_list[4] ip_dict['region'] = ip_list[5] ip_dict['city'] = ip_list[6] ip_dict['zip_code'] = ip_list[7] ip_dict['latitude'] = ip_list[8] ip_dict['longitude'] = ip_list[9] ip_dict['time_zone'] = ip_list[10] return ip_dict
Lets see what is happening in the code.
First I have imported the requests module
Then we have created a function with an optional parameter of
ipaddress
so that if the user has not given the value of the parameter then None
is assumed. Next we are creating a dictionary so that we can use it in our data request.
In the next line we are sending a request to get the value and storing the value in variable
r
.
In the next line we are converting the
In the following lines we are just manipulating this string and converting it into a dictionary.
To get a feel of what is happening in each and every line open your interpreter, declare a variable
We can also get the data in json format, you can check out the official documentation of IPInfoDB if you it directly. But here we have not used because some of you are here to learn something new. Also you can use their python module to get the data.
Next we will get the weather data from openweathermap API. This data is returned in json format and so the conversion of the data into dictionary format will be easy. For now we will use interpreter directly just for understanding and use the same concept in our main app.
Okay we are ready to weave ;)
Save the following file as app.py:(We will modify this file to create our web app)
Run the above code in command prompt and visit the following site:
http://localhost:8080/myip You should see something like this:
It will be returning the client ip address. But as we are in the development stage we will see 127.0.0.1. When the data related to this ip address(127.0.01) is seen, we will see the following data:
request
object to text and storing it in a variable ipinfo
.In the following lines we are just manipulating this string and converting it into a dictionary.
To get a feel of what is happening in each and every line open your interpreter, declare a variable
ipaddress
with your own value and then type each and every line in the body of the function ipinfo
.We can also get the data in json format, you can check out the official documentation of IPInfoDB if you it directly. But here we have not used because some of you are here to learn something new. Also you can use their python module to get the data.
Next we will get the weather data from openweathermap API. This data is returned in json format and so the conversion of the data into dictionary format will be easy. For now we will use interpreter directly just for understanding and use the same concept in our main app.
>>> from pprint import pprint >>> payload = {'lat':'39.8828','lon':'-105.106', 'units':'metric','appid':'#####'} >>> weather_data = requests.get('http://api.openweathermap.org/data/2.5/weather',params=payload) >>> weather = weather_data.json() >>> pprint(weather) {u'base': u'stations', u'clouds': {u'all': 20}, u'cod': 200, u'coord': {u'lat': 39.89, u'lon': -105.12}, u'dt': 1456590964, u'id': 7150586, u'main': {u'humidity': 27, u'pressure': 1015, u'temp': 11.41, u'temp_max': 18.3, u'temp_min': 6}, u'name': u'Countryside', u'sys': {u'country': u'US', u'id': 538, u'message': 0.0109, u'sunrise': 1456580176, u'sunset': 1456620632, u'type': 1}, u'visibility': 48279, u'weather': [{u'description': u'few clouds', u'icon': u'02d', u'id': 801, u'main': u'Clouds'}], u'wind': {u'deg': 180, u'speed': 1.5}} >>> description = weather['weather'][0]['description'] >>> print(description) few clouds >>>
Save the following file as app.py:(We will modify this file to create our web app)
from bottle import run, route, request @route('/myip') @route('/myip/') def test(): ip = request.remote_addr return ip run(reloader=True, debug=True)
http://localhost:8080/myip You should see something like this:
app.py with bottle |
>>> import ip >>> ip.ipinfo('127.0.0.1') {'status': u'OK', 'city': u'-', 'ip': u'127.0.0.1', 'region': u'-', 'time_zone': u'-', 'longitude': u'0', 'country_code': u'-', 'country': u'-', 'latitude': u'0', 'zip_code': u'-'}
To address this issue we will assume some value for our variable; so,
ip = '4.4.4.4'
and at the end we will revert it back to ip = request.remote_addr
, so that there will not be any error or bugs.Thus the changed code will be something like this:
from bottle import run, route #,request @route('/myip') @route('/myip/') def test(): ip = '4.4.4.4' return 'Your IP Address is {0}'.format(ip) run(reloader=True, debug=True)
`--app.py `--ip.py `--static |----css |----js |----images
ip.tpl
<!doctype html> <html lang='en'> <head> <meta charset='utf-8' /> <title>Radius of circle</title> <link rel="stylesheet" href="style.css" /> </head> <body> <h1>Hello Visitor!</h1> <h3>Your Details are as follows:</h3> <p>IP Address: {{ip}}</p> <p>City: {{city}}</p> <p>Region: {{region}}</p> <p>Country: {{country}}</p> <p>Country Code: {{country_code}}</p> <p>Zip Code: {{zip_code}}</p> <p>Latitude: {{latitude}}</p> <p>Longitude: {{longitude}}</p> <p>Time Zone: {{time_zone}}</p> </body> </html>
@import url(https://fonts.googleapis.com/css?family=Fauna+One); body{ padding: 10px; font-family: 'Fauna One', serif; } h1{ text-align: center; }
from bottle import run, route, template,get,static_file#,request import ip #To serve the static files @get('/<filename:re:.*\.css>') def stylesheets(filename): return static_file(filename, root='static/css') @route('/myip') @route('/myip/') def test(): ip_add = '4.4.4.4' data = ip.ipinfo(ip_add) if data['status'] == 'OK': city = data['city'] region = data['region'] time_zone = data['time_zone'] longitude = data['longitude'] country_code = data['country_code'] country = data['country'] latitude = data['latitude'] zip_code = data['zip_code'] return template('ip', ip=ip_add, city = city, region = region, country = country, country_code = country_code, zip_code = zip_code, latitude = latitude, longitude = longitude, time_zone = time_zone) else: return 'We are sorry some error occured' run(reloader=True, debug=True)
app.py returning the user ip address and related data |
<!doctype html> <html lang='en'> <head> <meta charset='utf-8' /> <title>Radius of circle</title> <link rel='stylesheet' href="style.css" /> </head> <body> <table border="1"> <tr> <td> <!--IP Data--> <h1>IP Details</h1> <h3> {{ip}}</h3> <p>City: {{city}}</p> <p>Region: {{region}}</p> <p>Country: {{country}}</p> <p>Country Code: {{country_code}}</p> <p>Zip Code: {{zip_code}}</p> <p>Latitude: {{latitude}}</p> <p>Longitude: {{longitude}}</p> <p>Time Zone: {{time_zone}}</p> </td> <td><!--Weather--> <h1>Weather</h1> <h3>{{city}}</h3> <p>Minimum Temperature: {{min_temp}} K</p> <p>Maximum Temperature: {{max_temp}} K</p> <p>Temperature: {{avg_temp}} K</p> <p>Pressure: {{pressure}} mm of Hg</p> <p>Description: {{description}}</p> <p>Wind Direction: {{wind_dir}}</p> <p>Wind Speed: {{wind_speed}}</p> <p>Humidity: {{humidity}}</p> </td> </tr> </table> </body> </html>
@import url(https://fonts.googleapis.com/css?family=Fauna+One); body{ padding: 10px; font-family: 'Fauna One', serif; } h1{ text-align: center; border-bottom: 1px solid black; } h3{ text-align: center; } td{ padding: 20px; }
from bottle import run, route, template,get,static_file#,request import ip, requests @get('/<filename:re:.*\.css>') def stylesheets(filename): return static_file(filename, root='static/css') @route('/') def test(): ip_add = '4.4.4.4' data = ip.ipinfo(ip_add) if data['status'] == 'OK': city = data['city'] region = data['region'] time_zone = data['time_zone'] longitude = data['longitude'] country_code = data['country_code'] country = data['country'] latitude = data['latitude'] zip_code = data['zip_code'] payload = {'q':city,'appid':'44db6a862fba0b067b1930da0d769e98'} url = 'http://api.openweathermap.org/data/2.5/weather' r = requests.get(url,params=payload) weather = r.json() humidity = weather['main']['humidity'] pressure = int(float(weather['main']['pressure'])*0.750062) avg_temp = int(round(weather['main']['temp'])) max_temp = int(round(weather['main']['temp_max'])) min_temp = int(weather['main']['temp_min']) description = weather['weather'][0]['description'] wind_direction = float(weather['wind']['deg']) wind_speed = weather['wind']['speed'] return template('weather_ip', ip=ip_add, city = city, region = region, country = country, country_code = country_code, zip_code = zip_code, latitude = latitude, longitude = longitude, time_zone = time_zone, humidity = humidity, pressure=pressure, avg_temp=avg_temp, max_temp = max_temp, min_temp=min_temp, description=description, wind_dir = wind_direction, wind_speed=wind_speed) else: return 'We are sorry some error occured' run(reloader=True, debug=True)
The only thing I would like to explain in the above code is the routing or the url. In the previous parts we have used something like this:
@route('/something') @route('/something/')
@route('/')
because even if the user visits 'http://localhost:8080' the same function test
will be called and the data is returned properly.Now start the server and visit the following url:
http://localhost:8080/, you should see something like this:
Bottle webapp returning weather and ip data |
- First change
ip = request.remote_addr
- I have used the HTML template from w3layouts for the design and can be found here: Clime and Timer Weather Responsive Widget Template
- I have modified the original template a little bit, I am assuming that with a basic HTML knowledge you can do that on your own.
- If you want to display the images based on the weather then you can get the icon name by typing this:
icon = weather['weather'][0]['icon']
- You can get the icons from here: Icons
- If you want to see the source code(this is not the original one hosted on web) you can see it from here: Github Weather
If you want to host your bottle application then I would seriously recommend pythonanywhere. It is very easy to deploy your app and also they have a very great customer support team who will help you if you have any trouble.
If you want to deploy on any other service then you can see other options from here:Web Hosting providers (All most all of them offer hosing)
Even though our web app is not suitable for very large traffic you can use it directly with some changes made to make it compatible with server, if you want to make it available for large traffic then you will have to make a few changes of the present web app which out of the scope of this tutorial.
Finally congrats, you are now a python developer. You can create dynamic websites on your own. It should be remembered that we have only seen one side of the n-sides that bottle can do for us. If you want to know what bottle can do for you, read the official documentation.
As always, I have tried to use simple terms in this post/part so that even the beginners will also be able to understand it easily. But if you didn't understand anything or have any doubt then please comment in the comment box below or contact me. You can contact me from here: Contact me
Please do comment on how I can improve this post so that it will be more comfortable even for small children. Also comment if I have missed any topic or want me to add any new topic or for anything else. I would be glad to give you a reply. "Let's share our knowledge and make this world beautiful!"
Thank you, Have a nice day :)