def featureset(): # This requires a valid user. result = UserController.login( request.headers.get("auth_token"), request.headers.get("Authorization")) # If not a user, return the error. if not isinstance(result, User): return result if request.method == "POST": if result.role != "admin": return error("Permission denied", "You must have administrator rights to upload features.") else: return Featureset1Controller.post(request.form.get("trial_id"), request.files.get("file")) else: return Featureset1Controller.get(result)
def participants(): # This requires a valid user. result = UserController.login( request.headers.get("auth_token"), request.headers.get("Authorization")) # If not a user, return the error. if not isinstance(result, User): return result # If the user isn't an admin, return the error. if result.role != "admin": return error("Permission denied", "You must have administrator rights to upload features.") if request.method == "POST": return ParticipantController.post( request.form.get("id"), request.form.get("dom_hand"), request.form.get("watch_hand"), request.form.get("gender")) else: return ParticipantController.get(request.args.get("id"))
def trials(): # This requires a valid user. result = UserController.login( request.headers.get("auth_token"), request.headers.get("Authorization")) # If not a user, return the error. if not isinstance(result, User): return result # Handle the trial response. if request.method == "POST": if result.role != "admin": return error("Permission denied", "You must have administrator rights to upload trials.") else: return TrialController.post( request.form.get("participant_id"), request.files.get("file"), request.form.get("activity_name"), request.form.get("trial_num")) else: return TrialController.get(result)
def post(trial_id, file): if file is None: return error( "Featureset 1 file is missing.", "The POST request is missing the file containing feature data.") if trial_id is None: return error( "Featureset 1 trial_id is missing.", "The POST request to add a new feature is missing the trial_id attribute." ) database_conn = get_database() cursor = database_conn.cursor() ids = [] index = 0 try: for line in file: index += 1 # Get the features from the line. features = line.split(",") # Validate the length. if len(features) != 7: remove_files(database_conn, cursor, ids) cursor.close() database_conn.close() return error( "The wrong amount of features were sent.", "On line {} there were {} values instead of 7. " "There should be 6 features and one target.".format( index, len(features))) # Store the data in the database. cursor.execute( """ INSERT INTO public."Featureset_1" (meanXYZ, stdXYZ, trial_id) VALUES (%s, %s, %s) RETURNING id; """, ([features[0], features[1], features[2] ], [features[3], features[4], features[5]], trial_id)) # Commit the transaction. database_conn.commit() # Get the ID and target of the new feature. idx = cursor.fetchone()[0] ids.append(idx) cursor.close() database_conn.close() return success("{} features added.".format(len(ids))) # Delete any database entries if there was an error. except (): remove_files(database_conn, cursor, ids) cursor.close() database_conn.close() return error("Error storing featureset.", "An unknown error occurred on line {}.".format(index))
def login(auth_token, authorization): # Check if the user is authenticated through a token. if not is_authenticated(auth_token): # Check if credentials were provided. if (authorization is None) or ("Basic " not in authorization): return error( "Authorization not provided.", "Using Basic Auth, a username and password must be " "included in the header.") # Decode the username & password. authorization = b64decode( authorization.split("Basic ")[1]).decode("utf-8") username, password = authorization.split(":") # Ensure there is a valid username. if username is None: return error("Username not provided.", "A username must be included in the header.") if not isinstance(username, str): return error( "Username is not valid.", "A username must be constituted of text and numbers.") # Check the password validity. valid = validate_password(password) if valid is not True: return valid # There's a valid password. database_conn = get_database() cursor = database_conn.cursor() # Get the id and password of the user. cursor.execute( """ SELECT id, password, role FROM public."User" WHERE username=(%s); """, (username, )) attrs = cursor.fetchone() # Check if there is a user with that username. if attrs is None: cursor.close() database_conn.close() return error( "User doesn't exist.", "No user exists with that username. You should register an account." ) idx = attrs[0] hashed_pwd = attrs[1] role = attrs[2] # Verify the passwords match. try: PasswordHasher().verify(hashed_pwd, password) # Handle the passwords not matching. except VerifyMismatchError: cursor.close() database_conn.close() return error( "Passwords don't match.", "The password supplied doesn't match the one stored.") # The passwords match. Create an auth token for the user. auth_token, expiry = get_auth_token() # Store the auth token. cursor.execute( """ UPDATE public."User" SET auth_token = %s, auth_expiry = %s WHERE id = %s; """, (auth_token, expiry, idx)) # Commit the transaction. database_conn.commit() # Close the connections. cursor.close() database_conn.close() # Return the logged in user. return User(idx, username, auth_token, role) # The user is authenticated. Update the expiry date. expiry = get_auth_token()[1] database_conn = get_database() cursor = database_conn.cursor() cursor.execute( """ UPDATE public."User" SET auth_expiry = %s WHERE auth_token=(%s) RETURNING id, username, role; """, (expiry, auth_token)) # Commit the transaction. database_conn.commit() attrs = cursor.fetchone() cursor.close() database_conn.close() return User(attrs[0], attrs[1], auth_token, attrs[2])
def classify(acceleration_data, model_name): if acceleration_data is None: return error("Acceleration data not provided.", "Post acceleration data in the request.") if model_name is None: return error( "Model name not provided.", "Post model_name in the request to dynamically select a model.") # Get the features from the data. features, time_intervals = get_features(acceleration_data, FEATURE_SET) # Connect to the database. database_conn = get_database() cursor = database_conn.cursor() cursor.execute( """ SELECT data, target_accuracies FROM public."Model" WHERE name = %s; """, (model_name, )) response = cursor.fetchone() # Decode the response. classifier = pickle.loads(response[0]) accuracies = pickle.loads(response[1]) # Close the database connection. cursor.close() database_conn.close() # Predict the activities. predictions = classifier.predict(features) return_values = [] if model_name.startswith("as1") or model_name.startswith("as2"): for activity_id, time_interval in zip(predictions, time_intervals): # Get the model's accuracy for the target. accuracy = accuracies[name_id_map[activity_id]] # Create a wrapper object. activity = Activity(int(activity_id), name_id_map[activity_id], time_interval[0], time_interval[1], accuracy) # Add a key-value dictionary representation. return_values.append(activity.__dict__) if model_name.startswith("energy"): for energy_id, time_interval in zip(predictions, time_intervals): # Get the confidence score. accuracy = accuracies[energy_id_map[energy_id]] # Append the data. return_values.append({ "id": int(energy_id), "name": energy_id_map[energy_id], "start_time": time_interval[0], "end_time": time_interval[1], "confidence": accuracy }) if model_name.startswith("watch_hand"): for hand_id, time_interval in zip(predictions, time_intervals): hand = "left" if hand_id == LEFT_TARGET else "right" # Get the confidence score. accuracy = accuracies[hand] # Append the data. return_values.append({ "id": int(hand_id), "name": hand, "start_time": time_interval[0], "end_time": time_interval[1], "confidence": accuracy }) # Return the activities in json. return jsonify({"predictions": return_values})