In this training, you will learn the basics of the Internet of Things. In this part, you will learn how to develop a web application with the CherryPy framework. This application will aim to provide weather data about a city chosen by the user.
The weather web service HTML template :
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<section class="vh-100" style="background-color: #E9F8FE;">
<div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-md-8 col-lg-6 col-xl-4">
<div class="card" style="color: #4B515D; border-radius: 35px;">
<div class="card-header">
<form class="" method="get">
<div class="input-group rounded">
<input type="search" name="q" class="form-control rounded" placeholder="City" aria-label="Search" aria-describedby="search-addon" />
<button type="submit">Search</button>
</div>
</form>
</div>
<div class="card-body p-4">
<div class="d-flex">
<h6 class="flex-grow-1">"Paris/FR</h6>
<h6>20/02 15h30<a href=""><i class="bi bi-arrow-clockwise"></i></a> </h6>
</div>
<div class="d-flex flex-column text-center mt-5 mb-4">
<h6 class="display-4 mb-0 font-weight-bold" style="color: #1C2331;"> 20°C </h6>
<span class="small" style="color: #868B94">Clear</span>
</div>
<div class="d-flex align-items-center">
<div class="flex-grow-1" style="font-size: 1rem;">
<div><i class="bi bi-wind"></i> <span class="ms-1"> 40km/h </span></div>
<div><i class="bi bi-moisture"></i> <span class="ms-1"> 50% </span></div>
</div>
<div>
<img src="" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
The weather web service program
import cherrypy
import requests
import json
from datetime import datetime
class WeatherWebService(object):
api_key = "your_openweather_api_key"
def current_weather(self, city):
context = {}
url = "https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=metric"%(city, self.api_key)
response = requests.get(url)
data = json.loads(response.text)
if data["cod"] != "404":
context["temperature"] = str(data["main"]["temp"])
context["humidity"] = str(data["main"]["humidity"])
context["windspeed"] = str(data["wind"]["speed"]*3.6)
context["description"] = data["weather"][0]["description"]
context["city"] = data["name"]
context["country"] = data["sys"]["country"]
localtime = datetime.fromtimestamp (data["timezone"] + datetime.utcnow().timestamp())
context["datetime"] = localtime.strftime("%b/%d %H:%M")
context["urlicon"] = "http://openweathermap.org/img/wn/%s@2x.png"%(data["weather"][0]["icon"])
return context
@cherrypy.expose
def index(self, q):
data = self.current_weather(q)
if data :
context = data
else:
context = self.current_weather("Rabat")
return """
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<section class="vh-100" style="background-color: #E9F8FE;">
<div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-md-8 col-lg-6 col-xl-4">
<div class="card" style="color: #4B515D; border-radius: 35px;">
<div class="card-header">
<form class="" method="get">
<div class="input-group rounded">
<input type="search" name="q" class="form-control rounded" placeholder="City" aria-label="Search" aria-describedby="search-addon" />
<button type="submit">Search</button>
</div>
</form>
</div>
<div class="card-body p-4">
<div class="d-flex">
<h6 class="flex-grow-1">"""+context["city"]+"""/"""+context["country"]+"""</h6>
<h6>"""+context["datetime"]+"""<a href=""><i class="bi bi-arrow-clockwise"></i></a> </h6>
</div>
<div class="d-flex flex-column text-center mt-5 mb-4">
<h6 class="display-4 mb-0 font-weight-bold" style="color: #1C2331;"> """+context["temperature"]+"""°C </h6>
<span class="small" style="color: #868B94">"""+context["description"]+"""</span>
</div>
<div class="d-flex align-items-center">
<div class="flex-grow-1" style="font-size: 1rem;">
<div><i class="bi bi-wind"></i> <span class="ms-1"> """+context["windspeed"]+""" km/h </span></div>
<div><i class="bi bi-moisture"></i> <span class="ms-1"> """+context["humidity"]+"""% </span></div>
</div>
<div>
<img src=" """+context["urlicon"]+""" " alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
"""
cherrypy.quickstart(WeatherWebService())
0 comment