use python pandas to show csv to placeholder in web file - python

I have a csv file and need to convert it to view it in html. I know python pandas can do it with
df = pd.read_csv("myfile.csv")
df.to_html('output.html')'
but I don't want to show it in single web page, I have index.html file and I want to show it in there but in another section.

found the answer using tablib
from flask import Flask, render_template
import tablib
import os
app = Flask (__name__)
dataset = tablib.Dataset()
with open(os.path.join(os.path.dirname(__file__),'email.csv')) as f:
dataset.csv = f.read()
#app.route("/")
def index():
data = dataset.html
#return dataset.html
return render_template('index.html', data=data)
if __name__ == "__main__":
app.run()
index.html
<html>
<head>
<meta charset="utf-8" />
<link rel=stylesheet type=text/css href="{{ url_for('static',
filename='css/style.css') }}"/>
<title>Show CSV</title>
</head>
<body>
<div class="table">
{% block body %}
{{ data|safe }}
{% endblock %}
</div>
</body>
</html>

Related

Python - Flask - MatPlotLib

I am trying to embed a plot from a function that I pass into my flask application.
The below does everything fine but launches the plot outside of the browser.
I've read a lot about IO and all but I'm confused on how/where to handle that.
The function runBB() in app.py returns plt.show(). After being passed symbol which is retrieved from the form. Should I be passing fig instead to do the IO calculations in app.py or should I do that in the file that holds the function?
I don't want to save the file anywhere as I want this to be dynamic from the stand point of multiple not overwriting the saved file which is what IO gets around I believe.
app.py
#Dashboard page
#app.route("/dashboard", methods = ["POST", "GET"])
def dashboard():
if person["is_logged_in"] == True:
return render_template("dashboard.html", email = person["email"], name = person["name"])
else:
return redirect(url_for('login'))
#app.route("/form", methods = ["POST", "GET"])
def form():
if request.method == "POST":
symbol = request.form["symbol"]
bytes_obj = runBB(symbol)
return render_template("dashboard.html", symbol=bytes_obj)
dashboard.html
{% extends "layout.html" %}
{% block content %}
<head>
<title>Welcome</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename = 'dashboard.css')}}">
<link rel="stylesheet" type="text/css" href="../static/dashboard.css">
</head>
<body>
<div class="main">
<h1 class="name">Hi, {{name}}</h1>
<form action="{{ url_for('form') }}" method ="POST">
<p><input placeholder="Enter your symbol" type="text" name="symbol"></p>
<p><input type="submit" value="Run Report" class="btn-default"></p>
</form>
<P>{{bytes_obj}}</P>
<!-- <hr style="width: 30%"> -->
<h3 class="email">{{email}}</h3>
</div>
</body>
{% endblock %}
Can someone point me in the right direction?
I've tried to comprehend other similar stackoverflow questions and can't seem to grasp this or put it together.
Please refer to this link to learn how to do this using:
import io
import base64
https://gitlab.com/snippets/1924163

Bokeh scatter plots not showing

I tried to make a flask app that gets a CSV file from the user, then fits my ML algorithm and finally shows two scatter plots.
Although I could show individual scatter plots via Markup(file_html(plot_obj, CDN, "my plot"), when I use components(plot_obj), and render_template to show both of them together it does not show any of them. Also, I have no error in the console.
I am able to upload the data, then run my algorithm and get the results in the console, however I still don't see the plots.
here is my app.py:
from prad_run import fit
from plots_anomalies import tsne_plot
from bokeh.resources import INLINE, CDN
from bokeh.plotting import figure
import os
from flask import Flask, flash, request, redirect, render_template
from pr_run import fit
from plots import tsne_plot
app = Flask(__name__)
#app.route('/',methods = ['GET'])
def home():
return render_template('home.html')
#app.route('/', methods=['POST'])
def results():
if request.method == 'POST':
file = request.files['file']
df = pd.read_csv(file)
gold_label, df_pr = fit(df)
y_pr = df_pr.loc[:, 'avg_score']
X_tsne = df_pr.drop(columns='avg_score')
tsne_value = plot(X_tsne)
p_true = figure(title="Data with True Labels",plot_width=300, plot_height=300,)
true_df = pd.DataFrame(data=tsne_value, columns=["v1", "v2"])
colormap = {1: 'red', 0: 'green'}
true_df['label'] = gold_label
true_df["color"] = true_df['label'].map(lambda x: colormap[x])
p_true.scatter(true_df['v1'], true_df['v2'], color=true_df['color'], fill_alpha=0.8, size=5)
p_pr = figure(title="Predicted results",plot_width=300, plot_height=300)
tsne_df = pd.DataFrame(data=tsne_value, columns=["v1", "v2"])
tsne_df["pr"] = [1 if x > 0.115 else 0 for x in y_pr]
colormap = {1: 'red', 0: 'green'}
tsne_df['color'] = tsne_df['pr'].map(lambda x: colormap[x])
print(tsne_df['color'].values)
p_pr.scatter(tsne_df['v1'], tsne_df['v2'], color=tsne_df['color'], fill_alpha=0.8, size=7)
js1, divs1 = components(p_true)
js2, divs2 = components(p_pr)
return render_template("home.html", js1=js1, divs1=divs1,js2=js2, divs2=divs2 )
In my home.html:
<!doctype html>
<html>
<title>Python Flask File Upload Example</title>
<h2>Select a file to upload</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="file" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
<meta charset="UTF-8">
<head>
<title>Figure examples</title>
<link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.css" type="text/css" />
<script type="text/javascript" src="http://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.js"></script>
<link
href="https://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.css"
rel="stylesheet" type="text/css">
<link
href="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.4.0.min.css"
rel="stylesheet" type="text/css">
<link
href="https://cdn.bokeh.org/bokeh/release/bokeh-tables-1.4.0.min.css"
rel="stylesheet" type="text/css">
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.4.0.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-1.4.0.min.js"></script>
{{ script|safe }}
</head>
<body>
<div style="width: 20%; display: inline-block;">
{{ divs1 | safe }}
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.4.0.min.js"></script>
{{ js1 | safe }}
</div>
<div style="width: 20%; display: inline-block;">
{{ divs2 | safe }}
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.4.0.min.js"></script>
{{ js2 | safe }}
</div>
</body>
</html>
Any idea what is causing this problem?
The <script> tags returned by components have to go in the <head> not <body>. Additionally, you don't need to load BokehJS from CDN multiple times as you are doing above.
You might also want to consider the newer json_items API for embedding, which can be simpler in many cases:
https://docs.bokeh.org/en/latest/docs/user_guide/embed.html?highlight=components#json-items
I found out that the reason that my plots did not display was using Conda environment. If you use Bokeh and Flask I encourage you to use virtualenv in the same folder that you are making your app instead of creating Conda environment.

Method Not Allowed in Flask for IntegerField form

I'm trying to set up integer field validation on a form in Flask, but I keep getting 'Method Not Allowed'. I can't see what is wrong with my routes?
My main file is:
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import IntegerField
# from perfect_numbers import classify
app = Flask(__name__)
app.config['SECRET_KEY'] = 'MySecretKey'
# num = 12
# Classify = classify(num)
class PerfectForm(FlaskForm):
number = IntegerField(4)
#app.route('/', methods=['POST'])
def form():
form = PerfectForm()
return render_template('index.html', form = form)
if __name__ == '__main__':
app.run(debug=True)
Then I have a standard layout.html file:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>PERFECT App</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
And my index.html is:
{% extends 'layout.html' %}
{% block body %}
<h1>PERFECT NUMBERS</h1>
<p>This is a basic Flask App to illustrate Aliquot Sums and Perfect Numbers</p>
<p>Input a number to check if it is abundant, perfect, or deficient</p>
<form action="{{ url_for('/') }}" method="POST">
{{ form.csrf_token }}
{{ form.number }}
</form>
<!-- {{ num }} is {{ classify }} -->
{% endblock %}
First, change the app.route() signature to
#app.route('/', methods=['POST', 'GET'])
You have to fill the form and submit for your app to receive a POST request. When you first load the page on your browser, you technically send a GET request to flask, and it returns the page.
To handle your POST request separately, do something like this :
#app.route('/', methods=['POST', 'GET'])
def form():
if request.method == 'POST':
# Do something with request (access form elements with request.get(key))
return 'Somehing here'
form = PerfectForm()
return render_template('index.html', form = form)

Why am I getting a 500 error with this code?

I am trying to create a site with a webform using Flask, but I keep getting a 500 error
Here is my template/main.html
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<meta name="viewport" content="width=device-width"
initial=scale=1/>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='favicon.ico') }}" rel="shortcut icon">
</head>
<h2>Hello, this site is meant to test my fill_web_form.py script</h2>
<br>
<br>
<h1>Test Form</h1>
<form action="/" method="post" name="login">
{{ render_field(form.test_form) }}<br>
<p><input type="submit" value="Sign In"></p>
</form>
</html>
Here is my init.py file
from flask import Flask, render_template
#import sqlite3
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template("main.html")
if __name__ == "__main__":
app.run()
Here is my form.py file
from flask.ext.wtf import Form
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class LoginForm(Form):
test_form = StringField('test_form', validators=[DataRequired()])
Why do I keep getting a 500 error? I cant figure it out.
Run in debug mode app.run(debug=True) to see more information in browser.
You should import form and send to template. You may need secret_key to use csrf. etc.
from form import LoginForm
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
#app.route('/')
def homepage():
return render_template("main.html", form=LoginForm())

werkzeug.routing.BuildError with Flask Python

**difference to the suggested repeat, my error stemmed from the following line being missing in the original code session['message']=request.form['message'] wherease in the suggested duplicate was missing the render_template component`
I am trying to create user sessions with Flask, I don't care about authentication. I just want a page where they enter their name, and then they are redirected to the main page. I tried to follow the example in this link here but I get a werkzeug.routing.BuildError. To summarise my python app is:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'F34TF$($e34D';
#app.route('/')
def home():
return render_template('index.html')
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
session['message']=request.form['message']
return redirect(url_for('message'))
#app.route("/message")
def message():
return render_template("message.html")
if __name__ == '__main__':
app.run(debug=True)
and index.html is:
{% extends "layout.html" %}
{% block content %}
<h1>Say something</h1>
<form method="post" action="{{ url_for('signup') }}">
<p><label>Username:</label> <input type="text" name="username" required></p>
<p><button type="submit">Send</button></p>
</form>
{% endblock %}
layout.html is:
<!doctype html>
<html lang="en">
<head>
<title>Say somthing</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
You are getting that error because you don't have a route called message and yet you are redirecting to it.
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
# Create a message route first
return redirect(url_for('message'))
Here's a sample route called message
#app.route("/message")
def message():
return render_template("message.html")

Categories

Resources