Lets create a simple weather App ⛈️- Part 1
Tags: tutorial, streamlit, python, beginners
Published: 2022-08-13 09:26:00

## Intro

With the help of technology, we can now track the weather with much more accuracy than ever before. By using a weather app, we can get real-time updates on the weather conditions in our area.

A weather app can be a great tool for planning your day or week. It can also help you avoid bad weather conditions. There are many different weather apps available and really useful. But why not built one?

![Weather forecast](https://media.giphy.com/media/za5xikuRr0OzK/giphy.gif)

For this project, we will be using **RapidAPI**, **WeatherAPI**, and **Streamlit**.

## What is RapidAPI?

**RapidAPI** is a platform that allows developers to easily find, connect, and use [API](https://aadarshkannan.hashnode.dev/building-qr-code-generator#heading-api)s. The platform provides a single place for developers to search for APIs, view documentation, and test APIs. RapidAPI also allows developers to manage their API keys and track their usage.

{% embed https://youtu.be/OcXEd0Qbvj0 %}

So [sign up](https://rapidapi.com/auth/sign-up) at RapidAPI or [Login](https://rapidapi.com/auth/login) to get started!


## Weather API ⛈️

This is the heart of our app. **The Weather API**!

[WeatherAPI.com](https://www.weatherapi.com/) is a powerful fully managed free weather and geolocation API provider that provides extensive APIs that range from the weather forecast, historical weather, future weather, and weather alerts, air quality data, IP lookup, and astronomy to sports, time zone, and geolocation.

We can get our credentials in two ways 
- Sign up at [WeatherAPI.com](https://www.weatherapi.com/signup.aspx) 
- Use [WeatherAPI](https://rapidapi.com/weatherapi/api/weatherapi-com/) in RapidAPI platform

I prefer using RapidAPI because we can explore all APIs in one place and we will be using it in my upcoming projects. It's up to you! 

We will be using the Realtime Weather API to get the current Weather details for the location. You can see the playground as shown below. 

[![Rapid API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g12a6ic71a7tabe4oxw3.png)](https://rapidapi.com/weatherapi/api/weatherapi-com/)


In order to use the API, click on the test endpoints.


![Get Realtime Weather API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36dn6f2qwh68by9q3874.png)

We will be using Python as our language to build our app. you can find the code snippet for each example in most of the possible languages. Select Python -> Requests. You will be able to see the code snippet as shown below. Keep it aside. We will use it later.


![Code snippet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmo8txrud7rsbdvlgo9e.png)

## Let's built it out! ⚒️

**`#01` Import necessary modules**

- [Requests](https://pypi.org/project/requests/) module - Requests is an elegant and simple HTTP library for Python, built for human beings.
- [Streamlit](https://pypi.org/project/streamlit/) module - The fastest way to build data apps in Python
- JSON - Python has a built-in package called json, which can be used to work with JSON 
data
- streamlit.components.v1 - To display an HTML string in an iframe.

```
import streamlit as st
import requests
import json
import streamlit.components.v1 as components
```

### About JSON

[JSON](https://www.json.org/json-en.html) - JavaScript Object Notation - Most famous and widely accepted data exchange format - originally specified by [Douglas Crockford](https://en.wikipedia.org/wiki/Douglas_Crockford).
Check out my thread on JSON

{% embed https://twitter.com/dotaadarsh/status/1545514799299117058 %}

**`#02` Displaying Texts**

```
st.title("Weather App") # Displays title
st.subheader("Exploring RapidAPI's weather Endpoints") # Displays subheader
```

**`#03` Setting up Weather API**

```
url = "https://weatherapi-com.p.rapidapi.com/current.json"

  headers: {
    'X-RapidAPI-Key': 'YOUR-API-KEY',
    'X-RapidAPI-Host': 'weatherapi-com.p.rapidapi.com'
  }

```

**`#04` Query** ❓

Lets get the location input from the user using the **st.text_input** function and We need to create a query param,  so we map the location with the q key with the dictionary name querystring which we will call using the GET method with the endpoint URL.

```
location = st.text_input("Enter the location", "Chennai")
querystring = {"q":{location}}
```

**`#05` GET: Get resources from the server**

We will be using the requests module which we imported earlier which has a [.request()](https://requests.readthedocs.io/en/latest/api/) method for making seven main kinds of requests to a web server. 

```
response = requests.request("GET", url, headers=headers, params=querystring)
result = response.text
```

**response.text** returns the content of the response

`#06` **Playing with JSON**

**json.loads()** method can be used to parse a valid JSON string and convert it into a Python Dictionary

```
data = json.loads(result)
```

We can visualize the json using the **st.json** function. It will help to understand what we get after the response from the server.

```
st.json(data)
```

You can use also use the [JSON Visio](https://jsonvisio.com/) tool to seamlessly visualize JSON data instantly into graphs. Try understanding the data we got from the response.


![weatherAPI_visualize](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v8dmtsbh17q6e3woqa3.png)

**`#07` Displaying data**

With the help of  [**st.columns**](https://docs.streamlit.io/library/api-reference/layout/st.columns) function we can create columns that insert containers laid out side-by-side. To add elements to the returned containers, you can use `with` notation (preferred) or just call methods directly on the returned object.

Let's access each data from JSON and display it with two side-by-side columns. 

```
col1, col2 = st.columns(2)

with col1:

    st.write(f'Name: {data["location"]["name"]}')
    st.write(f'Region: {data["location"]["region"]}')
    st.write(f'Country: {data["location"]["country"]}')
    st.write(f'Local Time: {data["location"]["localtime"]}')
    st.metric(label="wind_kph", value= f'{data["current"]["wind_kph"]}')
    st.write(f'Feels like: {data["current"]["feelslike_c"]} ℃')

with col2: 

    st.write(f'Temp in Celcius: {data["current"]["temp_c"]}')
    st.write(f'Temp in Farenheit: {data["current"]["temp_f"]}')
    st.write(f'Condition: {data["current"]["condition"]["text"]}')
    st.image(f'http:{data["current"]["condition"]["icon"]}')
    st.metric(label = "Humidity", value = f'{data["current"]["humidity"]}')
```

**`#08` Finishing up**

Displaying information using **st.info** function

```
st.info('⛅ Current weather or realtime weather API method allows a user to get up-to-date current weather information in json and xml. The data is returned as a Current Object.')
```

**components.html** works by giving you the ability to embed an iframe inside of a Streamlit app that contains your desired output.

```
components.html(
    """
    <a href="https://www.weatherapi.com/" title="Free Weather API"><img src='//cdn.weatherapi.com/v4/images/weatherapi_logo.png' alt="Weather data by WeatherAPI.com" border="0" target="_blank"></a>
    """
)
```

**`#09` Run** 🏃

Once you've created your script, say weather.py, the easiest way to run it is with a streamlit run

```
streamlit run weather.py
```

This will fire up the browser and you will be able to see the live app.

You can run this in the beginning and build your app by visualizing each element. This will help you understand quickly.

**`#10` Error** ❌

Try searching for a different location. You will see that some locations are not found and it shows an error. To tackle this issue we will use simple if else conditions. The status code will be `400` if there is no location found matching parameter 'q'. We can read the status code using the **response.status_code**. 
So if response.status_code == 400, let's indicate to the user with the help of the `st.error` function that the location is not found and try searching for a different location. 

```
if(response.status_code == 400):
    st.error("No location found matching parameter 'q', try searching for a different location.")

else:
    # rest of our code
```

![Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lv2wwazzibqrhuozwkvb.png)

## Deployment 🚀

Streamlit allows users to deploy apps freely. Check out [Deployment using streamlit](https://aadarshkannan.hashnode.dev/you-can-just-turn-data-scripts-into-apps#heading-deployment)

Wait!!! What about the credentials? It's not secure, right? It's on the code. How to secure and use it and deploy our app safely? 

### Secret Management 🔐

We all have secrets, keep them with us, and do not share unless trusted. It's the same for the apps. Whenever we sign up for API, credentials will be generated only for you. It is our purpose to take care of our secrets. 

In [streamlit cloud ☁️](https://streamlit.io/cloud), there is a feature called secrets management which helps you to store all the credentials safely without exposing them to others. You will be able to see the Secrets option in the setting of your app just like the below-shown image. 


![Streamlit secrets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpytd7lz91l093n9ju43.jpg)

We will be providing the environment variables and other secrets to our app using [TOML](https://toml.io/en/v1.0.0) format.

```
X-RapidAPI-Key = "YOUR_API_KEY"
X-RapidAPI-Host = "weatherapi-com.p.rapidapi.com"
```

How to use secrets in your Streamlit app?

We can access secrets as environment variables or by querying the **st.secrets** dict. Replace the header with st.secrets function.

Example
```
headers = {
	"X-RapidAPI-Key": st.secrets["X-RapidAPI-Key"],
	"X-RapidAPI-Host": st.secrets["X-RapidAPI-Host"]
}
```

To learn more about the secret management in streamlit -> [Secrets management - Streamlit](https://docs.streamlit.io/streamlit-cloud/get-started/deploy-an-app/connect-to-data-sources/secrets-management)

- Complete code of the app [↗️](https://github.com/dotaadarsh/streamlit-projects/blob/main/pages/%E2%9B%85weather.py)
- [Live demo 🌪️](https://dotaadarsh-streamlit-projects-app-6djlzp.streamlitapp.com/weather) of our app.

[![Weather App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uf1618w4qgke1eyidqv6.png)](https://dotaadarsh-streamlit-projects-app-6djlzp.streamlitapp.com/weather)

## References 

- [RapidAPI Account Creation and Management](https://docs.rapidapi.com/docs/account-creation-and-settings)
- [API Documentation](https://weatherapi.com/docs/)
- [JSON](https://www.json.org/json-en.html)
- [Streamlit API](https://docs.streamlit.io/library/api-reference)
- [Streamlit component](https://docs.streamlit.io/library/components/components-api)

## Conclusion 

Stay tuned for part 2 in which we will try to explore the Hourly Weather, Sports API, Astronomy API, Time Zone API, and other Weather-related endpoints.

And that's a wrap. Thanks for reading and don't forget to share your feedback. You can find me on Twitter - [@dotaadarsh](https://twitter.com/dotaadarsh). Stay tuned for more!

Stay safe 😷 Spread Love ❤️ and Keep Exploring 🚀