I am running a python flask app on Docker. The app consists of a frontend in which a user provides a search term and the app returns an HTML file with insights and images. The problem is that after the first time I try the app, the HTML file keeps returning the images of the first try.
If I erase cookies, the problem is solved. But I cannot ask a user to erase cookies every time she needs to use the app.
I tried using os.remove before saving every image, but this doesn't work.
from googleapiclient.discovery import build
import pandas as pd
import matplotlib.pyplot as plt
from flask_restful import Api
from flask import Flask,render_template,request
import math
application = Flask(__name__)
api = Api(application)
#application.route('/')
def home():
return render_template('home.html')
#application .route('/predict',methods=['POST'])
def predict():
term1 = request.form['term1']
my_results_list = []
def google_query(query, api_key, cse_id, **kwargs):
query_service = build("customsearch", "v1", developerKey=api_key)
query_results = query_service.cse().list(q=query, cx=cse_id, **kwargs).execute()
return query_results['items']
my_results = google_query(term1,'api_key','cse_id', num = 10)
for result in my_results:
my_results_list.append(result['link'])
data = pd.DataFrame(my_results_list)
values = [1] * len(data)
N = len(values)
values += values[:1]
angles = [n/float(N)*2*math.pi for n in range(N)]
angles += angles[:1]
plt.polar(angles,values, marker='.', color = 'red')
temp = 'graph'
temp = 'static/' + temp + '.png'
plt.savefig(temp)
html = []
html.append("""<!DOCTYPE html><html>""")
html.append("""<img src="{{url_for('static',filename='graph.png')}}"/>""")
html = ' '.join(html)
temp = 'templates/result_vf.html'
print(html, file = open(temp,'w',encoding='utf-8'))
return render_template('result_vf.html')
if __name__ == '__main__':
application.run(host=('0.0.0.0'), port=8080 ,debug=True)
Related
I have a little flask application, it is mostly written with methods (just one class).
Can someone explain me - example would be great - why I am receiving 1 missing argument after adding self to method declaration?
Here is a code:
from __future__ import print_function
from flask import Flask, render_template, make_response
from flask import redirect, request, jsonify, url_for
from multiprocessing import Value
from flask_classful import FlaskView
#from settings import *
from utils.settings import *
import logging
import linecache
import os
import simplejson as json
import mysql.connector
counter = Value('i', 0)
app = Flask(__name__)
class FlaskCLS(FlaskView):
app.debug = False
app._static_folder = os.path.abspath("templates/static/")
#app.route('/v1/api/cords', methods=['GET', 'POST', 'OPTIONS'])
def snd_post():
res = make_response({'x': '55.333', 'y': '18.666'})
return res
#app.route('/', methods=['GET', 'POST', 'OPTIONS'])
def index():
result = []
data = request.data
with counter.get_lock():
counter.value += 1
out = counter.value
with open(str(out), 'a') as dumping:
json.dump(data, dumping)
# ----------------------parser-section------------
with open(str(out), 'r+') as file:
content = file.readlines()
for line in content:
result.append(line.replace('\\', "").replace('"', "").
replace('{', "").replace('}', '').
replace(']', '').replace(',','\n').
replace('[',''))
f = open(str(out), 'w')
f.write('')
f.close()
with open(str(out), 'a') as appending:
appending.write('')
for line in result:
appending.write(line)
# --------------------cords-grabbing-------------
x = linecache.getline(str(out), 1)
y = linecache.getline(str(out), 2)
fx = open('x', 'w')
fy = open('y', 'w')
fx.write(x)
fx.close()
fy.write(y)
fy.close()
mydb = mysql.connector.connect(
host=db_host,
user='root',
auth_plugin='mysql_native_password',
password=password,
buffered=buffered,
database=database)
mycursor = mydb.cursor()
mycursor.execute('select nazwa, x, y, SQRT(POW(69.1 * (x - 54.111), 2) + POW(69.1 *(18.222 - y)\
* COS(x / 57.3), 2)) as distance from wet_dane having distance <125 order by distance;')
mycursor.fetchall()
mydb.commit()
# ---------------------empty-files----------------
str_directory = '/var/www/html/'
list_files = [x for x in os.listdir(str_directory) if x[0] != '.']
for each_file in list_files:
file_path = '%s/%s' % (str_directory, each_file)
if os.path.getsize(file_path) == 0:
os.remove(file_path)
else:
pass
return render_template('layouts/index.html')
flask = FlaskCLS()
# ---------------------runner-section-------------
if __name__ == '__main__':
log = logging.getLogger('werkzeug')
log.disabled = True
app.run(host, port, debug, ssl_context=context)
My point is - how properly add self to index and snd_post methods?
I want to pass - for example - x variable from index to snd_post in the same class.
Without self flask doesn't allow me to do such an operation.
Thanks.
I don't have experience with Flask-Classful, but it looks that you are supposed to register the routes to the app this way:
class QuotesView(FlaskView):
def index(self):
return "Hello"
QuotesView.register(app)
Instead of the #app.route(...) decorator.
Ok, i've made a solution for this, now my main python file looks like this:
from __future__ import print_function
from flask import Flask, render_template, make_response
from multiprocessing import Value
from utils.settings import *
from py_methods.post import Post
from py_methods.db_connect import Db_conn
from py_methods.empty_files_del import DeleteEmpty
from py_methods.files_operations import Files
import logging
import os
app = Flask(__name__)
app.debug = False
app._static_folder = os.path.abspath("templates/static/")
#app.route('/v1/api/cords', methods=['GET', 'POST', 'OPTIONS'])
def snd_post():
return Post.snd_post()
class Main():
#app.route('/', methods=['GET', 'POST', 'OPTIONS'])
def index():
Files.parsing()
DeleteEmpty.del_empty()
Db_conn.wet_db()
return render_template('layouts/index.html')
# ---------------------runner-section-------------
if __name__ == '__main__':
log = logging.getLogger('werkzeug')
log.disabled = True
app.run(host, port, debug, ssl_context=context)
So it's just a runner - every method I wrote has own file and own class. This allow me to inheritance the variables. We can close this topic. Thansk for the answers.
i am starting with Python and while i was working on a project found this issue:
I have 2 .py files. One that has a Login and one that has a chart built with the Streamlit library.
The thing is that i want to redirect the user to the chart once he logs in. I havent found any response to this issue or i just dont get it.
What i think i have to do is wrap the Streamlit Graph file into a function but i dont know how.
Thanks for anyone reading this.
Login File:
from flask import Flask, render_template, redirect, url_for,request, session
from flask_mysql_connector import MySQL
import pymysql
from templates.home import get_input
app = Flask(__name__)
app.secret_key = "120395"
app.config["MYSQL_HOST"] = "localhost"
app.config["MYSQL_USER"] = "root"
app.config["MYSQL_PASSWORD"] = "anto1203"
app.config["MYSQL_DB"] = "amsterdamdb"
db = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if ('email_usuario_form' in request.form) and ('password_usuario_form' in request.form):
usuarios_email_py = request.form['email_usuario_form']
usuarios_password_py = request.form['password_usuario_form']
cursor = db.connection.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT USUARIOS_EMAIL, USUARIOS_LOGIN_PASSWORD FROM amsterdamdb.usuarios WHERE "
"USUARIOS_EMAIL=%s AND USUARIOS_LOGIN_PASSWORD=%s", (usuarios_email_py,
usuarios_password_py))
info = cursor.fetchone()
print(info)
if info is None:
return "Usuario y contraseña incorrectos"
else:
if info[0] == usuarios_email_py and info[1] == usuarios_password_py:
session['loginsuccess'] = True
return redirect(url_for("home"))
return render_template("login.html")
#app.route('/registro')
def registro():
return render_template("register.html")
#app.route('/home')
def home():
if session['loginsuccess'] == True:
return get_input()
if __name__ == '__main__':
app.run(debug=True)
Streamlit Graph File
import streamlit as st
import pandas as pd
from PIL import Image
from datetime import datetime, timedelta
import json
import requests
import altair as alt
st.write("""
# Bienvenido a Ámsterdam
**Mostrando información del mercado de acciones**
""")
st.sidebar.header('Ingrese parámetros')
def get_input():
aux_datetime = datetime.now()
today_date = aux_datetime.date()
treinta_dias_date = today_date - timedelta(days=30)
get_fecha_desde = st.sidebar.text_input("Fecha Inicial", treinta_dias_date )
get_fecha_hasta = st.sidebar.text_input("Fecha Final", today_date)
get_nemotecnico = st.sidebar.text_input("Identificador", "goog" )
return get_fecha_desde, get_fecha_hasta, get_nemotecnico
def get_data(nemotecnico_empresa, fecha_desde, fecha_hasta):
nemotecnico = nemotecnico_empresa
from_input_fecha_desde,from_input_fecha_hasta,from_input_nemotecnico = get_input()
fecha_desde = datetime.strptime(from_input_fecha_desde, '%Y-%m-%d')
fecha_hasta = datetime.strptime(from_input_fecha_hasta, '%Y-%m-%d')
nemotecnico = from_input_nemotecnico.upper()
fecha_desde_tmsp = str(round(datetime.timestamp(fecha_desde)))
fecha_hasta_tmsp = str(round(datetime.timestamp(fecha_hasta)))
if nemotecnico=="":
r = requests.get(
'https://finnhub.io/api/v1/stock/candle?symbol=&resolution=1&from=0&to=0&token=btagn3v48v6vivh8p9n0')
accionesJson = r.json()
else:
r = requests.get(
'https://finnhub.io/api/v1/stock/candle?symbol=' + nemotecnico + '&resolution=D&from=' + fecha_desde_tmsp + '&to=' + fecha_hasta_tmsp + '&token=wathever')
accionesJson = r.json()
open_values = accionesJson["o"]
close_values = accionesJson["c"]
fecha_values = accionesJson["t"]
fecha_values_size = len(fecha_values)
fecha_values_int = []
fecha_values_datetime = []
for x in range(0, fecha_values_size):
fecha_values_int.append(int(fecha_values[x]))
for i in range(0, fecha_values_size):
valor_aux = datetime.fromtimestamp((fecha_values_int[i]))
fecha_values_datetime.append(valor_aux.strftime("%m/%d/%Y"))
data_ordenada = {'Apertura': open_values,
'Cierre': close_values,
'Fecha': fecha_values_datetime}
chart_data = pd.DataFrame(data_ordenada)
source = chart_data
alt_chart = alt.Chart(source).transform_fold(
['Apertura', 'Cierre']
).mark_line().encode(
x=alt.X('Fecha:O',axis=alt.Axis(title="Fechas")),
y=alt.Y('value:Q',scale=alt.Scale(zero=False), axis=alt.Axis(title="Valor")),
tooltip=['Fecha', 'Apertura', 'Cierre'],
color='key:N'
).interactive().properties(
width=800,
height=500
)
st.write("", "", alt_chart)
st.header('Puntos de interés')
st.write(source.describe())
print(accionesJson)
So I'm currently working in a personal project using flask that graphs a user's table and then rendesr it in a different page. However, when I try to do this I get the folowing error: RuntimeError: unsupported value. I have tried all sorts of stuff and none of it has worked. Any help would be appreciated.
Application.py:
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
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from helpers import apology, login_required, toBinary
#configure application
app = Flask(__name__)
#Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True
#Ensure responses aren't cached
#app.after_request
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Configure CS50 Library to use SQLite database
db = SQL("sqlite:///graph.db")
#login_required
def graph():
#check wether to return user to a form or graph their table
if request.method == "POST":
#define variables
table_name = request.form.get("table_name")
x_axis = request.form.get("x_axis")
y_axis = request.form.get("y_axis")
x_values = list(request.form.get("x_values"))
y_values = list(request.form.get("y_values"))
graph_type = request.form.get("graph_type")
#check wether there is an x value for every y value
if len(x_values) != len(y_values):
return apology("Every x value must have a y value and viceversa", code=400)
#check graph type to use
if graph_type == "line":
plt.plot(x_values, y_values)
elif graph_type == "bar":
height = []
first_value = min(y_values) - 1
for x in y_values:
height.append(x%first_value)
plt.bar(x_values, height)
else:
plt.scatter(x_values, y_values)
plt.xlabel(x_axis)
plt.ylabel(y_axis)
plt.savefig("user_graph")
#set user_graph.png PATH
script_location = Path(__file__).absolute().parent
file_location = script_location / 'user_graph.png'
#pass graph to binary
user_graph = toBinary(file_location)
print(user_graph)
#insert user table into history for later use
db.execute("INSERT INTO history (username, graph, table_name) VALUES(:username, :graph, :table_name)", username=session["username"], graph=user_graph, table_name=table_name)
return render_template("graphed.html")
else:
return render_template("graph.html")
toBinary code:
with open(filename, "rb") as file:
data = file.read()
return data```
To insert a BLOB value the VALUE has to be in the format of x'??????' where ?????? is the byte stream/array as hex values e.g. x'FFFE1266543267890A'. So you need to convert the byte stream/array to such a String and that string could then be used.
I am trying to run python with html using flask locally, i try to render a template within a class object, it compiles but when i try to access it on http://localhost:5000 it gives me 404. Could anyone tell what I'm doing wrong here?
I am trying to display values from a json format using chart.js library.
from flask import Flask
from flask import render_template
import os.path
import json
app = Flask(__name__)
#import the json file
_player_json_file = os.path.join(os.path.dirname(__file__), 'players.json')
def read_players(player_file=None):
if player_file is None:
player_file = _player_json_file
try:
data = json.loads(open(player_file).read())
except IOError:
return {}
#make player dictionary
players = {}
#get player ID from json file = data.
for playerID in data:
players[playerID] = Player_data(data[playerID])
return players
class Players_Data (object):
#app.route("/")
def __init__(self, data):
"""
Assign all the values from the json file to new variables
the values are birth date age weight...
"""
self.player_ID = data['gsis_id']
self.gsis_name = data.get('gsis_name', '')
self.player_fullname = data.get('full_name', '')
self.player_first_name = data.get('first_name', '')
self.player_last_name = data.get('last_name', '')
self.player_weight = data.get('weight','')
self.player_height = data.get('height' , '')
self.player_birth = data.get('birthdate', '')
self.player_pro_years = data.get('years_pro', '')
self.player_team = data.get('data', '')
values = [player_ID,gsis_name,player_fullname,player_first_name,player_last_name,player_weight]
return render_template('chart.html', data=data, values=values)
if __name__ == "__main__":
app.run(host='localhost')
I don't think template rendering is the issue here. You can just return a string from your view as an example.
You get a 404 because that's not how you do classy views in flask. You can have a look here: http://flask.pocoo.org/docs/0.12/views/
But essentially you have to extend from flask.views.View and then manually attach your route to app instance, so it looks something like this:
from flask import Flask
from flask.views import View
app = Flask(__name__)
class Players_Data(View):
def dispatch_request(self):
return 'LOL'
app.add_url_rule('/', view_func=Players_Data.as_view('show_users'))
if __name__ == "__main__":
app.run(host='localhost')
I made a script python app.py and I managed to store data from a javascript form, thanks to a flask app :
app = Flask(__name__)
app.config.from_object('config')
db.init_app(app)
#app.route('/getFormData', methods=['POST'])
def get_javascript_data():
params = request.form.to_dict()
sunElevation = params['sunElevation']
cloudCoverage = params['cloudCoverage']
thresholdNDVI = params['thresholdNDVI']
limitScene = params['limitScene']
city = params['city']
data_search = passData(sunElevation, cloudCoverage, thresholdNDVI, limitScene, city)
return jsonify(data_search.data_dict)
if __name__ == '__main__':
app.run()
Here is the definition of the class passData, in models.py :
class passData:
def __init__(self, sunElevation, cloudCoverage, thresholdNDVI, limitScene, city):
self.sunElevation = sunElevation
self.cloudCoverage = cloudCoverage
self.thresholdNDVI = thresholdNDVI
self.limitScene = limitScene
self.city = city
self.data_dict = [{'sunElevation':self.sunElevation,'cloudCoverage':self.cloudCoverage, 'thresholdNDVI':self.thresholdNDVI, 'limit':self.limitScene, 'city':self.city}]
I need to use those different parameters (sunElevation...) in an other script, in a other folder, to execute a search of imagery and then run the script associated. My problem is that I don't know how to pass those data, because they seem to only exist in the fonction defined in the get_javascript_data().
If someone has an idea that could help me !
You just have to import the other script, call the function and pass the parameters:
app = Flask(__name__)
app.config.from_object('config')
db.init_app(app)
from path.to.your.file import your_function
#app.route('/getFormData', methods=['POST'])
def get_javascript_data():
params = request.form.to_dict()
sunElevation = params['sunElevation']
cloudCoverage = params['cloudCoverage']
thresholdNDVI = params['thresholdNDVI']
limitScene = params['limitScene']
city = params['city']
data_search = passData(sunElevation, cloudCoverage, thresholdNDVI, limitScene, city)
# call the function and pass the parameters
your_function(sunElevation, cloudCoverage) #...
return jsonify(data_search.data_dict)
Try adding the following code in your file, then import the script
import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
from eosLandviewer.main_naturalite import search