File size: 5,976 Bytes
243f395 f2a79fa 3dbe011 dcc25fd 43d87b3 150cbc9 c6054f0 dcc25fd f2a79fa 7d6e00c 5b88544 fa76f5f dcc25fd 43d87b3 243f395 7d6e00c dcc25fd fa76f5f f2a79fa 3dbe011 7d6e00c f2a79fa 7d6e00c f2a79fa 4d26ef2 ee50e01 7d6e00c 150cbc9 6f1250c 7d6e00c ddb71db 8c1934b 150cbc9 4d26ef2 150cbc9 f2a79fa dcc25fd 43d87b3 6d1f220 4d26ef2 6d1f220 4d26ef2 9271aef 4d26ef2 9271aef 5b88544 b241742 4d26ef2 b241742 4d26ef2 b241742 5b88544 6d1f220 4d26ef2 dcc25fd 9271aef 43d87b3 9271aef 43d87b3 3dbe011 7d6e00c f2a79fa 6f1250c 7d6e00c 6f1250c c6054f0 dcc25fd 43d87b3 b241742 4d26ef2 43d87b3 6d1f220 5b88544 9271aef 7d6e00c 43d87b3 ee50e01 43d87b3 ee50e01 f2a79fa 7d6e00c f2a79fa dcc25fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
import json
import time
from http import HTTPStatus
from typing import Dict, List
from aws_lambda_powertools.event_handler import content_types
from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools.utilities.parser import BaseModel
from src import app_logger
from src.io.coordinates_pixel_conversion import get_latlng_to_pixel_coordinates
from src.prediction_api.predictors import samexporter_predict
from src.utilities.constants import CUSTOM_RESPONSE_MESSAGES, DEFAULT_LOG_LEVEL
from src.utilities.utilities import base64_decode
list_float = List[float]
llist_float = List[list_float]
class LatLngDict(BaseModel):
lat: float
lng: float
class RawBBox(BaseModel):
ne: LatLngDict
sw: LatLngDict
class RawPrompt(BaseModel):
type: str
data: LatLngDict
label: int = 0
class RawRequestInput(BaseModel):
bbox: RawBBox
prompt: RawPrompt
zoom: int | float
source_type: str = "Satellite"
class ParsedPrompt(BaseModel):
type: str
data: llist_float
label: int = 0
class ParsedRequestInput(BaseModel):
bbox: llist_float
prompt: ParsedPrompt
zoom: int | float
def get_response(status: int, start_time: float, request_id: str, response_body: Dict = None) -> str:
"""
Return a response for frontend clients.
Args:
status: status response
start_time: request start time (float)
request_id: str
response_body: dict we embed into our response
Returns:
str: json response
"""
app_logger.debug(f"response_body:{response_body}.")
response_body["duration_run"] = time.time() - start_time
response_body["message"] = CUSTOM_RESPONSE_MESSAGES[status]
response_body["request_id"] = request_id
response = {
"statusCode": status,
"header": {"Content-Type": content_types.APPLICATION_JSON},
"body": json.dumps(response_body),
"isBase64Encoded": False
}
app_logger.debug(f"response type:{type(response)} => {response}.")
return json.dumps(response)
def get_parsed_bbox_points(request_input: RawRequestInput) -> Dict:
app_logger.info(f"try to parsing input request {request_input}...")
bbox = request_input["bbox"]
app_logger.debug(f"request bbox: {type(bbox)}, value:{bbox}.")
ne = bbox["ne"]
sw = bbox["sw"]
app_logger.debug(f"request ne: {type(ne)}, value:{ne}.")
app_logger.debug(f"request sw: {type(sw)}, value:{sw}.")
ne_latlng = [float(ne["lat"]), float(ne["lng"])]
sw_latlng = [float(sw["lat"]), float(sw["lng"])]
bbox = [ne_latlng, sw_latlng]
zoom = int(request_input["zoom"])
for prompt in request_input["prompt"]:
app_logger.debug(f"current prompt: {type(prompt)}, value:{prompt}.")
data = prompt["data"]
if prompt["type"] == "point":
current_point = get_latlng_to_pixel_coordinates(ne, sw, data, zoom, "point")
app_logger.debug(f"current prompt: {type(current_point)}, value:{current_point}.")
new_prompt_data = [current_point['x'], current_point['y']]
app_logger.debug(f"new_prompt_data: {type(new_prompt_data)}, value:{new_prompt_data}.")
prompt["data"] = new_prompt_data
else:
raise ValueError("valid prompt type is only 'point'")
app_logger.debug(f"bbox => {bbox}.")
app_logger.debug(f'request_input-prompt updated => {request_input["prompt"]}.')
app_logger.info(f"unpacking elaborated {request_input}...")
return {
"bbox": bbox,
"prompt": request_input["prompt"],
"zoom": zoom
}
def lambda_handler(event: dict, context: LambdaContext):
app_logger.info(f"start with aws_request_id:{context.aws_request_id}.")
start_time = time.time()
if "version" in event:
app_logger.info(f"event version: {event['version']}.")
try:
body = get_parsed_request_body(context, event)
try:
prompt_latlng = body["prompt"]
app_logger.debug(f"prompt_latlng:{prompt_latlng}.")
body_request = get_parsed_bbox_points(body)
app_logger.info(f"body_request=> {type(body_request)}, {body_request}.")
body_response = samexporter_predict(body_request["bbox"], body_request["prompt"], body_request["zoom"])
app_logger.info(f"output body_response:{body_response}.")
response = get_response(HTTPStatus.OK.value, start_time, context.aws_request_id, body_response)
except Exception as ex2:
app_logger.error(f"exception2:{ex2}.")
response = get_response(HTTPStatus.UNPROCESSABLE_ENTITY.value, start_time, context.aws_request_id, {})
except Exception as ex1:
app_logger.error(f"exception1:{ex1}.")
response = get_response(HTTPStatus.INTERNAL_SERVER_ERROR.value, start_time, context.aws_request_id, {})
app_logger.info(f"response_dumped:{response}...")
return response
def get_parsed_request_body(context, event):
app_logger.info(f"event:{json.dumps(event)}...")
app_logger.info(f"context:{context}...")
try:
body = event["body"]
except Exception as e_constants1:
app_logger.error(f"e_constants1:{e_constants1}.")
body = event
app_logger.debug(f"body, #1: {type(body)}, {body}...")
if isinstance(body, str):
body_decoded_str = base64_decode(body)
app_logger.debug(f"body_decoded_str: {type(body_decoded_str)}, {body_decoded_str}...")
body = json.loads(body_decoded_str)
app_logger.info(f"body, #2: {type(body)}, {body}...")
try:
log_level = 'DEBUG' if body['debug'] else DEFAULT_LOG_LEVEL
app_logger.warning(f"set logger level to DEBUG")
app_logger.setLevel(log_level)
except KeyError:
app_logger.warning(f"can't set log level, reset it...")
app_logger.setLevel(DEFAULT_LOG_LEVEL)
app_logger.warning(f"logger level is {app_logger.log_level}.")
return body
|