Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add Historical Weather Data Comparison #152

Merged
merged 17 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b04cd6f
feat(api): add get_uv_history function for retrieving historical UV data
AITMAR-TAFE Oct 21, 2024
934d174
feat(helper): add print_historical_data function.Updated
AITMAR-TAFE Oct 21, 2024
d1ebbfb
feat(helper): add print_historical_data function
AITMAR-TAFE Oct 21, 2024
ef293d1
feat: add ocean_information_history function for retrieving past wave…
AITMAR-TAFE Oct 25, 2024
8d01d4c
fix: remove unnecessary print_historical_data function and update oce…
AITMAR-TAFE Oct 26, 2024
d734495
fix: keep print_historical_data function
AITMAR-TAFE Oct 27, 2024
5e947b7
fix(api): update get_uv_history to ensure accurate UV index by removi…
AITMAR-TAFE Oct 27, 2024
8a8e206
fix(api): update ocean_information_history for accurate decimal round…
AITMAR-TAFE Oct 27, 2024
62f2d2f
docs: Add comprehensive documentation to ocean_information_history, g…
AITMAR-TAFE Oct 27, 2024
3bc2791
fix: resolve linter issues and optimize variable usage in ocean_infor…
AITMAR-TAFE Oct 27, 2024
ff8bebb
test: Add unit tests for get_uv_history, ocean_information_history, a…
AITMAR-TAFE Oct 29, 2024
ec2320a
fix: Refactor tests to standard assert statements and add docstrings …
AITMAR-TAFE Oct 29, 2024
8ef8ab7
test: Add additional tests for print_historical_data function
AITMAR-TAFE Oct 29, 2024
9f2a0ea
fix: resolve line length issues in api.py for pre-commit compliance
AITMAR-TAFE Nov 4, 2024
54230b1
fix(helper): remove default print function and update arguments for h…
AITMAR-TAFE Nov 4, 2024
8e735bc
final changes
AITMAR-TAFE Nov 4, 2024
1bc944a
Run formatter and make final adjustment to aruments as per feedback
AITMAR-TAFE Nov 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/

*.cache.sqlite
*.pyc
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ Wave Period: 9.8
| show_rain_sum / srs | Show the rain sum |
| show_precipitation_prob / spp | Show the max precipitation chance |
| hide_uv / huv | Hide uv index |
| show_past_uv | Show past uv index |
| hide_past_uv | Hide past uv index |
| show_height_history | Show past wave height index |
| hide_height_history | Hide past wave height index |
| show_direction_history | Show past wave direction index |
| hide_direction_history | Hide past wave direction index |
| show_period_history | Show past wave period index |
| hide_period_history | Hide past wave period index |
| hide_height / hh | Hide surf height |
| hide_direction / hdir | Hide Swell direction |
| hide_period / hp | Hide swell period |
Expand All @@ -73,6 +81,7 @@ Wave Period: 9.8
* `curl localhost:8000`
* `curl localhost:8000?location=new_york,hide_height,hide_wave,show_large_wave`
* `curl localhost:8000?fc=3,hdate,loc=trestles`
* `curl localhost:8000?show_past_uv,show_height_history,show_direction_history,show_period_history`

**For detailed information you can access the [help](https://github.com/ryansurf/cli-surf/blob/main/help.txt) page**

Expand Down
170 changes: 170 additions & 0 deletions src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Functions that make API calls stored here
"""

from datetime import datetime, timedelta
from http import HTTPStatus

import numpy as np
Expand All @@ -14,6 +15,8 @@

from src import helper

testing = 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider replacing the global testing flag with dependency injection or a configuration object

Global variables for testing make code harder to maintain and test. Consider passing this as a parameter or using a configuration object that can be injected into the functions.

class Config:
    def __init__(self, testing=False):
        self.testing = testing

config = Config(testing=True)



def get_coordinates(args):
"""
Expand Down Expand Up @@ -90,6 +93,76 @@
return current_uv_index


def get_uv_history(lat, long, decimal, unit="imperial"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Extract common API setup and error handling logic into a shared utility function

There's significant duplication in API setup and error handling between get_uv_history and ocean_information_history. Consider creating a shared utility function to handle these common operations.

"""
Retrieve the UV index from one year ago for specified coordinates.

This function accesses the Open-Meteo API to fetch the hourly UV index
for the given latitude and longitude. It formats the result based on the
specified decimal precision.

Args:
lat (float): Latitude of the location.
long (float): Longitude of the location.
decimal (int): Number of decimal places to round the output.
unit (str): Unit of measurement ('imperial' or 'metric').
Defaults to 'imperial'.

Returns:
str: The historical UV index rounded to the specified decimal places,
or an error message if no data is found.

API Documentation:
https://open-meteo.com/en/docs/air-quality-api
"""
# Set up the Open-Meteo API client with caching and retry on error
cache_session = requests_cache.CachedSession(".cache", expire_after=3600)
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
openmeteo = openmeteo_requests.Client(session=retry_session)

# Calculate the date one year ago and the current hour
one_year_ago = datetime.now() - timedelta(days=365)
formatted_date_one_year_ago = one_year_ago.strftime("%Y-%m-%d")
current_hour = one_year_ago.hour

# Define the API request parameters
url = "https://air-quality-api.open-meteo.com/v1/air-quality"
params = {
"latitude": lat,
"longitude": long,
"length_unit": unit,
"hourly": ["uv_index"],
"start_date": formatted_date_one_year_ago,
"end_date": formatted_date_one_year_ago,
"timezone": "auto",
}

# For testing purposes if testing equals 1 it will continue
if testing == 1:
# Attempt to fetch the UV index data from the API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Fix misleading comment in ocean_information_history

This comment incorrectly refers to UV index data when the function is actually fetching ocean data.

try:
responses = openmeteo.weather_api(url, params=params)

except ValueError:
return "No data"

Check warning on line 147 in src/api.py

View check run for this annotation

Codecov / codecov/patch

src/api.py#L147

Added line #L147 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Implement consistent error handling across functions

Different functions return different types on error ('No data' string vs list). Consider implementing a consistent error handling strategy that maintains return type consistency.

Suggested change
return "No data"
return []


# Process the first response (assuming a single location)
response = responses[0]

# Extract hourly UV index values
hourly = response.Hourly()
hourly_uv_index = hourly.Variables(0).ValuesAsNumpy()

else:
hourly_uv_index = [0.5678] * 24

# Retrieve the UV index for the current hour from one year ago
historical_uv_index = hourly_uv_index[current_hour]

# Format the result to the specified decimal precision
return f"{historical_uv_index:.{decimal}f}"


def ocean_information(lat, long, decimal, unit="imperial"):
"""
Get Ocean Data at coordinates
Expand Down Expand Up @@ -129,6 +202,84 @@
return [current_wave_height, current_wave_direction, current_wave_period]


def ocean_information_history(lat, long, decimal, unit="imperial"):
"""
Retrieve ocean data from one year ago for specified coordinates.

This function accesses the Open-Meteo API to fetch
hourly ocean data including wave height,
direction, and period for the specified latitude
and longitude. It formats the results based on the
specified decimal precision.

Args:
lat (float): Latitude of the location.
long (float): Longitude of the location.
decimal (int): Number of decimal places to round the output.
unit (str): Unit of measurement ('imperial' or 'metric').
Defaults to 'imperial'.

Returns:
list: A list containing the wave height, direction, and period rounded
to the specified decimal places,
or an error message if no data is found.

API Documentation:
https://open-meteo.com/en/docs/marine-weather-api
"""
# Set up the Open-Meteo API client with caching and retry on error
cache_session = requests_cache.CachedSession(".cache", expire_after=3600)
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
openmeteo = openmeteo_requests.Client(session=retry_session)

# Calculate the date and current hour one year ago
one_year_ago = datetime.now() - timedelta(days=365)
formatted_date_one_year_ago = one_year_ago.strftime("%Y-%m-%d")
current_hour = one_year_ago.hour # Combined calculation here

# Define the API request parameters
url = "https://marine-api.open-meteo.com/v1/marine"
params = {
"latitude": lat,
"longitude": long,
"hourly": ["wave_height", "wave_direction", "wave_period"],
"length_unit": unit,
"timezone": "auto",
"start_date": formatted_date_one_year_ago,
"end_date": formatted_date_one_year_ago,
}

# For testing purposes if testing equals 1 it will continue
if testing == 1:
# Attempt to fetch the UV index data from the API
try:
responses = openmeteo.weather_api(url, params=params)

except ValueError:
return "No data"

Check warning on line 259 in src/api.py

View check run for this annotation

Codecov / codecov/patch

src/api.py#L258-L259

Added lines #L258 - L259 were not covered by tests

# Process the first response (assuming a single location)
response = responses[0]

# Extract hourly values for the specified metrics
hourly = response.Hourly()
hourly_wave_height = hourly.Variables(0).ValuesAsNumpy()
hourly_wave_direction = hourly.Variables(1).ValuesAsNumpy()
hourly_wave_period = hourly.Variables(2).ValuesAsNumpy()

else:
hourly_wave_height = [0.5678] * 24
hourly_wave_direction = [0.5678] * 24
hourly_wave_period = [0.5678] * 24

# Retrieve data for the current hour from one year ago
return [
f"{hourly_wave_height[current_hour]:.{decimal}f}",
f"{hourly_wave_direction[current_hour]:.{decimal}f}",
f"{hourly_wave_period[current_hour]:.{decimal}f}",
]


def current_wind_temp(lat, long, decimal, temp_unit="fahrenheit"):
"""
Gathers the wind and temperature data
Expand Down Expand Up @@ -364,6 +515,7 @@
ocean_data = ocean_information(
lat, long, arguments["decimal"], arguments["unit"]
)

uv_index = get_uv(lat, long, arguments["decimal"], arguments["unit"])

wind_temp = current_wind_temp(lat, long, arguments["decimal"])
Expand All @@ -385,9 +537,27 @@
"Long": long,
"Location": arguments["city"],
"Height": ocean_data[0],
"Height one year ago": (
ocean_information_history(
lat, long, arguments["decimal"], arguments["unit"]
)[0]
),
"Swell Direction": ocean_data[1],
"Swell Direction one year ago": (
ocean_information_history(
lat, long, arguments["decimal"], arguments["unit"]
)[1]
),
"Period": ocean_data[2],
"Period one year ago": (
ocean_information_history(
lat, long, arguments["decimal"], arguments["unit"]
)[2]
),
"UV Index": uv_index,
"UV Index one year ago": (
get_uv_history(lat, long, arguments["decimal"], arguments["unit"])
),
"Air Temperature": air_temp,
"Wind Speed": wind_speed,
"Wind Direction": wind_dir,
Expand Down
32 changes: 32 additions & 0 deletions src/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ def arguments_dictionary(lat, long, city, args):
"show_wave": 1,
"show_large_wave": 0,
"show_uv": 1,
"show_past_uv": 0,
"show_height": 1,
"show_direction": 1,
"show_period": 1,
"show_height_history": 0,
"show_direction_history": 0,
"show_period_history": 0,
"show_city": 1,
"show_date": 1,
"show_air_temp": 0,
Expand Down Expand Up @@ -63,12 +67,24 @@ def set_output_values(args, arguments_dictionary): # noqa
"slw": ("show_large_wave", 1),
"hide_uv": ("show_uv", 0),
"huv": ("show_uv", 0),
"show_past_uv": ("show_past_uv", 1),
"spuv": ("show_past_uv", 1),
"hide_past_uv": ("show_past_uv", 0),
"hide_height": ("show_height", 0),
"hh": ("show_height", 0),
"show_height_history": ("show_height_history", 1),
"shh": ("show_height_history", 1),
"hide_height_history": ("show_height_history", 0),
"hide_direction": ("show_direction", 0),
"hdir": ("show_direction", 0),
"show_direction_history": ("show_direction_history", 1),
"sdh": ("show_direction_history", 1),
"hide_direction_history": ("show_direction_history", 0),
"hide_period": ("show_period", 0),
"hp": ("show_period", 0),
"show_period_history": ("show_period_history", 1),
"sph": ("show_period_history", 1),
"hide_period_history": ("show_period_history", 0),
"hide_location": ("show_city", 0),
"hl": ("show_city", 0),
"hide_date": ("show_date", 0),
Expand Down Expand Up @@ -149,9 +165,25 @@ def print_ocean_data(arguments_dict, ocean_data_dict):
# List of tuples mapping argument keys to ocean data keys and labels
mappings = [
("show_uv", "UV Index", "UV index: "),
("show_past_uv", "UV Index one year ago", "UV Index one year ago: "),
("show_height", "Height", "Wave Height: "),
(
"show_height_history",
"Height one year ago",
"Wave Height one year ago: ",
),
("show_direction", "Swell Direction", "Wave Direction: "),
(
"show_direction_history",
"Swell Direction one year ago",
"Wave Direction one year ago: ",
),
("show_period", "Period", "Wave Period: "),
(
"show_period_history",
"Period one year ago",
"Wave Period one year ago:",
),
("show_air_temp", "Air Temperature", "Air Temp: "),
("show_wind_speed", "Wind Speed", "Wind Speed: "),
("show_wind_direction", "Wind Direction", "Wind Direction: "),
Expand Down
Loading