def get_items(event, context, is_test=False, session=None): """Returns the requested items. Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format #api-gateway-simple-proxy-for-lambda-input-format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ helper.log_method_initiated("Get items", event, logger) if session is None: session = get_db_session(is_test, session) if 'queryStringParameters' in event and event['queryStringParameters'] is not None: params = event['queryStringParameters'] for param in params: if hasattr(Item, param) is False: response = { "statusCode": 400, "body": "Could not get items. Query params do not match item model." } response_cors = helper.set_cors(response, event, is_test) return response_cors else: params = None items = item_handler.get_all_items(is_test, session, params=params) items_list = [] for item in items: items_list.append(item.to_dict()) response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(items_list) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def test_set_cors_header_plugin(monkeypatch, set_deployment_mode): origin = "http://www.spiegel.de" monkeypatch.setenv("CORS_ALLOW_ORIGIN", '') event = {'headers': {'origin': origin}} response = set_cors({}, event, True) assert response['headers']['Access-Control-Allow-Origin'] == origin response2 = set_cors({}, event) assert 'headers' not in response2
def submit_issue(event, context, is_test=False, session=None): helper.log_method_initiated("Submit issue", event, logger) if session == None: session = get_db_session(is_test, session) issue = Issue() #create object from issue_model.py (DB table: issues) issue = helper.body_to_object(event['body'], issue) # add ip address try: ip_address = event['requestContext']['identity']['sourceIp'] setattr(issue, 'ip_address', ip_address) except Exception: response = { "statusCode": 400, "body": "Could not read/add ip address. Check HTTP POST payload. Stacktrace: {}" .format(traceback.format_exc()) } issue = add_object(issue, is_test, session) if issue is None: response = { "statusCode": 400, "body": "Could not write issue to database. Check HTTP POST payload. Stacktrace: {}" .format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors response = send_issue_notification(issue) if response == False: response = { "statusCode": 500, "body": "Could not send issue mail. Stacktrace: {}".format( traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors else: response = {"statusCode": 201, "body": json.dumps(issue.to_dict())} response_cors = helper.set_cors(response, event, is_test) return response_cors
def test_set_cors_header_no_origin(monkeypatch): monkeypatch.setenv("CORS_ALLOW_ORIGIN", "http://localhost:4200") event = {'headers': None} response = {} response = set_cors(response, event, False)
def confirm_submission(event, context): helper.log_method_initiated("Confirm submission", event, logger) submission_id = event['pathParameters']['submission_id'] stage = os.environ['STAGE'] if stage == 'prod': link = 'https://codetekt.org' else: link = 'https://{}.codetekt.org'.format(stage) body_html = io.open(os.path.join(os.path.dirname(__file__), 'resources', 'submission_confirmed_webpage.html'), mode='r', encoding='utf-8').read().format(link) with Session() as session: try: submission_handler.confirm_submission(submission_id, session) response = { 'statusCode': 200, 'headers': {"content-type": "text/html; charset=utf-8"}, 'body': body_html } except Exception: response = { "statusCode": 500, "body": "Could not confirm submission. Stacktrace: {}".format(traceback.format_exc()) } return helper.set_cors(response, event)
def get_open_items(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get open items for user", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: # get cognito user id id = helper.cognito_id_from_event(event) # get number of items from url path if ('queryStringParameters' in event and 'num_items' in event['queryStringParameters']): num_items = int(event['queryStringParameters']['num_items']) else: num_items = 5 user = user_handler.get_user_by_id(id, is_test, session) response = item_handler.get_open_items_for_user( user, num_items, is_test, session) items = response['items'] if len(items) < 1: response = { "statusCode": 404, "body": "There are currently no open items for this user." } else: # Transform each item into dict items_dict = [] for item in items: items_dict.append(item.to_dict()) body = { "items": items_dict, "is_open_review": response['is_open_review'] } response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(body) } except Exception: response = { "statusCode": 400, "body": "Could not get user and/or num_items. Check URL path parameters. Stacktrace: {}" .format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def post_comment_on_item(event, context=None): """ Creates comment on item from archive """ with Session() as session: logger = logging.getLogger() logger.setLevel(logging.INFO) try: body = json.loads(event['body']) if isinstance( event['body'], str) else event['body'] except: return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event) try: user_id = helper.cognito_id_from_event(event) body = json.loads(event['body']) if isinstance( event['body'], str) else event['body'] except: return helper.get_text_response( 400, "Malformed request. Could not read user_id from context data.", event) if 'item_id' not in body: return helper.get_text_response( 400, "Malformed request. Please provide an item_id.", event) try: item = item_handler.get_item_by_id(body['item_id'], session) except: return helper.get_text_response(404, "Item not found", event) # Save qualitative_comment if 'comment' in body: try: comment = comment_handler.create_comment( session, comment=body['comment'], user_id=user_id, parent_type='item', parent_id=item.id) response = { "statusCode": 201, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(comment.to_dict()) } return helper.set_cors(response, event) except: return helper.get_text_response( 404, "No qualitative comment found.", event)
def test_set_cors_header_multiple_allowed(monkeypatch): origin = "http://localhost:4200" origin2 = "http://localhost:4201" monkeypatch.setenv("CORS_ALLOW_ORIGIN", f'{origin},{origin2}') event = {'headers': {'origin': origin}} response = {} response = set_cors(response, event, False) assert response['headers']['Access-Control-Allow-Origin'] == origin event2 = {'headers': {'origin': origin2}} response2 = {} response2 = set_cors(response2, event2, False) assert response2['headers']['Access-Control-Allow-Origin'] == origin2
def test_set_cors_header_non_capital(monkeypatch): origin = "http://localhost:4200" monkeypatch.setenv("CORS_ALLOW_ORIGIN", origin) event = {'headers': {'origin': origin}} response = {} response = set_cors(response, event, False) assert response['headers']['Access-Control-Allow-Origin'] == origin
def test_set_cors_header_simple(monkeypatch, set_deployment_mode): origin = "http://localhost:4200" monkeypatch.setenv("CORS_ALLOW_ORIGIN", origin) event = {'headers': {'Origin': origin}} response = {} response = set_cors(response, event) assert response['headers']['Access-Control-Allow-Origin'] == origin
def get_user(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get user", event, logger) if session == None: session = get_db_session(False, None) try: # get cognito id id = helper.cognito_id_from_event(event) try: user = user_handler.get_user_by_id(id, is_test, session) user_dict = user.to_dict() progress = user_handler.get_user_progress( user, is_test, session) total_rank = user_handler.get_user_rank( user, False, is_test, session) level_rank = user_handler.get_user_rank( user, True, is_test, session) solved_cases_total = user_handler.get_solved_cases( user, False, is_test, session) solved_cases_today = user_handler.get_solved_cases( user, True, is_test, session) exp_needed = user_handler.get_needed_exp(user, is_test, session) user_dict['progress'] = progress user_dict['total_rank'] = total_rank user_dict['level_rank'] = level_rank user_dict['solved_cases_total'] = solved_cases_total user_dict['solved_cases_today'] = solved_cases_today user_dict['exp_needed'] = exp_needed response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(user_dict) } except Exception: response = { "statusCode": 404, "body": "No user found with the specified id.{}".format(traceback.format_exc()) } except Exception: response = { "statusCode": 400, "body": "Could not get user. Check Cognito authentication. Stacktrace: {}".format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def submit_issue(event, context, is_test=False, session=None): helper.log_method_initiated("Submit issue", event, logger) if session == None: session = get_db_session(is_test, session) issue = Issue() issue = helper.body_to_object(event['body'], issue) issue = add_object(issue, is_test, session) if issue is None: response = { "statusCode": 400, "body": "Could not write issue to database. Check HTTP POST payload. Stacktrace: {}" .format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors response = send_issue_notification(issue) if response == False: response = { "statusCode": 500, "body": "Could not send issue mail. Stacktrace: {}".format( traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors else: response = {"statusCode": 201, "body": json.dumps(issue.to_dict())} response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_closed_items(event, context): helper.log_method_initiated("Get all closed items", event, logger) with Session() as session: try: # Get all closed items print("\n \n \n Getting items \n \n \n") allow_all_origins = False if 'queryStringParameters' in event and isinstance( event['queryStringParameters'], dict) and 'url' in event['queryStringParameters']: url_without_query_params = event['queryStringParameters'][ 'url'].split('?')[0] items = item_handler.get_closed_items_by_url( url_without_query_params, session) allow_all_origins = True else: items = item_handler.get_all_closed_items(session) if len(items) == 0: response = {"statusCode": 204, "body": "No closed items found"} else: items_list = [] for item in items: items_list.append( item.to_dict(with_tags=True, with_warnings=True)) response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(items_list) } except Exception: response = { "statusCode": 400, "body": "Could not get closed items. Stacktrace: {}".format( traceback.format_exc()) } response_cors = helper.set_cors(response, event, allow_all_origins) return response_cors
def delete_user(event, context, is_test=False, session=None): """Deletes a user from DB and Cognito. Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Delete user", event, logger) try: if session == None: session = get_db_session(is_test, session) user_handler.delete_user(event, is_test, session) response = {"statusCode": 200} except Exception: response = { "statusCode": 500, "body": "User could not be deleted. Exception: {}".format( traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_tags_for_item(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get tags by item id", event, logger) if session is None: session = get_db_session(is_test, None) try: # get id (str) from path id = event['pathParameters']['item_id'] try: tag_objects = tag_handler.get_tags_by_itemid(id, is_test, session) tags = [] for obj in tag_objects: tags.append(obj.to_dict()['tag']) except Exception as e: response = { "statusCode": 404, "body": "No tags found. Exception: {}".format(e) } except Exception as e: response = { "statusCode": 400, "body": "Could not get item ID. Check HTTP GET payload. Exception: {}". format(e) } body_json = {"Tags": tags} response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(body_json) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_item_types(event, context): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get Item Types", event, logger) with Session() as session: try: item_types = item_type_handler.get_all_item_types(session) if item_types == None: response = { "statusCode": 201, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": [] } else: response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps( [item_type.to_dict() for item_type in item_types]) } except Exception: response = { "statusCode": 500, "body": "Could not get item types. Stacktrace: {}".format( traceback.format_exc()) } return helper.set_cors(response, event)
def get_item(event, context): helper.log_method_initiated("Get closed item", event, logger) with Session() as session: try: # Get item id from path params item_id = event['pathParameters']['item_id'] except KeyError: return helper.get_text_response(400, 'Could not read item id from path params', event) item = item_handler.get_item_by_id(item_id, session) if item is None: return helper.get_text_response(404, 'No item found with the specified id', event) if item.status != 'closed': return helper.get_text_response(403, 'You are not allowed to access an item, that has not been closed', event) response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(item.to_dict(True, True, True, True, True, True)) } return helper.set_cors(response, event)
def get_closed_items(event, context, is_test=False, session=None): helper.log_method_initiated("Get all closed items", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: # Get all closed items items = item_handler.get_all_closed_items(is_test, session) if len(items) == 0: response = {"statusCode": 204, "body": "No closed items found"} else: items_list = [] for item in items: items_list.append(item.to_dict(with_tags=True)) response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(items_list) } except Exception: response = { "statusCode": 400, "body": "Could not get closed items. Stacktrace: {}".format( traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_user_ranking(event, context, is_test=False, session=None): """ returns a dictionary with list top_users: 10 top users list top_users_by_level: 10 top users on the user's level list top_users_by_period: 10 top users in a period p (1 week) """ n = 10 p = 1 descending = True attr = 'experience_points' logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get User Ranking", event, logger) if session == None: session = get_db_session(False, None) user_ranking_dict = {} top_users_list = [] top_users_by_level_list = [] top_users_by_period_list = [] try: my_user_id = helper.cognito_id_from_event(event) except Exception: response = { "statusCode": 400, "body": "Could not get User. Check Cognito Authentication. Stacktrace: {}".format(traceback.format_exc()) } try: helper.log_method_initiated("Get Top n Users", event, logger) top_users = user_handler.get_top_users(n, attr, descending, is_test, session) for user in top_users: top_users_list.append(user.to_dict()) user_ranking_dict['top_users'] = top_users_list helper.log_method_initiated("Get Top n Users on the User's Level", event, logger) my_user = user_handler.get_user_by_id(my_user_id, is_test, session) user_level = my_user.level_id top_users_by_level = user_handler.get_top_users_by_level(user_level, n, attr, descending, is_test, session) for user in top_users_by_level: top_users_by_level_list.append(user.to_dict()) user_ranking_dict['top_users_by_level'] = top_users_by_level_list helper.log_method_initiated("Get Top n Users in a Period", event, logger) top_users_by_period = user_handler.get_top_users_by_period(n, p, attr, descending, is_test, session) for user in top_users_by_period: top_users_by_period_list.append(user.to_dict()) user_ranking_dict['top_users_by_period'] = top_users_by_period_list except Exception: response = { "statusCode": 500, "body": "Server Error. Stacktrace: {}".format(traceback.format_exc()) } response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(user_ranking_dict) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def update_review(event, context, is_test=False, session=None): """Updates an existing review Args: event: AWS API Gateway event context ([type]): [description] is_test (bool, optional): Whether the function is executed in test mode. Defaults to False. session (optional): An sql alchemy session. Defaults to None. Returns ------ - Status code 200, 400, 404 or 500 (Created) - The updated review """ logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Create Review", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: user_id = helper.cognito_id_from_event(event) body = json.loads(event['body']) if isinstance(event['body'], str) else event['body'] except: return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event, is_test) if 'id' not in body: return helper.get_text_response( 400, "Malformed request. Please provide a review id.", event, is_test) try: review = review_handler.get_review_by_id(body['id'], is_test, session) except: return helper.get_text_response(404, "No review found", event, is_test) try: user = user_handler.get_user_by_id(user_id, is_test, session) except: return helper.get_text_response(404, "No user found.", event, is_test) if review.user_id != user.id: return helper.get_text_response(403, "Forbidden.", event, is_test) # If review is set closed if 'status' in body and body['status'] == 'closed': try: review = review_handler.close_review(review, is_test, session) if review.item.status == 'closed': notifications.notify_users(is_test, session, review.item) response = { "statusCode": 200, "body": json.dumps(review.to_dict_with_questions_and_answers()) } response_cors = helper.set_cors(response, event, is_test) return response_cors except: return helper.get_text_response( 500, "Internal server error. Stacktrace: {}".format( traceback.format_exc()), event, is_test) # If answers are appended elif 'questions' in body: if not isinstance(body['questions'], list): return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event, is_test) for question in body['questions']: if 'answer_value' in question: answer_value = question['answer_value'] else: return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event, is_test) if answer_value is not None: # Check if conditionality is met if question['parent_question_id'] is not None: for q in body['questions']: if q['question_id'] == question['parent_question_id']: parent_question = q parent_answer = review_answer_handler.get_parent_answer( question['answer_id'], is_test, session) if parent_question['answer_value'] > question[ 'upper_bound'] or parent_question[ 'answer_value'] < question['lower_bound']: return helper.get_text_response( 400, "Bad request. Please adhere to conditionality of questions.", event, is_test) # Update answer in db try: review_answer_handler.set_answer_value( question['answer_id'], question['answer_value'], is_test, session) except: return helper.get_text_response( 500, "Internal server error. Stacktrace: {}".format( traceback.format_exc()), event, is_test) response = { "statusCode": 200, "body": json.dumps(review.to_dict_with_questions_and_answers()) } response_cors = helper.set_cors(response, event, is_test) return response_cors else: return helper.get_text_response( 400, "Bad request. Please adhere to conditionality of questions.", event, is_test)
def submit_item(event, context): client = boto3.client('stepfunctions', region_name="eu-central-1") helper.log_method_initiated("Item submission", event, logger) with Session() as session: try: body = event['body'] if isinstance(body, str): body_dict = json.loads(body) else: body_dict = body content = body_dict["content"] del body_dict["content"] if "type" in body_dict: type = body_dict["type"] del body_dict["type"] else: type = None if "item_type_id" in body_dict: item_type_id = body_dict["item_type_id"] del body_dict["item_type_id"] else: item_type_id = None if "item" in body_dict: del body_dict["item"] submission = Submission() helper.body_to_object(body_dict, submission) # add ip address ip_address = event['requestContext']['identity']['sourceIp'] setattr(submission, 'ip_address', ip_address) try: # Item already exists, item_id in submission is the id of the found item item = item_handler.get_item_by_content(content, session) submission.item_id = item.id new_item_created = False except Exception: # Item does not exist yet, item_id in submission is the id of the newly created item item = Item() item.content = content item.item_type_id = item_type_id item.type = type item = item_handler.create_item(item, session) new_item_created = True if content: str_urls = re.findall( 'http[s]?://(?:[a-zA-ZäöüÄÖÜ]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', content) url_handler.prepare_and_store_urls(item, str_urls, session) submission.item_id = item.id submission.status = item.status # Create submission submission_handler.create_submission_db(submission, session) if submission.mail: if item.status != 'Unsafe': send_confirmation_mail(submission) # Create response if item.status == 'Unsafe': response = { "statusCode": 403, "headers": { "content-type": "application/json; charset=utf-8", "new-item-created": str(new_item_created) }, "body": "Item not valid" } else: response = { "statusCode": 201, "headers": { "content-type": "application/json; charset=utf-8", "new-item-created": str(new_item_created) }, "body": json.dumps(item.to_dict()) } except Exception as e: logger.error("Couldn't submit item. Exception: %s", e) response = { "statusCode": 400, "body": "Could not create item and/or submission. Check HTTP POST payload. Stacktrace: {}" .format(traceback.format_exc()) } ## start SearchFactChecks only for safe items if (item.status != 'Unsafe') and (new_item_created == True): stage = os.environ['STAGE'] client.start_execution( stateMachineArn= 'arn:aws:states:eu-central-1:891514678401:stateMachine:SearchFactChecks_new-' + stage, name='SFC_' + item.id, input="{\"item\":{" "\"id\":\"" + item.id + "\"," "\"content\":\"" + remove_control_characters(item.content) + "\" } }") response_cors = helper.set_cors(response, event) return response_cors
def post_tags_for_item(event, context): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Post tags by item id", event, logger) with Session() as session: # get list of existing tags tags_existing = [] try: # get id (str) from path id = event['pathParameters']['item_id'] tag_objects = tag_handler.get_tags_by_itemid(id, session) for obj in tag_objects: tags_existing.append(obj.to_dict()['tag']) except Exception as e: response = { "statusCode": 400, "body": "Could not get item ID. Check HTTP POST payload. Exception: {}" .format(e) } # get list of posted tags body = event['body'] if isinstance(body, str): body_dict = json.loads(body) else: body_dict = body if 'tags' in body_dict: tags_posted = body_dict['tags'] else: tags_posted = [] # save tags if tags_posted != []: for str_tag in tags_posted: tag_handler.store_tag_for_item(id, str_tag, session) # create response tags_new = list(set(tags_posted) - set(tags_existing)) tags_counter_increased = list(set(tags_posted) - set(tags_new)) response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps({ "added new tags": tags_new, "increased tag counter": tags_counter_increased }) } response_cors = helper.set_cors(response, event) return response_cors
def create_review(event, context, is_test=False, session=None): """Creates a new review. Parameters ---------- - user_id is retrieved from the event - item_id is retrieved from query parameters Returns ------ - Status code 201 (Created) - The newly created review """ logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Create Review", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: # get item id from body item_id = json.loads(event['body'])['item_id'] if isinstance( event['body'], str) else event['body']['item_id'] # get cognito id user_id = helper.cognito_id_from_event(event) except Exception: return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event, is_test) try: # get user and item from the db user = user_handler.get_user_by_id(user_id, is_test, session) except Exception: return helper.get_text_response(404, "No user found.", event, is_test) item = item_handler.get_item_by_id(item_id, is_test, session) if item is None: return helper.get_text_response(404, "No item found.", event, is_test) # Try to accept item try: review = review_handler.create_review(user, item, is_test, session) response = { "statusCode": 201, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(review.to_dict_with_questions_and_answers()) } response_cors = helper.set_cors(response, event, is_test) return response_cors except: return helper.get_text_response( 500, "Internal server error. Stacktrace: {}".format( traceback.format_exc()), event, is_test)
def submit_item(event, context, is_test=False, session=None): client = boto3.client('stepfunctions', region_name="eu-central-1") helper.log_method_initiated("Item submission", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: body = event['body'] if isinstance(body, str): body_dict = json.loads(body) else: body_dict = body content = body_dict["content"] del body_dict["content"] if ("type" in body_dict): type = body_dict["type"] del body_dict["type"] else: type = None if ("item_type_id" in body_dict): item_type_id = body_dict["item_type_id"] del body_dict["item_type_id"] else: item_type_id = None submission = Submission() helper.body_to_object(body_dict, submission) # add ip address ip_address = event['requestContext']['identity']['sourceIp'] setattr(submission, 'ip_address', ip_address) try: # Item already exists, item_id in submission is the id of the found item item = item_handler.get_item_by_content(content, is_test, session) submission.item_id = item.id new_item_created = False except Exception: # Item does not exist yet, item_id in submission is the id of the newly created item item = Item() item.content = content item.item_type_id = item_type_id item.type = type item = item_handler.create_item(item, is_test, session) new_item_created = True submission.item_id = item.id stage = os.environ['STAGE'] client.start_execution( stateMachineArn= 'arn:aws:states:eu-central-1:891514678401:stateMachine:SearchFactChecks_new-' + stage, name='SFC_' + item.id, input="{\"item\":{" "\"id\":\"" + item.id + "\"," "\"content\":\"" + remove_control_characters(item.content) + "\" } }") # Create submission submission_handler.create_submission_db(submission, is_test, session) if submission.mail: send_confirmation_mail(submission) response = { "statusCode": 201, 'headers': { "content-type": "application/json; charset=utf-8", "new-item-created": str(new_item_created) }, "body": json.dumps(item.to_dict()) } except Exception: response = { "statusCode": 400, "body": "Could not create item and/or submission. Check HTTP POST payload. Stacktrace: {}" .format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_online_factcheck(event, context): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get online factchecks by item id", event, logger) with Session() as session: try: # get id (str) from path id = event['pathParameters']['item_id'] try: item = item_handler.get_item_by_id(id, session) if item.language == None: raise Exception("Language of Claim not recognized.") entity_objects = entity_handler.get_entities_by_itemid(id, session) phrase_objects = keyphrase_handler.get_phrases_by_itemid_db(id, session) entities = [] for obj in entity_objects: entities.append(obj.to_dict()['entity']) phrases = [] for obj in phrase_objects: phrases.append(obj.to_dict()['phrase']) sfc_event = { "item": item.to_dict(), "KeyPhrases": phrases, "Entities": entities, } context = "" factcheck = SearchFactChecks.get_FactChecks(sfc_event, context) if 'claimReview' in factcheck[0]: factcheck_dict = { "id": "0", "url": factcheck[0]['claimReview'][0]['url']} if 'title' in factcheck[0]['claimReview'][0]: factcheck_dict["title"] = factcheck[0]['claimReview'][0]['title'] elif 'textualRating' in factcheck[0]['claimReview'][0]: factcheck_dict["title"] = factcheck[0]['claimReview'][0]['textualRating'] response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(factcheck_dict) } else: response = { "statusCode": 404, "body": "No factcheck found." } except Exception: response = { "statusCode": 404, "body": "No factcheck found. Stacktrace: {}".format(traceback.format_exc()) } except Exception: response = { "statusCode": 400, "body": "Could not get item ID. Check HTTP POST payload. Stacktrace: {}".format(traceback.format_exc()) } response_cors = helper.set_cors(response, event) return response_cors
def update_item(event, context, is_test=False, session=None): """Updates an item. Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format #api-gateway-simple-proxy-for-lambda-input-format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ helper.log_method_initiated("Update item", event, logger) if session is None: session = get_db_session(is_test, session) item_id = event['pathParameters']['item_id'] item = item_handler.get_item_by_id(item_id, is_test, session) if item is None: response = { "statusCode": 404, "body": "No item found with the specified id." } response_cors = helper.set_cors(response, event, is_test) return response_cors body = event['body'] body = json.loads(body) if isinstance(body, str) else body for key in body: if hasattr(item, key): if not isinstance(body[key], dict) and not isinstance( body[key], list): setattr(item, key, body[key]) else: response = { "statusCode": 400, "body": "Could not update item. Provided input does not match item model." } response_cors = helper.set_cors(response, event, is_test) return response_cors item = update_object(item, is_test, session) if item is None: response = { "statusCode": 500, "body": "Could not write changes to db. Event id: {}".format( event['requestContext']['requestId']) } response_cors = helper.set_cors(response, event, is_test) return response_cors response = {"statusCode": 200, "body": json.dumps(item.to_dict())} response_cors = helper.set_cors(response, event, is_test) return response_cors
def get_review(event, context, is_test=False, session=None): """Gets a review. Parameters ---------- - user_id is retrieved from the event - review_id is retrieved from query parameters Returns ------ - Status code 200 OK - The requested review """ logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get Review", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: # get review id from url query params review_id = event['pathParameters']['review_id'] # get cognito id user_id = helper.cognito_id_from_event(event) except: return helper.get_text_response( 400, "Malformed request. Please provide a valid request.", event, is_test) try: # get user from database user = user_handler.get_user_by_id(user_id, is_test, session) except: return helper.get_text_response(404, "No user found.", event, is_test) # Try to receive item try: review = review_handler.get_review_by_id(review_id, is_test, session) except: return helper.get_text_response(404, "No review found", event, is_test) try: if review.user_id == user.id: response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(review.to_dict_with_questions_and_answers()) } else: return helper.get_text_response(403, "Forbidden", event, is_test) except: return helper.get_text_response( 500, "Internal server error. Stacktrace: {}".format( traceback.format_exc()), event, is_test) response_cors = helper.set_cors(response, event, is_test) return response_cors
def post_tags_for_item(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Post tags by item id", event, logger) if session is None: session = get_db_session(is_test, None) tags_existing = [] try: # get id (str) from path id = event['pathParameters']['item_id'] tag_objects = tag_handler.get_tags_by_itemid(id, is_test, session) for obj in tag_objects: tags_existing.append(obj.to_dict()['tag']) except Exception as e: response = { "statusCode": 400, "body": "Could not get item ID. Check HTTP POST payload. Exception: {}". format(e) } body = event['body'] if isinstance(body, str): body_dict = json.loads(body) else: body_dict = body if 'tags' in body_dict: tags_posted = body_dict['tags'] else: tags_posted = [] tags_new = list(set(tags_posted) - set(tags_existing)) if tags_new != []: for str_tag in tags_new: tag_handler.store_tag_for_item(id, str_tag, is_test, session) tags_removed = list(set(tags_existing) - set(tags_posted)) for str_tag in tags_removed: # search for tag in database tag = tag_handler.get_tag_by_content(str_tag, is_test, session) if tag is not None: tag_handler.delete_itemtag_by_tag_and_item_id( tag.id, id, is_test, session) response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps({ "added tags": tags_new, "removed tags": tags_removed }) } response_cors = helper.set_cors(response, event, is_test) return response_cors