Featured image of post Learn Web Development with Python (3): Use Input and API

Learn Web Development with Python (3): Use Input and API

Use input to get user input, use API to get information on the Internet

Introduction

This is the third article in this series, which mainly introduces how to use the input box to get user input, and how to use the API to get information on the Internet.

Prerequisites

Get User Input

Add Input Box

First, we can use the <input> tag in the HTML page to create an input box. For example, we can add a form in templates/index.html to let users enter a city:

1
2
3
4
5
6
7
8
9
<section class="top-banner">
    <div class="container">
        <h1 class="heading">Weather App</h1>
        <form method="post">
            <input type="text" name="city" placeholder="Enter a city" autocomplete="off" required>
            <button type="submit">Search</button>
        </form>
    </div>
</section>

The style of the input box comes from the style.css file. This style file comes from https://webdesign.tutsplus.com/build-a-simple-weather-app-with-vanilla-javascript–cms-33893t, and the effect of the input box is as follows:

Input box

Get User Input

When the user enters the city name in the input box and clicks the “Search” button or presses the Enter key, the user’s input will be passed to the name defined in the <input> tag. We can add a POST request route in app.py to process user input. Since we have already added a route for the / path before, we only need to add a POST request for the / path:

1
2
3
4
5
6
7
@app.route('/', methods=['POST', 'GET'])
def index():
    if request.method == 'POST':
        city_name = request.form.get('city')
    else:
        #for default name 
        city_name = 'Beijing'

Here we use request.form.get('city') to get the city name entered by the user and assign it to the variable city_name.

Get Weather Information Using API

OpenWeather API

OpenWeather is a website that provides weather information. After the user registers an account, the API provided by OpenWeather can be used to obtain weather information. We can register an account at https://openweathermap.org/, and then get the API Key on the https://home.openweathermap.org/api_keys page. Here we use the free version of the API Key, which can send up to 60 requests per minute and up to 1000 requests per day. The free version is enough for me.

Get Weather Information Using API

In the previous step, we used the OpenWeather API to get weather information, but this information is returned in JSON format. In Python, we can use a dictionary to access the data in JSON and store it in the database. As for the weather information in JSON, you can check https://openweathermap.org/current#current_JSON

1
2
3
4
def get_weather(city_name):
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid={}'.format(city_name, API_KEY)
    response = urlopen(url).read()
    return json.loads(response)

Note:

  • The API_KEY here is the API Key we obtained on the OpenWeather website, and it needs to be assigned to the variable API_KEY.

  • The city name obtained earlier may contain spaces, but the OpenWeather API does not support spaces. Spaces in the OpenWeather API are replaced by +. Therefore, we need to replace the spaces in the city name with + and convert the city name to lowercase. For example, New York will be converted to new+york. We can use the following regular expression to implement this function:

    1
    
    re.sub(r"\s+", '+', str(city_name).lower())
    

Process the Weather Information Obtained

In the previous step, we used the OpenWeather API to get weather information, but this information is returned in JSON format. In Python, we can use a dictionary to access the data in JSON and store it in the database. As for the weather information in JSON, you can check https://openweathermap.org/current#current_JSON

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
data = get_weather(city_name)

db.session.add(Weather(
    name = data['name'],
    country = data['sys']['country'],
    temp = round(data['main']['temp']),
    feels_like = round(data['main']['feels_like']),
    icon = data['weather'][0]['icon'],
    description = data['weather'][0]['description'],
))
db.session.commit()

Other parts are the same as the previous code, get the weather information you want to display from the database, and then pass it to the template. The effect is as follows: Weather information

Display the Latest Weather Information

Finally, we add a slightly more complex database operation, such as displaying the latest weather information. We can add a piece of code in app.py to select the latest 4 weather information in the database, and then display them on the page:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
subquery = (
    db.session.query(
        Weather.name,
        func.max(Weather.time).label('max_time')
    )
    .group_by(Weather.name)
    .order_by(func.max(Weather.time).desc())
    .limit(4)
    .subquery()
)

query = (
    db.session.query(Weather)
    .join(subquery, and_(
        Weather.name == subquery.c.name,
        Weather.time == subquery.c.max_time
    ))
    .order_by(Weather.time.desc())
)

wd = query.all()

Note that we used a subquery of SQLAlchemy here, so we need to import from sqlalchemy.sql import func, and_. Finally, when we run the entire application, we first create the database. If the database already exists, it will not be created:

1
2
3
4
5
6
7
if __name__ == '__main__':
    with app.app_context():
        try:
            db.create_all()
        except ProgrammingError:
            pass
        app.run()

Here we also need to import related modules from sqlalchemy.exc import ProgrammingError.

Licensed under CC BY-NC-SA 4.0
Last updated on Jan 12, 2023 00:00 UTC
comments powered by Disqus