def parse_schedule_at(self, val): """ Tries to parse the schedule_at parameter and get the datetime value for scheduling :param val: schedule_at rest parameter :return: countdown in seconds or raising HTTPPreconditionFailed if parsing errored """ if val is None: return 0 else: # Do we have a ISO Date format ? try: schedule_at = datetime.strptime(val, '%Y-%m-%d %H:%M:%S') if schedule_at < datetime.now(): raise HTTPPreconditionFailed( 'Cannot schedule batch in past date', "Invalid past date given: %s" % schedule_at) except ValueError: # Do we have Seconds format ? m = re.match("^(\d+)s$", val) if not m: raise HTTPPreconditionFailed( 'Cannot parse scheduled_at value', ("Got unknown format: %s, correct formats are " "'YYYY-MM-DD mm:hh:ss' or number of seconds, " "c.f. http://docs.jasminsms.com/en/latest/apis/rest") % val) return int(m.group(1)) else: return (schedule_at - datetime.now()).total_seconds()
def raise_error(self, error_code=None, desc='Something went wrong in server'): if error_code and error_code != 500: if error_code == 401 or error_code == 403: redis_cli = Redis.get_redis_client() if redis_cli is not None: access_token = redis_cli.delete('sheets_v4_access') else: print('Redis client is not active') if error_code == 400: raise HTTPBadRequest(description=desc or '') elif error_code == 401: raise HTTPUnauthorized(description=desc or '') elif error_code == 403: raise HTTPForbidden(description=desc or '') elif error_code == 404: raise HTTPNotFound(description=desc or '') elif error_code == 409: raise HTTPConflict(description=desc or '') elif error_code == 412: raise HTTPPreconditionFailed(description=desc or '') elif error_code == 422: raise HTTPUnprocessableEntity(description=desc or '') elif error_code == 503: raise HTTPServiceUnavailable(description=desc or '') else: raise HTTPError(HTTP_400, description=desc or '', code=error_code) else: raise HTTPInternalServerError(description=desc or '')
def on_post(self, req, resp, spreadsheet_id): sheet_range = req.get_param('range', required=True) try: req_body = json.load(req.bounded_stream) if 'values' in req_body and isinstance( req_body['values'], list) and len(req_body['values']): dimensions = 'dimensions' in req_body and req_body[ 'dimensions'] or 'ROWS' value_input = 'value_input_option' in req_body and req_body[ 'value_input_option'] or 'USER_ENTERED' insert_option = 'insert_option' in req_body and req_body[ 'insert_option'] or 'INSERT_ROWS' try: spreadsheets = DataStore.get_sheet_instance() except Exception as e: print('Datastore is not configured properly', e) raise HTTPServiceUnavailable( description='Datastore is not configured properly') def run(): sheet_body = { "values": req_body['values'], "majorDimension": dimensions } response = spreadsheets.values().append( spreadsheetId=spreadsheet_id, body=sheet_body, range=sheet_range, valueInputOption=value_input, insertDataOption=insert_option).execute() resp.body = json.dumps( dict( status='Success', message='Successfully Inserted data into sheet', spreadsheet_id=response['spreadsheetId'], )) resp.status = HTTP_201 super().main(run) else: raise HTTPPreconditionFailed( description= 'Values is a mandatory and must be valid for this request') except JSONDecodeError as err: print('Request body received', req.bounded_stream.read()) print('Error while processing request', err) raise HTTPUnprocessableEntity( description='Cannot parse the body from the request') except (HTTPServiceUnavailable, HTTPPreconditionFailed, HTTPError) as err: raise err except Exception as e: print('Exception in creating sheet', e) raise HTTPInternalServerError( description='Something went wrong while creating sheet')
def decode_request_data(self, request): """Decode the request stream and return a valid json""" try: request_data = request.stream.read() params = json.loads(request_data) except Exception as e: raise HTTPPreconditionFailed( 'Cannot parse JSON data', 'Got unparseable json data: %s' % request_data) else: return params
def on_put(self, req, resp, spreadsheet_id): value_input = req.get_param('value_input_option', default='USER_ENTERED') try: req_body = json.load(req.bounded_stream) if 'data' in req_body and isinstance( req_body['data'], list) and len(req_body['data']): try: spreadsheets = DataStore.get_sheet_instance() except Exception as e: print('Datastore is not configured properly', e) raise HTTPServiceUnavailable( description='Datastore is not configured properly') def run(): sheet_body = { "data": req_body['data'], "valueInputOption": value_input } response = spreadsheets.values().batchUpdate( spreadsheetId=spreadsheet_id, body=sheet_body).execute() resp.body = json.dumps( dict( status='Success', message= 'Successfully updated the data in the sheet', spreadsheet_id=response['spreadsheetId'], )) resp.status = HTTP_200 super().main(run) else: raise HTTPPreconditionFailed( description= 'Data is a mandatory and must be valid for this request') except JSONDecodeError as err: print('Request body received', req.bounded_stream.read()) print('Error while processing request', err) raise HTTPUnprocessableEntity( description='Cannot parse the body from the request') except (HTTPServiceUnavailable, HTTPPreconditionFailed, HTTPError) as err: raise err except Exception as e: print('Exception in updating sheet info', e) raise HTTPInternalServerError( description='Something went wrong while updating sheet')
def on_post(self, req, resp, username): try: req_body = json.load(req.bounded_stream) if username and 'password' in req_body and len( req_body['password']) > 5: redis_cli = super().redis_client if redis_cli is not None: password = req_body['password'] api_key = super().generate_token(32) access_token = super().generate_token(32) hash_password = hashlib.pbkdf2_hmac( 'sha256', password.encode('utf-8'), api_key[8:32].encode('utf-8'), 100000, dklen=128) user_info = dict(username=username, password=hash_password.hex(), api_key=api_key) access_info = dict(username=username, is_active=True, access_token=access_token) try: if not redis_cli.hexists('USERS', username): redis_cli.hset('USERS', username, json.dumps(user_info)) redis_cli.hset('USERS_APIKEY', api_key, json.dumps(access_info)) redis_cli.set(access_token, api_key, ex=28800) resp.status = HTTP_201 resp.body = json.dumps( dict(status='Succcess', message='Successfully created the user', user=dict(api_key=api_key, access_token=access_token, username=username))) else: raise HTTPConflict( description= 'User already exists with username {}'.format( username)) except HTTPConflict as err: raise err except Exception as err: raise Exception( 'Something went wrong while executing redis commands', err) else: raise HTTPServiceUnavailable( description='Data instances are not yet active') else: raise HTTPPreconditionFailed( description= 'Username and password are mandatory and must be valid for this request' ) except JSONDecodeError as err: print('Request body received', req.bounded_stream.read()) print('Error while processing request', err) raise HTTPUnprocessableEntity( description='Cannot parse the body from the request') except (HTTPPreconditionFailed, HTTPServiceUnavailable, HTTPConflict) as err: raise err except Exception as e: print('Exception in creating user', e) raise HTTPInternalServerError( description='Something went wrong while creating user info')
def on_post(self, request, response): """ POST /secure/sendbatch request processing Note: Calls Jasmin http api /send resource """ # Authentify user before proceeding status, _ = self.call_jasmin('balance', params={ 'username': request.context.get('username'), 'password': request.context.get('password') }) if status != 200: raise HTTPPreconditionFailed( 'Authentication failed', "Authentication failed for user: %s" % request.context.get('username')) batch_id = uuid.uuid4() params = self.decode_request_data(request) config = { 'throughput': http_throughput_per_worker, 'smart_qos': smart_qos } # Batch scheduling countdown = self.parse_schedule_at( params.get('batch_config', {}).get('schedule_at', None)) message_count = 0 for _message_params in params.get('messages', {}): # Construct message params message_params = { 'username': request.context.get('username'), 'password': request.context.get('password') } message_params.update(params.get('globals', {})) message_params.update(_message_params) # Convert _ to - # Added for compliance with json encoding/decoding constraints on dev env like .Net _message_params = message_params.copy( ) # Avoid dictionary key changed error in python 3.8 for k, v in _message_params.items(): del (message_params[k]) message_params[re.sub('_', '-', k)] = v del _message_params # Unset the variable # Ignore message if these args are not found if 'to' not in message_params or ('content' not in message_params and 'hex-content' not in message_params): continue # Do we have multiple destinations for this message ? if isinstance(message_params.get('to', ''), list): to_list = message_params.get('to') for _to in to_list: message_params['to'] = _to if countdown == 0: httpapi_send.delay(batch_id, params.get('batch_config', {}), message_params, config) else: httpapi_send.apply_async(args=[ batch_id, params.get('batch_config', {}), message_params, config ], countdown=countdown) message_count += 1 else: if countdown == 0: httpapi_send.delay(batch_id, params.get('batch_config', {}), message_params, config) else: httpapi_send.apply_async(args=[ batch_id, params.get('batch_config', {}), message_params, config ], countdown=countdown) message_count += 1 response.body = { 'data': { "batchId": '%s' % batch_id, "messageCount": message_count } } if countdown > 0: response.body['data']['scheduled'] = '%ss' % countdown
def on_post(self, req, resp, auth_type): if auth_type == 'login': try: req_body = json.load(req.bounded_stream) if 'username' in req_body and req_body[ 'username'] and 'password' in req_body and len( req_body['password']) > 5: username = req_body['username'] redis_cli = super().redis_client if redis_cli is not None: user_info = redis_cli.hget('USERS', username) if user_info is not None: user_info = json.loads(user_info) api_key = user_info['api_key'] hash_password = hashlib.pbkdf2_hmac( 'sha256', req_body['password'].encode('utf-8'), api_key[8:32].encode('utf-8'), 100000, dklen=128) if user_info['password'] == hash_password.hex(): access_info = redis_cli.hget( 'USERS_APIKEY', api_key) access_info = json.loads(access_info) if access_info is not None and access_info[ 'is_active']: access_token = access_info['access_token'] if not redis_cli.exists(access_token): access_token = super().generate_token( 32) access_info[ 'access_token'] = access_token access_info = redis_cli.hset( 'USERS_APIKEY', api_key, json.dumps(access_info)) redis_cli.set(access_token, api_key, ex=28800) resp.status = HTTP_200 resp.body = json.dumps( dict(status='Success', user=dict( api_key=api_key, access_token=access_token, username=username))) else: raise HTTPNotAcceptable( description='User is not active') else: raise HTTPUnauthorized( description= 'Username and password doesnot match') else: raise HTTPNotFound( description='No user with username {}'.format( username)) else: raise HTTPServiceUnavailable( description='Data instances are not yet active') else: raise HTTPPreconditionFailed( description= 'Username and password are mandatory and must be valid for this request' ) except JSONDecodeError as err: print('Request body received', req.bounded_stream.read()) print('Error while processing request', err) raise HTTPUnprocessableEntity( description='Cannot parse the body from the request') except (HTTPPreconditionFailed, HTTPServiceUnavailable, HTTPNotFound, HTTPUnauthorized, HTTPNotAcceptable) as err: raise err except Exception as e: print('Exception in signing in user', e) raise HTTPInternalServerError( description='Something went wrong while creating user info' ) elif auth_type == 'logout': try: api_key = req.get_header('Authorization') redis_cli = super().redis_client if redis_cli is not None: access_info = redis_cli.hget('USERS_APIKEY', api_key) access_info = json.loads(access_info) access_token = access_info['access_token'] redis_cli.delete(access_token) resp.status = HTTP_200 resp.body = json.dumps( dict(status='Succcess', message='Successfully signed out')) else: raise HTTPServiceUnavailable( description='Data instances are not yet active') except Exception as err: print('Exception while signing out', err) raise HTTPInternalServerError( description='Something went wrong while signing out') else: raise HTTPBadRequest(description='The request is not valid')