From d94b5d2513ef48b506cb49a9df2d5a88a1590b10 Mon Sep 17 00:00:00 2001 From: kim Date: Fri, 5 Apr 2024 11:12:09 -0800 Subject: [PATCH 01/10] ASFSession now supports restricted/hidden dataset access via creds/cookiejar auth methods --- CHANGELOG.md | 9 +++++++++ asf_search/ASFSession.py | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 474ec27f..a0918ebd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,15 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - --> +------ +## [v7.0.9](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.8...v7.0.9) +### Added +- Improved logging in `ASFSession` authentication methods + +### Changed +- `ASFSession` now allows for authorized user access to hidden/restricted CMR datasets via `auth_with_creds()` or `auth_with_cookiejar()` authentication methods (previously only supported via `auth_with_token()` method) +- `ASFSession.auth_with_token()` now authenticates directly against EDL endpoint + ------ ## [v7.0.8](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.7...v7.0.8) ### Added diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index cf1a65ae..f4f8c135 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -3,7 +3,8 @@ import requests from requests.utils import get_netrc_auth import http.cookiejar -from asf_search import __name__ as asf_name, __version__ as asf_version + +from asf_search import ASF_LOGGER, __name__ as asf_name, __version__ as asf_version from asf_search.exceptions import ASFAuthenticationError class ASFSession(requests.Session): @@ -72,11 +73,22 @@ def auth_with_creds(self, username: str, password: str): login_url = f'https://{self.edl_host}/oauth/authorize?client_id={self.edl_client_id}&response_type=code&redirect_uri=https://{self.asf_auth_host}/login' self.auth = (username, password) + + ASF_LOGGER.info(f'Attempting to login via "{login_url}"') self.get(login_url) if not self._check_auth_cookies(self.cookies.get_dict()): raise ASFAuthenticationError("Username or password is incorrect") + ASF_LOGGER.info(f'Login successful') + token = self.cookies.get_dict().get('urs-access-token') + if token is not None: + ASF_LOGGER.info(f'Acquired valid application bearer token, ASFSession will use this to validate future queries (required for accessing authorized hidden/restricted datasets)') + self.auth = None + self._update_edl_token(token=token) + else: + ASF_LOGGER.error(f"Configured ASFSession Auth Host {self.asf_auth_host} failed to return a user token. A valid token is required for accessing hidden/restricted datasets") + return self def auth_with_token(self, token: str): @@ -87,16 +99,24 @@ def auth_with_token(self, token: str): :return ASFSession: returns self for convenience """ - self.headers.update({'Authorization': 'Bearer {0}'.format(token)}) - - url = f"https://{self.cmr_host}{self.cmr_collections}" - response = self.get(url) + oauth_authorization = f"https://{self.edl_host}/oauth/tokens/user?client_id={self.edl_client_id}" + + ASF_LOGGER.info(f"Authenticating EDL token against {oauth_authorization}") + response = self.post(url=oauth_authorization, data={ + 'token': token + }) if not 200 <= response.status_code <= 299: raise ASFAuthenticationError("Invalid/Expired token passed") + ASF_LOGGER.info(f"EDL token authenticated successfully") + self._update_edl_token(token=token) + return self + def _update_edl_token(self, token: str): + self.headers.update({'Authorization': 'Bearer {0}'.format(token)}) + def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): """ Authenticates the session using a pre-existing cookiejar @@ -115,6 +135,15 @@ def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): self.cookies = cookies + token = self.cookies.get_dict().get('urs-access-token') + if token is not None: + ASF_LOGGER.info(f'Found EDL token cookie "urs-access-token" in cookiejar, attempting to validate to enable Restricted/Hidden CMR datasets access for current ASFSession') + try: + self.auth_with_token(token) + except ASFAuthenticationError: + ASF_LOGGER.warning(f'Unable to use EDL token (cookie: "urs-access-token") from cookiejar. \ + Restricted/Hidden CMR datasets will not be accessible \ + unless re-authenticated with "auth_with_creds()" or "auth_with_token()"') return self def _check_auth_cookies(self, cookies: Union[http.cookiejar.CookieJar, Dict]) -> bool: From 158b677de531aacff8d9b0162d812bb25a2f0895 Mon Sep 17 00:00:00 2001 From: kim Date: Fri, 5 Apr 2024 11:45:49 -0800 Subject: [PATCH 02/10] update token auth tests --- tests/ASFSession/test_ASFSession.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ASFSession/test_ASFSession.py b/tests/ASFSession/test_ASFSession.py index 21382372..0766cfdc 100644 --- a/tests/ASFSession/test_ASFSession.py +++ b/tests/ASFSession/test_ASFSession.py @@ -16,7 +16,7 @@ def run_auth_with_creds(username: str, password: str): def run_auth_with_token(token: str): session = ASFSession() - with patch('asf_search.ASFSession.get') as mock_token_session: + with patch('asf_search.ASFSession.post') as mock_token_session: if not token.startswith('Bearer EDL'): mock_token_session.return_value.status_code = 400 session.auth_with_token(token) @@ -43,7 +43,7 @@ def run_test_asf_session_rebuild_auth( session = ASFSession() - with patch('asf_search.ASFSession.get') as mock_token_session: + with patch('asf_search.ASFSession.post') as mock_token_session: mock_token_session.return_value.status_code = 200 session.auth_with_token("bad_token") From 3094c60398ec8b484ba42ac76298611de944a6c1 Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 8 Apr 2024 12:32:15 -0800 Subject: [PATCH 03/10] adds deprecation warning when setting `cmr_host` keyword in ASFSession --- asf_search/ASFSession.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index f4f8c135..700d3a02 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -6,6 +6,7 @@ from asf_search import ASF_LOGGER, __name__ as asf_name, __version__ as asf_version from asf_search.exceptions import ASFAuthenticationError +from warnings import warn class ASFSession(requests.Session): def __init__(self, @@ -29,7 +30,7 @@ def __init__(self, `edl_host`: the Earthdata login endpoint used by auth_with_creds(). Defaults to `asf_search.constants.INTERNAL.EDL_HOST` `edl_client_id`: The Earthdata Login client ID for this package. Defaults to `asf_search.constants.INTERNAL.EDL_CLIENT_ID` `asf_auth_host`: the ASF auth endpoint . Defaults to `asf_search.constants.INTERNAL.ASF_AUTH_HOST` - `cmr_host`: the base CMR endpoint to test EDL login tokens against. Defaults to `asf_search.constants.INTERNAL.CMR_HOST` + `cmr_host (DEPRECATED V7.0.9)`: the base CMR endpoint to test EDL login tokens against. Defaults to `asf_search.constants.INTERNAL.CMR_HOST` `cmr_collections`: the CMR endpoint path login tokens will be tested against. Defaults to `asf_search.constants.INTERNAL.CMR_COLLECTIONS` `auth_domains`: the list of authorized endpoints that are allowed to pass auth credentials. Defaults to `asf_search.constants.INTERNAL.AUTH_DOMAINS`. Authorization headers WILL NOT be stripped from the session object when redirected through these domains. `auth_cookie_names`: the list of cookie names to use when verifying with `auth_with_creds()` & `auth_with_cookiejar()` @@ -50,11 +51,18 @@ def __init__(self, self.edl_host = INTERNAL.EDL_HOST if edl_host is None else edl_host self.edl_client_id = INTERNAL.EDL_CLIENT_ID if edl_client_id is None else edl_client_id self.asf_auth_host = INTERNAL.ASF_AUTH_HOST if asf_auth_host is None else asf_auth_host - self.cmr_host = INTERNAL.CMR_HOST if cmr_host is None else cmr_host self.cmr_collections = INTERNAL.CMR_COLLECTIONS if cmr_collections is None else cmr_collections self.auth_domains = INTERNAL.AUTH_DOMAINS if auth_domains is None else auth_domains self.auth_cookie_names = INTERNAL.AUTH_COOKIES if auth_cookie_names is None else auth_cookie_names + self.cmr_host = INTERNAL.CMR_HOST + + if cmr_host is not None: + warn(f'Use of `cmr_host` keyword with `ASFSession` is deprecated for asf-search versions >= 7.0.9, and will be removed with the next major version. \ + \nTo authenticate an EDL token for a non-prod deployment of CMR, set the `edl_host` keyword instead. \ + \n(ex: session arugments for authenticating against uat: `ASFSession(edl_host="uat.urs.earthdata.nasa.gov")`)', category=DeprecationWarning, stacklevel=2) + self.cmr_host = cmr_host + def __eq__(self, other): return self.auth == other.auth \ and self.headers == other.headers \ @@ -107,13 +115,29 @@ def auth_with_token(self, token: str): }) if not 200 <= response.status_code <= 299: - raise ASFAuthenticationError("Invalid/Expired token passed") + if not self._try_legacy_token_auth(token=token): + raise ASFAuthenticationError("Invalid/Expired token passed") ASF_LOGGER.info(f"EDL token authenticated successfully") self._update_edl_token(token=token) return self + def _try_legacy_token_auth(self, token: str) -> False: + """ + Checks `cmr_host` search endpoint directly with provided token using method used in previous versions of asf-search (<7.0.9). + """ + from asf_search.constants import INTERNAL + + if self.cmr_host != INTERNAL.CMR_HOST: + self.headers.update({'Authorization': 'Bearer {0}'.format(token)}) + legacy_auth_url = f"https://{self.cmr_host}{self.cmr_collections}" + response = self.get(legacy_auth_url) + self.headers.pop('Authorization') + return 200 <= response.status_code <= 299 + + return False + def _update_edl_token(self, token: str): self.headers.update({'Authorization': 'Bearer {0}'.format(token)}) From 6891d6be6967583a67bd783ceeea307e24c8e10f Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 8 Apr 2024 15:14:09 -0800 Subject: [PATCH 04/10] fixes cookiejar auth bug, changes ASF_LOGGER.error call to ASFAuthenticationError --- asf_search/ASFSession.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index 700d3a02..9377a884 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -88,15 +88,14 @@ def auth_with_creds(self, username: str, password: str): if not self._check_auth_cookies(self.cookies.get_dict()): raise ASFAuthenticationError("Username or password is incorrect") - ASF_LOGGER.info(f'Login successful') token = self.cookies.get_dict().get('urs-access-token') - if token is not None: - ASF_LOGGER.info(f'Acquired valid application bearer token, ASFSession will use this to validate future queries (required for accessing authorized hidden/restricted datasets)') - self.auth = None - self._update_edl_token(token=token) - else: - ASF_LOGGER.error(f"Configured ASFSession Auth Host {self.asf_auth_host} failed to return a user token. A valid token is required for accessing hidden/restricted datasets") + if token is None: + raise ASFAuthenticationError(f'Provided asf_auth_host "{self.asf_auth_host}" failed to return an EDL token during ASFSession validation. "urs-access-token" cookie expected.') + self.auth = None + self._update_edl_token(token=token) + ASF_LOGGER.info(f'Login successful') + return self def auth_with_token(self, token: str): @@ -118,7 +117,7 @@ def auth_with_token(self, token: str): if not self._try_legacy_token_auth(token=token): raise ASFAuthenticationError("Invalid/Expired token passed") - ASF_LOGGER.info(f"EDL token authenticated successfully") + ASF_LOGGER.info(f"EDL token authentication successful") self._update_edl_token(token=token) return self @@ -126,6 +125,7 @@ def auth_with_token(self, token: str): def _try_legacy_token_auth(self, token: str) -> False: """ Checks `cmr_host` search endpoint directly with provided token using method used in previous versions of asf-search (<7.0.9). + This is to prevent breaking changes until next major release """ from asf_search.constants import INTERNAL @@ -150,24 +150,21 @@ def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): :return ASFSession: returns self for convenience """ - if not self._check_auth_cookies(cookies): + if not self._check_auth_cookies(dict(cookies)): raise ASFAuthenticationError("Cookiejar does not contain login cookies") for cookie in cookies: if cookie.is_expired(): raise ASFAuthenticationError("Cookiejar contains expired cookies") + token = cookies.get_dict().get('urs-access-token') + if token is None: + raise ASFAuthenticationError(f'Failed to find EDL Token in cookiejar. "urs-access-token" cookie expected.') + + ASF_LOGGER.info(f'Authenticating EDL token found in "urs-access-token" cookie') + self.auth_with_token(token) self.cookies = cookies - token = self.cookies.get_dict().get('urs-access-token') - if token is not None: - ASF_LOGGER.info(f'Found EDL token cookie "urs-access-token" in cookiejar, attempting to validate to enable Restricted/Hidden CMR datasets access for current ASFSession') - try: - self.auth_with_token(token) - except ASFAuthenticationError: - ASF_LOGGER.warning(f'Unable to use EDL token (cookie: "urs-access-token") from cookiejar. \ - Restricted/Hidden CMR datasets will not be accessible \ - unless re-authenticated with "auth_with_creds()" or "auth_with_token()"') return self def _check_auth_cookies(self, cookies: Union[http.cookiejar.CookieJar, Dict]) -> bool: From 3703364ebbc260e37e7cfde95d0f415349992874 Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 8 Apr 2024 15:17:41 -0800 Subject: [PATCH 05/10] update type hinting on ASFSession internal method --- asf_search/ASFSession.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index 9377a884..9e3a37b6 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -1,5 +1,5 @@ import platform -from typing import Dict, List, Union +from typing import Dict, List import requests from requests.utils import get_netrc_auth import http.cookiejar @@ -167,7 +167,7 @@ def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): return self - def _check_auth_cookies(self, cookies: Union[http.cookiejar.CookieJar, Dict]) -> bool: + def _check_auth_cookies(self, cookies: Dict) -> bool: return any(cookie in self.auth_cookie_names for cookie in cookies) def rebuild_auth(self, prepared_request: requests.Request, response: requests.Response): From b7848df2898427040c68331b5fd7663825bf4b15 Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 8 Apr 2024 15:51:18 -0800 Subject: [PATCH 06/10] auth_with_cookiejar test update and explicit RequestsCookieJar support --- asf_search/ASFSession.py | 12 +++++++----- tests/ASFSession/test_ASFSession.py | 7 ++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index 9e3a37b6..d070aae5 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -1,5 +1,5 @@ import platform -from typing import Dict, List +from typing import Dict, List, Union import requests from requests.utils import get_netrc_auth import http.cookiejar @@ -141,7 +141,7 @@ def _try_legacy_token_auth(self, token: str) -> False: def _update_edl_token(self, token: str): self.headers.update({'Authorization': 'Bearer {0}'.format(token)}) - def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): + def auth_with_cookiejar(self, cookies: Union[http.cookiejar.CookieJar, requests.cookies.RequestsCookieJar]): """ Authenticates the session using a pre-existing cookiejar @@ -149,8 +149,7 @@ def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): :return ASFSession: returns self for convenience """ - - if not self._check_auth_cookies(dict(cookies)): + if not self._check_auth_cookies(cookies): raise ASFAuthenticationError("Cookiejar does not contain login cookies") for cookie in cookies: @@ -167,7 +166,10 @@ def auth_with_cookiejar(self, cookies: http.cookiejar.CookieJar): return self - def _check_auth_cookies(self, cookies: Dict) -> bool: + def _check_auth_cookies(self, cookies: Union[http.cookiejar.CookieJar, requests.cookies.RequestsCookieJar]) -> bool: + if isinstance(cookies, requests.cookies.RequestsCookieJar): + cookies = dict(cookies) + return any(cookie in self.auth_cookie_names for cookie in cookies) def rebuild_auth(self, prepared_request: requests.Request, response: requests.Response): diff --git a/tests/ASFSession/test_ASFSession.py b/tests/ASFSession/test_ASFSession.py index 0766cfdc..4c560281 100644 --- a/tests/ASFSession/test_ASFSession.py +++ b/tests/ASFSession/test_ASFSession.py @@ -28,8 +28,13 @@ def run_auth_with_cookiejar(cookies: List): cookiejar = http.cookiejar.CookieJar() for cookie in cookies: cookiejar.set_cookie(create_cookie(name=cookie.pop('name'), **cookie)) + + # requests.cookies.RequestsCookieJar, which has slightly different behaviour session = ASFSession() - session.auth_with_cookiejar(cookies) + session.auth_with_cookiejar(cookiejar) + + request_cookiejar_session = ASFSession() + request_cookiejar_session.auth_with_cookiejar(session.cookies) def run_test_asf_session_rebuild_auth( original_domain: str, From 07278a69762cac38b7b58b48b4cc5e2c942f4a0e Mon Sep 17 00:00:00 2001 From: kim Date: Tue, 16 Apr 2024 16:27:24 -0800 Subject: [PATCH 07/10] use warning instead of raising error in ASFSession auth_with_creds and auth_with_token --- asf_search/ASFSession.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/asf_search/ASFSession.py b/asf_search/ASFSession.py index d070aae5..33762739 100644 --- a/asf_search/ASFSession.py +++ b/asf_search/ASFSession.py @@ -88,13 +88,17 @@ def auth_with_creds(self, username: str, password: str): if not self._check_auth_cookies(self.cookies.get_dict()): raise ASFAuthenticationError("Username or password is incorrect") + ASF_LOGGER.info(f'Login successful') + token = self.cookies.get_dict().get('urs-access-token') + if token is None: - raise ASFAuthenticationError(f'Provided asf_auth_host "{self.asf_auth_host}" failed to return an EDL token during ASFSession validation. "urs-access-token" cookie expected.') + ASF_LOGGER.warning(f'Provided asf_auth_host "{self.asf_auth_host}" returned no EDL token during ASFSession validation. EDL Token expected in "urs-access-token" cookie, required for hidden/restricted dataset access. The current session will use basic authorization.') + else: + ASF_LOGGER.info(f'Found "urs-access-token" cookie in response from auth host, using token for downloads and cmr queries.') + self.auth = None + self._update_edl_token(token=token) - self.auth = None - self._update_edl_token(token=token) - ASF_LOGGER.info(f'Login successful') return self @@ -158,10 +162,14 @@ def auth_with_cookiejar(self, cookies: Union[http.cookiejar.CookieJar, requests. token = cookies.get_dict().get('urs-access-token') if token is None: - raise ASFAuthenticationError(f'Failed to find EDL Token in cookiejar. "urs-access-token" cookie expected.') + ASF_LOGGER.warning(f'Failed to find EDL Token in cookiejar. EDL Token expected in "urs-access-token" cookie, required for hidden/restricted dataset access.') + else: + ASF_LOGGER.info(f'Authenticating EDL token found in "urs-access-token" cookie') + try: + self.auth_with_token(token) + except ASFAuthenticationError: + ASF_LOGGER.warning(f'Failed to authenticate with found EDL token found. Access to hidden/restricted cmr data may be limited.') - ASF_LOGGER.info(f'Authenticating EDL token found in "urs-access-token" cookie') - self.auth_with_token(token) self.cookies = cookies return self From 08b7a2503db17083c01cb75ff3b731db5cd975cc Mon Sep 17 00:00:00 2001 From: kim Date: Thu, 18 Apr 2024 17:10:02 -0800 Subject: [PATCH 08/10] uses ciso8601 for umm date parsing --- CHANGELOG.md | 5 +++++ asf_search/CMR/translate.py | 8 ++++++-- setup.py | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3fa10d2..486d8900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - --> +------ +## [v7.0.11](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.10...v7.0.11) +### Changed +- Uses `ciso8601` module for parsing dates from CMR response, significant performance improvement post-query + ------ ## [v7.0.10](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.9...v7.0.10) ### Added diff --git a/asf_search/CMR/translate.py b/asf_search/CMR/translate.py index 1c57de58..ff7c1053 100644 --- a/asf_search/CMR/translate.py +++ b/asf_search/CMR/translate.py @@ -10,6 +10,7 @@ from .field_map import field_map from .datasets import collections_per_platform import dateparser +import ciso8601 import logging @@ -157,8 +158,11 @@ def try_parse_date(value: str) -> Optional[str]: if value is None: return None - date = dateparser.parse(value) - + try: + date = ciso8601.parse_datetime(value) + except ValueError: + return None + if date is None: return value diff --git a/setup.py b/setup.py index d88008cf..69e29546 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,8 @@ "importlib_metadata", "numpy", "dateparser", - "tenacity == 8.2.2" + "tenacity == 8.2.2", + "ciso8601" ] test_requirements = [ From 77fe65b02c6ec2a6450f985f0dfd1a0fa44a7bd4 Mon Sep 17 00:00:00 2001 From: kim Date: Thu, 18 Apr 2024 17:11:25 -0800 Subject: [PATCH 09/10] bumps version from patch to minor release in changelog --- CHANGELOG.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 486d8900..b56cac13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,16 +26,12 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --> ------ -## [v7.0.11](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.10...v7.0.11) -### Changed -- Uses `ciso8601` module for parsing dates from CMR response, significant performance improvement post-query - ------- -## [v7.0.10](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.9...v7.0.10) +## [v7.1.0](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.9...v7.1.0) ### Added - Improved logging in `ASFSession` authentication methods ### Changed +- Uses `ciso8601` module for parsing dates from CMR response, significant performance improvement post-query - `ASFSession` now allows for authorized user access to hidden/restricted CMR datasets via `auth_with_creds()` or `auth_with_cookiejar()` authentication methods (previously only supported via `auth_with_token()` method) - `ASFSession.auth_with_token()` now authenticates directly against EDL endpoint From c2818576cd8a054b0b9e8d6dbf6fe630751349a9 Mon Sep 17 00:00:00 2001 From: kim Date: Fri, 19 Apr 2024 09:20:48 -0800 Subject: [PATCH 10/10] remove unused dateparser imports --- asf_search/CMR/translate.py | 1 - tests/ASFSearchResults/test_ASFSearchResults.py | 1 - 2 files changed, 2 deletions(-) diff --git a/asf_search/CMR/translate.py b/asf_search/CMR/translate.py index ff7c1053..d564d9c7 100644 --- a/asf_search/CMR/translate.py +++ b/asf_search/CMR/translate.py @@ -9,7 +9,6 @@ from shapely.geometry.base import BaseGeometry from .field_map import field_map from .datasets import collections_per_platform -import dateparser import ciso8601 import logging diff --git a/tests/ASFSearchResults/test_ASFSearchResults.py b/tests/ASFSearchResults/test_ASFSearchResults.py index 68e55ec2..7f80a124 100644 --- a/tests/ASFSearchResults/test_ASFSearchResults.py +++ b/tests/ASFSearchResults/test_ASFSearchResults.py @@ -1,6 +1,5 @@ from typing import Dict, List -import dateparser import asf_search as asf from asf_search import ASFSearchResults import defusedxml.ElementTree as DefusedETree