· 7 years ago · Mar 05, 2018, 04:48 AM
1#from base64 import b64decode, b64encode
2import json
3import logging
4import sys
5import os
6import base64
7import datetime
8import hashlib
9import hmac
10import requests
11import urllib.parse
12import io
13
14import matplotlib
15matplotlib.use('AGG')
16import matplotlib.pyplot as plt
17
18# ************* REQUEST VALUES *************
19ES_ENDPOINT = 'https://search-sensordata-6xony62c6ndp7be6j7hxv5e37m.us-east-1.es.amazonaws.com/sensor-data/_search'
20ES_ENDPOINT_OBJ = urllib.parse.urlparse(ES_ENDPOINT)
21METHOD = 'GET'
22SERVICE = 'es'
23HOST = ES_ENDPOINT_OBJ.netloc
24CANONICAL_URI = ES_ENDPOINT_OBJ.path
25REGION = os.environ.get('AWS_REGION')
26endpoint = ES_ENDPOINT
27# Read AWS access key from env. variables or configuration file.
28ACCESS_KEY = os.environ.get('AWS_ACCESS_KEY_ID')
29SECRET_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
30SECURITY_TOKEN = os.environ.get('AWS_SECURITY_TOKEN')
31
32logging.basicConfig(level=logging.INFO)
33log = logging.getLogger()
34log.setLevel(logging.INFO)
35
36log.info('Loading function')
37
38# Key derivation functions. See:
39# http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
40def sign(key, msg):
41 return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
42
43def getSignatureKey(key, dateStamp, regionName, serviceName):
44 kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
45 kRegion = sign(kDate, regionName)
46 kService = sign(kRegion, serviceName)
47 kSigning = sign(kService, 'aws4_request')
48 return kSigning
49
50def lambda_handler(event, context):
51 log.info(event)
52 # Create a date for headers and the credential string
53 t = datetime.datetime.utcnow()
54 amzdate = t.strftime('%Y%m%dT%H%M%SZ')
55 datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
56
57 uid = event['queryStringParameters']['uid']
58 request_parameters = urllib.parse.urlencode({'q':uid, 'sort':'timestamp:desc'})
59 # Ask Elasticsearch for data
60 # ************* CREATE A CANONICAL REQUEST *************
61 # http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
62 canonical_querystring = request_parameters
63 canonical_headers = 'host:' + HOST + '\n' + 'x-amz-date:' + amzdate + '\n'
64 SIGNED_HEADERS = 'host;x-amz-date'
65 payload_hash = hashlib.sha256(''.encode('utf-8')).hexdigest()
66 canonical_request = METHOD + '\n' + CANONICAL_URI + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + SIGNED_HEADERS + '\n' + payload_hash
67 ALGORITHM = 'AWS4-HMAC-SHA256'
68 credential_scope = datestamp + '/' + REGION + '/' + SERVICE + '/' + 'aws4_request'
69 string_to_sign = ALGORITHM + '\n' + amzdate + '\n' + credential_scope + '\n' + \
70 hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
71 signing_key = getSignatureKey(SECRET_KEY, datestamp, REGION, SERVICE)
72 signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
73 authorization_header = ALGORITHM + ' ' + 'Credential=' + ACCESS_KEY + '/' + credential_scope + ', ' + \
74 'SignedHeaders=' + SIGNED_HEADERS + ', ' + 'Signature=' + signature
75 headers = {'x-amz-date':amzdate, 'Authorization':authorization_header, 'x-amz-security-token':SECURITY_TOKEN}
76
77 # # ************* SEND THE REQUEST *************
78 request_url = endpoint + '?' + canonical_querystring
79 log.info("Requesting sensor data from url: {}".format(request_url))
80 esResponse = requests.get(request_url, headers=headers)
81 esResponse.raise_for_status()
82 esPayload = esResponse.json()
83 instantDemand = [data['_source']['InstantaneousDemand'] for data in esPayload['hits']['hits']]
84 plt.plot(instantDemand)
85 # Save figure to memory
86 plt.savefig('/tmp/test.png',transparent=True)
87 with open('/tmp/test.png','rb') as f:
88 figureBytes = f.read()
89 # Base64 encode image and convert to string for API Gateway
90 img_b64 = base64.b64encode(figureBytes)
91 img_out = img_b64.decode('utf-8')
92 return {
93 'statusCode': 200,
94 'body': img_out,
95 'isBase64Encoded': True,
96 'headers': {'Content-Type': 'image/png'},
97 }