Unable to delete uploaded file Flask - python

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

Related

API works with only 1 file type?

I have a C# script that uploads a video to a Flask API, the API processes the video using openCV and it creates and sends back a text file. The only issue is, it only seems to work with the .qt filetype, and any other video I send will not work properly (mov, mp4, etc). The API receives a valid video, or so it says, but it is as if the video comes across totally empty with no data in it. The text file it creates is blank because it seemingly is processing nothing. There is nothing in either script that makes the .qt file only work, and I have tried everything including tinkering with the 'MediaTypeHeaderValue.' I am absolutely stumped. Also, I am posting again because my first post on stack overflow wasn't good enough or had all the scripts, so I am just starting over. I'll post the C# script to upload the video, the Python script to process it, and the requirements.txt.
C# Code
using System.Net.Http.Headers;
var filePath = "run.mp4";
using var client = new HttpClient();
using (var multipartFormContent = new MultipartFormDataContent())
{
//Add the file
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "run.mp4");
//Send it
var response = await client.PostAsync("http://127.0.0.1:5000/", multipartFormContent);
//Ensure it was successful.
response.EnsureSuccessStatusCode();
//Grab the animation data from the content.
var animation_data = await response.Content.ReadAsStringAsync();
//Save to file.
await File.WriteAllTextAsync("AnimationFile.txt", animation_data);
}
Python Code Below
from flask import Flask, request, redirect, url_for, send_from_directory, request
from werkzeug.utils import secure_filename
import cv2
from cvzone.PoseModule import PoseDetector
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'3gp', 'mov', 'qt', 'avi', 'wmv', 'mp4'}
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000 # Limit upload size to 16 megabytes per file.
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/uploads/<name>')
def download_file(name):
return send_from_directory(app.config["UPLOAD_FOLDER"], name)
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
return redirect(request.url,400, "File part not found in request.")
file = request.files['file']
if file.filename == '':
return redirect(request.url,400, "Filename is empty.")
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
cap = cv2.VideoCapture(filename)
detector = PoseDetector()
posList = []
while True:
success, img = cap.read()
if img is None:
break
img = detector.findPose(img)
lmList, bboxInfo = detector.findPosition(img)
if bboxInfo:
lmString = ''
for lm in lmList:
lmString += f'{lm[1]},{img.shape[0] - lm[2]},{lm[3]},'
posList.append(lmString)
# file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) Don't need to save the file
with open("uploads/AnimationFile.txt", 'w') as f:
f.writelines(["%s\n" % item for item in posList])
return redirect(url_for('download_file', name="AnimationFile.txt"))
return '''<h1>Test Api!</h1>'''
app.run()
Requirements.txt
absl-py==1.2.0
attrs==22.1.0
click==8.1.3
cvzone==1.5.6
cycler==0.11.0
Flask==2.2.2
fonttools==4.37.1
itsdangerous==2.1.2
Jinja2==3.1.2
kiwisolver==1.4.4
MarkupSafe==2.1.1
matplotlib==3.5.3
mediapipe==0.8.10.1
numpy==1.23.2
opencv-contrib-python==4.6.0.66
opencv-python==4.6.0.66
packaging==21.3
Pillow==9.2.0
protobuf==3.20.1
pyparsing==3.0.9
python-dateutil==2.8.2
six==1.16.0
Werkzeug==2.2.2

Uploading xml file and processing using flask

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 !!!

How to read some images from a local file then display on a web page by using flask and python3?

I want to read some images(.jpg) from a local file path, then display those images on a web page(127.0.0.1:8000) by using flask and python3.I have already display single image on web page by use the following code:
from flask import Flask,render_template
app = Flask(__name__)
def return_img_stream(img_local_path):
import base64
img_stream = ''
with open(img_local_path, 'rb') as img_f:
img_stream = img_f.read()
img_stream = base64.b64encode(img_stream).decode()
return img_stream
#app.route('/')
def hello_world():
img_path = 'D:\\1111\\1.jpg'
img_stream = return_img_stream(img_path)
return render_template('index.html',img_stream=img_stream)
if __name__ == '__main__':
app.run(debug=True,host='127.0.0.1',port=8080)
How should I modify this code?

pass parameters from Flask main

I'm new at Flask. I try to pass a parameter from the main, but it doesn't work. Hope somebody can help me. Here is my code
from flask import Flask, render_template, request
import controllFlask
import pickle
app = Flask(__name__) # creates a flask object
import subprocess
#app.route('/', methods=['GET', 'POST'])
def ner():
'''controlls input of Webapp and calls proccessing methods'''
knownEntities = pickle.load( open( "entityDictThis.p", "rb" ))
print("loades")
content = ""
if request.method == 'POST':
testText = (request.form['input'])
app.ma = controllFlask.controll(testText, knownEntities)
subprocess.call("controllFlask.py", shell=True)
with open("test.txt", "r") as f:
content = f.read()
return render_template("ner.jinja2", content=content)
def flaskApp():
app.debug = True
app.run()
I want to open entityDictThis in flaskApp and give it to the ner-function. Because I hope in this way it loads only one time. At the moment it loads every time the page is reloaded and it takes very long. Is there a easy way?
This seems to be only a scoping problem, simply put the line that loads the pickle file in the scope above and it should solve the issue.
from flask import Flask, render_template, request
import controllFlask
import pickle
app = Flask(__name__) # creates a flask object
import subprocess
knownEntities = pickle.load( open( "entityDictThis.p", "rb" ))
#app.route('/', methods=['GET', 'POST'])
def ner():
'''controlls input of Webapp and calls proccessing methods'''
print("loades")
content = ""
if request.method == 'POST':
testText = (request.form['input'])
app.ma = controllFlask.controll(testText, knownEntities)
subprocess.call("controllFlask.py", shell=True)
with open("test.txt", "r") as f:
content = f.read()
return render_template("ner.jinja2", content=content)
def flaskApp():
app.debug = True
app.run()
I would also suggest, as #bouteillebleu mentioned, to close the loaded file, using the with keyword, which does this automagically for you.
with open( "entityDictThis.p", "rb" ) as f:
knownEntities = pickle.load(f)

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