def devices_route(): # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) response_details = construct_response(request_details) if not response_details['error']: if request_details['method'] == 'GET': list_kwargs = {} params, error, code = ingest_query('devices-get', request_details, request_models) if error: response_details['error'] = error response_details['code'] = code else: list_kwargs = { 'sql_table': sql_tables['device_registration'], 'record_id': '' } if 'query' in params.keys(): list_kwargs['query_criteria'] = params['query'] if 'results' in params.keys(): list_kwargs['max_results'] = params['results'] if not response_details['error']: record_list, record_updates = list_records(**list_kwargs) response_details['details'] = record_list response_details['updated'] = record_updates # create a new device elif request_details['method'] == 'POST': response_details = construct_response(request_details, request_models['devices-post']) if not response_details['error']: # retrieve asset associated with device asset_id = request_details['json']['asset_id'] asset_details = {} for asset in sql_tables['asset_registration'].list({'.id': {'equal_to': asset_id}}): asset_details = asset if not asset_details: response_details['error'] = 'Asset %s does not exist.' % asset_id response_details['code'] = 400 else: # create new record for device and associate with asset device_details = { 'dt': time(), 'active': True } for key, value in request_details['json'].items(): device_details[key] = value device_id = sql_tables['device_registration'].create(device_details) asset_details['devices'].append(device_id) sql_tables['asset_registration'].update(asset_details) response_details['details'] = { 'device_id': device_id } return jsonify(response_details), response_details['code']
def device_route(device_id=''): # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) response_details = construct_response(request_details) if not response_details['error']: # validate device id exists if not response_details['error']: if not device_id: response_details['error'] = 'Method requires a device_id on endpoint.' response_details['code'] = 400 elif not sql_tables['device_registration'].exists(device_id): response_details['error'] = 'Device ID does not exist.' response_details['code'] = 400 # retrieve current record if request_details['method'] == 'GET': device_details = sql_tables['device_registration'].read(device_id) response_details['details'] = device_details # update record elif request_details['method'] == 'PATCH': response_details = construct_response(request_details, request_models['device-patch']) if not response_details['error']: device_details = sql_tables['device_registration'].read(device_id) device_details['dt'] = time() for key, value in request_details['json'].items(): device_details[key] = value sql_tables['device_registration'].update(device_details) response_details['details'] = { 'device_id': device_id } response_details['updated'] = device_details['dt'] # delete device if request_details['method'] == 'DELETE': # remove device from asset device_details = sql_tables['device_registration'].read(device_id) if 'asset_id' in device_details.keys(): if device_details['asset_id']: if sql_tables['asset_registration'].exists(device_details['asset_id']): asset_details = sql_tables['asset_registration'].read(device_details['asset_id']) device_index = asset_details['devices'].index(device_id) if device_index > -1: asset_details['devices'].pop(device_index) sql_tables['asset_registration'].update(asset_details) # remove device sql_tables['device_registration'].delete(device_id) response_details['details'] = { 'status': 'ok' } return jsonify(response_details), response_details['code']
def works_route(): # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) response_details = construct_response(request_details) if not response_details['error']: # get list of work requests if request_details['method'] == 'GET': list_kwargs = {} params, error, code = ingest_query('work-get', request_details, request_models) if error: response_details['error'] = error response_details['code'] = code else: list_kwargs = { 'sql_table': sql_tables['work_request'], 'record_id': '' } if 'query' in params.keys(): list_kwargs['query_criteria'] = params['query'] if 'results' in params.keys(): list_kwargs['max_results'] = params['results'] if not response_details['error']: record_list, record_updates = list_records(**list_kwargs) response_details['details'] = record_list response_details['updated'] = record_updates # create a new asset elif request_details['method'] == 'POST': response_details = construct_response(request_details, request_models['work-patch']) if not response_details['error']: # create new record for device and associate with asset record_id = labID().id24 work_details = { 'id': record_id, 'dt': time(), 'active': True } work_details = sql_tables['work_request'].model.ingest(**work_details) sql_tables['work_request'].create(work_details) response_details['details'] = { 'work_id': record_id } return jsonify(response_details), response_details['code']
def work_route(work_id=''): # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) response_details = construct_response(request_details) if not response_details['error']: # validate device id exists if not response_details['error']: if not work_id: response_details['error'] = 'Method requires an work_id on endpoint.' response_details['code'] = 400 elif not sql_tables['work_request'].exists(work_id): response_details['error'] = 'Work ID does not exist.' response_details['code'] = 400 # retrieve current record if request_details['method'] == 'GET': work_details = sql_tables['work_request'].read(work_id) response_details['details'] = work_details # create new record elif request_details['method'] == 'PATCH': response_details = construct_response(request_details, request_models['work-patch']) if not response_details['error']: work_details = sql_tables['work_request'].read(work_id) work_details['dt'] = time() for key, value in request_details['json'].items(): work_details[key] = value sql_tables['work_request'].update(work_details) response_details['details'] = { 'work_id': work_id } response_details['updated'] = work_details['dt'] # delete device elif request_details['method'] == 'DELETE': sql_tables['work_request'].delete(work_id) response_details['details'] = { 'status': 'ok' } return jsonify(response_details), response_details['code']
def users_route(): # ingest request request_details = extract_request_details(request) app.logger.debug(request_details) response_details = construct_response(request_details) user_list = [] for record in sql_tables['users'].list(): user_list.append(record) response_details['details'] = user_list app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def sources_route(): ''' sources route ''' # ingest request params from labpack.parsing.flask import extract_request_details request_details = extract_request_details(request) response_details = construct_response(request_details) # send response response_details['details'] = attesters_map app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def query_route(): ''' query route ''' # ingest request params from labpack.parsing.flask import extract_request_details request_details = extract_request_details(request) user_token = request_details['params'].get('token', '') query_type = request_details['json'].get('type', '') query_text = request_details['json'].get('text', '') # construct generic response response_details = construct_response(request_details) details = { 'msg': "Yeah... I didn't get that. Try again.", 'audio': {}, 'content': {} } # parse text query_map = parse_query(query_text, producers_map) # request attestations if query_map['action'] == 'verify': attestation_list = get_attestations(query_map, attesters_map) msg, content = synthesize_attestations(attestation_list, producers_map, attesters_map) details['msg'] = msg details['content'] = content elif query_map['action'] == 'attest': attester_signature = user_token attestation_result = post_attestation(query_map, attester_signature) msg = synthesize_attestation(attestation_result, producers_map) details['msg'] = msg if query_type == 'speech' and details['msg']: from base64 import b64encode synthesize_response = speech_client.synthesize(details['msg'], voice_id='Nicole') audio_stream = synthesize_response['audio_stream'] content_type = synthesize_response['content_type'] base64_audio = b64encode(audio_stream).decode() details['audio'] = { 'audio_data': base64_audio, 'content_type': content_type, 'volume_level': 1.0 } response_details['details'] = details app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def webhook_route(webhook_token=''): # ingest request request_details = extract_request_details(request) # flask_app.logger.debug(request_details) response_details = construct_response(request_details) call_on_close = None if webhook_token not in webhook_map.keys(): response_details['error'] = 'Invalid webhook token.' response_details['code'] = 404 # send webhook content to bot if not response_details['error']: if request_details['json']: observation_details = { 'callback': False, 'gateway': 'webhook', 'details': request_details } for key, value in webhook_map[webhook_token].items(): observation_details[key] = value if observation_details['callback']: response_details = bot_client.analyze_observation(**observation_details) else: def webhook_callable(): bot_client.analyze_observation(**observation_details) # add placeholder for telegram if observation_details['service'] == 'telegram': telegram_client.send_message(request_details['json']['message']['chat']['id'], message_text='Gotcha. Working on it...') call_on_close = webhook_callable # response to request if call_on_close: response_kwargs = { 'response': json.dumps(response_details), 'status': response_details['code'], 'mimetype': 'application/json' } response_object = Response(**response_kwargs) response_object.call_on_close(call_on_close) # flask_app.logger.debug(response_details) return response_object else: # flask_app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def profile_route(): ''' profile page route ''' request_details = extract_request_details(request) app.logger.debug(request_details) response_details = construct_response(request_details) access_token = request_details['params'].get('token', '') if not access_token: response_details['error'] = 'Access token is missing' if not response_details['error']: # retrieve flightplan if request_details['method'] == 'GET': flightplan_details = retrieve_flightplan(access_token) response_details['details'] = flightplan_details # update flightplan elif request_details['method'] == 'POST': success = update_flightplan(access_token, request_details['json']) response_details['details'] = {'success': success} app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def authorize_service_route(service_name=''): ''' a method to handle the oauth2 callback ''' # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) request_details['json'] = {'service': service_name} request_details['json'].update(**request_details['params']) response_details = construct_response(request_details, request_models['authorize-get']) # validate existence of service if not response_details['error']: service_name = request_details['json']['service'] if not service_name in oauth2_configs.keys(): response_details['error'] = '%s is not an available oauth2 service.' % service_name response_details['code'] = 400 # retrieve state from record state_value = '' state_details = {} if not response_details['error']: state_value = request_details['json']['state'] state_details = read_state(state_value) if not state_details: response_details['error'] = 'OAuth2 request does not exist or expired.' response_details['code'] = 400 # retrieve access token access_token = {} oauth2_config = {} if not response_details['error']: oauth2_config = oauth2_configs[service_name] oauth2_kwargs = { 'client_id': oauth2_config['oauth2_client_id'], 'client_secret': oauth2_config['oauth2_client_secret'], 'auth_endpoint': oauth2_config['oauth2_auth_endpoint'], 'token_endpoint': oauth2_config['oauth2_token_endpoint'], 'redirect_uri': oauth2_config['oauth2_redirect_uri'], 'request_mimetype': oauth2_config['oauth2_request_mimetype'], 'requests_handler': handle_requests } oauth2_client = oauth2Client(**oauth2_kwargs) auth_code = request_details['json']['code'] access_token = oauth2_client.get_token(auth_code) if access_token['error']: response_details['error'] = access_token['error'] response_details['code'] = access_token['code'] # save access token if not response_details['error']: token_kwargs = { 'account_id': state_details['account_id'], 'service_scope': state_details['service_scope'], 'service_name': service_name } if access_token['json']: token_kwargs['token_details'] = access_token['json'] create_token(**token_kwargs) else: response_details['error'] = 'Access token response is blank.' response_details['code'] = 400 # remove state record if not response_details['error']: delete_state(state_value) service_title = service_name.replace('_', ' ').capitalize() authorize_kwargs = { 'auth_name': service_title, 'bot_name': bot_config['bot_brand_name'] } authorize_kwargs.update(**landing_kwargs) authorize_kwargs['landing_page'] = False authorize_kwargs['page_details']['subtitle'] = 'OAuth2 Confirmation' if 'oauth2_service_logo' in oauth2_config.keys(): authorize_kwargs['auth_logo'] = oauth2_config['oauth2_service_logo'] return render_template('authorize.html', **authorize_kwargs), 200 flask_app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def telemetry_route(): # ingest request request_details = extract_request_details(request) app.logger.debug(request_details) call_on_close = None # handle get telemetry if request_details['method'] == 'GET': response_details = construct_response(request_details) user_id = request_details['params'].get('user') start_date = request_details['params'].get('start') end_date = request_details['params'].get('end') telemetry_list = [] if user_id and start_date and end_date: query_criteria = { '.user_id': { 'equal_to': user_id }, '.date': { 'min_value': start_date, 'max_value': end_date } } for record in sql_tables['telemetry'].list(query_criteria): telemetry_list.append(record) else: for record in sql_tables['telemetry'].list(): telemetry_list.append(record) response_details['details'] = telemetry_list app.logger.debug(response_details) return jsonify(response_details), response_details['code'] # handle post telemetry if request_details['method'] == 'POST': response_details = construct_response(request_details, telemetry_model) if not response_details['error']: telemetry_dt = request_details['json']['dt'] telemetry_record = { 'date': labDT.fromEpoch(telemetry_dt).zulu()[0:10], } for key, value in request_details['json'].items(): telemetry_record[key] = value telemetry_id = sql_tables['telemetry'].create(telemetry_record) response_details['details'] = {'id': telemetry_id} # test for consistent anomalies if telemetry_record['anomalous']: user_id = telemetry_record['user_id'] query_criteria = {'user_id': user_id} sort_criteria = [{'.dt': 'descend'}] count = 0 for record in sql_tables['telemetry'].list( query_criteria, sort_criteria): if not record['anomalous']: break count += 1 if count > 2: # send alert from server.utils import send_email def alert_user(): user_email = '' user_name = '' for user in sql_tables['users'].list( {'user_id': user_id}): user_email = user['email'] user_name = user['name'] break send_email(email_client, user_email, user_name) # call_on_close = alert_user # compose response if call_on_close: response_kwargs = { 'response': json.dumps(response_details), 'status': response_details['code'], 'mimetype': 'application/json' } response_object = Response(**response_kwargs) response_object.call_on_close(call_on_close) app.logger.debug(response_details) return response_object else: app.logger.debug(response_details) return jsonify(response_details), response_details['code']
def telemetry_route(device_id): # ingest request request_details = extract_request_details(request) flask_app.logger.debug(request_details) response_details = construct_response(request_details) if not response_details['error']: # retrieve telemetry from device if request_details['method'] == 'GET': list_kwargs = {} params, error, code = ingest_query('telemetry-get', request_details, request_models) if error: response_details['error'] = error response_details['code'] = code else: list_kwargs = { 'sql_table': sql_tables['device_telemetry'], 'record_id': '', 'query_criteria': { '.device_id': { 'equal_to': device_id } } } if 'query' in params.keys(): list_kwargs['query_criteria'].update(**params['query']) if 'results' in params.keys(): list_kwargs['max_results'] = params['results'] if not response_details['error']: record_list, record_updates = list_records(**list_kwargs) response_details['details'] = record_list response_details['updated'] = record_updates # create new record if request_details['method'] == 'PUT': response_details = construct_response(request_details, request_models['telemetry-put']) if not response_details['error']: # TODO analyze acoustic signature # evaluate change in acoustics # filter_criteria = { '.device_id': { 'equal_to': device_id } } # sort_criteria = [ { '.dt': 'descend' } ] # for telemetry in sql_tables['device_telemetry'].list(filter_criteria, sort_criteria): # if telemetry['fft'][0] < request_details['json']['fft'][0]: # asset_status = 'anomalous' # break # retrieve asset details device_details = sql_tables['device_registration'].read(device_id) asset_details = sql_tables['asset_registration'].read(device_details['asset_id']) # analyze temperature for range in manufacturers specs asset_status = 'normal' if asset_details['status'] == 'anomalous': asset_status = 'anomalous' if asset_details['specs']['temp_high'] or asset_details['specs']['temp_low']: device_temp = request_details['json']['temp'] if device_temp > asset_details['specs']['temp_high'] or device_temp < asset_details['specs']['temp_low']: asset_status = 'anomalous' # update asset details asset_details['status'] = asset_status sql_tables['asset_registration'].update(asset_details) # add new telemetry record telemetry_details = { 'dt': time(), 'device_id': device_id } for key, value in request_details['json'].items(): if key not in telemetry_details.keys(): telemetry_details[key] = value telemetry_id = sql_tables['device_telemetry'].create(telemetry_details) response_details['details'] = { 'telemetry_id': telemetry_id } return jsonify(response_details), response_details['code']