diff --git a/CHANGELOG.md b/CHANGELOG.md index 76460a3..54ee354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ------ ## [1.0.8](https://github.com/asfadmin/Discovery-SearchAPI-v3/compare/v1.0.7...v1.0.8) ### Changed -- bump asf-search to v9.0.9 for NISAR `GUNW` and `GSLC` `processingLevel` search keyword collection aliases +- bump asf-search to v10.0.0 for NISAR `GUNW` and `GSLC` `processingLevel` search keyword collection aliases, and ARIA-S1 GUNW Stacking support ------ ## [1.0.7](https://github.com/asfadmin/Discovery-SearchAPI-v3/compare/v1.0.6...v1.0.7) diff --git a/requirements.txt b/requirements.txt index 0872825..85fc44d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,14 +17,13 @@ python-multipart>=0.0.7 PyYAML==6.0.2 rfc3986==1.5.0 sniffio==1.3.0 -typing_extensions==4.10.0 +typing_extensions>=4.10.0 ujson==5.7.0 uvicorn==0.21.1 watchfiles==0.19.0 -asf_search==9.0.9 +asf-search[asf-enumeration]==10.0.0 python-json-logger==2.0.7 -asf_enumeration pyshp==2.1.3 geopandas diff --git a/src/SearchAPI/application/__init__.py b/src/SearchAPI/application/__init__.py index 56ff4d4..f502421 100644 --- a/src/SearchAPI/application/__init__.py +++ b/src/SearchAPI/application/__init__.py @@ -2,6 +2,5 @@ from .output import * from .logger import * from .log_router import * -from .search import * from .SearchAPISession import * from .application import * \ No newline at end of file diff --git a/src/SearchAPI/application/application.py b/src/SearchAPI/application/application.py index f44fbe4..c95e6d6 100644 --- a/src/SearchAPI/application/application.py +++ b/src/SearchAPI/application/application.py @@ -15,12 +15,10 @@ from .asf_opts import process_baseline_request, process_search_request, process_wkt_request from .health import get_cmr_health from .models import BaselineSearchOptsModel, SearchOptsModel -from .output import as_output, get_asf_search_script, make_filename +from .output import as_output, get_asf_search_script from .files_to_wkt import FilesToWKT from . import constants from .SearchAPISession import SearchAPISession -from .search import get_aria_groups_for_frame, stack_aria_gunw -import time from asf_search.ASFSearchOptions.config import config as asf_config asf_config['session'] = SearchAPISession() @@ -98,19 +96,8 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces reference = searchOptions.reference request_method = searchOptions.request_method - if searchOptions.opts.dataset is not None: - if searchOptions.opts.dataset[0] == asf.DATASET.ARIA_S1_GUNW: - if output.lower() == 'count': - return Response( - content=str(len(get_aria_groups_for_frame(reference)[1])), - status_code=200, - media_type='text/html; charset=utf-8', - headers=constants.DEFAULT_HEADERS - ) - - stack = stack_aria_gunw(reference) - response_info = as_output(stack, output=output) - return Response(**response_info) + is_frame_based = searchOptions.opts.dataset is not None + # Load the reference scene: if output.lower() == 'python': @@ -125,15 +112,24 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces 'Content-Disposition': f"attachment; filename={file_name}", } ) - try: - reference_product = asf.granule_search(granule_list=[reference], opts=opts)[0] - except (KeyError, IndexError, ValueError) as exc: - raise HTTPException(detail=f"Reference scene not found: {reference}", status_code=400) from exc + + # reference_product = None + if is_frame_based and opts.dataset[0] == asf.DATASET.ARIA_S1_GUNW: + try: + reference_product = asf.search(frame=int(reference), opts=opts, maxResults=1)[0] + except (KeyError, IndexError, ValueError) as exc: + raise HTTPException(detail=f"Reference scene not found with frame: {reference}", status_code=400) from exc + + else: + try: + reference_product = asf.granule_search(granule_list=[reference], opts=opts)[0] + except (KeyError, IndexError, ValueError) as exc: + raise HTTPException(detail=f"Reference scene not found: {reference}", status_code=400) from exc try: if reference_product.get_stack_opts() is None: reference_product = asf.ASFStackableProduct(args={'umm': reference_product.umm, 'meta': reference_product.meta}, session=reference_product.session) - if not reference_product.has_baseline() or not reference_product.is_valid_reference(): + if (not reference_product.has_baseline() or not reference_product.is_valid_reference() or not reference_product.has_baseline()) and not is_frame_based: raise asf.exceptions.ASFBaselineError(f"Requested reference scene has no baseline") except (asf.exceptions.ASFBaselineError, ValueError) as exc: raise HTTPException(detail=f"Search failed to find results: {exc}", status_code=400) diff --git a/src/SearchAPI/application/models.py b/src/SearchAPI/application/models.py index c1a5e9e..38909d6 100644 --- a/src/SearchAPI/application/models.py +++ b/src/SearchAPI/application/models.py @@ -14,7 +14,7 @@ class SearchOptsModel(BaseModel): """ opts: InstanceOf[ASFSearchOptions] request_method: str # ["GET", "POST", "HEAD"] - output: Optional[str] = 'metalink' + output: str = 'metalink' merged_args: dict = {} output_types: ClassVar[list[str]] = ['metalink', 'csv', 'geojson', 'json', 'jsonlite', 'jsonlite2', 'kml', 'count', 'download', 'python'] diff --git a/src/SearchAPI/application/search.py b/src/SearchAPI/application/search.py deleted file mode 100644 index 1291adf..0000000 --- a/src/SearchAPI/application/search.py +++ /dev/null @@ -1,22 +0,0 @@ -from collections import defaultdict - -import dateparser -import asf_search as asf -from asf_search import ASFSearchResults, ASFProduct -from shapely.wkt import dumps as dump_to_wkt -from shapely import Polygon - -from asf_enumeration import aria_s1_gunw - -def stack_aria_gunw(frame_id: str): - reference, aria_groups = get_aria_groups_for_frame(frame_id) - - stack = ASFSearchResults([group.products[0] for group in aria_groups]) - target_stack, warnings = asf.baseline.get_baseline_from_stack(reference, stack) - - return target_stack - -def get_aria_groups_for_frame(frame: str) -> tuple[ASFProduct, list[aria_s1_gunw.Sentinel1Acquisition]]: - aria_frame = aria_s1_gunw.get_frame(frame_id=int(frame)) - groups = aria_s1_gunw.get_acquisitions(aria_frame) - return groups[0].products[0], groups