def build_api_endpoint( current_request: Request, request_path: str, query_params: Optional[Dict] = None ) -> str: logger.info(f"Enter build_api_endpoint for {request_path}") request_dict = current_request.to_dict() context = request_dict["context"] stage = context["stage"] api_domain = context["domainName"] api_id = context["apiId"] if query_params is not None: if "api_id" in query_params: # replace api value with current api id query_params["api_id"] = api_id if "stage" in query_params: query_params["stage"] = stage if query_params is not None: url = f"https://{api_domain}/{stage}/{request_path.strip('/')}/?" url = url + urlencode(query_params) else: url = f"https://{api_domain}/{stage}/{request_path.strip('/')}" logger.info(f"Exit build_api_endpoint: {url}") return url
def test_lazy_listeners(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def command_handler(ack): ack() def say_it(say): say("Done!") app.command("/hello-world")(ack=command_handler, lazy=[say_it]) input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input chalice_app = Chalice(app_name="bolt-python-chalice") slack_handler = ChaliceSlackRequestHandler(app=app, chalice=chalice_app) headers = self.build_headers(timestamp, body) headers["x-slack-bolt-lazy-only"] = "1" headers["x-slack-bolt-lazy-function-name"] = "say_it" request: Request = Request({ "requestContext": { "httpMethod": "NONE", "resourcePath": "/slack/events", }, "multiValueQueryStringParameters": {}, "pathParameters": {}, "context": {}, "stageVariables": None, "isBase64Encoded": False, "body": body, "headers": headers, }) response: Response = slack_handler.handle(request) assert response.status_code == 200 assert self.mock_received_requests["/auth.test"] == 1 assert self.mock_received_requests["/chat.postMessage"] == 1
def test_http_request_to_dict_is_json_serializable(http_request_kwargs): # We have to do some slight pre-preocessing here # to maintain preconditions. If the # is_base64_encoded arg is True, we'll # base64 encode the body. We assume API Gateway # upholds this precondition. is_base64_encoded = http_request_kwargs['is_base64_encoded'] if is_base64_encoded: # Confirmed that if you send an empty body, # API Gateway will always say the body is *not* # base64 encoded. assume(http_request_kwargs['body'] is not None) body = base64.b64encode(http_request_kwargs['body'].encode('utf-8')) http_request_kwargs['body'] = body.decode('ascii') request = Request(**http_request_kwargs) assert isinstance(request.raw_body, bytes) request_dict = request.to_dict() # We should always be able to dump the request dict # to JSON. assert json.dumps(request_dict, default=handle_decimals)
def www_request_of(data: Dict[Text, Text], headers=None): merged = {"token": "foobar123", "channel_name": "privategroup"} merged.update(data) body = "&".join(f"{quote(k)}={quote(v)}" for k, v in merged.items()) return Request(query_params={}, headers=headers or {}, uri_params={}, method="POST", body=body.encode("utf-8"), context={}, stage_vars={}, is_base64_encoded=False)
def test_http_request_to_dict_is_json_serializable(http_request_kwargs): # We have to do some slight pre-preocessing here # to maintain preconditions. If the # is_base64_encoded arg is True, we'll # base64 encode the body. We assume API Gateway # upholds this precondition. is_base64_encoded = http_request_kwargs['is_base64_encoded'] if is_base64_encoded: # Confirmed that if you send an empty body, # API Gateway will always say the body is *not* # base64 encoded. assume(http_request_kwargs['body'] is not None) body = base64.b64encode( http_request_kwargs['body'].encode('utf-8')) http_request_kwargs['body'] = body.decode('ascii') request = Request(**http_request_kwargs) assert isinstance(request.raw_body, bytes) request_dict = request.to_dict() # We should always be able to dump the request dict # to JSON. assert json.dumps(request_dict, default=handle_decimals)
def test_url_build(): mock_rq = Request({ "multiValueQueryStringParameters": None, "headers": { "a": "b", "c": "d" }, "pathParameters": None, "body": None, "stageVariables": None, "requestContext": { "resourcePath": None, "httpMethod": None, "stage": MOCK_STAGE, "domainName": MOCK_DOMAIN, "apiId": MOCK_API_ID, }, }) request_dict = mock_rq.to_dict() # print(request_dict.keys()) context = request_dict["context"] # print(context) stage = context["stage"] assert stage == MOCK_STAGE # print(stage) api_domain = context["domainName"] # print(api_domain) assert api_domain == MOCK_DOMAIN api_id = context["apiId"] # print(api_id) assert api_id == MOCK_API_ID # build url url = build_api_endpoint(mock_rq, "/") # Is the url valid? result = parse.urlparse(url) # print(result) assert result is not None
def handle(self, request: Request): body: str = request.raw_body.decode( "utf-8") if request.raw_body else "" self.logger.debug( f"Incoming request: {request.to_dict()}, body: {body}") method = request.method if method is None: return not_found() if method == "GET": if self.app.oauth_flow is not None: oauth_flow: OAuthFlow = self.app.oauth_flow bolt_req: BoltRequest = to_bolt_request(request, body) query = bolt_req.query is_callback = query is not None and ( (_first_value(query, "code") is not None and _first_value(query, "state") is not None) or _first_value(query, "error") is not None) if is_callback: bolt_resp = oauth_flow.handle_callback(bolt_req) return to_chalice_response(bolt_resp) else: bolt_resp = oauth_flow.handle_installation(bolt_req) return to_chalice_response(bolt_resp) elif method == "POST": bolt_req: BoltRequest = to_bolt_request(request, body) # https://docs.aws.amazon.com/lambda/latest/dg/python-context.html aws_lambda_function_name = self.chalice.lambda_context.function_name bolt_req.context[ "aws_lambda_function_name"] = aws_lambda_function_name bolt_req.context["chalice_request"] = request.to_dict() bolt_resp = self.app.dispatch(bolt_req) aws_response = to_chalice_response(bolt_resp) return aws_response elif method == "NONE": bolt_req: BoltRequest = to_bolt_request(request, body) bolt_resp = self.app.dispatch(bolt_req) aws_response = to_chalice_response(bolt_resp) return aws_response return not_found()