From b854e7639d535c901c9484aab0f9e37d2473bf54 Mon Sep 17 00:00:00 2001 From: Jessica Scheick Date: Fri, 5 Jan 2024 14:36:23 -0500 Subject: [PATCH] Revert "format all code files using black (#476)" This reverts commit 3e6ab7a127525fefbf632c92557d52a1522f6a93. --- icepyx/core/APIformatting.py | 1 + icepyx/core/auth.py | 71 +++++++++++++----------------- icepyx/core/exceptions.py | 3 +- icepyx/core/icesat2data.py | 5 +-- icepyx/core/query.py | 7 +-- icepyx/core/spatial.py | 3 ++ icepyx/core/temporal.py | 8 ++++ icepyx/core/validate_inputs.py | 10 ++--- icepyx/core/variables.py | 48 ++++++++++---------- icepyx/core/visualization.py | 4 ++ icepyx/tests/conftest.py | 1 - icepyx/tests/test_APIformatting.py | 1 - icepyx/tests/test_Earthdata.py | 2 +- icepyx/tests/test_auth.py | 15 +++---- icepyx/tests/test_query.py | 1 - icepyx/tests/test_read.py | 2 + icepyx/tests/test_spatial.py | 2 + icepyx/tests/test_temporal.py | 1 - icepyx/tests/test_visualization.py | 1 + 19 files changed, 93 insertions(+), 93 deletions(-) diff --git a/icepyx/core/APIformatting.py b/icepyx/core/APIformatting.py index b5d31bdfa..55d49f84c 100644 --- a/icepyx/core/APIformatting.py +++ b/icepyx/core/APIformatting.py @@ -205,6 +205,7 @@ class Parameters: """ def __init__(self, partype, values=None, reqtype=None): + assert partype in [ "CMR", "required", diff --git a/icepyx/core/auth.py b/icepyx/core/auth.py index cf771f420..7c36126f9 100644 --- a/icepyx/core/auth.py +++ b/icepyx/core/auth.py @@ -4,16 +4,14 @@ import earthaccess - class AuthenticationError(Exception): - """ + ''' Raised when an error is encountered while authenticating Earthdata credentials - """ - + ''' pass -class EarthdataAuthMixin: +class EarthdataAuthMixin(): """ This mixin class generates the needed authentication sessions and tokens, including for NASA Earthdata cloud access. Authentication is completed using the [earthaccess library](https://nsidc.github.io/earthaccess/). @@ -23,27 +21,26 @@ class EarthdataAuthMixin: 3. Storing credentials in a .netrc file (not recommended for security reasons) More details on using these methods is available in the [earthaccess documentation](https://nsidc.github.io/earthaccess/tutorials/restricted-datasets/#auth). - This class can be inherited by any other class that requires authentication. For - example, the `Query` class inherits this one, and so a Query object has the + This class can be inherited by any other class that requires authentication. For + example, the `Query` class inherits this one, and so a Query object has the `.session` property. The method `earthdata_login()` is included for backwards compatibility. - + The class can be created without any initialization parameters, and the properties will - be populated when they are called. It can alternately be initialized with an - earthaccess.auth.Auth object, which will then be used to create a session or + be populated when they are called. It can alternately be initialized with an + earthaccess.auth.Auth object, which will then be used to create a session or s3login_credentials as they are called. - + Parameters ---------- auth : earthaccess.auth.Auth, default None Optional parameter to initialize an object with existing credentials. - + Examples -------- >>> a = EarthdataAuthMixin() >>> a.session # doctest: +SKIP >>> a.s3login_credentials # doctest: +SKIP """ - def __init__(self, auth=None): self._auth = copy.deepcopy(auth) # initializatin of session and s3 creds is not allowed because those are generated @@ -61,27 +58,25 @@ def __str__(self): @property def auth(self): - """ - Authentication object returned from earthaccess.login() which stores user authentication. - """ + ''' + Authentication object returned from earthaccess.login() which stores user authentication. + ''' # Only login the first time .auth is accessed if self._auth is None: auth = earthaccess.login() # check for a valid auth response if auth.authenticated is False: - raise AuthenticationError( - "Earthdata authentication failed. Check output for error message" - ) + raise AuthenticationError('Earthdata authentication failed. Check output for error message') else: self._auth = auth - + return self._auth @property def session(self): - """ + ''' Earthaccess session object for connecting to Earthdata resources. - """ + ''' # Only generate a session the first time .session is accessed if self._session is None: self._session = self.auth.get_session() @@ -89,26 +84,24 @@ def session(self): @property def s3login_credentials(self): - """ + ''' A dictionary which stores login credentials for AWS s3 access. This property is accessed if using AWS cloud data. - + Because s3 tokens are only good for one hour, this function will automatically check if an hour has elapsed since the last token use and generate a new token if necessary. - """ - + ''' + def set_s3_creds(): - """Store s3login creds from `auth`and reset the last updated timestamp""" + ''' Store s3login creds from `auth`and reset the last updated timestamp''' self._s3login_credentials = self.auth.get_s3_credentials(daac="NSIDC") self._s3_initial_ts = datetime.datetime.now() - + # Only generate s3login_credentials the first time credentials are accessed, or if an hour - # has passed since the last login + # has passed since the last login if self._s3login_credentials is None: set_s3_creds() - elif (datetime.datetime.now() - self._s3_initial_ts) >= datetime.timedelta( - hours=1 - ): + elif (datetime.datetime.now() - self._s3_initial_ts) >= datetime.timedelta(hours=1): set_s3_creds() return self._s3login_credentials @@ -116,7 +109,7 @@ def earthdata_login(self, uid=None, email=None, s3token=None, **kwargs) -> None: """ Authenticate with NASA Earthdata to enable data ordering and download. Credential storage details are described in the EathdataAuthMixin class section. - + **Note:** This method is maintained for backward compatibility. It is no longer required to explicitly run `.earthdata_login()`. Authentication will be performed by the module as needed when `.session` or `.s3login_credentials` are accessed. Parameters @@ -141,14 +134,12 @@ def earthdata_login(self, uid=None, email=None, s3token=None, **kwargs) -> None: """ warnings.warn( - "It is no longer required to explicitly run the `.earthdata_login()` method. Authentication will be performed by the module as needed.", - DeprecationWarning, - stacklevel=2, - ) - + "It is no longer required to explicitly run the `.earthdata_login()` method. Authentication will be performed by the module as needed.", + DeprecationWarning, stacklevel=2 + ) + if uid != None or email != None or s3token != None: warnings.warn( "The user id (uid) and/or email keyword arguments are no longer required.", - DeprecationWarning, - stacklevel=2, + DeprecationWarning, stacklevel=2 ) diff --git a/icepyx/core/exceptions.py b/icepyx/core/exceptions.py index d20bbfe61..a36a1b645 100644 --- a/icepyx/core/exceptions.py +++ b/icepyx/core/exceptions.py @@ -2,7 +2,6 @@ class DeprecationError(Exception): """ Class raised for use of functionality that is no longer supported by icepyx. """ - pass @@ -28,3 +27,5 @@ def __init__( def __str__(self): return f"{self.msgtxt}: {self.errmsg}" + + diff --git a/icepyx/core/icesat2data.py b/icepyx/core/icesat2data.py index aa35fd433..cebce4160 100644 --- a/icepyx/core/icesat2data.py +++ b/icepyx/core/icesat2data.py @@ -2,9 +2,8 @@ class Icesat2Data: - def __init__( - self, - ): + def __init__(self,): + warnings.filterwarnings("always") warnings.warn( "DEPRECATED. Please use icepyx.Query to create a download data object (all other functionality is the same)", diff --git a/icepyx/core/query.py b/icepyx/core/query.py index d857bbb3d..4ffe4c241 100644 --- a/icepyx/core/query.py +++ b/icepyx/core/query.py @@ -351,9 +351,9 @@ class Query(GenQuery, EarthdataAuthMixin): files : string, default None A placeholder for future development. Not used for any purposes yet. auth : earthaccess.auth.Auth, default None - An earthaccess authentication object. Available as an argument so an existing - earthaccess.auth.Auth object can be used for authentication. If not given, a new auth - object will be created whenever authentication is needed. + An earthaccess authentication object. Available as an argument so an existing + earthaccess.auth.Auth object can be used for authentication. If not given, a new auth + object will be created whenever authentication is needed. Returns ------- @@ -411,6 +411,7 @@ def __init__( auth=None, **kwargs, ): + # Check necessary combination of input has been specified if ( (product is None or spatial_extent is None) diff --git a/icepyx/core/spatial.py b/icepyx/core/spatial.py index c34e928ed..7702acdf2 100644 --- a/icepyx/core/spatial.py +++ b/icepyx/core/spatial.py @@ -80,6 +80,7 @@ def geodataframe(extent_type, spatial_extent, file=False, xdateline=None): # DevGoal: the crs setting and management needs to be improved elif extent_type == "polygon" and file == False: + # if spatial_extent is already a Polygon if isinstance(spatial_extent, Polygon): spatial_extent_geom = spatial_extent @@ -247,6 +248,7 @@ def validate_polygon_pairs(spatial_extent): if (spatial_extent[0][0] != spatial_extent[-1][0]) or ( spatial_extent[0][1] != spatial_extent[-1][1] ): + # Throw a warning warnings.warn( "WARNING: Polygon's first and last point's coordinates differ," @@ -434,6 +436,7 @@ def __init__(self, spatial_extent, **kwarg): # Check if spatial_extent is a list of coordinates (bounding box or polygon) if isinstance(spatial_extent, (list, np.ndarray)): + # bounding box if len(spatial_extent) == 4 and all( isinstance(i, scalar_types) for i in spatial_extent diff --git a/icepyx/core/temporal.py b/icepyx/core/temporal.py index 67f59882a..c7e2dda1c 100644 --- a/icepyx/core/temporal.py +++ b/icepyx/core/temporal.py @@ -51,6 +51,7 @@ def convert_string_to_date(date): def check_valid_date_range(start, end): + """ Helper function for checking if a date range is valid. @@ -88,6 +89,7 @@ def check_valid_date_range(start, end): def validate_times(start_time, end_time): + """ Validates the start and end times passed into __init__ and returns them as datetime.time objects. @@ -143,6 +145,7 @@ def validate_times(start_time, end_time): def validate_date_range_datestr(date_range, start_time=None, end_time=None): + """ Validates a date range provided in the form of a list of strings. @@ -187,6 +190,7 @@ def validate_date_range_datestr(date_range, start_time=None, end_time=None): def validate_date_range_datetime(date_range, start_time=None, end_time=None): + """ Validates a date range provided in the form of a list of datetimes. @@ -226,6 +230,7 @@ def validate_date_range_datetime(date_range, start_time=None, end_time=None): def validate_date_range_date(date_range, start_time=None, end_time=None): + """ Validates a date range provided in the form of a list of datetime.date objects. @@ -263,6 +268,7 @@ def validate_date_range_date(date_range, start_time=None, end_time=None): def validate_date_range_dict(date_range, start_time=None, end_time=None): + """ Validates a date range provided in the form of a dict with the following keys: @@ -324,6 +330,7 @@ def validate_date_range_dict(date_range, start_time=None, end_time=None): # if is string date elif isinstance(_start_date, str): + _start_date = convert_string_to_date(_start_date) _start_date = dt.datetime.combine(_start_date, start_time) @@ -404,6 +411,7 @@ def __init__(self, date_range, start_time=None, end_time=None): """ if len(date_range) == 2: + # date range is provided as dict of strings, dates, or datetimes if isinstance(date_range, dict): self._start, self._end = validate_date_range_dict( diff --git a/icepyx/core/validate_inputs.py b/icepyx/core/validate_inputs.py index a69f045fb..d74768eea 100644 --- a/icepyx/core/validate_inputs.py +++ b/icepyx/core/validate_inputs.py @@ -105,17 +105,15 @@ def tracks(track): return track_list - def check_s3bucket(path): """ Check if the given path is an s3 path. Raise a warning if the data being referenced is not in the NSIDC bucket """ - split_path = path.split("/") - if split_path[0] == "s3:" and split_path[2] != "nsidc-cumulus-prod-protected": + split_path = path.split('/') + if split_path[0] == 's3:' and split_path[2] != 'nsidc-cumulus-prod-protected': warnings.warn( - "s3 data being read from outside the NSIDC data bucket. Icepyx can " - "read this data, but available data lists may not be accurate.", - stacklevel=2, + 's3 data being read from outside the NSIDC data bucket. Icepyx can ' + 'read this data, but available data lists may not be accurate.', stacklevel=2 ) return path diff --git a/icepyx/core/variables.py b/icepyx/core/variables.py index 4dd5444fe..4c52003df 100644 --- a/icepyx/core/variables.py +++ b/icepyx/core/variables.py @@ -29,7 +29,7 @@ class Variables(EarthdataAuthMixin): contained in ICESat-2 products. Parameters - ---------- + ---------- vartype : string This argument is deprecated. The vartype will be inferred from data_source. One of ['order', 'file'] to indicate the source of the input variables. @@ -49,9 +49,9 @@ class Variables(EarthdataAuthMixin): wanted : dictionary, default None As avail, but for the desired list of variables auth : earthaccess.auth.Auth, default None - An earthaccess authentication object. Available as an argument so an existing - earthaccess.auth.Auth object can be used for authentication. If not given, a new auth - object will be created whenever authentication is needed. + An earthaccess authentication object. Available as an argument so an existing + earthaccess.auth.Auth object can be used for authentication. If not given, a new auth + object will be created whenever authentication is needed. """ def __init__( @@ -65,28 +65,28 @@ def __init__( auth=None, ): # Deprecation error - if vartype in ["order", "file"]: + if vartype in ['order', 'file']: raise DeprecationError( - "It is no longer required to specify the variable type `vartype`. Instead please ", - "provide either the path to a local file (arg: `path`) or the product you would ", - "like variables for (arg: `product`).", + 'It is no longer required to specify the variable type `vartype`. Instead please ', + 'provide either the path to a local file (arg: `path`) or the product you would ', + 'like variables for (arg: `product`).' ) - + if path and product: raise TypeError( - "Please provide either a path or a product. If a path is provided ", - "variables will be read from the file. If a product is provided all available ", - "variables for that product will be returned.", + 'Please provide either a path or a product. If a path is provided ', + 'variables will be read from the file. If a product is provided all available ', + 'variables for that product will be returned.' ) # initialize authentication properties EarthdataAuthMixin.__init__(self, auth=auth) - + # Set the product and version from either the input args or the file if path: self._path = val.check_s3bucket(path) # Set up auth - if self._path.startswith("s3"): + if self._path.startswith('s3'): auth = self.auth else: auth = None @@ -98,19 +98,15 @@ def __init__( self._product = is2ref._validate_product(product) # Check for valid version string # If version is not specified by the user assume the most recent version - self._version = val.prod_version( - is2ref.latest_version(self._product), version - ) + self._version = val.prod_version(is2ref.latest_version(self._product), version) else: - raise TypeError( - "Either a path or a product need to be given as input arguments." - ) - + raise TypeError('Either a path or a product need to be given as input arguments.') + self._avail = avail self.wanted = wanted # DevGoal: put some more/robust checks here to assess validity of inputs - + @property def path(self): if self._path: @@ -118,14 +114,15 @@ def path(self): else: path = None return path - + @property def product(self): return self._product - + @property def version(self): return self._version + def avail(self, options=False, internal=False): """ @@ -146,7 +143,7 @@ def avail(self, options=False, internal=False): """ if not hasattr(self, "_avail") or self._avail == None: - if not hasattr(self, "path") or self.path.startswith("s3"): + if not hasattr(self, 'path') or self.path.startswith('s3'): self._avail = is2ref._get_custom_options( self.session, self.product, self.version )["variables"] @@ -631,6 +628,7 @@ def remove(self, all=False, var_list=None, beam_list=None, keyword_list=None): for bkw in beam_list: if bkw in vpath_kws: for kw in keyword_list: + if kw in vpath_kws: self.wanted[vkey].remove(vpath) except TypeError: diff --git a/icepyx/core/visualization.py b/icepyx/core/visualization.py index 001ae178e..32c81e3e7 100644 --- a/icepyx/core/visualization.py +++ b/icepyx/core/visualization.py @@ -142,6 +142,7 @@ def __init__( cycles=None, tracks=None, ): + if query_obj: pass else: @@ -240,6 +241,7 @@ def query_icesat2_filelist(self) -> tuple: is2_file_list = [] for bbox_i in bbox_list: + try: region = ipx.Query( self.product, @@ -362,6 +364,7 @@ def request_OA_data(self, paras) -> da.array: # get data we need (with the correct date) try: + df_series = df.query(expr="date == @Date").iloc[0] beam_data = df_series.beams @@ -480,6 +483,7 @@ def viz_elevation(self) -> (hv.DynamicMap, hv.Layout): return (None,) * 2 else: + cols = ( ["lat", "lon", "elevation", "canopy", "rgt", "cycle"] if self.product == "ATL08" diff --git a/icepyx/tests/conftest.py b/icepyx/tests/conftest.py index 9ce8e4081..fca31847a 100644 --- a/icepyx/tests/conftest.py +++ b/icepyx/tests/conftest.py @@ -2,7 +2,6 @@ import pytest from unittest import mock - # PURPOSE: mock environmental variables @pytest.fixture(scope="session", autouse=True) def mock_settings_env_vars(): diff --git a/icepyx/tests/test_APIformatting.py b/icepyx/tests/test_APIformatting.py index 213c1cf8a..83e88a131 100644 --- a/icepyx/tests/test_APIformatting.py +++ b/icepyx/tests/test_APIformatting.py @@ -11,7 +11,6 @@ # CMR temporal and spatial formats --> what's the best way to compare formatted text? character by character comparison of strings? - ########## _fmt_temporal ########## def test_time_fmt(): obs = apifmt._fmt_temporal( diff --git a/icepyx/tests/test_Earthdata.py b/icepyx/tests/test_Earthdata.py index 60b92f621..8ad883e6a 100644 --- a/icepyx/tests/test_Earthdata.py +++ b/icepyx/tests/test_Earthdata.py @@ -8,7 +8,6 @@ import shutil import warnings - # PURPOSE: test different authentication methods @pytest.fixture(scope="module", autouse=True) def setup_earthdata(): @@ -66,6 +65,7 @@ def earthdata_login(uid=None, pwd=None, email=None, s3token=False) -> bool: url = "urs.earthdata.nasa.gov" mock_uid, _, mock_pwd = netrc.netrc(netrc).authenticators(url) except: + mock_uid = os.environ.get("EARTHDATA_USERNAME") mock_pwd = os.environ.get("EARTHDATA_PASSWORD") diff --git a/icepyx/tests/test_auth.py b/icepyx/tests/test_auth.py index 8507b1e40..6ac77c864 100644 --- a/icepyx/tests/test_auth.py +++ b/icepyx/tests/test_auth.py @@ -8,35 +8,30 @@ @pytest.fixture() def auth_instance(): - """ + ''' An EarthdatAuthMixin object for each of the tests. Default scope is function level, so a new instance should be created for each of the tests. - """ + ''' return EarthdataAuthMixin() - # Test that .session creates a session def test_get_session(auth_instance): assert isinstance(auth_instance.session, requests.sessions.Session) - # Test that .s3login_credentials creates a dict with the correct keys def test_get_s3login_credentials(auth_instance): assert isinstance(auth_instance.s3login_credentials, dict) - expected_keys = set( - ["accessKeyId", "secretAccessKey", "sessionToken", "expiration"] - ) + expected_keys = set(['accessKeyId', 'secretAccessKey', 'sessionToken', + 'expiration']) assert set(auth_instance.s3login_credentials.keys()) == expected_keys - # Test that earthdata_login generates an auth object def test_login_function(auth_instance): auth_instance.earthdata_login() assert isinstance(auth_instance.auth, earthaccess.auth.Auth) assert auth_instance.auth.authenticated - # Test that earthdata_login raises a warning if email is provided def test_depreciation_warning(auth_instance): with pytest.warns(DeprecationWarning): - auth_instance.earthdata_login(email="me@gmail.com") + auth_instance.earthdata_login(email='me@gmail.com') diff --git a/icepyx/tests/test_query.py b/icepyx/tests/test_query.py index 15eebfcbd..7738c424a 100644 --- a/icepyx/tests/test_query.py +++ b/icepyx/tests/test_query.py @@ -9,7 +9,6 @@ # seem to be adequately covered in docstrings; # may want to focus on testing specific queries - # ------------------------------------ # icepyx-specific tests # ------------------------------------ diff --git a/icepyx/tests/test_read.py b/icepyx/tests/test_read.py index d6727607e..018435968 100644 --- a/icepyx/tests/test_read.py +++ b/icepyx/tests/test_read.py @@ -21,6 +21,7 @@ def test_check_datasource_type(): ], ) def test_check_datasource(filepath, expect): + source_type = read._check_datasource(filepath) assert source_type == expect @@ -89,6 +90,7 @@ def test_validate_source_str_not_a_dir_or_file(): ], ) def test_check_run_fast_scandir(dir, fn_glob, expect): + (subfolders, files) = read._run_fast_scandir(dir, fn_glob) assert (sorted(subfolders), sorted(files)) == expect diff --git a/icepyx/tests/test_spatial.py b/icepyx/tests/test_spatial.py index 4d6369d9e..2666d857d 100644 --- a/icepyx/tests/test_spatial.py +++ b/icepyx/tests/test_spatial.py @@ -351,6 +351,7 @@ def test_poly_list_auto_close(): def test_poly_file_simple_one_poly(): + poly_from_file = spat.Spatial( str( Path( @@ -390,6 +391,7 @@ def test_bad_poly_inputfile_type_throws_error(): def test_gdf_from_one_bbox(): + obs = spat.geodataframe("bounding_box", [-55, 68, -48, 71]) geom = [Polygon(list(zip([-55, -55, -48, -48, -55], [68, 71, 71, 68, 68])))] exp = gpd.GeoDataFrame(geometry=geom) diff --git a/icepyx/tests/test_temporal.py b/icepyx/tests/test_temporal.py index c93b30a38..83926946e 100644 --- a/icepyx/tests/test_temporal.py +++ b/icepyx/tests/test_temporal.py @@ -235,7 +235,6 @@ def test_range_str_yyyydoy_dict_time_start_end(): # Date Range Errors - # (The following inputs are bad, testing to ensure the temporal class handles this elegantly) def test_bad_start_time_type(): with pytest.raises(AssertionError): diff --git a/icepyx/tests/test_visualization.py b/icepyx/tests/test_visualization.py index dfd41116f..0a1f2fa43 100644 --- a/icepyx/tests/test_visualization.py +++ b/icepyx/tests/test_visualization.py @@ -62,6 +62,7 @@ def test_files_in_latest_cycles(n, exp): ], ) def test_gran_paras(filename, expect): + para_list = vis.gran_paras(filename) assert para_list == expect