Skip to content

Commit

Permalink
Directly use python_cmr's temporal methods.
Browse files Browse the repository at this point in the history
Bump `python_cmr` version to make use of additional logic in
the `temporal` methods that were pushed from `earthaccess`
up to `python_cmr` itself.

Fixes #190 #330
  • Loading branch information
itcarroll authored and chuckwondo committed Apr 30, 2024
1 parent 73e7959 commit 3f43a01
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-mindeps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defaults:
shell: bash -l {0}

jobs:
test:
test-mindeps:
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down
4 changes: 1 addition & 3 deletions ci/environment-mindeps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ channels:
dependencies:
# required dependencies
- python=3.8
- python-cmr=0.9.0
- python-cmr=0.10.0
- pqdm=0.1
- requests=2.26
- s3fs=2022.11
- fsspec=2022.11
- tinynetrc=1.3.1
- multimethod=1.8
- python-dateutil=2.8.2
- importlib-resources=6.3.2
- typing-extensions=4.10.0
# test dependencies
Expand All @@ -24,7 +23,6 @@ dependencies:
- pytest-cov
- python-magic
- mypy
- types-python-dateutil
- types-requests
- types-setuptools
- ruff
Expand Down
20 changes: 9 additions & 11 deletions docs/tutorials/SSL.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,8 @@
"source": [
"granules = earthaccess.search_data(\n",
" short_name = \"SEA_SURFACE_HEIGHT_ALT_GRIDS_L4_2SATS_5DAY_6THDEG_V_JPL2205\",\n",
" temporal = (\"2017-01\",\"2018-01\"),\n",
" count = -1\n",
")\n",
"print(len(granules))"
" count = 1\n",
")"
]
},
{
Expand Down Expand Up @@ -185,10 +183,10 @@
" print(f\"Retrieving data for year: {year}\")\n",
" results = earthaccess.search_data(\n",
" doi = \"10.5067/SLREF-CDRV3\",\n",
" temporal=(f\"{year}-05\", f\"{year}-06\")\n",
" temporal=(f\"{year}-05\", f\"{year}-05\"),\n",
" count = 1,\n",
" )\n",
" if len(results)>0:\n",
" granules.append(results[0])\n",
" granules.append(results[0])\n",
"print(f\"Total granules: {len(granules)}\")"
]
},
Expand Down Expand Up @@ -259,11 +257,11 @@
"def ssl_area(lats):\n",
" \"\"\"\n",
" Calculate the area associated with a 1/6 by 1/6 degree box at latitude specified in 'lats'.\n",
" \n",
"\n",
" Parameter\n",
" ==========\n",
" lats: a list or numpy array of size N the latitudes of interest. \n",
" \n",
" lats: a list or numpy array of size N the latitudes of interest.\n",
"\n",
" Return\n",
" =======\n",
" out: Array (N) area values (unit: m^2)\n",
Expand Down Expand Up @@ -357,7 +355,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions earthaccess/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def search_datasets(count: int = -1, **kwargs: Any) -> List[DataCollection]:
* **daac**: e.g. NSIDC or PODAAC
* **provider**: particular to each DAAC, e.g. POCLOUD, LPDAAC etc.
* **temporal**: a tuple representing temporal bounds in the form
`("yyyy-mm-dd", "yyyy-mm-dd")`
`(date_from, date_to)`
* **bounding_box**: a tuple representing spatial bounds in the form
`(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat)`
Expand Down Expand Up @@ -94,7 +94,7 @@ def search_data(count: int = -1, **kwargs: Any) -> List[DataGranule]:
* **daac**: e.g. NSIDC or PODAAC
* **provider**: particular to each DAAC, e.g. POCLOUD, LPDAAC etc.
* **temporal**: a tuple representing temporal bounds in the form
`("yyyy-mm-dd", "yyyy-mm-dd")`
`(date_from, date_to)`
* **bounding_box**: a tuple representing spatial bounds in the form
`(lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat)`
Expand Down
71 changes: 25 additions & 46 deletions earthaccess/search.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import datetime as dt
from inspect import getmembers, ismethod

import dateutil.parser as parser
import requests
from typing_extensions import (
Any,
Expand Down Expand Up @@ -409,18 +408,23 @@ def daac(self, daac_short_name: str) -> Self:
@override
def temporal(
self,
date_from: Optional[Union[str, dt.datetime]] = None,
date_to: Optional[Union[str, dt.datetime]] = None,
date_from: Optional[Union[str, dt.date, dt.datetime]] = None,
date_to: Optional[Union[str, dt.date, dt.datetime]] = None,
exclude_boundary: bool = False,
) -> Self:
"""Filter by an open or closed date range. Dates can be provided as datetime
objects or ISO 8601 formatted strings. Multiple ranges can be provided by
successive calls to this method before calling execute().
"""Filter by an open or closed date range. Dates can be provided as date objects
or ISO 8601 strings. Multiple ranges can be provided by successive method calls.
???+ Tip
Giving either `datetime.date(YYYY, MM, DD)` or `"YYYY-MM-DD"` as the `date_to`
parameter includes that entire day (i.e. the time is set to `23:59:59`).
Using `datetime.datetime(YYYY, MM, DD)` is different, because `datetime.datetime`
objects have `00:00:00` as their built-in default.
Parameters:
date_from (String or Datetime object): earliest date of temporal range
date_to (String or Datetime object): latest date of temporal range
exclude_boundary (Boolean): whether or not to exclude the date_from/to in
date_from: start of temporal range
date_to: end of temporal range
exclude_boundary: whether or not to exclude the date_from/to in
the matched range.
Returns:
Expand All @@ -432,20 +436,6 @@ def temporal(
object; or `date_from` and `date_to` are both datetime objects (or
parsable as such) and `date_from` is after `date_to`.
"""
DEFAULT = dt.datetime(1979, 1, 1)
if date_from is not None and not isinstance(date_from, dt.datetime):
try:
date_from = parser.parse(date_from, default=DEFAULT).isoformat() + "Z"
except Exception:
print("The provided start date was not recognized")
date_from = ""

if date_to is not None and not isinstance(date_to, dt.datetime):
try:
date_to = parser.parse(date_to, default=DEFAULT).isoformat() + "Z"
except Exception:
print("The provided end date was not recognized")
date_to = ""

return super().temporal(date_from, date_to, exclude_boundary)

Expand Down Expand Up @@ -817,20 +807,23 @@ def debug(self, debug: bool = True) -> Self:
@override
def temporal(
self,
date_from: Optional[Union[str, dt.datetime]] = None,
date_to: Optional[Union[str, dt.datetime]] = None,
date_from: Optional[Union[str, dt.date, dt.datetime]] = None,
date_to: Optional[Union[str, dt.date, dt.datetime]] = None,
exclude_boundary: bool = False,
) -> Self:
"""Filter by an open or closed date range.
"""Filter by an open or closed date range. Dates can be provided as date objects
or ISO 8601 strings. Multiple ranges can be provided by successive method calls.
Dates can be provided as a datetime objects or ISO 8601 formatted strings.
Multiple ranges can be provided by successive calls to this method before
calling execute().
???+ Tip
Giving either `datetime.date(YYYY, MM, DD)` or `"YYYY-MM-DD"` as the `date_to`
parameter includes that entire day (i.e. the time is set to `23:59:59`).
Using `datetime.datetime(YYYY, MM, DD)` is different, because `datetime.datetime`
objects have `00:00:00` as their built-in default.
Parameters:
date_from: earliest date of temporal range
date_to: latest date of temporal range
exclude_boundary: whether to exclude the date_from/to in the matched range
date_from: start of temporal range
date_to: end of temporal range
exclude_boundary: whether to exclude the date_from and date_to in the matched range
Returns:
self
Expand All @@ -841,20 +834,6 @@ def temporal(
object; or `date_from` and `date_to` are both datetime objects (or
parsable as such) and `date_from` is after `date_to`.
"""
DEFAULT = dt.datetime(1979, 1, 1)
if date_from is not None and not isinstance(date_from, dt.datetime):
try:
date_from = parser.parse(date_from, default=DEFAULT).isoformat() + "Z"
except Exception:
print("The provided start date was not recognized")
date_from = ""

if date_to is not None and not isinstance(date_to, dt.datetime):
try:
date_to = parser.parse(date_to, default=DEFAULT).isoformat() + "Z"
except Exception:
print("The provided end date was not recognized")
date_to = ""

return super().temporal(date_from, date_to, exclude_boundary)

Expand Down
22 changes: 17 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ classifiers = [
# here, make sure to also update `ci/environment-mindeps.yaml`.
[tool.poetry.dependencies]
python = ">=3.8,<4.0"
python-cmr = ">=0.9.0"
python-cmr = ">=0.10.0"
pqdm = ">=0.1"
requests = ">=2.26"
s3fs = ">=2022.11"
fsspec = ">=2022.11"
tinynetrc = "^1.3.1"
multimethod = ">=1.8"
python-dateutil = ">=2.8.2"
kerchunk = { version = ">=0.1.2", optional = true }
dask = { version = ">=2022.1.0", optional = true }
importlib-resources = ">=6.3.2"
Expand All @@ -68,7 +67,6 @@ pymdown-extensions = ">=9.2"
pygments = ">=2.11.1"
responses = ">=0.14"
ruff = "^0.1.6"
types-python-dateutil = ">=2.8.2"
types-requests = ">=0.1"
types-setuptools = ">=0.1"
ipywidgets = ">=7.7.0"
Expand Down
6 changes: 3 additions & 3 deletions stubs/cmr/queries.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from datetime import datetime
from datetime import date, datetime
from typing import Any, Optional, SupportsFloat, Union

if sys.version_info < (3, 9):
Expand Down Expand Up @@ -48,8 +48,8 @@ class GranuleCollectionBaseQuery(Query):
def online_only(self, online_only: bool = True) -> Self: ...
def temporal(
self,
date_from: Optional[Union[str, datetime]],
date_to: Optional[Union[str, datetime]],
date_from: Optional[Union[str, date, datetime]],
date_to: Optional[Union[str, date, datetime]],
exclude_boundary: bool = False,
) -> Self: ...
def short_name(self, short_name: str) -> Self: ...
Expand Down
Loading

0 comments on commit 3f43a01

Please sign in to comment.