def data(): try: conn = mysql.connect() cursor = conn.cursor() '''SELECT * FROM data_upload_notes ORDER BY upload_time DESC LIMIT 10;''' cursor.callproc('GetUploadNotes') upload_notes = cursor.fetchall() # Close database connection cursor.close() conn.close() return render_template('views/data.html', notes_data=upload_notes) except Exception as e: return render_template('error.html', error=str(e))
def model(): try: conn = mysql.connect() cursor = conn.cursor() # SELECT * FROM model_update # ORDER BY id # DESC LIMIT 1; cursor.callproc('GetLatestModelParameters') model_notes = cursor.fetchall() # Close database connection cursor.close() conn.close() return render_template('views/model.html', model_notes=model_notes) except Exception as e: return render_template('error.html', error=str(e))
def searchpage(): conn = mysql.connect() cursor = conn.cursor() cursor.callproc('GetPatientData') patient_data = cursor.fetchall() if request.method == "POST": patient = request.form['patient'] patient_fname = str(patient).split()[0] patient_lname = str(patient).split()[1] cursor.callproc('GetOnePatient', (patient_fname, patient_lname)) searched_patient_data = cursor.fetchall()[0] cursor.close() conn.close() if not searched_patient_data: return render_template('views/search.html', patient=None, patients=patient_data) else: return render_template('views/search.html', patient=searched_patient_data, patients=patient_data) return render_template('views/search.html', patient=None, patients=patient_data) else: cursor.close() conn.close() return render_template('views/search.html', patient=None, patients=patient_data)
def login(): error = None try: if request.method == 'POST': conn = mysql.connect() cursor = conn.cursor() cursor.callproc('GetUserData') user_data = cursor.fetchall() cursor.close() conn.close() username = request.form['username'] password = request.form['password'] for users in user_data: if username == users[3]: if password == users[4]: session['logged_in'] = True session['username'] = username return redirect(url_for('main_page')) else: error = "Invalid credentials. Try again" return render_template('views/login.html') error = "Invalid credentials. Try again" return render_template('views/login.html', error=error) else: return render_template('views/login.html', error=error) except Exception as e: error = "Invalid credentials. Try again" return render_template('views/login.html', error=error)
def model_update(): try: if request.method == 'POST': # 1. Load in all the form values and change them to the appropriate type # 2. Load dataset from database # 3. Train model # 4. Save model # STEP 1 # Load in all the form values and change them to the appropriate type # String criterion = request.form['criterion'] # String splitter = request.form['splitter'] # None, or int max_depth = request.form['max_depth'] if max_depth == "None": max_depth = None else: max_depth = int(max_depth) # Float, or int min_samples_split = request.form['min_samples_split'] if isint(min_samples_split): min_samples_split = int(min_samples_split) else: min_samples_split = float(min_samples_split) # Float, or int min_samples_leaf = request.form['min_samples_leaf'] if isint(min_samples_leaf): min_samples_leaf = int(min_samples_leaf) else: min_samples_leaf = float(min_samples_leaf) # Float min_weight_fraction_leaf = request.form['min_weight_fraction_leaf'] min_weight_fraction_leaf = float(min_weight_fraction_leaf) # None, float, int, or string max_features = request.form['max_features'] if max_features == "None": max_features = None elif isint(max_features): max_features = int(max_features) elif isfloat(max_features): max_features = float(max_features) # None, or int (also suppose to accept RandomState instance) # Cannot accept for a string value RandomState instance a it is an object random_state = request.form['random_state'] if random_state == "None": random_state = None else: random_state = int(random_state) # None, or int max_leaf_nodes = request.form['max_leaf_nodes'] if max_leaf_nodes == "None": max_leaf_nodes = None else: max_leaf_nodes = int(max_leaf_nodes) # Float min_impurity_decrease = request.form['min_impurity_decrease'] min_impurity_decrease = float(min_impurity_decrease) # None, dict, list of dicts, or "balanced" class_weight = request.form['class_weight'] if class_weight == "None": class_weight = None elif class_weight == "Balanced": pass else: class_weight = literal_eval(class_weight) # Boolean presort = request.form['presort'] if presort == "False": presort = False else: presort = True # STEP 2 # Load dataset from database # Connect to database to download entries # Create directory to store temporary files if not os.path.exists("blueprints/temporary_files"): os.makedirs("blueprints/temporary_files") conn = mysql.connect() cursor = conn.cursor() '''SELECT diagnosis, ... , fractal_dimension_mean FROM train_data;''' cursor.callproc('GetTrainData') data = cursor.fetchall() with open("blueprints/temporary_files/breast_cancer.csv", "w") as dataset: fieldnames = [ 'diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean', 'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean', 'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean' ] writer = csv.DictWriter(dataset, fieldnames=fieldnames) # Create file writer.writeheader() for row in data: # First two rows are the id and upload_notes_id writer.writerow({ 'diagnosis': row[0], 'radius_mean': row[1], 'texture_mean': row[2], 'perimeter_mean': row[3], 'area_mean': row[4], 'smoothness_mean': row[5], 'compactness_mean': row[6], 'concavity_mean': row[7], 'concave points_mean': row[8], 'symmetry_mean': row[9], 'fractal_dimension_mean': row[10] }) # STEP 3 # Train model breast_cancer_df = pd.read_csv( "blueprints/temporary_files/breast_cancer.csv") # All values are used for training, since model with the above parameters is assumed to be tested X = breast_cancer_df.drop('diagnosis', axis=1) Y = breast_cancer_df['diagnosis'] # Gini index for splitting clf = DecisionTreeClassifier( criterion=criterion, splitter=splitter, max_depth=max_depth, min_samples_split=min_samples_split, min_samples_leaf=min_samples_leaf, min_weight_fraction_leaf=min_weight_fraction_leaf, max_features=max_features, random_state=random_state, max_leaf_nodes=max_leaf_nodes, min_impurity_decrease=min_impurity_decrease, class_weight=class_weight, presort=presort) # Train clf.fit(X, Y) # STEP 4 # Save model into file for later use joblib.dump(clf, 'blueprints/temporary_files/decision_tree_model.pkl') # STEP 5 # Save parameters to database (we know model training went smoothly, without excepts) # Convert back to strings before running the query, as all values will be saved as strings # in the database criterion = str(criterion) splitter = str(splitter) max_depth = str(max_depth) min_samples_split = str(min_samples_split) min_samples_leaf = str(min_samples_leaf) min_weight_fraction_leaf = str(min_weight_fraction_leaf) max_features = str(max_features) random_state = str(random_state) max_leaf_nodes = str(max_leaf_nodes) min_impurity_decrease = str(min_impurity_decrease) class_weight = str(class_weight) presort = str(presort) # Get username of current user if 'username' in session: _user = session.get('username') else: raise ValueError("Username missing. How are you logged in?!") '''INSERT INTO model_update ( clinician_id, update_time, criterion, ... , presort ) VALUES ( entry_clinician_id, NOW(), entry_criterion, ... , entry_presort );''' cursor.callproc( 'AddToModelUpdates', (_user, criterion, splitter, max_depth, min_samples_split, min_samples_leaf, min_weight_fraction_leaf, max_features, random_state, max_leaf_nodes, min_impurity_decrease, class_weight, presort)) # Save the insertion conn.commit() # Close database connection cursor.close() conn.close() # Return to data route flash('Dataset successfully uploaded') return redirect(url_for('model_training.model')) else: return render_template( 'error.html') # Forces redirection to this url except Exception as e: return render_template('error.html', error=str(e))
def data_upload(): try: if request.method == 'POST': # Check if the post request has the file part if 'file' not in request.files: flash('No file part') return redirect(url_for('data.data')) file = request.files['file'] if file: # Get username of current user if 'username' in session: _user = session.get('username') else: raise ValueError( "Username missing. How are you logged in?!") # Time database rows are started to be updated _current_time = time.strftime('%Y-%m-%d %H:%M:%S') # Store userform data into data_upload_notes table _updateNotes = request.form['inputNotes'] # Connect to database to store entries conn = mysql.connect() cursor = conn.cursor() '''INSERT INTO data_upload_notes ( clinician_id, upload_time, source_notes ) VALUES ( entry_clinician_id, entry_upload_time, entry_source_notes );''' cursor.callproc('AddToUploadNotes', (_user, _current_time, _updateNotes)) # Save the row insertion conn.commit() # Make call to data_upload_notes table to get current id for most recent entry # The foregin key will ensure CSV and upload tables can be joined to find time of # upload for each table entry # Get last update notes ID inserted - Get the last ID auto-increment added to any table '''SELECT LAST_INSERT_ID();''' cursor.callproc('GetUploadNotesMostRecentID') update_notes_id = cursor.fetchone() # Read csv file to save into mySQL database stream = io.StringIO(file.stream.read().decode("UTF8"), newline=None) reader = csv.DictReader(stream) # Check that label exists for set of features, for each row # Check that all values are char/float, for each row # Limit the amount of decimal places to be able to store value in mySQL database for row in reader: if not row['diagnosis'].isalpha( ) or row['diagnosis'] == "": continue if isfloat(row['radius_mean']): v_radius_mean = float("{0:.5f}".format( float(row['radius_mean']))) else: v_radius_mean = -1.0 if isfloat(row['texture_mean']): v_texture_mean = float("{0:.5f}".format( float(row['texture_mean']))) else: v_texture_mean = -1.0 if isfloat(row['perimeter_mean']): v_perimeter_mean = float("{0:.5f}".format( float(row['perimeter_mean']))) else: v_perimeter_mean = -1.0 if isfloat(row['area_mean']): v_area_mean = float("{0:.5f}".format( float(row['area_mean']))) else: v_area_mean = -1.0 if isfloat(row['smoothness_mean']): v_smoothness_mean = float("{0:.5f}".format( float(row['smoothness_mean']))) else: v_smoothness_mean = -1.0 if isfloat(row['compactness_mean']): v_compactness_mean = float("{0:.5f}".format( float(row['compactness_mean']))) else: v_compactness_mean = -1.0 if isfloat(row['concavity_mean']): v_concavity_mean = float("{0:.5f}".format( float(row['concavity_mean']))) else: v_concavity_mean = -1.0 if isfloat(row['concave points_mean']): v_concave_points_mean = float("{0:.5f}".format( float(row['concave points_mean']))) else: v_concave_points_mean = -1.0 if isfloat(row['symmetry_mean']): v_symmetry_mean = float("{0:.5f}".format( float(row['symmetry_mean']))) else: v_symmetry_mean = -1.0 if isfloat(row['fractal_dimension_mean']): v_fractal_dimension_mean = float("{0:.5f}".format( float(row['fractal_dimension_mean']))) else: v_fractal_dimension_mean = -1.0 '''INSERT INTO train_data ( upload_notes_id, diagnosis, radius_mean, ... , fractal_dimension_mean ) VALUES ( entry_upload_notes_id, entry_diagnosis, entry_radius_mean, ... , entry_fractal_dimension_mean );''' cursor.callproc( 'AddToTrainData', (update_notes_id, row['diagnosis'], v_radius_mean, v_texture_mean, v_perimeter_mean, v_area_mean, v_smoothness_mean, v_compactness_mean, v_concavity_mean, v_concave_points_mean, v_symmetry_mean, v_fractal_dimension_mean)) # Save the row insertion conn.commit() # Close connection to database cursor.close() conn.close() # Return to data route flash('Dataset successfully uploaded') return redirect(url_for('data.data')) else: return render_template( 'error.html', error=str(e)) # Forces redirection to this url except Exception as e: return render_template('error.html', error=str(e))
def export_file(): try: # Connect to database to download entries conn = mysql.connect() cursor = conn.cursor() '''SELECT diagnosis, radius_mean, ... , fractal_dimension_mean FROM train_data;''' cursor.callproc('GetTrainData') data = cursor.fetchall() with open("blueprints/temporary_files/breast_cancer.csv", "w") as download_file: fieldnames = [ 'diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean', 'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean', 'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean' ] writer = csv.DictWriter(download_file, fieldnames=fieldnames) # Create file writer.writeheader() for row in data: # First two rows are the id and upload_notes_id writer.writerow({ 'diagnosis': row[0], 'radius_mean': row[1], 'texture_mean': row[2], 'perimeter_mean': row[3], 'area_mean': row[4], 'smoothness_mean': row[5], 'compactness_mean': row[6], 'concavity_mean': row[7], 'concave points_mean': row[8], 'symmetry_mean': row[9], 'fractal_dimension_mean': row[10] }) # Close database connection cursor.close() conn.close() # Download file return send_from_directory("blueprints/temporary_files", "breast_cancer.csv", as_attachment=True) except Exception as e: return render_template('error.html', error=str(e)) else: ''' Add send_from_directory maybe? I don't know if Response actually sends the file to the client, or it just creates the file for the server only. ''' # Return to data route flash('Dataset successfully downloaded') return redirect(url_for('data.data'))