def render(self, api_context: ApiInvocationContext): response = api_context.response integration = api_context.integration # we set context data with the response content because later on we use context data as # the body field in the template. We need to improve this by using the right source # depending on the type of templates. api_context.data = response._content int_responses = integration.get("integrationResponses") or {} if not int_responses: return response._content entries = list(int_responses.keys()) return_code = str(response.status_code) if return_code not in entries and len(entries) > 1: LOG.info("Found multiple integration response status codes: %s", entries) return response._content return_code = entries[0] response_templates = int_responses[return_code].get( "responseTemplates", {}) template = response_templates.get(APPLICATION_JSON, {}) if not template: return response variables = self.build_variables_mapping(api_context) response._content = self.render_vtl(template, variables=variables) LOG.info("Endpoint response body after transformations:\n%s", response._content) return response._content
def render(self, api_context: ApiInvocationContext, **kwargs) -> Union[bytes, str]: # XXX: keep backwards compatibility until we migrate all integrations to this new classes # api_context contains a response object that we want slowly remove from it data = kwargs["response"] if "response" in kwargs else "" response = data or api_context.response integration = api_context.integration # we set context data with the response content because later on we use context data as # the body field in the template. We need to improve this by using the right source # depending on the type of templates. api_context.data = response._content integration_responses = integration.get("integrationResponses") or {} if not integration_responses: return response._content entries = list(integration_responses.keys()) return_code = str(response.status_code) if return_code not in entries and len(entries) > 1: LOG.info("Found multiple integration response status codes: %s", entries) return response._content return_code = entries[0] response_templates = integration_responses[return_code].get( "responseTemplates", {}) template = response_templates.get(APPLICATION_JSON, {}) if not template: return response._content variables = self.build_variables_mapping(api_context) response._content = self.render_vtl(template, variables=variables) LOG.info("Endpoint response body after transformations:\n%s", response._content) return response._content
def forward_request(self, method, path, data, headers): invocation_context = ApiInvocationContext(method, path, data, headers) forwarded_for = headers.get(HEADER_LOCALSTACK_EDGE_URL, "") if re.match(PATH_REGEX_USER_REQUEST, path) or "execute-api" in forwarded_for: result = invoke_rest_api_from_request(invocation_context) if result is not None: return result data = data and json.loads(to_str(data)) if re.match(PATH_REGEX_AUTHORIZERS, path): return handle_authorizers(method, path, data, headers) if re.match(PATH_REGEX_DOC_PARTS, path): return handle_documentation_parts(method, path, data, headers) if re.match(PATH_REGEX_VALIDATORS, path): return handle_validators(method, path, data, headers) if re.match(PATH_REGEX_RESPONSES, path): return handle_gateway_responses(method, path, data, headers) if re.match(PATH_REGEX_PATH_MAPPINGS, path): return handle_base_path_mappings(method, path, data, headers) if helpers.is_test_invoke_method(method, path): # if call is from test_invoke_api then use http_method to find the integration, # as test_invoke_api makes a POST call to request the test invocation match = re.match(PATH_REGEX_TEST_INVOKE_API, path) invocation_context.method = match[3] if data: orig_data = data path_with_query_string = orig_data.get("pathWithQueryString", None) if path_with_query_string: invocation_context.path_with_query_string = path_with_query_string invocation_context.data = data.get("body") invocation_context.headers = orig_data.get("headers", {}) result = invoke_rest_api_from_request(invocation_context) result = { "status": result.status_code, "body": to_str(result.content), "headers": dict(result.headers), } return result return True