Having trouble with jsonify in Flask - python

I am fairly new to Flask and am currently working on a project whose goal is to transcribe mp3 files into JSON. I decided to attempt to use Flask, but it's been more challenging than I thought.
As of right now, I am able to display a example JSON file in one of my html pages, but I have not been able to format it. I looked at some previous answers that told me to use jsonify, but it hasn't worked apparently. If you guys could give me a hand, any kind of comment would be really apreciated. Here is my code:
from flask import Flask, render_template, url_for, request, redirect, json, jsonify
import json
import os
from pathlib import Path
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload', methods=['POST'])
def upload():
file = request.files['inputFile']
if Path(file.filename).suffix == '.mp3':
filename = os.path.join(app.static_folder, 'data', 'json_test.json')
with open(filename) as json_test:
data = json.load(json_test)
return render_template('index2.html', data=data)
else:
return render_template('erro.html')
if __name__ == "__main__":
app.run(debug=True)

Related

Use Flask path string to refer to variables

I have the following Flask app. It renders a html page with a form for each cell of the dataframe and allows the user to edit the cells and post the form data. The app then updates the dataframe.
'''
from flask import Flask, render_template, url_for, request, redirect
import pandas
app = Flask(__name__)
df_abc = pandas.read_excel('source1.xlsx')
#app.route('/modify/', methods=['POST', 'GET'])
def modify():
if request.method == 'POST':
global df_abc
df_abc = update_df_function() # this function returns an updated df based on the POST data
return redirect(url_for('modify'))
else:
table_data = df_abc.to_dict(orient='records')
return render_template('modify.html', table_data=table_data)
'''
However, I would like the following to work:
from flask import Flask, render_template, url_for, request, redirect
import pandas
app = Flask(__name__)
df_abc = pandas.read_excel('source1.xlsx')
df_xyz = pandas.read_excel('source2.xlsx')
#app.route('/modify/<name>', methods=['POST', 'GET'])
def modify(name):
if request.method == 'POST':
global name
name = update_df_function() # this function returns an updated df based on the POST data
return redirect(url_for('modify'))
else:
table_data = name.to_dict(orient='records')
return render_template('modify.html', table_data=table_data)
'''
This app would get the variable name from the Flask path. How can I set the variable names in the modify function (e.g. global df_abc) by using the string < name > from the Flask path? I.e. posting data from www.site.com/modify/df_abc should update df_abc, ./modify/df_xyz should update df_xyz etc.
Any help would be greatly appreciated. Thanks!
The answer is using globals() with globals()[name], as shown below, and explained in this answer https://stackoverflow.com/a/1373201
from flask import Flask, render_template, url_for, request, redirect
import pandas
app = Flask(__name__)
df_abc = pandas.read_excel('source1.xlsx')
df_xyz = pandas.read_excel('source2.xlsx')
#app.route('/modify/<name>', methods=['POST', 'GET'])
def modify(name):
if request.method == 'POST':
globals()[name] = update_df_function() # this function returns an updated df based on the POST data
return redirect(url_for('modify'))
else:
table_data = globals()[name].to_dict(orient='records')
return render_template('modify.html', table_data=table_data)

How to display csv data in tabular form in Flask Python?

I'm making a web app using the Flask framework with python, I want to make the web able to upload csv without saving and displaying data in a table with the template I made, I've added the syntax for uploading and processing the data until it's in a table view, but after running the website it goes to the 404 not found error message, how can I fix it?
I've made a code in main.py
from datetime import datetime
from flask import Flask, render_template, request, session
from FlaskWebProject2 import app
import os
import pandas as pd
from werkzeug.utils import secure_filename
#*** Flask configuration
UPLOAD_FOLDER = os.path.join('staticFiles', 'uploads')
ALLOWED_EXTENSIONS = {'csv'}
app = Flask(__name__, template_folder='templateFiles', static_folder='staticFiles')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = 'This is your secret key to utilize session in Flask'
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload', methods=['POST', 'GET'])
def uploadFile():
if request.method == 'POST':
# upload file flask
uploaded_df = request.files['uploaded-file']
# Extracting uploaded data file name
data_filename = secure_filename(uploaded_df.filename)
# flask upload file to database (defined uploaded folder in static path)
uploaded_df.save(os.path.join(app.config['UPLOAD_FOLDER'], data_filename))
# Storing uploaded file path in flask session
session['uploaded_data_file_path'] = os.path.join(app.config['UPLOAD_FOLDER'], data_filename)
return render_template('index_upload_and_show_data_page2.html')
#app.route('/show_data')
def showData():
# Retrieving uploaded file path from session
data_file_path = session.get('uploaded_data_file_path', None)
# read csv file in python flask (reading uploaded csv file from uploaded server location)
uploaded_df = pd.read_csv(data_file_path)
# pandas dataframe to html table flask
uploaded_df_html = uploaded_df.to_html()
return render_template('show_csv_data.html', data_var = uploaded_df_html)
I want the website can show the home page and upload, read and show csv data works properly
If you are requesting /upload and getting a 404. This is natural. You have added a handler for /upload endpoint:
#app.route('/upload', methods=['POST', 'GET'])
def uploadFile():
...
But uploadFile only supports POST requests. When you enter localhost/upload into the browser, the browser sends a GET request to the web server. There are two solutions for you with the same result:
Add another if to uploadFile function and check if incoming request is GET and if it is, show a page(e.g. a form to upload file).
Write another function like upload_file_form exclusively for GET requests to show a form.
P.S.: per PEP8, you should use camel_case for function names. e.g. upload_file rather than uploadFile

How to render Flask output to a string instead of browser

I have a template (.html file) that I want to render to a string instead of sending the rendered result to a browser.
I expected something like this to work, where the rendered html code is assigned to output as a string:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def index():
output = render_template("template.html")
if __name__ == "__main__":
app.run()
print(output)
Templates/template.html
<h1>some random text</h1>
manually push the required context might have solved the problem for me:
app = Flask(__name__)
with app.app_context():
template = render_template("template.html")
returning the string
If you are trying to escape the HTML tag and display the content in templete.html as a string on a browser you can use escape as shown below:
from flask import Flask, render_template
from markupsafe import escape, Markup
app = Flask(__name__)
#app.route("/")
def index():
output = render_template("template.html")
return escape(output)
if __name__ == "__main__":
app.run(debug=True)

how to enter url having two forward slashes in it

I am entering an url to process a file and return me an api with an output example: 12.334.198.190:5000/home/files/xyx.pdf and in my linux vm the address of the file is /home/files/xyz.pdf so the error is 'No such file or directory: home/files/xyz.pdf'. I think the '/' before home is not being picked up and thus the error. Any idea how to fix this?
Adding code for reference:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
#categorie
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def get_dir(path):
categories = convert(path)
return categories
##app.route('/get_dir/<path>')
#def get_dir(path):
# return path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)

How to make a dataframe global inside a function and use it in another function in python flask

I am creating a Dataframe by taking input file from user on a website and processing it.After that I want the user to download the final result in a csv file.For that a Dataframe is required from previous function.
I have tried passing the dataframe but it is giving me error as it is defined in another function.
My code is
from flask import Flask, render_template, request, redirect
from werkzeug import secure_filename
app = Flask(__name__)
#app.route('/uploader', methods = ['GET','POST'])
def upload():
new=nrecs[['UserID','ProductID','Rating']]
new['Recommendations'] = list(zip(new.ProductID, new.Rating))
res=new[['UserID','Recommendations']]
res_new=res['Recommendations'].groupby([res.UserID]).apply(list).reset_index()
pd.options.display.max_colwidth = 500
return render_template('simple.html', tables=[res_new.to_html(classes='data')], titles='')
#app.route('/download-csv', methods = ['GET'])
def download():
return res_new.to_csv('Recommendations.csv')
This is a small snipet of my code not the full code.
When a user will click on download recommendations button it should download the csv file.
Is there any other way around it can be done.
You can also store the file on the server and send it to the user in your download-csv route. Here is a send file tutorial
from flask import Flask, render_template, send_file
app = Flask(__name__)
#app.route('/uploader', methods = ['GET','POST'])
def upload():
new=nrecs[['UserID','ProductID','Rating']]
new['Recommendations'] = list(zip(new.ProductID, new.Rating))
res=new[['UserID','Recommendations']]
res_new=res['Recommendations'].groupby([res.UserID]).apply(list).reset_index()
# store the dataframe on the server.
res_new.to_csv('Recommendations.csv')
pd.options.display.max_colwidth = 500
return render_template('simple.html', tables=[res_new.to_html(classes='data')], titles='')
#app.route('/download-csv', methods = ['GET'])
def download():
# return the CSV file to the user here.
return send_file('Recommendations.csv')
You can try using a session object. See this question/answer. However, depending on the size of the dataframe, and what you are ultimately trying to do, this may not be the best way to do this. If you are trying to set up upload/download routes, storing the file on the server/elsewhere and then sending it to the user when they request it may be a better solution.
from flask import Flask, render_template, session
app = Flask(__name__)
# secret key is needed for session
app.secret_key = 'your secret key'
#app.route('/uploader', methods = ['GET','POST'])
def upload():
new=nrecs[['UserID','ProductID','Rating']]
new['Recommendations'] = list(zip(new.ProductID, new.Rating))
res=new[['UserID','Recommendations']]
res_new=res['Recommendations'].groupby([res.UserID]).apply(list).reset_index()
session['reco_df'] = res_new
pd.options.display.max_colwidth = 500
return render_template('simple.html', tables=[res_new.to_html(classes='data')], titles='')
#app.route('/download-csv', methods = ['GET'])
def download():
return session['reco_df'].to_csv('Recommendations.csv')

Categories