diff --git a/app/main.py b/app/main.py index 380e5f8..585df7a 100755 --- a/app/main.py +++ b/app/main.py @@ -17,6 +17,10 @@ from fastapi_utils.tasks import repeat_every from app.settings import * +from services.grib import Grib + +service_grib = Grib() + # App middleware = [ Middleware( @@ -37,8 +41,8 @@ async def get_test(): # check source availability # fresh one might be missing and old ones get deleted, so check yesterday's yesterday_news = datetime.now(tz=ZoneInfo("US/Eastern")) - timedelta(days=1) - url = form_gfswave_link(target_time=yesterday_news) - if not is_reachable(url): # just one should be fine + url = service_grib.form_gfswave_link(target_time=yesterday_news) + if not service_grib.is_reachable(url): # just one should be fine print(url, " is not reachable at this time") # TODO: should we actually error out? return JSONResponse(content={"status": "success"}) @@ -59,61 +63,6 @@ async def task_gc() -> None: gc.collect() -def is_reachable(url: str): - """Check if url is reachable at all with the current setup - - :param url: URL to check - :return: True if url is reachable, False otherwise - """ - if requests.head(url): - return True - return False - - -def form_gfs_link(target_time=None, prod_hour=384): - """Return well formed link to gfs data which - should be available by given time - - :param target_time: time to check, defaults to current time - :param prod_hour: forecast hour to link to, defaults to 384 - :returns: URL to gfs file - """ - if not target_time: - target_time = datetime.now( - tz=ZoneInfo("US/Eastern") - ) # noaa is located in washington - - looking_at = "atmos" - prod_hour = str(prod_hour).zfill(3) - - date_str = target_time.strftime("%Y%m%d") - hour_str = str((target_time.hour // 6) * 6).zfill(2) - target_url = f"https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.{date_str}/{hour_str}/{looking_at}/gfs.t{hour_str}z.pgrb2.0p25.f{prod_hour}" - return target_url - - -def form_gfswave_link(target_time=None, prod_hour=384): - """Return well formed link to gfs data which - should be available by given time - - :param target_time: time to check, defaults to current time - :param prod_hour: forecast hour to link to, defaults to 384 - :returns: URL to gfs file - """ - if not target_time: - target_time = datetime.now( - tz=ZoneInfo("US/Eastern") - ) # noaa is located in washington - - looking_at = "wave" - prod_hour = str(prod_hour).zfill(3) - - date_str = target_time.strftime("%Y%m%d") - hour_str = str((target_time.hour // 6) * 6).zfill(2) - target_url = f"https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.{date_str}/{hour_str}/{looking_at}/gridded/gfs{looking_at}.t{hour_str}z.global.0p25.f{prod_hour}.grib2" - return target_url - - def fresh_grib_time(target_time=None): """Find most recent available GRIB file for GFS atmospheric and GFSWave forecasts @@ -132,9 +81,13 @@ def fresh_grib_time(target_time=None): fallback_hours = fallback * 6 target_time = target_time - timedelta(hours=fallback_hours) - if not is_reachable(form_gfs_link(target_time=target_time, prod_hour=384)): + if not service_grib.is_reachable( + service_grib.form_gfs_link(target_time=target_time, prod_hour=384) + ): continue - if not is_reachable(form_gfswave_link(target_time=target_time, prod_hour=384)): + if not service_grib.is_reachable( + service_grib.form_gfswave_link(target_time=target_time, prod_hour=384) + ): continue break else: @@ -151,8 +104,10 @@ def download_fresh_grib(target_time, prod_hour=0): :param prod_hour: download forecast for this hour :returns: filenames where GRIB files are downloaded to """ - gfs_atmos = form_gfs_link(target_time=target_time, prod_hour=prod_hour) - gfs_wave = form_gfswave_link(target_time=target_time, prod_hour=prod_hour) + gfs_atmos = service_grib.form_gfs_link(target_time=target_time, prod_hour=prod_hour) + gfs_wave = service_grib.form_gfswave_link( + target_time=target_time, prod_hour=prod_hour + ) return ( wget.download(gfs_atmos, out=SAVE_DIR), diff --git a/services/__init__.py b/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/grib/__init__.py b/services/grib/__init__.py new file mode 100644 index 0000000..c2a71b5 --- /dev/null +++ b/services/grib/__init__.py @@ -0,0 +1 @@ +from .service import Grib diff --git a/services/grib/service.py b/services/grib/service.py new file mode 100644 index 0000000..1fe8fc9 --- /dev/null +++ b/services/grib/service.py @@ -0,0 +1,58 @@ +import requests + + +class Grib: + @staticmethod + def is_reachable(url: str): + """Check if url is reachable at all with the current setup + + :param url: URL to check + :return: True if url is reachable, False otherwise + """ + if requests.head(url): + return True + return False + + @staticmethod + def form_gfs_link(target_time=None, prod_hour=384): + """Return well formed link to gfs data which + should be available by given time + + :param target_time: time to check, defaults to current time + :param prod_hour: forecast hour to link to, defaults to 384 + :returns: URL to gfs file + """ + if not target_time: + target_time = datetime.now( + tz=ZoneInfo("US/Eastern") + ) # noaa is located in washington + + looking_at = "atmos" + prod_hour = str(prod_hour).zfill(3) + + date_str = target_time.strftime("%Y%m%d") + hour_str = str((target_time.hour // 6) * 6).zfill(2) + target_url = f"https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.{date_str}/{hour_str}/{looking_at}/gfs.t{hour_str}z.pgrb2.0p25.f{prod_hour}" + return target_url + + @staticmethod + def form_gfswave_link(target_time=None, prod_hour=384): + """Return well formed link to gfs data which + should be available by given time + + :param target_time: time to check, defaults to current time + :param prod_hour: forecast hour to link to, defaults to 384 + :returns: URL to gfs file + """ + if not target_time: + target_time = datetime.now( + tz=ZoneInfo("US/Eastern") + ) # noaa is located in washington + + looking_at = "wave" + prod_hour = str(prod_hour).zfill(3) + + date_str = target_time.strftime("%Y%m%d") + hour_str = str((target_time.hour // 6) * 6).zfill(2) + target_url = f"https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.{date_str}/{hour_str}/{looking_at}/gridded/gfs{looking_at}.t{hour_str}z.global.0p25.f{prod_hour}.grib2" + return target_url