content: from __future__ import division
  
  from flask import render_template, request, Response, jsonify,redirect,url_for,flash
  from werkzeug.utils import secure_filename
  
  from app import app
  import pandas
  from pandas.util import hash_pandas_object
  
  
  import json
  import psycopg2
  import psycopg2.extras
  import os
  import pandas as pd
  import hashlib
  import datetime
  from datetime import date
  import numpy as np
  
  TRAINING_DATA={}
  TESTING_DATA={}
  
  
  ALLOWED_EXTENSIONS=set(['txt','csv'])
  SECRET_KEY='ml4all'
  app.secret_key='ml4all'
  
  @app.route('/index')
  def index():
  	return render_template('home.html')
  
  
  @app.route('/viz')
  def viz():
  	return render_template('viz.html')
  
  
  def to_csv(d, fields):
  	d.insert(0, fields)
  	return Response('\n'.join([",".join(map(str, e)) for e in d]), mimetype='text/csv')
  
  def allowed_file(filename):
  	return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  
  @app.route('/')
  def datset():
     return render_template('home.html')
  
  @app.route('/dataset',methods=['POST'])
  def upload_file():
  	train_file_name = 'train'
  	test_file_name ='test'
  	error=None
  	if request.method == 'POST':
  
  		# check if the post request has the file part
  		if train_file_name not in request.files or test_file_name not in request.files:
  			#flash('No file part')
  			error='Kindly upload both training and testing files'
  			#print("helllllo")
  			#print(request.url)
  			flash("load files")
  			#return redirect(request.url)
  			return render_template('home.html',error=error)
  
  
  		file = request.files[train_file_name]
  
  		# if user does not select file, browser also
  		# submit a empty part without filename
  		if file.filename == '':
  
  			print("hiiio")
  			print(request.url)
  			error='Kindly upload both training and testing files'
  
  			flash('No selected files')
  			return redirect(request.url)
  			#return render_template('home.html',error=error)
  
  		if file and allowed_file(file.filename):
  			flash("training file uplaoded")
  			filename = secure_filename(file.filename)
  			print(os.path.abspath(os.path.join('app/','uploads/')))
  			#file.save(os.path.abspath(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename)))
  			file.save(os.path.abspath(os.path.join('app/','uploads/', filename)))
  			print("done")
  			## convert file to pandas dataframe
  			#df_train=pd.read_csv(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename))
  			df_train=pd.read_csv(os.path.join('app/','uploads/', filename))
  
  			print("df_train1",df_train.head(5))
  
  			## hash the pd , change to binary --> get fom Jason
  			temp_hash=hash_pandas_object(df_train)
  			hash_train = hashlib.sha256(str(temp_hash).encode('utf-8','ignore')).hexdigest()
  			print("hash train1",hash_train)
  
  			## update dict ---> key:hash ,value: dataframe
  			#TRAINING_DATA[hash_train]=df_train
  
  		## For the test file
  		file = request.files[test_file_name]
  
  			# if user does not select file, browser also
  			# submit a empty part without filename
  		if file.filename == '':
  			print(request_url)
  			flash('No selected files')
  			return redirect(request.url)
  		if file and allowed_file(file.filename):
  			filename = secure_filename(file.filename)
  			#file.save(os.path.abspath(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename)))
  			file.save(os.path.abspath(os.path.join('app/','uploads/', filename)))
  
  			## convert file to pandas dataframe
  			#df_test=pd.read_csv(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename))
  			df_test=pd.read_csv(os.path.join('app/','uploads/', filename))
  			print("df test1",df_test.head(5))
  
  			## hash the pd , change to binary --> get fom Jason
  			temp_hash=hash_pandas_object(df_test)
  			hash_test = hashlib.sha256(str(temp_hash).encode('utf-8','ignore')).hexdigest()
  			print("test1",hash_test)
  
  			## update dict ---> key:hash ,value: dataframe
  
  			if df_train.shape[1]==(df_test.shape[1]-1):
  				temp=hash_test
  				hash_test=hash_train
  				hash_train=temp
  				temp_df=df_test
  				df_test=df_train
  				df_train=temp_df
  
  			TESTING_DATA[hash_test]=df_test
  			TRAINING_DATA[hash_train]=df_train
  			print("hash train2",hash_train)
  			print("hash test2",hash_test)
  			print("df train2",df_train)
  			print("df_test2",df_test)
  			flash("Uploaded files all training")
  			#return redirect('home.html')
  			#return jsonify({"hash":hash})
  			#return redirect(request.url)
  			return redirect(url_for('datset'))
  
  ## may look to add another app.route for test data hash but later
  
  #@app.route('/dataset_test',methods=['POST'])
  #def upload_testfile():
  
  
  #        file_name = 'test[]'
  #
  #        if request.method == 'POST':
  #
  #                # check if the post request has the file part
  #                if file_name not in request.files:
  #                        print(request.files)
  #                        flash('No file part')
  #                        return redirect(request.url)
  #
  #                file = request.files[file_name]
  #
  #                print (file.filename)
  #                # if user does not select file, browser also
  #                # submit a empty part without filename
  #                if file.filename == '':
  #
  #                        flash('No selected files')
  #                        return redirect(request.url)
  #                if file and allowed_file(file.filename):
  #
  #                        filename = secure_filename(file.filename)
  #
  #                        print(os.path.join(app.config['UPLOAD_FOLDER'], filename))
  #                        print(os.getcwd())
  #                        file.save(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename))
  #
  #                        ## convert file to pandas dataframe
  #
  #                        df_test=pd.read_csv(os.path.join('app/',app.config['UPLOAD_FOLDER'], filename))
  #                        print(df_test.head(5))
  
  #                        ## hash the pd , change to binary --> get fom Jason
  #                        temp_hash_test=hash_pandas_object(df_test)
  
  #                        print(temp_hash_test)
  #                        testing_data_hash = hashlib.sha256(str(temp_hash_test).encode('utf-8','ignore')).hexdigest()
  #                        print(testing_data_hash)
  #                        ## update dict ---> key:hash ,value: dataframe
  #                        TESTING_DATA[temp_hash_test]=df_test
  
  #                        return jsonify({"test_data_hash":testing_data_hash})
  
  
  BASIC_STATS = {}
  ##replace with actual function
  def jacky_function(df):
  	return date.today(),1,len(list(df))
  
  @app.route('/basic-stats/<hash>',methods=['GET'])
  def basic_stat(hash):
  	## step 1 if hash in BASIC_STATS return jsonify(BASIC_STATS[hash])
  	## else step 2
  	## pull in training data
          ## compute basic stats(basically call Jacky's function)  add results to dictionary BASIC_STATS, return jsonify(BASIC_STATS[hash])
          ## which is basically {"metadata": {"date": <ISO Format>, "version": <int>}, "data": {<data collection 1>: {}, <data collection 2>: {}, ...}}
  	print(TRAINING_DATA)
  
  	if hash in BASIC_STATS:
  		return jsonify({BASIC_STATS[hash]})
  		# error can be sent the same way jsonify(BASIC_STATS[error])
  	else:
  		#for key,value in TRAINING_DATA.items():
  			#print (key,value)
  		train_df=TRAINING_DATA[hash_train]
  		date_fn,version_fn,stats=jacky_function(train_df)
  		BASIC_STATS[hash_train]=stats
  		return jsonify({"metadata":{"date":str(date_fn),"version":version_fn},"data":stats})
  
  
  ## Prediction stats work the same way as basic stats except i need to call Jason's function instead of Jacky's function
  ## this would need a MODELS dictionary - key is the hash value, value is the model we train
  ## input to a function that Jason will write ---> model ( from the MODELS dictionary)
  ## output would be {"metadata": {"date": <ISO Format>, "version": <int>}, "data": {"technical_scores": [{"name": "AUC", "value": .867}, {"name": "Accuracy", "value": "79%"}], <data collection 2>: {}, ...}}
  # ( inform JAcky of the structure --how its returned)
  
  MODELS={}
  ##replace with actual function
  sample={}
  temp={}
  temp
  sample["technical_scores"]=[]
  def jason_function(df):
          return date.today(),100,len(list(df))
  
  @app.route('/prediction-stats/<hash>',methods=['GET'])
  def prediction_stat(hash):
  	print(TRAINING_DATA)
  	if hash in MODELS:
          	return jsonify({MODELS[hash]})
  	else:
  		train_df=TRAINING_DATA[hash]
  		date_fn,version_fn,pred_stats=jason_function(train_df)
  		MODELS[hash]=pred_stats
  		return jsonify({"metadata":{"date":str(date_fn),"version":version_fn},"data":pred_stats})
  
  
  
  ## test data prediction
  
  #replace by actual code
  def jason_model_creation(hash):
  	return 100
  def jason_prediction(model_saved,hash,testing_data_hash):
  	return 200
  
  ## this one should return a df
  def jason_add_pred_to_test(pred,testing_data_hash,hash):
  	return pd.DataFrame(np.random.randn(10, 5))
  
  from flask import send_from_directory
  MODELS_SAVED={}
  ## the below is for checking stuff only
  #TESTING_DATA["e0d47420dd0157af6af54d64b14f348f1fada3c050a73cd50fad2716a38fc2b2"]=1234
  @app.route('/predict/<hash>/<testing_data_hash>',methods=['GET'])
  def prediction_test(hash,testing_data_hash):
  	print("step1")
  	print(TRAINING_DATA)
  	for key, value in TRAINING_DATA.items() :
  		print (key, value)
  
  	if hash not in MODELS_SAVED:
  		train_df=TRAINING_DATA[hash]
  		test_df=TESTING_DATA[testing_data_hash]
  		temp=jason_model_creation(hash)
  		## replace above based on actual model
  		MODELS_SAVED[hash]=temp
  		print("step 2")
  	pred=jason_prediction(MODELS_SAVED[hash],hash,testing_data_hash)
  	pred_df=jason_add_pred_to_test(pred,testing_data_hash,hash)
  	print("step 3")
  	pred_filename="abcd.csv"  # need to have some component of date,version etc
  	pred_df.to_csv(pred_filename)
  	print(os.getcwd())
  	#pred_filename = secure_filename(pred_filename)
  	#file.save(os.path.join('app/',app.config['UPLOAD_FOLDER'], pred_filename))
  	#return send_from_directory(app.config['UPLOAD_FOLDER'],pred_filename)
  	print("step 4")
  	return send_from_directory(os.getcwd(),pred_filename)
  
  ## may add 2 more app.routes
  