Reputation: 65
I am having a python program that receives a CSV file (using pandas.read_csv option) from the user and returns the size of the CSV file as output.
My requirement is to have a GUI with an upload button and show the size of dataset in that GUI itself. I am a beginner in Python and Flask. Could anyone guide me here how to achieve this requirement in Python Flask?
I tried the following code but it says "Internal Server Error" and I don't know how to implement upload button.
import pandas as pd
from flask import Flask
app = Flask(__name__)
@app.route('/')
def data_shape():
data = pd.read_csv('iris.csv') # there should be an upload option / button for this dataset in the flask webservice
return data.shape
if __name__ == '__main__':
app.run(host='0.0.0.0')
I have to upload the csv file in the webservice and get the output of the python code in the webservice itself.
Upvotes: 3
Views: 1290
Reputation: 13349
app.py
import os
import shutil
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
from flask import Flask, session
from fastai.vision import *
basedir = os.path.abspath(os.path.dirname(__file__))
UPLOAD_FOLDER = os.path.join('static', 'csv')
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['csv','xls'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def upload_form():
return render_template('index.html')
@app.after_request
def add_header(response):
"""
Add headers to both force latest IE rendering engine or Chrome Frame,
and also to cache the rendered page for 10 minutes.
"""
response.headers['X-UA-Compatible'] = 'IE=Edge,chrome=1'
response.headers['Cache-Control'] = 'public, max-age=0'
return response
@app.route('/', methods=['POST'])
def upload_file():
# shutil.rmtree(UPLOAD_FOLDER)
# os.mkdir(UPLOAD_FOLDER)
disp_div = 'none'
disp_div_tumor = 'none'
d = request.form.to_dict()
# print("dddd;",d)
button_name = 'None'
if (len(d)!=0):
button_name = list(d.items())[-1][0]
file = request.files['file']
print("file:",file)
if file.filename == '':
flash('No file selected for uploading','red')
# return redirect(request.url)
return render_template('index.html', disp_div = disp_div)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
shutil.rmtree(UPLOAD_FOLDER)
os.mkdir(UPLOAD_FOLDER)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File successfully uploaded!', 'green')
print(UPLOAD_FOLDER)
print("==>",os.path.join(UPLOAD_FOLDER, sorted(os.listdir(app.config['UPLOAD_FOLDER']))[0]))
csv_file = pd.read_csv(os.path.join(UPLOAD_FOLDER, sorted(os.listdir(app.config['UPLOAD_FOLDER']))[0]))
csv_shape = csv_file.shape
return render_template('index.html', csv_shape=csv_shape)
# return redirect('/')
else:
flash('Allowed file types are txt, pdf, png, jpg, jpeg, gif', 'red')
# return redirect(request.url)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=False, port=5006)
## For deploying the app use `app.run(debug=False, host="0.0.0.0", port=80)`
templates/index.html
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="static/js/index.js"></script>
<script>
$(document).ready(function(){
$("#target").on('submit',function(){
// alert("It works");
});
});
</script>
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<form id="target" method="post" enctype="multipart/form-data">
<div name ="up" class="upload-btn-wrapper">
<button name="upload" class="btn">Upload CSV File</button>
<input type="file" id="file" value="go" name="file" onchange="$('#target').submit();"/>
</div>
</form>
<p>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class=flashes>
{% for category_color, message in messages %}
<p class="error_text" style="color:{{ category_color }};width:500px;">{{ message }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
</p>
===> {{ csv_shape }}
</body>
</html>
static/css/main.css:
.upload-btn-wrapper {
position: absolute;
overflow: hidden;
display: inline-block;
top:0;
left:5%;
}
.btn {
width: 15vw;
height: 4vh;
padding: 0 0 2px;
font-size: 2.2vh;
/* font: 90% "Trebuchet MS", Tahoma, Arial, sans-serif; */
font-family: sans-serif;
font-weight: bold;
line-height: 32px;
text-transform: uppercase;
margin: 0.2em auto;
display: block;
outline: none;
position: relative;
cursor: pointer;
border-radius: 3px;
color: #ffffff;
text-shadow: 1px 1px #024bde;
border: 1px solid #507def;
border-top: 1px solid #2f73ff;
border-bottom: 1px solid #2a67ff;
box-shadow: inset 0 1px #4a82ff, inset 1px 0 #2653b9, inset -1px 0 #2d69e8, inset 0 -1px #4372e8, 0 2px #1c3d9e, 0 6px #2553a2, 0 4px 2px rgba(0,0,0,0.4);
background: -moz-linear-gradient(top, #cae285 0%, #a3cd5a 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#cae285), color-stop(100%,#a3cd5a));
background: -webkit-linear-gradient(top, #6292ff 0%,#2b6cff 100%);
background: -o-linear-gradient(top, #cae285 0%,#a3cd5a 100%);
background: -ms-linear-gradient(top, #cae285 0%,#a3cd5a 100%);
background: linear-gradient(top, #cae285 0%,#a3cd5a 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cae285', endColorstr='#a3cd5a',GradientType=0 );
background-color: #1c3c9e;
}
.btn::-moz-focus-inner{border:0}
.btn:active {
/*top: 3px;*/
/* border: 1px solid #88A84E;
border-top: 1px solid #6E883F;
border-bottom: 1px solid #95B855;
background: #A7CF5F;*/
box-shadow: inset 0 1px 2px #779441;
transform: translateY(3px);
}
.pred {
position: absolute;
left: 10%;
bottom: 0;
}
.upload-btn-wrapper input[type=file] {
font-size: 100px;
position: absolute;
left: 0;
top: 0;
opacity: 0;
}
.submit_btn {
border: 2px solid gray;
color: gray;
background-color: white;
padding: 8px 20px;
border-radius: 8px;
font-size: 20px;
font-weight: bold;
}
.error_text {
position: absolute;
top: 2.7vh;
font-weight: bold;
font-size: 2vh;
left: 5%;
}
Directory structure:
|-- fapp.py
|-- static
| |-- css
| | `-- main.css
| `-- csv
`-- templates
`-- index.html
Upvotes: 2