Skip to content

Commit 3d2aa7a

Browse files
Merge pull request #29 from asfadmin/dev
aws request id, logging cleanup, asf-search bump, fix file uploads
2 parents 38a853a + 0a47f0c commit 3d2aa7a

6 files changed

Lines changed: 39 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,17 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
3434

3535
### Changed
3636
- Include wkt in error when raising in `validate_wkt()`
37+
- Specify which binary file types are allowed to be passed to lambda
3738

3839
### Added
3940
- Add dedicated dev branch for test-staging deployment
4041
- Intended Dev->Release workflow
4142
- dev -> test -> prod-staging -> prod
43+
- Added more files to integration testing endpoint
44+
- Add remaining file upload support for .zip and .shp files. All previous file formats now supported
4245

4346
### Changed
44-
- pin `asf-search` to v8.3.1, All basic Vertex dataset searches working
47+
- pin `asf-search` to v8.3.3, All basic Vertex dataset searches working
4548

4649
## [1.0.0](https://github.com/asfadmin/Discovery-SearchAPI-v3/compare/v0.1.0...v1.0.0)
4750

cdk/cdk/cdk_stack.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def __init__(self, scope: Construct, construct_id: str, staging: bool = False, *
5959
timeout=Duration.seconds(30),
6060
memory_size=5308,
6161
code=lambda_.DockerImageCode.from_image_asset(
62-
directory='..'
62+
directory='..',
63+
# build_args={'MATURITY': }
6364
),
6465
**lambda_vpc_kwargs,
6566
)
@@ -70,6 +71,7 @@ def __init__(self, scope: Construct, construct_id: str, staging: bool = False, *
7071
id=api_id,
7172
handler=search_api_lambda,
7273
proxy=True,
74+
binary_media_types=['multipart/form-data', 'application/octet-stream'],
7375
default_cors_preflight_options=apigateway.CorsOptions(
7476
allow_origins=apigateway.Cors.ALL_ORIGINS, allow_methods=apigateway.Cors.ALL_METHODS
7577
),

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ujson==5.7.0
2222
uvicorn==0.21.1
2323
watchfiles==0.19.0
2424

25-
asf_search==8.3.1
25+
asf_search==8.3.3
2626
python-json-logger==2.0.7
2727

2828
pyshp==2.1.3

src/SearchAPI/application/application.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ async def query_params(searchOptions: SearchOptsModel = Depends(process_search_r
5454
raise HTTPException(detail=repr(exc), status_code=400) from exc
5555

5656
if output.lower() == 'count':
57-
start = time.perf_counter()
5857
count=asf.search_count(opts=opts)
59-
api_logger.info(f'/services/search/param count query time {time.perf_counter()-start}')
6058
return Response(
6159
content=str(count),
6260
status_code=200,
@@ -65,10 +63,8 @@ async def query_params(searchOptions: SearchOptsModel = Depends(process_search_r
6563
)
6664

6765
if output.lower() == 'python':
68-
start = time.perf_counter()
6966
file_name, search_script = get_asf_search_script(opts)
7067

71-
api_logger.info(f'/services/search/param count query time {time.perf_counter()-start}')
7268
return Response(
7369
content=search_script,
7470
status_code=200,
@@ -79,9 +75,7 @@ async def query_params(searchOptions: SearchOptsModel = Depends(process_search_r
7975
}
8076
)
8177
try:
82-
start = time.perf_counter()
8378
results = asf.search(opts=opts)
84-
api_logger.info(f'/services/search/param query time {time.perf_counter()-start}')
8579
response_info = as_output(results, output)
8680
return Response(**response_info)
8781

@@ -102,10 +96,8 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces
10296
# Load the reference scene:
10397

10498
if output.lower() == 'python':
105-
start = time.perf_counter()
10699
file_name, search_script = get_asf_search_script(opts, reference=reference, search_endpoint='baseline')
107100

108-
api_logger.info(f'/services/search/param count query time {time.perf_counter()-start}')
109101
return Response(
110102
content=search_script,
111103
status_code=200,
@@ -116,9 +108,7 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces
116108
}
117109
)
118110
try:
119-
start = time.perf_counter()
120111
reference_product = asf.granule_search(granule_list=[reference], opts=opts)[0]
121-
api_logger.info(f'/services/search/baseline reference query time {time.perf_counter()-start}')
122112
except (KeyError, IndexError, ValueError) as exc:
123113
raise HTTPException(detail=f"Reference scene not found: {reference}", status_code=400) from exc
124114

@@ -148,9 +138,7 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces
148138
# Figure out the response params:
149139
if output.lower() == 'count':
150140
stack_opts = reference_product.get_stack_opts()
151-
start = time.perf_counter()
152141
count = asf.search_count(opts=stack_opts)
153-
api_logger.info(f'/services/search/baseline count stack query time {time.perf_counter()-start}')
154142

155143
return Response(
156144
content=str(count),
@@ -161,9 +149,7 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces
161149

162150
# Finally stream everything back:
163151
try:
164-
start = time.perf_counter()
165152
stack = reference_product.stack(opts=opts)
166-
api_logger.info(f'/services/search/baseline stack query time {time.perf_counter()-start}')
167153
response_info = as_output(stack, output)
168154
return Response(**response_info)
169155

src/SearchAPI/application/log_router.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from fastapi.routing import APIRoute
77

88
from .logger import api_logger
9-
9+
import json
1010

1111
class LoggingRoute(APIRoute):
1212
"""
@@ -39,22 +39,29 @@ def get_route_handler(self) -> Callable:
3939

4040
async def custom_route_handler(request: Request) -> Response:
4141
# Grab the AWS UUID and set it for every log:
42-
context = request.scope.get("aws.context")
43-
if context is not None:
44-
self.aws_request_id = context.aws_request_id
42+
43+
if context := request.headers.get('x-amzn-request-context'):
44+
context_object = json.loads(context)
45+
self.aws_request_id = context_object.get('requestId')
46+
4547
logging.setLogRecordFactory(self.record_factory)
4648
# Time the request itself:
4749
before = time.time()
4850
try:
4951
response: Response = await original_route_handler(request)
5052
finally:
53+
queryBody = {}
54+
if (content_type := request.headers.get('content-type')) is not None:
55+
if content_type == 'application/json':
56+
queryBody = await request.json()
5157
# What to ALWAYS log:
5258
duration = time.time() - before
5359
api_logger.info(
5460
"Query finished running.",
5561
extra={
5662
"QueryTime": duration,
5763
"QueryParams": dict(request.query_params),
64+
"QueryBody": queryBody,
5865
"Endpoint": request.scope['path'],
5966
}
6067
)

tests/integration/test_stack.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
session = asf.ASFSession()
1010

1111
cwd = os.getcwd()
12-
test_file_path= os.path.join(cwd, 'tests/integration/', 'elvey.geojson')
12+
geojson_test_file_path= os.path.join(cwd, 'tests/integration/', 'elvey.geojson')
13+
kml_test_file_path = os.path.join(cwd, 'tests/yml_tests/Resources/kmls_valid/', '3D_coords.kml')
14+
shp_test_file_path = os.path.join(cwd, 'tests/yml_tests/Resources/shps_valid/', 'NED1_F.shp')
15+
zip_test_file_path = os.path.join(cwd, 'tests/yml_tests/Resources/zips_valid/', 'NED1_F.zip')
1316

1417
basic_search_params = {
1518
'maxResults': 250,
@@ -102,9 +105,22 @@ def test_wkt_endpoint_post_json():
102105
assert response.status_code == 200, f'Non-200 status code from baseline POST endpoint (data): \nstatus code: {response.status_code}\nresponse: {response.text}'
103106

104107
### WKT FILE UPLOAD TEST
105-
def test_wkt_file_upload_endpoint():
106-
files = {'files': open(test_file_path,'rb')}
108+
def test_wkt_file_upload_endpoint_geojson():
109+
_wkt_file_upload_endpoint(geojson_test_file_path)
110+
111+
def test_wkt_file_upload_endpoint_kml():
112+
_wkt_file_upload_endpoint(kml_test_file_path)
113+
114+
def test_wkt_file_upload_endpoint_shp():
115+
_wkt_file_upload_endpoint(shp_test_file_path)
116+
117+
def test_wkt_file_upload_endpoint_zip():
118+
_wkt_file_upload_endpoint(zip_test_file_path)
119+
120+
121+
def _wkt_file_upload_endpoint(file: str):
122+
files = {'files': open(file,'rb')}
107123
response = session.post(files_wkt_endpoint, files=files)
108124
response.raise_for_status()
109125

110-
assert response.status_code == 200, f'Non-200 status code from baseline POST endpoint (data): \nstatus code: {response.status_code}\nresponse: {response.text}'
126+
assert response.status_code == 200, f'Non-200 status code from files_to_wkt endpoint for file {file.split("/")[-1]}: \nstatus code: {response.status_code}\nresponse: {response.text}'

0 commit comments

Comments
 (0)