├── README.md ├── api.py ├── bootstrap.sh ├── database.py ├── fakesensor └── fakesensor.py ├── gateway └── gateway.py ├── managementsystem ├── managment_system.py └── restapi.py ├── project_test.py ├── reqs.txt ├── requierments.txt └── test.py /README.md: -------------------------------------------------------------------------------- 1 | # SmartHomeManagementSystem 2 | Implementation of a smart home management system at the edge of network for a research project on Edge Computing 3 | -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | import json 3 | from six.moves.urllib.request import urlopen 4 | from functools import wraps 5 | from flask_cors import cross_origin 6 | from flask import Flask, request, jsonify, _request_ctx_stack 7 | from jose import jwt 8 | 9 | AUTH0_DOMAIN = '' 10 | API_AUDIENCE = '' 11 | ALGORITHMS = ["RS256"] 12 | 13 | APP = Flask(__name__) 14 | 15 | # Error handler 16 | class AuthError(Exception): 17 | def __init__(self, error, status_code): 18 | self.error = error 19 | self.status_code = status_code 20 | 21 | @APP.errorhandler(AuthError) 22 | def handle_auth_error(ex): 23 | response = jsonify(ex.error) 24 | response.status_code = ex.status_code 25 | return response 26 | 27 | 28 | def get_token_auth_header(): 29 | """Obtains the Access Token from the Authorization Header 30 | """ 31 | auth = request.headers.get("Authorization", None) 32 | if not auth: 33 | raise AuthError({"code": "authorization_header_missing", 34 | "description": 35 | "Authorization header is expected"}, 401) 36 | 37 | parts = auth.split() 38 | 39 | if parts[0].lower() != "bearer": 40 | raise AuthError({"code": "invalid_header", 41 | "description": 42 | "Authorization header must start with" 43 | " Bearer"}, 401) 44 | elif len(parts) == 1: 45 | raise AuthError({"code": "invalid_header", 46 | "description": "Token not found"}, 401) 47 | elif len(parts) > 2: 48 | raise AuthError({"code": "invalid_header", 49 | "description": 50 | "Authorization header must be" 51 | " Bearer token"}, 401) 52 | 53 | token = parts[1] 54 | return token 55 | 56 | def requires_auth(f): 57 | """Determines if the Access Token is valid 58 | """ 59 | @wraps(f) 60 | def decorated(*args, **kwargs): 61 | token = get_token_auth_header() 62 | jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json") 63 | jwks = json.loads(jsonurl.read()) 64 | unverified_header = jwt.get_unverified_header(token) 65 | rsa_key = {} 66 | for key in jwks["keys"]: 67 | if key["kid"] == unverified_header["kid"]: 68 | rsa_key = { 69 | "kty": key["kty"], 70 | "kid": key["kid"], 71 | "use": key["use"], 72 | "n": key["n"], 73 | "e": key["e"] 74 | } 75 | if rsa_key: 76 | try: 77 | payload = jwt.decode( 78 | token, 79 | rsa_key, 80 | algorithms=ALGORITHMS, 81 | audience=API_AUDIENCE, 82 | issuer="https://"+AUTH0_DOMAIN+"/" 83 | ) 84 | except jwt.ExpiredSignatureError: 85 | raise AuthError({"code": "token_expired", 86 | "description": "token is expired"}, 401) 87 | except jwt.JWTClaimsError: 88 | raise AuthError({"code": "invalid_claims", 89 | "description": 90 | "incorrect claims," 91 | "please check the audience and issuer"}, 401) 92 | # except Exception: 93 | # raise AuthError({"code": "invalid_header", 94 | # "description": 95 | # "Unable to parse authentication" 96 | # " token."}, 401) 97 | 98 | _request_ctx_stack.top.current_user = payload 99 | return f(*args, **kwargs) 100 | raise AuthError({"code": "invalid_header", 101 | "description": "Unable to find appropriate key"}, 401) 102 | return decorated 103 | 104 | 105 | # This doesn't need authentication 106 | @APP.route("/ping") 107 | @cross_origin(headers=['Content-Type', 'Authorization']) 108 | def ping(): 109 | return "All good. You don't need to be authenticated to call this" 110 | 111 | # This does need authentication 112 | @APP.route("/secured/ping") 113 | @cross_origin(headers=['Content-Type', 'Authorization']) 114 | @requires_auth 115 | def secured_ping(): 116 | return "All good. You only get this message if you're authenticated" 117 | 118 | if __name__ == "__main__": 119 | 120 | APP.debug = True 121 | APP.run(host = '0.0.0.0', port = '80') 122 | 123 | 124 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export FLASK_APP=./api.py 3 | flask run -h 0.0.0.0 -------------------------------------------------------------------------------- /database.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | """ 3 | Testing Database 4 | """ 5 | 6 | #MongoClient object, specifying connection URL with IP address of connection 7 | client = pymongo.MongoClient("") 8 | 9 | gateway_db = client["gateway"] 10 | 11 | management_db = client["api"] 12 | gateway = management_db["gateway"] 13 | device = management_db["device"] 14 | config = management_db["config"] 15 | 16 | dblist = client.list_database_names() 17 | if "local_gateway_storage" in dblist: 18 | print("The database exists.") 19 | 20 | deviceTest = {"identifier":"floor_lamp", 21 | "name":"floor lamp", 22 | "device_type":"switch", 23 | "controller_gateway":"" 24 | } 25 | 26 | 27 | x = device.insert_one(deviceTest) 28 | -------------------------------------------------------------------------------- /fakesensor/fakesensor.py: -------------------------------------------------------------------------------- 1 | import paho.mqtt.client as mqtt 2 | import random 3 | import threading 4 | import json 5 | from datetime import datetime 6 | """ 7 | This class is used to simulate a DHT22 sensor which sends humidity and temperature data to the gateway. The sensor data 8 | is randomly generated. When an instance of DHT22 is created, it takes the parameters of gateway_name, ca_cert and 9 | optional device_crt, device_key, and port number. These values are used in order for the device to successfully connect 10 | to the gateway broker for sending data. 11 | Author: Haya Majeed 12 | """ 13 | 14 | class DHT22: 15 | __deviceName = "DHT22" 16 | __humidity = "Humidity" 17 | __temperature = "Temperature" 18 | toggle = 0 # used to determine whether device should send humidity data or temperature data 19 | 20 | # MQTT settings for sensor to send data to gateway through MQTT 21 | # Needs to be updated to send once device is authenticated and has gateway ID info 22 | __broker = "" 23 | __port = 1871 24 | 25 | """ 26 | Values passed in when creating a sensor object is the host name of the gateway used for sending 27 | MQTT data and port it will be sent on. 28 | When device is created it is authenticated with the gateway and will connect to it using MQTT 29 | It will then automatically begin publishing sensor data to gateway in encrypted format 30 | """ 31 | def __init__(self, gateway_name, ca_cert, device_crt = None, device_key = None, port = None): 32 | self.__broker = gateway_name 33 | self.ca_cert = ca_cert 34 | self.device_crt = device_crt 35 | self.device_key = device_key 36 | self.__port = port 37 | self.__keep_alive_interval = 45 38 | # MQTT broker connection 39 | self.__client = mqtt.Client(self.__deviceName) 40 | self.__client.on_connect = self.on_connect 41 | self.__client.on_disconnect = self.on_disconnect 42 | self.__client.on_publish = self.on_publish 43 | self.__client.tls_set(self.ca_cert, self.device_crt, self.device_key) 44 | self.__client.connect(self.__broker, int(self.__port), int(self.__keep_alive_interval)) 45 | self.publish_fake_sensor_values_to_mqtt() 46 | self.__client.loop_forever() 47 | 48 | def on_connect(self, client, userdata, rc): 49 | if rc != 0: 50 | pass 51 | print("Unable to connect to MQTT Broker...") 52 | else: 53 | print("Connected with MQTT Broker: " + self.__broker) 54 | 55 | def on_publish(self, client, userdata, mid): 56 | pass 57 | 58 | def on_disconnect(self, client, userdata, rc): 59 | if rc != 0: 60 | pass 61 | 62 | """ 63 | This method generates random temperature and humidity data from a DHT22 sensor and publishes them 64 | to the gateway broker 65 | """ 66 | def publish_fake_sensor_values_to_mqtt(self): 67 | threading.Timer(3.0, self.publish_fake_sensor_values_to_mqtt).start() # loop to continuously send sensor data 68 | if self.toggle == 0: 69 | humidity_fake_value = float("{0:.2f}".format(random.uniform(50, 100))) 70 | 71 | humidity_data = {} 72 | humidity_data['Sensor_ID'] = self.__deviceName 73 | humidity_data['Date'] = (datetime.today()).strftime("%d-%b-%Y %H:%M:%S:%f") 74 | humidity_data['Humidity'] = humidity_fake_value 75 | humidity_json_data = json.dumps(humidity_data) 76 | 77 | print("Publishing fake Humidity Value: " + str(humidity_fake_value) + "...") 78 | self.toggle = 1 79 | topic = self.__broker + "/" + self.__deviceName + "/" + self.__humidity 80 | self.publish_to_topic(topic, humidity_json_data) 81 | else: 82 | temperature_fake_value = float("{0:.2f}".format(random.uniform(1, 30))) 83 | 84 | temperature_data = {} 85 | temperature_data['Sensor_ID'] = self.__deviceName 86 | temperature_data['Date'] = (datetime.today()).strftime("%d-%b-%Y %H:%M:%S:%f") 87 | temperature_data['Temperature'] = temperature_fake_value 88 | temperature_json_data = json.dumps(temperature_data) 89 | 90 | print("Publishing fake Temperature Value: " + str(temperature_fake_value) + "...") 91 | self.toggle = 0 92 | topic = self.__broker + "/" + self.__deviceName + "/" + self.__temperature 93 | self.publish_to_topic(topic, temperature_json_data) 94 | 95 | """ 96 | This method is used for publishing data to appropriate topics on the broker and prints to the console what data 97 | is being published. 98 | """ 99 | def publish_to_topic(self, topic, message): 100 | self.__client.publish(topic, message) 101 | print("Published: " + str(message) + " " + "on MQTT Topic: " + str(topic)) 102 | print("\n") 103 | 104 | def get_device(self): 105 | return self.__deviceName 106 | 107 | def get_sensor_type(self): 108 | global toggle 109 | if toggle == 0: 110 | return self.__humidity 111 | else: 112 | return self.__temperature 113 | -------------------------------------------------------------------------------- /gateway/gateway.py: -------------------------------------------------------------------------------- 1 | import paho.mqtt.client as mqtt 2 | import random 3 | import threading 4 | import json 5 | from datetime import datetime 6 | from pymongo import MongoClient 7 | from http.client import HTTPSConnection 8 | 9 | """ 10 | 11 | Author: Haya Majeed 12 | """ 13 | 14 | 15 | class Gateway: 16 | 17 | # Gateway Name 18 | __name = "Pi_Gateway" 19 | __gateway_port = 1883 20 | # MQTT settings for MQTT communication that takes place locally on gateway 21 | # Enter Name for local gateway 22 | __gateway_broker = "" 23 | 24 | # MQTT Settings for CloudMQTT broker working in cloud 25 | __cloud_broker = "postman.cloudmqtt.com" 26 | __cloud_port = 18467 27 | __username = "" 28 | __password = "" 29 | 30 | # MongoDB Name 31 | # Must enter unique credentials for MongoDB host 32 | db = MongoClient() 33 | database = db['gateway'] 34 | collection = database['DHT22'] 35 | mqtt_topics = __name + "/#" # all topics/devices under Pi_Gateway 36 | mqtt_post_topics = __name + "/" 37 | __Keep_Alive_Interval = 45 38 | 39 | def __init__(self, token, api_link): 40 | # connecting to MQTT Cloud broker and setting commands 41 | __cloud_client = mqtt.Client(self.__name) 42 | __cloud_client.on_connect = self.on_connect 43 | __cloud_client.on_disconnect = self.on_disconnect 44 | __cloud_client.on_publish = self.on_publish 45 | __cloud_client.on_message = self.on_message 46 | __cloud_client.connect(self.__cloud_broker, int(self.__cloud_port), int(self.__Keep_Alive_Interval)) 47 | __cloud_client.username_pw_set(self.__username, self.__password) # must log in with username/pass for broker 48 | __cloud_client.loop_forever() 49 | 50 | """ 51 | This function is used as a callback to paho-mqtt on_connect function. It verifies if a connection is made 52 | successfully or not and then subscribes to appropriate topics. 53 | """ 54 | def on_connect(self, client, userdata, rc): 55 | if rc != 0: 56 | pass 57 | print("Unable to connect to MQTT Broker...") 58 | else: 59 | print("Connected with MQTT Broker: " + str(self.__cloud_broker)) 60 | client.subscribe(self.mqtt_topics) 61 | 62 | """ 63 | Callback function to paho-mqtt on_publish function 64 | """ 65 | def on_publish(self, client, userdata, mid): 66 | pass 67 | 68 | """ 69 | Callback function to paho-mqtt on_disconnect function 70 | """ 71 | def on_disconnect(self, client, userdata, rc): 72 | if rc != 0: 73 | pass 74 | 75 | """ 76 | This method is responsible for adding sensor data to the gateway local storage which is implemented with 77 | MongoDB 78 | """ 79 | def on_message(self, client, userdata, msg): 80 | receive_time = datetime.datetime.now() 81 | message = msg.payload.decode("utf-8") 82 | is_float_value = False 83 | try: 84 | val = float(message) 85 | is_float_value = True 86 | except: 87 | is_float_value = False 88 | 89 | if is_float_value: 90 | print(str(receive_time) + ": " + msg.topic + " " + str(val)) 91 | post = {"time": receive_time, "topic": msg.topic, "value": val} 92 | else: 93 | print(str(receive_time) + ": " + msg.topic + " " + message) 94 | post = {"time": receive_time, "topic": msg.topic, "value": message} 95 | self.collection.insert_one(post) # inserting data to database 96 | 97 | -------------------------------------------------------------------------------- /managementsystem/managment_system.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: 3 | Make managment_system file 4 | connect it to broker with code 5 | have it send broker on_message() data to mongoDB in cloud 6 | TEST with data from Haya 7 | 8 | """ 9 | 10 | 11 | import paho.mqtt.client as mqtt 12 | import random 13 | import threading 14 | import json 15 | from datetime import datetime 16 | from pymongo import MongoClient 17 | import http.client 18 | import json 19 | import socket 20 | import ssl 21 | from six.moves.urllib.request import urlopen 22 | 23 | #Gateway Name 24 | __name = "Pi_Gateway" 25 | __gateway_port = 1883 26 | # MQTT settings for MQTT communication that takes place locally on gateway 27 | __gateway_broker = "" 28 | 29 | # MQTT Settings for CloudMQTT broker working in cloud 30 | __cloud_broker = "postman.cloudmqtt.com" 31 | __cloud_port = 18467 32 | __username = "" 33 | __password = "" 34 | 35 | 36 | # MongoDB Name 37 | # Populate with unique uri 38 | uri = "" 39 | db = MongoClient(uri) 40 | database = db['gateway'] 41 | collection = database['DHT22'] 42 | mqtt_topics = __name + "/#" # all topics/devices under Pi_Gateway 43 | mqtt_post_topics = __name + "/" 44 | __Keep_Alive_Interval = 45 45 | 46 | def on_connect(client, userdata,flags, rc): 47 | 48 | if rc != 0: 49 | pass 50 | print("Unable to connect to MQTT Broker...") 51 | else: 52 | print("Connected with MQTT Broker: " + str(__cloud_broker)) 53 | client.subscribe(mqtt_topics) 54 | print("On_connect") 55 | publish_fake_message("gateway_identifier/DHT22/Humidity",__cloud_client) 56 | 57 | def on_publish(client, userdata,flags, mid): 58 | pass 59 | 60 | def on_disconnect(client, userdata, rc): 61 | if rc != 0: 62 | pass 63 | 64 | """ 65 | This method is responsible for adding sensor data to the gateway local storage which is implemented with 66 | MongoDB 67 | """ 68 | def on_message(client, userdata,flags, msg): 69 | print("Message recived") 70 | receive_time = datetime.datetime.now() 71 | message = msg.payload.decode("utf-8") 72 | is_float_value = False 73 | try: 74 | val = float(message) 75 | is_float_value = True 76 | except: 77 | is_float_value = False 78 | 79 | if is_float_value: 80 | print(str(receive_time) + ": " + msg.topic + " " + str(val)) 81 | post = {"time": receive_time, "topic": msg.topic, "value": val} 82 | else: 83 | print(str(receive_time) + ": " + msg.topic + " " + message) 84 | post = {"time": receive_time, "topic": msg.topic, "value": message} 85 | collection.insert_one(data) 86 | 87 | 88 | # connecting to MQTT Cloud broker and setting commands 89 | __cloud_client = mqtt.Client(__name) 90 | __cloud_client.on_connect = on_connect 91 | __cloud_client.on_disconnect = on_disconnect 92 | __cloud_client.on_publish = on_publish 93 | __cloud_client.on_message = on_message 94 | __cloud_client.connect(__cloud_broker, int(__cloud_port), int(__Keep_Alive_Interval)) 95 | __cloud_client.username_pw_set(__username, __password) # must log in with username/pass for broker 96 | 97 | def publish_fake_message(topic, clients): 98 | __cloud_client = clients 99 | humidity_data = {} 100 | humidity_data['Sensor_ID'] = "Dummy-1" 101 | humidity_data['Date'] = (datetime.today()).strftime("%d-%b-%Y %H:%M:%S:%f") 102 | humidity_data['Humidity'] = 322 103 | humidity_json_data = json.dumps(humidity_data) 104 | message = humidity_json_data 105 | __cloud_client.publish(topic, message) 106 | 107 | 108 | __cloud_client.loop_forever() 109 | -------------------------------------------------------------------------------- /managementsystem/restapi.py: -------------------------------------------------------------------------------- 1 | 2 | """" 3 | app = Flask(__name__) #creates instance of flask application 4 | 5 | @app.route("/") #defines route code is executed if we access localhost:5000/ 6 | 7 | def hello_world(): 8 | return "Hello, World!" 9 | 10 | if __name__== '__main__': 11 | app.run(debug=True) 12 | """ 13 | from flask import Flask 14 | from flask import jsonify 15 | from flask import request 16 | from flask_pymongo import PyMongo 17 | 18 | app = Flask(__name__) 19 | app.config['MONGO_DBNAME'] = 'api' 20 | app.config['MONGO_URI'] = '' 21 | mongo =PyMongo(app) 22 | 23 | #/api/gateway/[—downloads information about a gateway with identification number expressed by a gateway_id parameter 24 | #/api/device/[—downloads information about a device with identification number expressed by a gateway_id parameter 25 | #/api/config/[—downloads most up-to-date configuration for a gateway with identification number expressed by a gateway_id parameter 26 | 27 | """ 28 | downloads information about a gateway with identification number expressed by a gateway_id parameter 29 | """ 30 | @app.route('/gateway/') 31 | def get_gateway(gateway_id): 32 | return 33 | 34 | 35 | # downloads information about all devices 36 | @app.route("/device", methods=['GET']) 37 | def get_all_devices(): 38 | device = mongo.db.device 39 | output = [] 40 | for d in device.find(): 41 | output.append({'name':d['name'], 'device_type': d['device_type']}) 42 | return jsonify({'result' : output}) 43 | 44 | """ 45 | downloads information about a device with identification number expressed by a DEVICE_id parameter 46 | Information returned is a json format containing: device id, identifier, name, device_type, controller_gateway 47 | """ 48 | @app.route("/device/", methods = ['GET']) 49 | def get_device(device_id): 50 | device = mongo.db.device 51 | d = device.find_one({'device_id' : device_id}) 52 | if(d): 53 | output = {'device_id': d['device_id'], 'identifier' : d['identifier'], 'name' : d['name'], 'device_type' : d['device_type'], 'controller_gateway' : d['controller_gateway']} 54 | else: 55 | output = "No such device ID" 56 | return jsonify({'result' : output}) 57 | 58 | """ 59 | api/device—adds to the system information about a device described in a message 60 | Information added is a json format containing: device id, identifier, name, device_type, controller_gateway 61 | """ 62 | @app.route("/device", methods = ['PUT']) 63 | def add_device(): 64 | device = mongo.db.device 65 | device_id = request.json['device_id'] 66 | identifier = request.json['identifier'] 67 | name = request.json['name'] 68 | device_type = request.json['device_type'] 69 | controller_gateway = request.json['controller_gateway'] 70 | new_device_id = device.insert({'device_id' : device_id, 'identifier' : identifier, 'name': name, 'device_type' : device_type, 'controller_gateway' : controller_gateway}) 71 | new_device = device.find_one({'_id': new_device_id}) 72 | output = {'device_id' : new_device['device_id'], 'identifier' : new_device['identifier'], 'name': new_device['name'], 'device_type' : new_device['device_type'], 'controller_gateway' : new_device['controller_gateway']} 73 | return jsonify({'result': output}) 74 | 75 | 76 | 77 | 78 | if __name__ == '__main__': 79 | app.run(debug=True) 80 | 81 | -------------------------------------------------------------------------------- /project_test.py: -------------------------------------------------------------------------------- 1 | from fakesensor import DHT22 2 | """ 3 | This file is used as a test file for connecting to the gateway broker and publishing messages. Certificates were switched 4 | out for incorrectly signed certificates or removed entirely for testing. 5 | Author: Haya Majeed 6 | """ 7 | 8 | __ca_cert = "certificates/ca.crt" 9 | __DHT22_cert = "certificates/client.crt" 10 | __DHT22_key = "certificates/client.key" 11 | __gateway_name = "" 12 | __TLS_PORT = 8883 13 | dummy = DHT22(__gateway_name, __ca_cert, __TLS_PORT) 14 | -------------------------------------------------------------------------------- /reqs.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.12 2 | anaconda-client==1.7.2 3 | anaconda-navigator==1.9.7 4 | anaconda-project==0.8.2 5 | asn1crypto==0.24.0 6 | astroid==2.2.5 7 | astropy==3.1.2 8 | atomicwrites==1.3.0 9 | attrs==19.1.0 10 | Babel==2.6.0 11 | backcall==0.1.0 12 | backports.os==0.1.1 13 | backports.shutil-get-terminal-size==1.0.0 14 | beautifulsoup4==4.7.1 15 | bitarray==0.8.3 16 | bkcharts==0.2 17 | bleach==3.1.0 18 | bokeh==1.0.4 19 | boto==2.49.0 20 | Bottleneck==1.2.1 21 | certifi==2019.3.9 22 | cffi==1.12.3 23 | chardet==3.0.4 24 | Click==7.0 25 | cloudpickle==0.8.0 26 | clyent==1.2.2 27 | colorama==0.4.1 28 | comtypes==1.1.7 29 | conda==4.6.11 30 | conda-build==3.17.8 31 | conda-verify==3.1.1 32 | contextlib2==0.5.5 33 | cryptography==2.6.1 34 | cycler==0.10.0 35 | Cython==0.29.6 36 | cytoolz==0.9.0.1 37 | dask==1.1.4 38 | decorator==4.4.0 39 | defusedxml==0.5.0 40 | distributed==1.26.0 41 | docutils==0.14 42 | ecdsa==0.13.2 43 | entrypoints==0.3 44 | et-xmlfile==1.0.1 45 | fastcache==1.0.2 46 | filelock==3.0.10 47 | Flask==1.0.2 48 | Flask-Cors==3.0.7 49 | future==0.17.1 50 | gevent==1.4.0 51 | glob2==0.6 52 | greenlet==0.4.15 53 | h5py==2.9.0 54 | heapdict==1.0.0 55 | html5lib==1.0.1 56 | idna==2.8 57 | imageio==2.5.0 58 | imagesize==1.1.0 59 | importlib-metadata==0.0.0 60 | ipykernel==5.1.0 61 | ipython==7.4.0 62 | ipython-genutils==0.2.0 63 | ipywidgets==7.4.2 64 | isort==4.3.16 65 | itsdangerous==1.1.0 66 | jdcal==1.4 67 | jedi==0.13.3 68 | Jinja2==2.10.1 69 | jose==1.0.0 70 | jsonschema==3.0.1 71 | jupyter==1.0.0 72 | jupyter-client==5.2.4 73 | jupyter-console==6.0.0 74 | jupyter-core==4.4.0 75 | jupyterlab==0.35.4 76 | jupyterlab-server==0.2.0 77 | keyring==18.0.0 78 | kiwisolver==1.0.1 79 | lazy-object-proxy==1.3.1 80 | libarchive-c==2.8 81 | llvmlite==0.28.0 82 | locket==0.2.0 83 | lxml==4.3.2 84 | MarkupSafe==1.1.1 85 | matplotlib==3.0.3 86 | mccabe==0.6.1 87 | menuinst==1.4.16 88 | mistune==0.8.4 89 | mkl-fft==1.0.10 90 | mkl-random==1.0.2 91 | more-itertools==6.0.0 92 | mpmath==1.1.0 93 | msgpack==0.6.1 94 | multipledispatch==0.6.0 95 | navigator-updater==0.2.1 96 | nbconvert==5.4.1 97 | nbformat==4.4.0 98 | networkx==2.2 99 | nltk==3.4 100 | nose==1.3.7 101 | notebook==5.7.8 102 | numba==0.43.1 103 | numexpr==2.6.9 104 | numpy==1.16.3 105 | numpydoc==0.8.0 106 | olefile==0.46 107 | openpyxl==2.6.1 108 | packaging==19.0 109 | pandas==0.24.2 110 | pandocfilters==1.4.2 111 | parso==0.3.4 112 | partd==0.3.10 113 | path.py==11.5.0 114 | pathlib2==2.3.3 115 | patsy==0.5.1 116 | pep8==1.7.1 117 | pickleshare==0.7.5 118 | Pillow==5.4.1 119 | pkginfo==1.5.0.1 120 | pluggy==0.9.0 121 | ply==3.11 122 | prometheus-client==0.6.0 123 | prompt-toolkit==2.0.9 124 | psutil==5.6.1 125 | py==1.8.0 126 | pyasn1==0.4.5 127 | pycodestyle==2.5.0 128 | pycosat==0.6.3 129 | pycparser==2.19 130 | pycrypto==2.6.1 131 | pycurl==7.43.0.2 132 | pyflakes==2.1.1 133 | Pygments==2.3.1 134 | pylint==2.3.1 135 | pyodbc==4.0.26 136 | pyOpenSSL==19.0.0 137 | pyparsing==2.3.1 138 | pyreadline==2.1 139 | pyrsistent==0.14.11 140 | PySocks==1.6.8 141 | pytest==4.3.1 142 | pytest-arraydiff==0.3 143 | pytest-astropy==0.5.0 144 | pytest-doctestplus==0.3.0 145 | pytest-openfiles==0.3.2 146 | pytest-remotedata==0.3.1 147 | python-dateutil==2.8.0 148 | python-dotenv==0.10.2 149 | python-jose==3.0.1 150 | pytz==2018.9 151 | PyWavelets==1.0.2 152 | pywin32==223 153 | pywinpty==0.5.5 154 | PyYAML==5.1 155 | pyzmq==18.0.0 156 | QtAwesome==0.5.7 157 | qtconsole==4.4.3 158 | QtPy==1.7.0 159 | requests==2.21.0 160 | rope==0.12.0 161 | rsa==4.0 162 | ruamel-yaml==0.15.46 163 | scikit-image==0.14.2 164 | scikit-learn==0.20.3 165 | scipy==1.2.1 166 | seaborn==0.9.0 167 | Send2Trash==1.5.0 168 | simplegeneric==0.8.1 169 | singledispatch==3.4.0.3 170 | six==1.12.0 171 | snowballstemmer==1.2.1 172 | sortedcollections==1.1.2 173 | sortedcontainers==2.1.0 174 | soupsieve==1.8 175 | Sphinx==1.8.5 176 | sphinxcontrib-websupport==1.1.0 177 | spyder==3.3.3 178 | spyder-kernels==0.4.2 179 | SQLAlchemy==1.3.1 180 | statsmodels==0.9.0 181 | sympy==1.3 182 | tables==3.5.1 183 | tblib==1.3.2 184 | terminado==0.8.1 185 | testpath==0.4.2 186 | toolz==0.9.0 187 | tornado==6.0.2 188 | tqdm==4.31.1 189 | traitlets==4.3.2 190 | unicodecsv==0.14.1 191 | urllib3==1.24.1 192 | wcwidth==0.1.7 193 | webencodings==0.5.1 194 | Werkzeug==0.15.2 195 | widgetsnbextension==3.4.2 196 | win-inet-pton==1.1.0 197 | win-unicode-console==0.5 198 | wincertstore==0.2 199 | wrapt==1.11.1 200 | xlrd==1.2.0 201 | XlsxWriter==1.1.5 202 | xlwings==0.15.4 203 | xlwt==1.3.0 204 | zict==0.1.4 205 | zipp==0.3.3 206 | -------------------------------------------------------------------------------- /requierments.txt: -------------------------------------------------------------------------------- 1 | Flask<1 2 | python-dotenv 3 | python-jose-cryptodome 4 | flask-cors 5 | six 6 | flask_pymongo -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import http.client 2 | import json 3 | from six.moves.urllib.request import urlopen 4 | conn = http.client.HTTPSConnection("") 5 | payload = "" 6 | headers = {} 7 | conn.request("POST", "/oauth/token", payload, headers) 8 | res = conn.getresponse() 9 | data = res.read() 10 | token = json.loads(data)['access_token'] 11 | jsonurl = urlopen("") 12 | jwks = json.loads(jsonurl.read()) 13 | 14 | import socket 15 | import ssl 16 | 17 | conn = http.client.HTTPConnection("") 18 | 19 | headers = { 'authorization': "Bearer "+ token } 20 | 21 | 22 | conn.request("GET", "/device", headers=headers) 23 | 24 | res = conn.getresponse() 25 | data = res.read() 26 | # print(token) 27 | # print(data.decode("utf-8")) 28 | 29 | 30 | from flask import Flask, request 31 | from flask import render_template 32 | from flask_pymongo import PyMongo,MongoClient 33 | app = Flask(__name__) 34 | uri = "" 35 | db = MongoClient(uri) 36 | database = db['db'] 37 | collection = database['device'] 38 | post_data = { 39 | 'name': 'Python and MongoDB', 40 | 'device_type':'this that test' 41 | } 42 | # result = collection.insert_one(post_data) 43 | 44 | # device = db.db.device 45 | # output = [] 46 | # for d in device.find(): 47 | # output.append({'name':d['name'], 'device_type': d['device_type']}) 48 | # print(output) device = mongo.db.device 49 | headers = { 'authorization': "Bearer "+ token, 'device_id':'try', 'name':'Ethan', 50 | 'identifier':'Ethan', 'device_type':'Ethan', 'controller_gateway':'Ethan'} 51 | 52 | conn.request("PUT", "/device", headers=headers) 53 | 54 | res = conn.getresponse() 55 | data = res.read() 56 | print(data.decode("utf-8")) 57 | 58 | 59 | # device_id = request.json['device_id'] 60 | # identifier = request.json['identifier'] 61 | # name = request.json['name'] 62 | # device_type = request.json['device_type'] 63 | # controller_gateway = request.json['controller_gateway'] 64 | # new_device_id = device.insert({'device_id' : device_id, 'identifier' : identifier, 'name': name, 'device_type' : device_type, 'controller_gateway' : controller_gateway}) 65 | # new_device = device.find_one({'_id': new_device_id}) 66 | # output = {'device_id' : new_device['device_id'], 'identifier' : new_device['identifier'], 'name': new_device['name'], 'device_type' : new_device['device_type'], 'controller_gateway' : new_device['controller_gateway']} 67 | # print(jsonify({'result': output})) 68 | --------------------------------------------------------------------------------