This question already has an answer here:
Flask css not updating [closed]
(1 answer)
Closed 2 years ago.
Flask app is rendering a previous version of my css file (I have saved and made changes, but when I inspect page, the css file shown is a previous version). Maybe previous version of css file is somehow stuck in the cache? I tried restarting browser, no luck .
Here is the code:
Part of app.py file (the part where I'm rendering the HTML file):
from flask import Flask,render_template,url_for,request
from twilio.rest import Client
app = Flask(__name__, template_folder='templates')
app.static_folder = 'static'
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader as pdr
#import yahoo finance api fixer
import fix_yahoo_finance as fyf
from pandas_datareader import data as pdr
from datetime import datetime, timedelta
#app.route('/')
def home():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}" />
</head>
<body>
<h1>Ticker Predictor</h1>
<h2>Using Machine Learning to Predict Tomorrow's Stock Prices</h2>
<br>
<h3>Simply enter a valid stock ticker below and hit the predict button to receive a text message of tomorrow's predicted opening price of that stock within around 10 minutes!</h3>
<!-- Main Input For Receiving Query to our ML -->
<form action="{{ url_for('predict')}}"method="post">
<input type="text" placeholder="Input Stock Ticker Here" required="required" />
<button type="submit">Predict</button>
</form>
{{ prediction_text }}
</body>
</html>
And here is the file structure:
TickerPredictor
|--static/
|--styles.css
|--templates/
|--index.html
|--app.py
Any help would be much appreciated! Thank you!
your app.py should be something like this
from flask import Flask,render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('index.html')
if __name__ == "__main__":
DEBUG = True
HOST = '0.0.0.0'
app.run(debug=DEBUG, host=HOST)
In your app.py file you did not mention the host. Update your app.py file and it should work.
Thanks to help from Rahul and stackoverflow.com/questions/21714653/flask-css-not-updating , I just performed a hard reload in my browser to clear the cache (CMD + SHIFT + R). In other words, the previous version of the css file was getting stored in the browser cache, clearing the cache gets rid of previous css file version and most recent version is then displayed (which is obviously what I want). Thanks everyone!
Related
First of all, I am very new to this so I hope I can explain myself the best I can.
I have a project in college in which we are using Flask to create a web app.
We need to gather inputs from users and then predict certain values with a model I have created, saved with Pickle and load it in my app .Now when I access to my page , I can see the home page shows and I am able to enter inputs but then the 'predict' page is not showing and giving me the error 'The method is not allowed for the requested URL'. I have consulted and follow different approaches to do this, for example from this article: https://www.kdnuggets.com/2019/10/easily-deploy-machine-learning-models-using-flask.html and this https://towardsdatascience.com/deploy-a-machine-learning-model-using-flask-da580f84e60c but still not able to make it work.
Any help, tips or good tutorials would be so much appreciated! Thank you so much in advance and sorry for this long post.
My project folder has the following contents:
app.py
model.pkl(This is my model saved on my disk using Pickle)
Powerproduction dataset.csv( the original dataset)
request.py
model.py ( this is the model )
import numpy as np
from flask import Flask, request, jsonify, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open('model.pkl', 'rb'))
#app.route('/')
def home():
return render_template('index.html')
#app.route('/predict',methods=['POST'])
def predict():
int_features = [float(x) for x in request.form.values()]
final_features = [np.array(int_features)]
prediction = model.predict(final_features)
output = round(prediction[0], 2)
return render_template('index.html', prediction_text='Power output should be $ {}'.format(output))
#app.route('/results',methods=['POST'])
def results():
data = request.get_json(force=True)
prediction = model.predict(final_features)
output = prediction[0]
return jsonify(output)
if __name__ == "__main__":
app.run(debug=True)`
import requests
url = 'http://127.0.0.1:5000/'
r = requests.post(url,json={'wind speed':})
print(r.json())
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pickle
dataset = pd.read_csv('Powerproduction dataset.csv')
X = dataset.loc['speed']
y = dataset.loc['power']
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X.values.reshape(-1,1), y)
pickle.dump(regressor, open('model.pkl','wb'))
model = pickle.load(open('model.pkl','rb'))
print(model.predict(np.array([[34.00]]))[0])
<head>
<meta charset="UTF-8">
<title>Wind speed and power output prediction</title>
</head>
<body style="background: #000;">
<h1>Power output predictions</h1>
<!-- Main Input For Receiving Query to our ML -->
<form action="{{ url_for('home')}}"method="post">
< />
<input type="text" name="wind speed" placeholder="wind speed" required="required" />
<button type="submit" class="btn btn-primary btn-block btn-large">Predict power output</button>
</form>
<br>
<br>
{{ prediction_text }}
</div>
</body>
</html>
Your action references your home route:
action="{{ url_for('home')}}
You want this to point to your predict route:
action="{{ url_for('predict') }}"
You should also have a space after " (but most browsers parse this correctly):
action="{{ url_for('predict') }}" method="post">
The empty < /> in your index.html should also be removed.
I'd also fix the indentation, usually you don't indent after #app.route(..) and make sure you have an empty line between function end and your next route to make it more readable (there is a standard named PEP-8 that defines how Python code should look - Pycharm and other editors will usually give you hints if you don't conform):
#app.route('/predict',methods=['POST'])
def predict():
..
#app.route(...)
def foo():
..
i am currently working on a website using html, flask, sqlite3 and Python.
in my python code i run this SQL query:
profile_rows = db.execute("SELECT * FROM profile WHERE profile_id = :profile_id", profile_id=session["user_id"])
in the flask feed i can see that it works just fine and correctly inserts the id:
SELECT * FROM profile WHERE profile_id = 11
The query does not return any rows like it should. it acts as if there was no row in the database.
if instead i run the code used by my program:
SELECT * FROM profile WHERE profile_id = 11
via "phpLiteAdmin v1.9.7.1" directly on the database i get the correct rows (those which are in the database and have the profile_id 11).
how can this happen? I directly copied the query that was used by python (from the feed) into phpLiteAdmin so it cannot give out a different result. but it does!!!. please help.
If it helps: i know that the query does not return a row because i tried the following things:
1
if len(profile_rows) == 0:
return render_template("frontpage.html", warning="there are no rows in the db!")
returns the warning message
2
if profile_rows[0]["job"] is None:
return redirect("/update_profile")
returns: "IndexError: list index out of range"
3
return render_template("frontpage.html", warning="row count: " + len(profile_rows))
returns the warning "row count: 0"
with all other querys in my code this works just fine. just this one does not
reproductive example:
Python:
import os
import sys
import hashlib, binascii, os
import time
from functools import wraps
from cs50 import SQL
from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash
db = SQL("sqlite:///yourdatabase.db")
#app.route("/profile")
def profile():
profile_rows = db.execute"SELECT * FROM profile WHERE profile_id = :profile_id", profile_id="1")
if len(profile_rows) == 0:
return render_template("profile.html", warning="row count: " + len(profile_rows))
return render_template("profile.html")
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<title>Profile</title>
</head>
<body>
{% if warning != NULL %}
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Warning!</strong> {{ warning }}
</div>
{% endif %}
</body>
</html>
SQLite3:
CREATE TABLE 'profile' ('profile_id' integer PRIMARY KEY NOT NULL, 'title' varchar(150), 'text' varchar(15000), 'job' varchar(100), 'area' varchar(150))
INSERT INTO "profile" ("profile_id","title","text","job","area") VALUES ('1','Hello world,','test','job','workfield')
Thank you for all the helpful comments. Somehow the problem solved itself. As i started the CS50 IDE today the program worked just fine without changing a single line of code. I don't know what the problem was but as long as it does not happen again thats fine by me. Have a great day everyone!!!
I cant close the topic today for some reason, so if somebody knows how this could happen i am all ears :D
I will close this in the next days
Following this tutorial, I am trying to visualise a dataset using Holoviews instead of Bokeh (sample data available here as a CSV file), serving the results using Flask. I decided to use Flask and not Bokeh Server because I am building a larger workflow using the former.
My code is the following:
from flask import Flask, render_template, request
import numpy as np
import pandas as pd
from datetime import datetime
from bokeh.embed import components
from bokeh.io import curdoc
import holoviews as hv
hv.extension("bokeh")
app = Flask(__name__)
renderer = hv.renderer('bokeh')
infile = "./uploads/test.csv"
def loadRegionData(regionProperty, **kwargs):
df = pd.read_csv(infile, parse_dates=['Datetime'])
df1 = df[regionProperty]
df = pd.concat([df['Datetime'],df1], axis=1)
return hv.Curve(df)
colNames = ((pd.read_csv(infile, nrows=1)).drop(['Datetime'], axis=1)).columns.values
dmap = hv.DynamicMap(loadRegionData, kdims='RegionProperty').redim.values(RegionProperty=colNames)
hvplot = renderer.get_plot(dmap)
plot = hvplot.state
plot.name = 'plot'
curdoc().add_root(plot)
#app.route("/")
def index():
# Embed plot into HTML via Flask Render
script, div = components(plot)
return render_template("index.html", script=script, div=div)
if __name__ == '__main__':
app.run(port=5000, debug=True)
I am running into the following (unrelated issues)
When I deploy using Flask, the dropdowns to select the columns do not appear. I suspect that is because I am not returning/referring to the correct variables from the index() function into my index.html:
<html>
<head>
<link
href="http://cdn.bokeh.org/bokeh/release/bokeh-1.0.2.min.css"
rel="stylesheet" type="text/css">
<link
href="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.0.2.min.css"
rel="stylesheet" type="text/css">
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-1.0.2.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.0.2.min.js"></script>
</head>
<body>
<h1>Holoview test</h1>
{{ script|safe }}
{{ div|safe }}
</body>
</html>
How can I get Flask to also show the dropdown selector?
An unrelated issue which I found when I tested this app using Bokeh Server, and which could also arise in the Flask implementation, is that the scales do not adjust dynamically based on my column selection. Perhaps this can go as a separate question on SO, but I thought to include it here for now to keep things together.
I have a basic flask app where data frames are formed from two CSVs and some transformations happen and on the HTML page , a final result dataframe can be seen in a tabular format. It works fine till here.
Apart from that, I also want the user to have an option to download the same table as a CSV.
Below is my flask code:
from flask import *
import pandas as pd
app = Flask(__name__)
#app.route("/tables")
def show_tables():
df1 = pd.read_csv('daily.csv')
df2 = pd.read_csv('companies.csv')
df1['date']= pd.to_datetime(df1['date'], format='%m/%d/%y')
df3 = pd.merge(df1,df2,how='left',on='id')
dates = pd.DataFrame({"date": pd.date_range("2017-01-01", "2017-01-10")})
df4 = (df3.groupby(['id', 'name'])['date', 'value']
.apply(lambda g: g.merge(dates, how="outer"))
.fillna(0)
.reset_index(level=[0,1])
.reset_index(drop=True))
df4 = df4.sort_values(by=['id','date'])
df4.value = df4.value.astype(int)
df4['difference'] = df4.groupby('id')['value'].diff()
return render_template('view.html',tables=[df4.to_html(classes='Company_data')],
titles = [ 'Company_data'],filename=df4.to_csv())
#app.route('/tables_download/<filename>')
def tables_download(filename):
return response(filename) //--right way to pass the csv file?
if __name__ == "__main__":
app.run()
Below is my HTML code:
<!doctype html>
<title>Simple tables</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>Company data</h1>
{% for table in tables %}
<h2>{{titles[loop.index]}}</h2>
{{ table|safe }}
{% endfor %}
</div>
Download
On my HTML page, I don't even see the Download option.
Struggling to figure out what's wrong so looking for help
As documented in the Flask API, I believe that send_file or send_from_directory would be the way to implement this.
#app.route('/uploads/<path:filename>')
def download_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)
These are both documented on http://flask.pocoo.org/docs/0.12/api/
send_from_directory is more secure (if used correctly) as it limits the file available to download to just those in a specific directory preventing any 'hackers' from downloading your private information.
I'm trying to create a simple program which will replace {{ test }} with 'Hello world' by following a tutorial, however I am stumped and when I open the HTML file - as {{ test }} is shown on the page instead of 'Hello World' which is what should be appearing.
Any help would be appreciated because I am very unsure on what to do to fix this, thanks.
I am unsure if I have even linked the two files, as to my knowledge it was never specified in the video and I have only just noticed that there is no link between the two files.
Python Code:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template('index.html', test='hello world')
if __name__ == '__main__':
homepage()
else:
print('Please run this file as main, not as module.')
HTML Code:
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<p> {{ test }} </p>
</body>
</html>
Flask is a webserver. You are not meant to call the functions with app.route. Replace the last part with:
if __name__ == '__main__':
app.run()
and then visit http://127.0.0.1:5000/ in your browser. The template file is not meant to change.
If for some reason you don't want to run a server but you just want to create HTML files, then use Jinja2, the template engine behind Flask.