CTRLK

Set up a personalized AI-powered weather forecast delivered by SMS

|

View as Markdown

There are many use cases for combining AI and messaging, and your only limit is your imagination. This tutorial will guide you through setting up a personalized AI-powered weather report delivered by SMS every morning. You can also customize it to your liking or use the same principle for other AI-driven reports.

Prerequisites

  1. Infobip account. If you do not have one, you can easily register.
  2. Python 3.7 or higher installed on your machine.
  3. API keys for Azure OpenAI and Infobip.
  4. The following Python libraries installed:
    • openmeteo-requests
    • requests-cache
    • retry-requests
    • pandas
    • openai
    • requests
    • json
    • numpy

Implementation

Step 1: Set up an Infobip account

Create an Infobip account. After a quick registration, you will obtain your API Base URL and API key, which will enable you to send SMS messages. Make sure to write these two values down as they will be required later on.

Tutorials - SMS weather report

Step 2: Create an Azure account

Create an account with Azure and create a new GPT-4 deployment. After creating the deployment, make sure to write down your GPT endpoint URL and key.

Tutorials - SMS key and endpoint

Step 3: Draft your app

The application flow will have three main elements:

  1. Open Meteo to fetch the current weather details.
  2. Azure OpenAI to read the Open Meteo data and transform it into a personalized message.
  3. Infobip SMS API to actually send the message to the user.

Step 4: Start building your app

First, create a virtual environment and install all the dependencies that we'll use:

bash
1python3 -m venv venv
2source venv/bin/activate

After creating the virtual environment, install the dependencies:

bash
pip install openmeteo-requests requests-cache retry-requests numpy pandas openai

Step 5: Set up Open Meteo

Open Meteo is both free and doesn't require an API key, so it works out of the box. First, create a function that will accept latitude and longitude as arguments and return the daily weather forecast in JSON format. This is something that we can feed into GPT and use as a basis for a witty, personalized weather forecast:

json
1import openmeteo_requests
2import requests_cache
3import pandas as pd
4from retry_requests import retry
5 
6def get_forecast(latitude: float, longitude: float):
7 # Setup the Open-Meteo API client with cache and retry on error
8 cache_session = requests_cache.CachedSession(".cache", expire_after=3600)
9 retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
10 openmeteo = openmeteo_requests.Client(session=retry_session)
11 
12 # Make sure all required weather variables are listed here
13 url = "https://api.open-meteo.com/v1/forecast"
14 params = {
15 "latitude": latitude,
16 "longitude": longitude,
17 "hourly": [
18 "temperature_2m",
19 "rain",
20 "showers",
21 "snowfall",
22 "snow_depth",
23 "visibility"
24 ]
25 }
26 responses = openmeteo.weather_api(url, params=params)
27 
28 # Process the first location
29 response = responses[0]
30 
31 # Process hourly data
32 hourly = response.Hourly()
33 hourly_temperature_2m = hourly.Variables(0).ValuesAsNumpy()
34 hourly_rain = hourly.Variables(1).ValuesAsNumpy()
35 hourly_showers = hourly.Variables(2).ValuesAsNumpy()
36 hourly_snowfall = hourly.Variables(3).ValuesAsNumpy()
37 hourly_snow_depth = hourly.Variables(4).ValuesAsNumpy()
38 hourly_visibility = hourly.Variables(5).ValuesAsNumpy()
39 
40 hourly_data = {
41 "date": pd.date_range(
42 start=pd.to_datetime(hourly.Time(), unit="s", utc=True),
43 end=pd.to_datetime(hourly.TimeEnd(), unit="s", utc=True),
44 freq=pd.Timedelta(seconds=hourly.Interval()),
45 inclusive="left"
46 )
47 }
48 hourly_data["temperature_2m"] = hourly_temperature_2m
49 hourly_data["rain"] = hourly_rain
50 hourly_data["showers"] = hourly_showers
51 hourly_data["snowfall"] = hourly_snowfall
52 hourly_data["snow_depth"] = hourly_snow_depth
53 hourly_data["visibility"] = hourly_visibility
54 
55 hourly_dataframe = pd.DataFrame(data=hourly_data)
56 
57 return hourly_dataframe.to_json(orient="records", lines=True)

Step 6: Set up Azure OpenAI

After obtaining the weather information, start the Azure OpenAI integration. Create an AzureLLM class with two methods defined: one to send the message and the other to read the response and extract our message:

json
1import os
2from typing import List
3from openai import AzureOpenAI
4from openai.types.chat import ChatCompletion, ChatCompletionMessage
5from openai.types.chat.chat_completion import Choice
6 
7class AzureLLM:
8 def __init__(self, model: str, deployment: str):
9 super().__init__()
10 self.model = model
11 self.deployment = deployment
12 self.client = AzureOpenAI(
13 api_key=<your_key>,
14 api_version=<gpt_deployment_version_you_want_to_use>, # The latest version is 2023-10-01-preview
15 azure_endpoint="https://<your_endpoint>.openai.azure.com/"
16 )
17 
18 def send_message(self, messages: List[ChatCompletionMessage]) -> ChatCompletion:
19 response = self.client.chat.completions.create(
20 model=os.environ.get(self.model, "gpt-4-32k"),
21 messages=messages
22 )
23 return response
24 
25 def extract_response_message(self, response: ChatCompletion) -> ChatCompletionMessage:
26 # Take the first choice
27 choices: List[Choice] = response.choices
28 chosen_response: Choice = choices[0]
29 message: ChatCompletionMessage = chosen_response.message
30 return message

Step 7: Set up Infobip SMS

Finally, create a function to send an SMS message:

json
1import requests
2import json
3
4
5def send_sms(message: str):
6 r: requests.Response = requests.post(
7 url="https://ggx9k6.api.infobip.com/sms/2/text/advanced",
8 headers={
9 'Authorization': f"App <your_infobip_api_key>",
10 'Content-Type': 'application/json',
11 'Accept': 'application/json'
12 },
13 data=json.dumps({
14 "messages": [
15 {
16 "destinations": [{"to": "<your_phone_number>"}],
17 "from": "ServiceSMS",
18 "text": f"{message}"
19 }
20 ]
21 })
22 )
23 return json.dumps(r.json(), indent=4)

Step 8: Put it all together

Call these functions and introduce a descriptive prompt, instructing GPT what you would like it to do with the data that you are sending.

json
1from gpt import AzureLLM
2from forecast import get_forecast
3from infobip import send_sms
4
5# Let's check the weather forecast for Zagreb, Croatia
6forecast_data = get_forecast(latitude=45.8144, longitude=15.978)
7
8azure = AzureLLM(model="gpt-4-32k", deployment="gpt-4-32k")
9response = azure.send_message(
10 messages=[
11 {
12 "role": "system",
13 "content": f"Evaluate this weather data: {forecast_data} and send a message that would fit into a SMS.
14 It should be a greeting message for the user in the morning, instructing what the weather will be like,
15 how to dress, and what to prepare for. Make it light and funny",
16 }
17 ]
18)
19message = azure.extract_response_message(response).content
20sms_response = send_sms(message)
21print(sms_response)

Several seconds after executing this, you should receive your first weather report! You can easily schedule this to be executed every morning, using a scheduler (such as cron), or a simple script that will be running in a while loop, and only send messages at a certain time.