def store(event, context): """store file""" # check the store on load configuration if runtime_context.STORE: return { 'statusCode': 400, 'body': json.dumps({ 'message': 'Configured to store files at the time of upload.' }) } # get the list of files from the request file_ids = json.loads(event.get('body')) file_ids = file_ids[:runtime_context. QUERY_LIMIT] # limit the number of files to store stored_file_ids = [] dt = datetime.utcnow() for file_id in file_ids: FileModel.update({ 'id': file_id, 'stored_at': dt, }) LOGGER.debug( 'Files item updated (stored). service=ddb method=update_item id={}' .format(file_id)) stored_file_ids.append(file_id) return {"statusCode": 200, "body": json.dumps(stored_file_ids)}
def is_long(self, event): """determine if the document is too long and needs summarizing""" # NOTE: this is a mock implementation import string val = (string.ascii_lowercase + string.digits).find(self.id[0]) < 18 LOGGER.debug('DocumentReviewMachine.is_long = {}'.format(val)) return val
def info(event, context): """get the info for a list of files""" query_string_parameters = event.get('queryStringParameters') or {} include_deleted = query_string_parameters.get('deleted') == 'yes' include_nonstored = query_string_parameters.get('nonstored') == 'yes' LOGGER.debug('File info includes deleted={} includes non-stored={}'.format( include_deleted, include_nonstored)) file_ids = json.loads(event.get('body')) file_ids = file_ids[:runtime_context. QUERY_LIMIT] # limit the number of files queried files = FileModel.get_by_ids(file_ids) for file in files: if not file.get('deleted_at') and file.get( 'stored_at'): # only return not deleted and stored file['url'] = get_presigned_url_for_download(file) else: if (file.get('deleted_at') and include_deleted) or (not file.get('stored_at') and include_nonstored): pass else: # remove deleted or non-stored files.remove(file) return { "statusCode": 200, "body": json.dumps(files, cls=utils.DateTimeEncoder) }
def enter(self, event_data): """Extends `transitions.core.State.enter` see examples: https://github.com/pytransitions/transitions/blob/master/transitions/extensions/states.py """ LOGGER.debug('LambdaCall.enter - call: {}'.format(self.lambda_call)) if self.lambda_call: # process calls if there is any defined self._process_lambda_call(event_data) super(LambdaCall, self).enter(event_data)
def delete(event, context): """delete files""" file_ids = json.loads(event.get('body')) deleted_file_ids = [] for file_id in file_ids: # NOTE: there is no check if file has already been deleted FileModel.update({'id': file_id, 'deleted_at': datetime.utcnow()}) LOGGER.debug( 'Files item updated (deleted). service=ddb method=update_item id={}' .format(file_id)) S3_CLIENT.delete_object(Bucket=runtime_context.BUCKET_NAME, Key=file_id) LOGGER.debug( 'S3 object deleted. service=s3 method=delete_object id={}'.format( file_id)) deleted_file_ids.append(file_id) return {"statusCode": 200, "body": json.dumps(deleted_file_ids)}
def expire(event, context): """remove files that are uploaded, not stored, and older than the expiration time scheduled event """ # scan the database for expired files expiry_at = datetime.utcnow() - runtime_context.NONSTORED_TIMEOUT files = FileModel.list_expired(expiry_at) # remove all files and all items one-by-one for file in files: file_id = file['id']['S'] FileModel.update({'id': file_id, 'deleted_at': datetime.utcnow()}) LOGGER.debug( 'Files item updated (expired). service=ddb method=update_item id={}' .format(file_id)) S3_CLIENT.delete_object(Bucket=runtime_context.BUCKET_NAME, Key=file_id) LOGGER.debug( 'S3 object deleted. service=s3 method=delete_object id={}'.format( file_id))
def get_presigned_url_for_download(file): """get presigned url for download""" url = S3_CLIENT.generate_presigned_url( ClientMethod='get_object', Params={ 'Bucket': runtime_context.BUCKET_NAME, 'Key': file['id'], 'ResponseContentDisposition': 'attachment; filename="{}"'.format(file['name']), 'ResponseContentType': file['type'] }, ExpiresIn=runtime_context.EXPIRATION) LOGGER.debug( 'Presigned URL generated. service=s3 method=get_object id={}'.format( file['id'])) return url
def uploaded(event, context): """S3 event triggers when file is uploaded event: https://docs.aws.amazon.com/AmazonS3/latest/dev/notification-content-structure.html """ dt = datetime.utcnow() # NOTE: the event might include multiple records for r in event['Records']: file_id = r['s3']['object']['key'] file = { 'id': file_id, 'size': r['s3']['object']['size'], 'type': get_s3_file_type(file_id), 'uploaded_at': dt, } if runtime_context.STORE: file['stored_at'] = dt FileModel.update(file) LOGGER.debug( 'Files item updated (uploaded). service=ddb method=update_item id={}' .format(file_id)) return {"statusCode": 200}
def get_top_story(event, context): """retrieve the top story from HackerNews https://github.com/HackerNews/API """ LOGGER.debug('get_top_story - ENTRY') top_stories = requests.get( 'https://hacker-news.firebaseio.com/v0/topstories.json') assert top_stories.status_code == 200, 'Failed to get top stories [{}]'.format( top_stories.status_code) top_story_id = top_stories.json()[0] LOGGER.info('get_top_story - top_story_id={}'.format(top_story_id)) top_story = requests.get( 'https://hacker-news.firebaseio.com/v0/item/{}.json'.format( top_story_id)) assert top_story.status_code == 200, 'Failed to get the top story [{}]'.format( top_stories.status_code) story = top_story.json() LOGGER.debug('get_top_story - EXIT') return { 'statusCode': 200, 'body': '"{}" by {} on {}'.format(story.get('title'), story.get('by'), story.get('url')), 'headers': { 'content-type': 'text/plain' } }
def preprocess(event, context): """Sample pure Lambda function event: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ # create file in DDB file_id = utils.generate_id() file_request = json.loads(event.get('body')) FileModel.create({'id': file_id, 'name': file_request.get('name')}) LOGGER.debug( 'Files item created. service=ddb method=put_item id={}'.format( file_id)) # generate signed URL for posting file url = S3_CLIENT.generate_presigned_url( ClientMethod='put_object', Params={ 'Bucket': runtime_context.BUCKET_NAME, 'Key': file_id }, ExpiresIn=runtime_context.EXPIRATION) LOGGER.debug( 'Presigned URL generated. service=s3 method=put_object id={}'.format( file_id)) # send back the signed url return { "statusCode": 200, "body": json.dumps({ 'id': file_id, 'url': url }), # CORS header "headers": { "Access-Control-Allow-Origin": "*" } }
def notify_reviewer(event, context): """notify reviewer function""" LOGGER.info('Notify reviewer') LOGGER.info(event.get('body')) return {'statusCode': 200}
def archive_document(event, context): """archive original document function""" LOGGER.info('Archive original document') LOGGER.info(event.get('body')) return {'statusCode': 200}
def delete_document(event, context): """delete document function""" LOGGER.info('Delete document') LOGGER.info(event.get('body')) return {'statusCode': 200}
def summarize_document(event, context): """summarize document function""" LOGGER.info('Summarize document') LOGGER.info(event.get('body')) return {'statusCode': 200}