Uploading xml file and processing using flask - python

I am developing a Python backend to which I send an xml file from the front end. This is so that I can generate python code based on it and show the contents in the front end. How can I do this using flask?
I have attached the code I tried below. It does not work for me. I was not able to save the xml file into a directory.
from flask import Flask, request, render_template
app = Flask(__name__, template_folder='templates')
from main import run
import os
#app.route('/')
def home():
return render_template('home.html')
#app.route('/submit/', methods=['POST'])
def upload():
if request.method == 'POST':
uploaded_file = xmltodict.parse(request.get_data())
file = os.path.join(app.config['upload'].uploaded_file.filename)
uploaded_file.save(file)
return "Successfully uploaded"
#app.route('/submit/')
def convert():
path='upload'
os.chdir(path)
for file in os.listdir():
if file.endswith(".py"):
file_path = f"{path}\{file}"
run(file_path,'tmp','python')
return "Code generated"
#app.route('/view/')
def view_python_script():
# Folder path
path='tmp'
os.chdir(path)
content=""
for file in os.listdir():
if file.endswith(".py"):
file_path = f"{path}\{file}"
with open(file_path, "r") as f:
content = content + f.read().replace('\n','<br>')
return render_template('upload.html', details=content)
if __name__ == "__main__":
app.run(port=3000, debug=True)

I occupy this: uploaded_file = request.files ['file_upload'].
file_upload I pass it from the html with the parameter name = "file_upload" of input contained within the form.
The problem I have is that when I want to share it in another html page it closes and throws me a ValueError: I / O operation on closed file.
But well, I hope it helps you !!!

Related

Unable to delete uploaded file Flask

I am fairly inexperienced in this topic. I am working on Windows. I am doing an application in which I need to upload a file, get its signatures and use for some purposes. At the instant I extract the signature, I want to delete the file that was uploaded. I am using Flask in backend. When I try to delete the file using os.remove() or pathlib.unlink, it gives me permission error
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'uploads\\file.exe'
This is app.py file
from flask import Flask, render_template, request, jsonify
import pefile
import os
from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage
from extracter import extract_infos
import pathlib
ALLOWED_EXTENSIONS = {'exe'}
app = Flask(__name__)
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload', methods = ['POST'])
def uploadFile():
if request.method == 'POST':
if 'file' not in request.files:
return render_template('page.html')
f = request.files['file']
if f.filename == '':
return render_template('page.html')
if f and allowed_file(f.filename):
fileLink = secure_filename(f.filename)
p = f.read()
with open('uploads/file.exe', 'wb') as w:
w.write(p)
w.close()
pe = extract_infos('uploads/file.exe')
f.close()
file_to_rem = pathlib.Path("uploads/file.exe")
file_to_rem.unlink()
#delete_link = app.config['UPLOAD_FOLDER'] + '\\' + fileLink
#os.remove(delete_link)
return jsonify(pe)
if __name__ == '__main__':
app.run(debug = True)
The error I get is
And the file gets uploaded in the uploads folder but it is not deleted
I did do some research and realized that this kind of error occurs usually when you forget to close a stream once you open it to read. But I don't understand where this could be happening in my code. I need help

Handle multiple request at same time on Flask web app

What I have: I've a Flask web app deployed to Heroku's server, which consists of only one web process app.py. Here it is:
#importation
from flask import Flask, render_template, current_app, send_file, request, json, send_file
import os
#working functions
#json write
def json_write(dictionary):
with open("./json/info.json", "w+") as f:
json.dump(dictionary, f, indent=4)
#make file name
def make_file_name(name):
filename = "tube4u_"
for t in str(name):
if t.isalnum():
filename += t
filename += ".mp4"
return filename
#application initialisation
app=Flask(__name__)
#home
#app.route("/")
def home():
return render_template("index.html")
#processor
#app.route("/process/", methods=["GET"])
def process():
#get url
url = request.args["url"]
#import & initialisation
from pytube import YouTube
import pickle
json_dict = {}
try:
yt = YouTube(url)
except:
return "<h1>Invalid URL</h1>"
all_videos = yt.streams.filter(type="video", progressive=True)
json_dict["title"] = yt.title
json_dict["thumbnail"] = yt.thumbnail_url
json_dict["name"] = make_file_name(yt.title)
with open("./pickle/ytobj.pkl", "wb") as f:
pickle.dump(all_videos, f)
#videos with itag
json_dict["videos"] = [ {"itag": item.itag, "res": item.resolution} for item in all_videos]
json_write(json_dict)
return render_template("menu.html")
#download
#app.route("/download/", methods=["GET"])
def download():
import pickle
itag = int(request.args["itag"])
with open("./json/info.json") as f:
json_dict = json.load(f)
with open("./pickle/ytobj.pkl", "rb") as f:
all_videos = pickle.load(f)
video = all_videos.get_by_itag(itag)
video.download(output_path="./video", filename=f"{json_dict['name']}")
return render_template("thank.html")
#return video
#app.route("/video/", methods=["GET"])
def video():
filename = request.args["filename"]
return send_file(f"./video/{filename}", as_attachment=True)
#return json
#app.route("/json")
def fetchjson():
with open("./json/info.json") as f:
content = json.load(f)
return content
#get name
#app.route("/name")
def fetchname():
with open("./json/info.json") as f:
content = json.load(f)
return content
#app.route("/list")
def listall():
return f"{os.listdir('./video')}"
#running the app
if __name__ == "__main__":
app.run(debug=True)
How it works: here I made the app like that, whenever someone enter a URL and click Go then it creates a json file with the name info.json. after it gets everything properly it performs some task with the given URL reading from the file.
My problem:
Now the problem is, if I make a request of the web it will create a json with my given URL, suppose at the same time someone else make a request and enter a URL then server will lost my information and rewrite the json file with another client's given input URL my task will be performed with another's input url. It's really weird.
How to fix it? Like if there any way to create the info.json file on separate path for each client and gets deleted after work done?
There is a lot of ways in my point of view
When the server get client request then check if there is already a file.if there is already a file then add timestamp or add something else in the filename so the file will not be overwritten.
Ask the user file name and also add timestamp in the name and save it.
You can also use databases to store data of different clients .may be you can create login system and give every user an id and store data for every user in database accordingly.
So on...
You can see there is a lot of ways to solve this.

How to properly use for loop in order to get full text out of transcribed .wav file in Flask

I'm trying to get the content out of the audio file using for loop to iterate through content of the file but what I get is the last line of the text. I'm sure the problem is in the main code which is main.py and I can't figure out what could go wrong. Here is some code:
from flask import Flask, render_template, request, redirect
from google.cloud import speech
import os
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'PATH'
app = Flask(__name__)
#app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
if "file" not in request.files:
return redirect(request.url)
file = request.files["file"]
if file.filename == "":
return redirect(request.url)
if file:
client = speech.SpeechClient()
config = speech.RecognitionConfig(
encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
sample_rate_hertz=8000,
language_code="en-US",
)
content = request.files['file'].read()
audio = speech.RecognitionAudio(content=content)
response = client.recognize(config=config, audio=audio)
for result in response.results:
text = result.alternatives[0].transcript
return render_template('index.html', text=text)
if __name__ == "__main__":
app.run(debug=True)
The problem is in this line:
for result in response.results:
text = result.alternatives[0].transcript
Text is always the last one. What you can do is append text to a list and return the list like this
lines = []
for result in response.results:
text = result.alternatives[0].transcript
lines.append(text)
And change the return to
return render_template('index.html', text=lines)
And don't forget to add a for loop in your jinja template to work with the returned list.

How do I save a image using a flask API then return it to my React App can use it

I am trying to use my Flask API to save an image to the database OR just a file system but this is something I have never done and am getting nowhere with it.
I would like to be able to return the image back when the route is called and be able to use it in my ReactJS Application using just a img tag.
All I have been able to find is how to save the image to the Database and then download it using a route. I need to be able to return it. (It works just not what I need.)
Here is what that was:
#app.route('/img-upload', methods=['POST'])
def img_upload():
file = request.files['image']
newFile = Mealplan(name=file.filename, data=file.read())
db.session.add(newFile)
db.session.commit()
return jsonify({"Done!" : "The file has been uploaded."})
#app.route('/get-mealplan-image/<given_mealplan_id>')
def download_img(given_mealplan_id):
file_data = MealPlan.query.filter_by(id=given_mealplan_id).first()
return send_file(BytesIO(file_data.data), attachment_filename=file_data.name, as_attachment=True)
Save the files on the file system will be a more proper method. Here is a minimal example:
from flask import send_from_directory
basedir = os.path.abspath(os.path.dirname(__file__))
uploads_path = os.path.join(basedir, 'uploads') # assume you have created a uploads folder
#app.route('/img-upload', methods=['POST'])
def upload_image():
f = request.files['image']
f.save(os.path.join(uploads_path , f.filename)) # save the file into the uploads folder
newFile = Mealplan(name=f.filename) # only save the filename to database
db.session.add(newFile)
db.session.commit()
return jsonify({"Done!" : "The file has been uploaded."})
#app.route('/images/<path:filename>')
def serve_image(filename):
return send_from_directory(uploads_path, filename) # return the image
In your React app, you can use the filename to build to the image URL: /images/hello.jpg
Update:
If you can only get the id, the view function will be similar:
#app.route('/get-mealplan-image/<given_mealplan_id>')
def download_img(given_mealplan_id):
file_data = MealPlan.query.filter_by(id=given_mealplan_id).first()
return send_from_directory(uploads_path, file_data.name)

Reading input file and processing it in flask

I'm trying to write a simple flask program that will create a web page in which it receives a file (by uploading it), and then using that file's data and displaying a filtered part of it in my web page, I just cant seem to understand how to do that.
This is the code I used to upload the file, which worked fine.
import os
from flask import Flask, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = 'C:/Users/ohadt/PycharmProjects/logFiles'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'log'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit a empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('read_uploaded_file',
filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
Then I tried writing the method for opening the file and reading the data from it, but I couldn't figure how to do that, could you please help me understand how to read the file content and presenting a filtered version of it on my site?
Thanks!
You already saved it here
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
just open it up and read as you work with any other files, example:
#app.route('/read_file', methods=['GET'])
def read_uploaded_file():
filename = secure_filename(request.args.get('filename'))
try:
if filename and allowed_filename(filename):
with open(os.path.join(app.config['UPLOAD_FOLDER'], filename)) as f:
return f.read()
except IOError:
pass
return "Unable to read file"
You need to carefully sanitize user input here, otherwise method could be used to read something unintended (like app source code for example). Best is just not grant user ability to read arbitrary files - for example when you save a file, store it's path in database with some token and give user just this token:
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
token = store_in_db(filepath)
return redirect(url_for('read_uploaded_file',
token=token))
Then accept a token, not a filename when you read a file:
#app.route('/read_file', methods=['GET'])
def read_uploaded_file():
filepath = get_filepath(request.args.get('token'))
try:
if filepath and allowed_filepath(filepath):
with open(filepath) as f:
return f.read()
except IOError:
pass
return "Unable to read file"
Tokens need to be random, long, not guessable (uuid4 for example) - otherwise there will be a possibility to easily read other users files. Or you need to store relation between file and user in database and check it too. Finally, you need to control size of file uploads to prevent user from uploading huge files (app.config['MAX_CONTENT_LENGTH']) and control amount of info you read in memory when you display "filtered" file content (f.read(max_allowed_size)).

Categories