From 45281af9c9340448e9b8c90f7fe949b5c4a3dd02 Mon Sep 17 00:00:00 2001 From: Frieder Schlesier Date: Thu, 22 Dec 2022 19:20:31 +0100 Subject: [PATCH] add README and openWeatherMap example --- README.org | 6 ++ openwheatherAPI-rust.org | 223 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 README.org create mode 100644 openwheatherAPI-rust.org diff --git a/README.org b/README.org new file mode 100644 index 0000000..0ecf30f --- /dev/null +++ b/README.org @@ -0,0 +1,6 @@ +#+title: chatgpt + +https://chat.openai.com + +I asked ChatGPT to generate some code templates for a couple of my spare time projects. + diff --git a/openwheatherAPI-rust.org b/openwheatherAPI-rust.org new file mode 100644 index 0000000..cc84017 --- /dev/null +++ b/openwheatherAPI-rust.org @@ -0,0 +1,223 @@ +* OpenWeatherMap Client + +build a tiny Rust program that collects weather data for a collection of POI of +mine and writes it into a SQLite database + +** initial prompt + +#+begin_quote +please parse OpenWeatherAPI response in rust +#+end_quote + +Accidently I used not the full name which should bei *openWeatherMap* + +Response: + +#+begin_src rust + extern crate reqwest; +extern crate serde; +extern crate serde_json; + +use serde::Deserialize; +use std::error::Error; + +#[derive(Deserialize, Debug)] +struct WeatherResponse { + main: Main, + weather: Vec, +} + +#[derive(Deserialize, Debug)] +struct Main { + temp: f64, + pressure: f64, + humidity: f64, + temp_min: f64, + temp_max: f64, +} + +#[derive(Deserialize, Debug)] +struct Weather { + id: u32, + main: String, + description: String, + icon: String, +} + +fn get_weather(city: &str) -> Result<(), Box> { + let url = format!( + "https://api.openweathermap.org/data/2.5/weather?q={}&appid={API_KEY}", + city, API_KEY=API_KEY + ); + + let mut resp = reqwest::get(&url)?; + let weather: WeatherResponse = resp.json()?; + + println!("Temperature: {}°F", weather.main.temp); + println!("Pressure: {} hPa", weather.main.pressure); + println!("Humidity: {}%", weather.main.humidity); + println!("Minimum temperature: {}°F", weather.main.temp_min); + println!("Maximum temperature: {}°F", weather.main.temp_max); + for w in weather.weather { + println!("{}: {}", w.main, w.description); + } + + Ok(()) +} +#+end_src + +#+begin_quote +This example uses the reqwest crate to make an HTTP request to the +OpenWeatherAPI and the serde and serde_json crates to parse the JSON response. + +The WeatherResponse struct represents the top-level JSON object in the response, +with fields for the main weather information and a list of weather conditions. +The Main struct represents the main weather information, with fields for +temperature, pressure, humidity, and minimum and maximum temperature. The +Weather struct represents a single weather condition, with fields for the +condition ID, main condition, description, and icon. + +The get_weather function makes a request to the OpenWeatherAPI for the given +city and parses the response into a WeatherResponse struct. It then prints out +the main weather information and the list of weather conditions. + +You'll need to replace API_KEY with your own API key, which you can get by +signing up for a free account at https://home.openweathermap.org/users/sign_up. +#+end_quote + +See how it even shows me where to get and put the API key required for the HTTP request + +** Ask for Async and SQLITE + +#+begin_quote +please use async and send the result to sqlite database +#+end_quote + +Response: + +#+begin_quote +Sure! Here's an example of how you can use async and send the result to a SQLite +database in Rust: + +First, you'll need to add the following dependencies to your Cargo.toml file: +#+end_quote + +#+begin_src toml +[dependencies] +async-std = { version = "1", features = ["attributes"] } +sqlx = { version = "0.4", features = ["macros"] } +#+end_src + +#+begin_src rust + + use async_std::task; +use sqlx::{query, query_as, Executor}; + +#[derive(Deserialize, Insertable)] +#[table_name = "weather"] +struct WeatherData { + city: String, + temperature: f64, + pressure: f64, + humidity: f64, + temp_min: f64, + temp_max: f64, + main: String, + description: String, +} + +async fn get_weather_async(city: &str, db: &mut sqlx::SqliteConnection) -> Result<(), Box> { + let url = format!( + "https://api.openweathermap.org/data/2.5/weather?q={}&appid={API_KEY}", + city, API_KEY=API_KEY + ); + + let resp: WeatherResponse = reqwest::get(&url) + .await? + .json() + .await?; + + let weather_data = WeatherData { + city: city.to_string(), + temperature: resp.main.temp, + pressure: resp.main.pressure, + humidity: resp.main.humidity, + temp_min: resp.main.temp_min, + temp_max: resp.main.temp_max, + main: resp.weather[0].main, + description: resp.weather[0].description, + }; + + query!( + "INSERT INTO weather (city, temperature, pressure, humidity, temp_min, temp_max, main, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + weather_data.city, + weather_data.temperature, + weather_data.pressure, + weather_data.humidity, + weather_data.temp_min, + weather_data.temp_max, + weather_data.main, + weather_data.description + ) + .execute(db) + .await?; + + Ok(()) +} + +#[async_std::main] +async fn main() -> Result<(), Box> { + let mut db = sqlx::SqliteConnection::connect("sqlite://./weather.db").await?; + + task::spawn(async { + get_weather_async("New York", &mut db).await.unwrap(); + }); + + task::spawn(async { + get_weather_async("London", &mut db).await.unwrap(); + }); + + task::spawn(async { + + +#+end_src + +The last part of the response is snipped here again. I assume, that the number +of token for my free account is reached here. We can probably work around that +by requesting more concise parts of the code. + +** I dont want to use the 'city' parameter + +#+begin_quote +can I use lat,lon coordinates instead of the city parameter? +#+end_quote + +Response: + +#+begin_quote +Yes, you can use latitude and longitude coordinates instead of the city +parameter to get the weather information for a specific location from the +OpenWeatherAPI. + +To do this, you'll need to modify the API request URL to include the lat and lon parameters. For example: +#+end_quote + +#+begin_src rust + let url = format!( + "https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API_KEY}", + lat=lat, lon=lon, API_KEY=API_KEY +); + +#+end_src + +#+begin_quote +Here, lat and lon are the latitude and longitude coordinates of the location you +want to get the weather information for. Make sure to replace API_KEY with your +own API key, which you can get by signing up for a free account at +https://home.openweathermap.org/users/sign_up. + +You can then use the modified URL to make the API request and parse the response +as shown in the previous example. +#+end_quote + +I like how it refers to the previous output and tells me which part to update.