-
-
Save vagelim/fe9fead8da3f4a7ff4457b764e125205 to your computer and use it in GitHub Desktop.
Example Lambda to illustrate concepts in lambda blog post
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
import flask | |
import boto3 | |
import time | |
## CONFIG ## | |
BUCKET = 'evan-lambda-longform' | |
FILEPATH = 'hashes' | |
SEP = '\t' | |
metric_namespace = 'hasher.' | |
app = flask.Flask(__name__) | |
def log(metric, mtype='count', value=1, tags=[]): | |
# format: | |
# MONITORING|unix_epoch_timestamp|metric_value|metric_type|my.metric.name|#tag1:value,tag2 | |
print "MONITORING|{}|{}|{}|{}|#{}".format(int(time.time()), value, mtype, metric, ', '.join(tags)) | |
def read_s3(bucket=BUCKET, path=FILEPATH): | |
client = boto3.client('s3') | |
resp = client.get_object(Bucket=bucket, Key=path) | |
resp = resp['Body'].read() | |
log(metric=metric_namespace + 'db_reads', tags=['hash-service']) | |
return resp | |
def hash_exists(hash, address=False): | |
resp = read_s3() | |
resp = resp.split('\n') | |
# Obviously not an ideal solution as hash db grows | |
for each in resp: | |
if each.split(SEP)[0] == hash: | |
log(metric=metric_namespace + 'hashes_found', tags=['hash-service']) | |
if address: # True if we want to return the hash | |
return each.split(SEP)[0] | |
# Otherwise return the original (unhashed) string | |
return each.split(SEP)[1] | |
return False | |
@app.route('/messages/', methods=['POST', 'GET']) | |
@app.route('/messages/<hash>', methods=['GET']) | |
def main(hash=None, address=None): | |
log(metric=metric_namespace + 'requests', tags=['hash-service']) | |
if hash: | |
# Check if we saw it before | |
if hash_exists(hash): | |
log(metric=metric_namespace + 'hashes_retrieved', tags=['hash-service']) | |
log(metric=metric_namespace + 'responses', tags=['hash-service', 'status:200']) | |
return hash_exists(hash) | |
else: | |
log(metric=metric_namespace + 'hashes_not_found', tags=['hash-service']) | |
log(metric=metric_namespace + 'responses', tags=['hash-service', 'status:404']) | |
flask.abort(404) | |
elif flask.request.data: | |
req = flask.request.get_json() | |
message = req.get('message', None) | |
if message: | |
# log payload size | |
payload_size = len(message) | |
log(metric=metric_namespace + 'payload_size', | |
value=payload_size, tags=['hash-service']) | |
# Store hash and return | |
hash = hashlib.sha256(message).hexdigest() | |
log(metric=metric_namespace + 'strings_received', tags=['hash-service']) | |
if hash_exists(hash): | |
# Search through the hashes to find it | |
# address = true because we want to match on the hash | |
log(metric=metric_namespace + 'responses', tags=['hash-service', 'status:200']) | |
return hash_exists(hash, address=True) | |
else: | |
data = read_s3() | |
data = "{}\n{}{}{}".format(data, hash, SEP, message) | |
client = boto3.client('s3') | |
client.put_object(Bucket=BUCKET, Key=FILEPATH, Body=data) | |
log(metric=metric_namespace + 'response.200', tags=['hash-service']) | |
return hash | |
else: | |
log(metric=metric_namespace + 'malformed_payloads', tags=['hash-service']) | |
log(metric=metric_namespace + 'responses', tags=['hash-service', 'status:400']) | |
flask.abort(400) | |
else: | |
log(metric='evan.hashes_not_found', tags=['hash-service']) | |
log(metric=metric_namespace + 'responses', tags=['hash-service', 'status:200']) | |
return "Nothing to see here" | |
if __name__ == "__main__": | |
app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment