Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V6.7.3 Release #252

Merged
merged 22 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a928393
adds OPERA-S1 PRODUCT_TYPE constants
Dec 19, 2023
3b7f3bb
harmonizes search/geo_search/search_count params
Dec 19, 2023
245caa7
changes instances of list validators to work with iterables in general
Dec 21, 2023
0a345f9
changes instance check to check for Iterable instance instead of just…
Dec 21, 2023
ed18378
updates parser test cases from _list to _iterable
Dec 21, 2023
47185b0
checks if iterable is sting in validator
Dec 21, 2023
b6b350a
update changelog
Dec 22, 2023
a2fc3c4
Merge pull request #249 from asfadmin/search-param-harmonization
SpicyGarlicAlbacoreRoll Dec 22, 2023
3eff6dd
Merge branch 'master' into bugfix_iterator_parsing_tuples
SpicyGarlicAlbacoreRoll Dec 22, 2023
164f29f
Merge pull request #251 from asfadmin/bugfix_iterator_parsing_tuples
SpicyGarlicAlbacoreRoll Dec 22, 2023
baeaa3c
Merge branch 'master' into opera-PRODUCT_TYPE-constants
SpicyGarlicAlbacoreRoll Dec 22, 2023
85d1521
Merge pull request #250 from asfadmin/opera-PRODUCT_TYPE-constants
SpicyGarlicAlbacoreRoll Dec 22, 2023
43541fd
Merge branch 'stable' into master
SpicyGarlicAlbacoreRoll Dec 22, 2023
a0a19bb
fixes List return typing, updates python min version, update CHANGELOG
Jan 8, 2024
c5193fd
removes 3.7 and below from classifiers in setup.py
Jan 8, 2024
78fa28f
changes instances of Iterable type hinting to Sequence
Jan 9, 2024
d410a29
update changelog
Jan 9, 2024
939b626
optimizes range() when step=1, allows ranges in lists
Jan 9, 2024
fec73b9
moves range object parser logic into method, adds valueError exception
Jan 9, 2024
2c914f5
updates type hinting with range for certain search params
Jan 9, 2024
efea8b4
simplifies range validation, removes unecessary if statement
Jan 9, 2024
a5f017e
Merge pull request #254 from asfadmin/range-object-validator-support
SpicyGarlicAlbacoreRoll Jan 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,22 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-

-->
------
## [v6.7.3](https://github.com/asfadmin/Discovery-asf_search/compare/v6.7.2...v6.7.3)
### Added
- Adds OPERA-S1 constants `RTC`, `RTC_STATIC` (RTC-STATIC), `CSLC`, `CSLC_STATIC` (CSLC-STATIC) to `PRODUCT_TYPE.py`

### Fixed
- Harmonizes `search()`, `geo_search()`, and `search_count()` parameters
- Updates python version requirement in `setup.py` to 3.8+

### Changed
- search method params with `Iterable` type hinting now changed to `Sequence`
- search method param validators updated to support `Sequence` type

------
## [v6.7.2](https://github.com/asfadmin/Discovery-asf_search/compare/v6.7.1...v6.7.2)
### Adds
### Added
- Adds constants for `dataset` keyword, under `asf_search.DATASET`
- Adds CALVAL concept-ids to 'OPERA-S1' dataset
- Adds `validityStartDate` for applicable OPERA-S1 products
Expand Down
60 changes: 32 additions & 28 deletions asf_search/ASFSearchOptions/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import datetime

import requests
from typing import Union, Tuple, TypeVar, Callable, List, Type
from typing import Union, Tuple, TypeVar, Callable, List, Type, Sequence

import math
from shapely import wkt, errors
Expand Down Expand Up @@ -93,60 +93,64 @@ def parse_float_range(value: Tuple[float, float]) -> Tuple[float, float]:
return parse_range(value, float)


# Parse and validate a list of values, using h() to validate each value: "a,b,c", "1,2,3", "1.1,2.3"
def parse_list(value: list, h) -> list:
if not isinstance(value, list):
# Parse and validate an iterable of values, using h() to validate each value: "a,b,c", "1,2,3", "1.1,2.3"
def parse_list(value: Sequence, h) -> List:
if not isinstance(value, Sequence) or isinstance(value, str):
value = [value]
try:
return [h(a) for a in value]
except ValueError as exc:
raise ValueError(f'Invalid {h.__name__} list: {exc}') from exc

# Parse and validate a list of strings: "foo,bar,baz"
def parse_string_list(value: List[str]) -> List[str]:
# Parse and validate an iterable of strings: "foo,bar,baz"
def parse_string_list(value: Sequence[str]) -> List[str]:
return parse_list(value, str)


# Parse and validate a list of integers: "1,2,3"
def parse_int_list(value: List[int]) -> List[int]:
# Parse and validate an iterable of integers: "1,2,3"
def parse_int_list(value: Sequence[int]) -> List[int]:
return parse_list(value, int)


# Parse and validate a list of floats: "1.1,2.3,4.5"
def parse_float_list(value: List[float]) -> List[float]:
# Parse and validate an iterable of floats: "1.1,2.3,4.5"
def parse_float_list(value: Sequence[float]) -> List[float]:
return parse_list(value, float)


def parse_number_or_range(value: Union[list, Tuple[number, number]], h):
def parse_number_or_range(value: Union[List, Tuple[number, number], range], h):
try:
if isinstance(value, tuple):
return parse_range(value, h)
if isinstance(value, range):
if value.step == 1:
return [value.start, value.stop]

return h(value)

except ValueError as exc:
raise ValueError(f'Invalid {h.__name__} or range: {exc}') from exc


# Parse and validate a list of numbers or number ranges, using h() to validate each value: "1,2,3-5", "1.1,1.4,5.1-6.7"
def parse_number_or_range_list(value: list, h) -> list:
if not isinstance(value, list):

# Parse and validate an iterable of numbers or number ranges, using h() to validate each value: "1,2,3-5", "1.1,1.4,5.1-6.7"
def parse_number_or_range_list(value: Sequence, h) -> List:
if not isinstance(value, Sequence) or isinstance(value, range):
value = [value]
return [parse_number_or_range(x, h) for x in value]

return [parse_number_or_range(x, h) for x in value]

# Parse and validate a list of integers or integer ranges: "1,2,3-5"
def parse_int_or_range_list(value: list) -> list:
# Parse and validate an iterable of integers or integer ranges: "1,2,3-5"
def parse_int_or_range_list(value: Sequence) -> List:
return parse_number_or_range_list(value, int)


# Parse and validate a list of float or float ranges: "1.0,2.0,3.0-5.0"
def parse_float_or_range_list(value: list) -> list:
# Parse and validate an iterable of float or float ranges: "1.0,2.0,3.0-5.0"
def parse_float_or_range_list(value: Sequence) -> List:
return parse_number_or_range_list(value, parse_float)


# Parse and validate a coordinate list
def parse_coord_list(value: List[float]) -> List[float]:
if not isinstance(value, list):
raise ValueError(f'Invalid coord list list: Must pass in a list. Got {type(value)}.')
def parse_coord_list(value: Sequence[float]) -> List[float]:
if not isinstance(value, Sequence):
raise ValueError(f'Invalid coord list list: Must pass in an iterable. Got {type(value)}.')
for coord in value:
try:
float(coord)
Expand All @@ -158,9 +162,9 @@ def parse_coord_list(value: List[float]) -> List[float]:


# Parse and validate a bbox coordinate list
def parse_bbox_list(value: List[float]) -> List[float]:
def parse_bbox_list(value: Sequence[float]) -> List[float]:
try:
# This also makes sure v is a list:
# This also makes sure v is an iterable:
value = parse_coord_list(value)
except ValueError as exc:
raise ValueError(f'Invalid bbox: {exc}') from exc
Expand All @@ -170,9 +174,9 @@ def parse_bbox_list(value: List[float]) -> List[float]:


# Parse and validate a point coordinate list
def parse_point_list(value: List[float]) -> List[float]:
def parse_point_list(value: Sequence[float]) -> List[float]:
try:
# This also makes sure v is a list:
# This also makes sure v is an iterable:
value = parse_coord_list(value)
except ValueError as exc:
raise ValueError(f'Invalid point: {exc}') from exc
Expand Down
6 changes: 6 additions & 0 deletions asf_search/constants/PRODUCT_TYPE.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,9 @@
# SEASAT
GEOTIFF = 'GEOTIFF'
# L1 provided by RADARSAT

# OPERA-S1
RTC = 'RTC'
CSLC = 'CSLC'
RTC_STATIC = 'RTC-STATIC'
CSLS_STATIC = 'CSLC-STATIC'
50 changes: 34 additions & 16 deletions asf_search/search/geo_search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Union, Iterable
from typing import Tuple, Union, Sequence
import datetime
from copy import copy

Expand All @@ -8,25 +8,43 @@


def geo_search(
intersectsWith: str,
absoluteOrbit: Iterable[Union[int, range]] = None,
asfFrame: Iterable[Union[int, range]] = None,
beamMode: Iterable[str] = None,
beamSwath: Union[str, Iterable[str]] = None,
campaign: Union[str, Iterable[str]] = None,
absoluteOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
asfFrame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
beamMode: Union[str, Sequence[str]] = None,
beamSwath: Union[str, Sequence[str]] = None,
campaign: Union[str, Sequence[str]] = None,
maxDoppler: float = None,
minDoppler: float = None,
end: Union[datetime.datetime, str] = None,
flightDirection: Iterable[str] = None,
frame: Iterable[Union[int, range]] = None,
instrument: Iterable[str] = None,
lookDirection: Iterable[str] = None,
platform: Iterable[str] = None,
polarization: Iterable[str] = None,
maxFaradayRotation: float = None,
minFaradayRotation: float = None,
flightDirection: str = None,
flightLine: str = None,
frame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
granule_list: Union[str, Sequence[str]] = None,
groupID: Union[str, Sequence[str]] = None,
insarStackId: str = None,
instrument: Union[str, Sequence[str]] = None,
intersectsWith: str = None,
lookDirection: Union[str, Sequence[str]] = None,
offNadirAngle: Union[float, Tuple[float, float], Sequence[Union[float, Tuple[float, float]]]] = None,
platform: Union[str, Sequence[str]] = None,
polarization: Union[str, Sequence[str]] = None,
processingDate: Union[datetime.datetime, str] = None,
processingLevel: Iterable[str] = None,
relativeOrbit: Iterable[Union[int, range]] = None,
processingLevel: Union[str, Sequence[str]] = None,
product_list: Union[str, Sequence[str]] = None,
relativeOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
season: Tuple[int, int] = None,
start: Union[datetime.datetime, str] = None,
absoluteBurstID: Union[int, Sequence[int]] = None,
relativeBurstID: Union[int, Sequence[int]] = None,
fullBurstID: Union[str, Sequence[str]] = None,
collections: Union[str, Sequence[str]] = None,
temporalBaselineDays: Union[str, Sequence[str]] = None,
operaBurstID: Union[str, Sequence[str]] = None,
dataset: Union[str, Sequence[str]] = None,
maxResults: int = None,
opts: ASFSearchOptions = None
opts: ASFSearchOptions = None,
) -> ASFSearchResults:
"""
Performs a geographic search using the ASF SearchAPI
Expand Down
6 changes: 3 additions & 3 deletions asf_search/search/granule_search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Iterable
from typing import Sequence
from copy import copy

from asf_search.search import search
Expand All @@ -7,8 +7,8 @@


def granule_search(
granule_list: Iterable[str],
opts: ASFSearchOptions = None,
granule_list: Sequence[str],
opts: ASFSearchOptions = None
) -> ASFSearchResults:
"""
Performs a granule name search using the ASF SearchAPI
Expand Down
4 changes: 2 additions & 2 deletions asf_search/search/product_search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Iterable
from typing import Sequence
from copy import copy

from asf_search.search import search
Expand All @@ -7,7 +7,7 @@


def product_search(
product_list: Iterable[str],
product_list: Sequence[str],
opts: ASFSearchOptions = None
) -> ASFSearchResults:
"""
Expand Down
48 changes: 24 additions & 24 deletions asf_search/search/search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Union, Iterable, Tuple
from typing import Union, Sequence, Tuple
from copy import copy
import datetime

Expand All @@ -7,41 +7,41 @@
from asf_search.search.search_generator import search_generator

def search(
absoluteOrbit: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
asfFrame: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
beamMode: Union[str, Iterable[str]] = None,
beamSwath: Union[str, Iterable[str]] = None,
campaign: Union[str, Iterable[str]] = None,
absoluteOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
asfFrame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
beamMode: Union[str, Sequence[str]] = None,
beamSwath: Union[str, Sequence[str]] = None,
campaign: Union[str, Sequence[str]] = None,
maxDoppler: float = None,
minDoppler: float = None,
end: Union[datetime.datetime, str] = None,
maxFaradayRotation: float = None,
minFaradayRotation: float = None,
flightDirection: str = None,
flightLine: str = None,
frame: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
granule_list: Union[str, Iterable[str]] = None,
groupID: Union[str, Iterable[str]] = None,
frame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
granule_list: Union[str, Sequence[str]] = None,
groupID: Union[str, Sequence[str]] = None,
insarStackId: str = None,
instrument: Union[str, Iterable[str]] = None,
instrument: Union[str, Sequence[str]] = None,
intersectsWith: str = None,
lookDirection: Union[str, Iterable[str]] = None,
offNadirAngle: Union[float, Tuple[float, float], Iterable[Union[float, Tuple[float, float]]]] = None,
platform: Union[str, Iterable[str]] = None,
polarization: Union[str, Iterable[str]] = None,
lookDirection: Union[str, Sequence[str]] = None,
offNadirAngle: Union[float, Tuple[float, float], Sequence[Union[float, Tuple[float, float]]]] = None,
platform: Union[str, Sequence[str]] = None,
polarization: Union[str, Sequence[str]] = None,
processingDate: Union[datetime.datetime, str] = None,
processingLevel: Union[str, Iterable[str]] = None,
product_list: Union[str, Iterable[str]] = None,
relativeOrbit: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
processingLevel: Union[str, Sequence[str]] = None,
product_list: Union[str, Sequence[str]] = None,
relativeOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
season: Tuple[int, int] = None,
start: Union[datetime.datetime, str] = None,
absoluteBurstID: Union[int, Iterable[int]] = None,
relativeBurstID: Union[int, Iterable[int]] = None,
fullBurstID: Union[str, Iterable[str]] = None,
collections: Union[str, Iterable[str]] = None,
temporalBaselineDays: Union[str, Iterable[str]] = None,
operaBurstID: Union[str, Iterable[str]] = None,
dataset: Union[str, Iterable[str]] = None,
absoluteBurstID: Union[int, Sequence[int]] = None,
relativeBurstID: Union[int, Sequence[int]] = None,
fullBurstID: Union[str, Sequence[str]] = None,
collections: Union[str, Sequence[str]] = None,
temporalBaselineDays: Union[str, Sequence[str]] = None,
operaBurstID: Union[str, Sequence[str]] = None,
dataset: Union[str, Sequence[str]] = None,
maxResults: int = None,
opts: ASFSearchOptions = None,
) -> ASFSearchResults:
Expand Down
41 changes: 24 additions & 17 deletions asf_search/search/search_count.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import datetime
from typing import Iterable, Tuple, Union
from typing import Sequence, Tuple, Union
from copy import copy
from asf_search.ASFSearchOptions import ASFSearchOptions
from asf_search.CMR.subquery import build_subqueries
Expand All @@ -9,34 +9,41 @@


def search_count(
absoluteOrbit: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
asfFrame: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
beamMode: Union[str, Iterable[str]] = None,
beamSwath: Union[str, Iterable[str]] = None,
campaign: Union[str, Iterable[str]] = None,
absoluteOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
asfFrame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
beamMode: Union[str, Sequence[str]] = None,
beamSwath: Union[str, Sequence[str]] = None,
campaign: Union[str, Sequence[str]] = None,
maxDoppler: float = None,
minDoppler: float = None,
end: Union[datetime.datetime, str] = None,
maxFaradayRotation: float = None,
minFaradayRotation: float = None,
flightDirection: str = None,
flightLine: str = None,
frame: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
granule_list: Union[str, Iterable[str]] = None,
groupID: Union[str, Iterable[str]] = None,
frame: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
granule_list: Union[str, Sequence[str]] = None,
groupID: Union[str, Sequence[str]] = None,
insarStackId: str = None,
instrument: Union[str, Iterable[str]] = None,
instrument: Union[str, Sequence[str]] = None,
intersectsWith: str = None,
lookDirection: Union[str, Iterable[str]] = None,
offNadirAngle: Union[float, Tuple[float, float], Iterable[Union[float, Tuple[float, float]]]] = None,
platform: Union[str, Iterable[str]] = None,
polarization: Union[str, Iterable[str]] = None,
lookDirection: Union[str, Sequence[str]] = None,
offNadirAngle: Union[float, Tuple[float, float], Sequence[Union[float, Tuple[float, float]]]] = None,
platform: Union[str, Sequence[str]] = None,
polarization: Union[str, Sequence[str]] = None,
processingDate: Union[datetime.datetime, str] = None,
processingLevel: Union[str, Iterable[str]] = None,
product_list: Union[str, Iterable[str]] = None,
relativeOrbit: Union[int, Tuple[int, int], Iterable[Union[int, Tuple[int, int]]]] = None,
processingLevel: Union[str, Sequence[str]] = None,
product_list: Union[str, Sequence[str]] = None,
relativeOrbit: Union[int, Tuple[int, int], range, Sequence[Union[int, Tuple[int, int], range]]] = None,
season: Tuple[int, int] = None,
start: Union[datetime.datetime, str] = None,
absoluteBurstID: Union[int, Sequence[int]] = None,
relativeBurstID: Union[int, Sequence[int]] = None,
fullBurstID: Union[str, Sequence[str]] = None,
collections: Union[str, Sequence[str]] = None,
temporalBaselineDays: Union[str, Sequence[str]] = None,
operaBurstID: Union[str, Sequence[str]] = None,
dataset: Union[str, Sequence[str]] = None,
maxResults: int = None,
opts: ASFSearchOptions = None,
) -> int:
Expand Down
Loading
Loading