Skip to content

Commit

Permalink
correct errors in s3 file pathing specific to windows (#37)
Browse files Browse the repository at this point in the history
* correct errors in s3 file pathing specific to windows

* update param validation for rest endpoints
  • Loading branch information
rileyhales authored May 22, 2024
1 parent 2121219 commit 14ca779
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
author = 'Riley Hales, PhD'

# The full version, including alpha/beta/rc tags
release = '1.6.1'
release = '1.6.2'
master_doc = 'index'

# -- General configuration ---------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ channels:
- conda-forge
dependencies:
- python>=3
- cftime
- dask >=2024
- fastparquet
- HydroErr
Expand Down
2 changes: 1 addition & 1 deletion geoglows/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
'bias', 'plots', 'data', 'analyze', 'streams', 'tables', 'streamflow',
'get_metadata_table_path', 'set_metadata_table_path',
]
__version__ = '1.6.1'
__version__ = '1.6.2'
__author__ = 'Riley Hales'
__license__ = 'BSD 3-Clause Clear License'
40 changes: 23 additions & 17 deletions geoglows/_download_decorators.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import os
import warnings
from io import StringIO

import numpy as np
import pandas as pd
import requests
import s3fs
import xarray as xr
import numpy as np

from .analyze import (
simple_forecast as calc_simple_forecast,
forecast_stats as calc_forecast_stats,
)

from ._constants import (
ODP_FORECAST_S3_BUCKET_URI,
ODP_RETROSPECTIVE_S3_BUCKET_URI,
ODP_S3_BUCKET_REGION,
)
from .analyze import (
simple_forecast as calc_simple_forecast,
forecast_stats as calc_forecast_stats,
)

DEFAULT_REST_ENDPOINT = 'https://geoglows.ecmwf.int/api/'
DEFAULT_REST_ENDPOINT_VERSION = 'v2' # 'v1, v2, latest'
Expand All @@ -29,14 +27,22 @@


def _forecast(function):
def _river_id_is_iterable(river_id):
return bool(
isinstance(river_id, list) or
isinstance(river_id, tuple) or
isinstance(river_id, set) or
isinstance(river_id, np.ndarray)
)

def from_aws(*args, **kwargs):
product_name = function.__name__.replace("_", "").lower()
if product_name == 'forecastrecords':
warnings.warn('forecast_records are not available from the AWS Open Data Program.')
return from_rest(*args, **kwargs)

river_id = args[0] if len(args) > 0 else kwargs.get('river_id', '')
if river_id is None or river_id == '':
river_id = args[0] if len(args) > 0 else kwargs.get('river_id', None)
if river_id is None:
raise ValueError('River ID must be provided to retrieve forecast data.')

return_format = kwargs.get('format', 'df')
Expand All @@ -51,7 +57,7 @@ def from_aws(*args, **kwargs):
date = kwargs.get('date', False)
if not date:
zarr_vars = ['rivid', 'Qout', 'time', 'ensemble']
dates = [s3.glob(os.path.join(ODP_FORECAST_S3_BUCKET_URI, f'*.zarr/{var}')) for var in zarr_vars]
dates = [s3.glob(ODP_FORECAST_S3_BUCKET_URI + '/' + f'*.zarr/{var}') for var in zarr_vars]
dates = [set([d.split('/')[1].replace('.zarr', '') for d in date]) for date in dates]
dates = sorted(set.intersection(*dates), reverse=True)
if product_name == 'dates':
Expand Down Expand Up @@ -119,11 +125,11 @@ def from_rest(*args, **kwargs):

product_name = function.__name__.replace("_", "").lower()

river_id = args[0] if len(args) > 0 else kwargs.get('river_id', '')
if isinstance(river_id, list):
raise ValueError('Multiple river_ids are not available via REST API or on v1. '
'Use data_source="aws" for multiple river_ids.')
river_id = int(river_id) if river_id else None
river_id = args[0] if len(args) > 0 else kwargs.get('river_id', None)
if river_id is None:
raise ValueError('River ID must be provided to retrieve forecast data.')
if not isinstance(river_id, (int, np.int64, )):
raise ValueError('Multiple river_ids are not available via REST API. Provide a single 9 digit integer.')
if river_id and version == 'v2':
assert 1_000_000_000 > river_id >= 110_000_000, ValueError('River ID must be a 9 digit integer')

Expand Down Expand Up @@ -182,8 +188,8 @@ def _retrospective(function):
def main(*args, **kwargs):
product_name = function.__name__.replace("_", "-").lower()

river_id = args[0] if len(args) > 0 else kwargs.get('river_id', '')
if river_id is None or river_id == '':
river_id = args[0] if len(args) > 0 else kwargs.get('river_id', None)
if river_id is None:
raise ValueError('River ID must be provided to retrieve retrospective data.')

return_format = kwargs.get('format', 'df')
Expand Down

0 comments on commit 14ca779

Please sign in to comment.