Python code works on linux, error occurs on windows(backslashes) [closed]
So I have a personal project which I know is pretty inefficient but works. I am writing a python code that executes the non pip version of tesseract(apt installed in linux). My code works on linux, but I get this error on windows:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'DRIVE_LETTER:\PROJECT_FOLDER\FOLDER/FILE.txt'
I am using the Atom IDE, pretty new to python so if anyone can point out my idiotic mistakes I would appreciate it, thanks! The error occurs on the subprocess.run line because the error.txt file says it cannot find the specific path.
This is my code:
from flask import Flask,url_for,redirect,render_template,request,send_file
from werkzeug.utils import secure_filename
import subprocess
app=Flask(__name__)
app.config['UPLOAD_DIRECTORY']="uploads/"
app.config['FILE_NAME']=""
app.config['OUTPUT_DIRECTORY']="textresult/"
app.config['EXTENSION']=".txt"
@app.route("/",methods=["POST","GET"])
def to_upload():
err_msg=""
if request.method=="POST":
if request.files['fileupload']:
f=request.files['fileupload']
filename=secure_filename(f.filename)
app.config['FILE_NAME']=filename
f.save(app.config['UPLOAD_DIRECTORY']+filename)
return redirect(url_for("process_upload",filename=filename))
else:
err_msg="No file selected!"
return render_template("index.html",error=err_msg)
@app.route("/upload/<filename>",methods=["POST","GET"])
def process_upload(filename):
f1=open("logs/out.txt","w")
f2=open("logs/error.txt","w")
out=subprocess.run([f"tesseract uploads/{filename}"+f" textresult/{filename}"],shell=True,stdout=f1,stderr=f2)
return redirect(url_for("output_file"))
@app.route("/result/",methods=["GET"])
def output_file():
return render_template("output.html")
@app.route("/download/")
def download_file():
file=app.config['OUTPUT_DIRECTORY']+app.config['FILE_NAME']+app.config['EXTENSION']
return send_file(file,as_attachment=True)
if __name__=="__main__":
app.run(host="0.0.0.0",port="2000",debug=True)
EDIT: Finally got it to work! Removed / in app.config['UPLOAD_DIRECTORY'] and app.config['OUTPUT_DIRECTORY'] since now I am using os.path.join and these are the following lines for both Linux and Windows that I got them to work at:
Linux:
to_convert=os.path.join(app.config['UPLOAD_DIRECTORY'],filename)
convert2txt=os.path.join(app.config['OUTPUT_DIRECTORY'],filename)
out=subprocess.run(["tesseract %s %s"%(to_convert,convert2txt)],shell=True,stdout=f1,stderr=f2)
Windows:
to_convert=os.path.join(app.config['UPLOAD_DIRECTORY'],filename)
convert2txt=os.path.join(app.config['OUTPUT_DIRECTORY'],filename)
out=subprocess.run(["tesseract",to_convert,convert2txt],shell=True,stdout=f1,stderr=f2)
Thank you all for your inputs!
This question does not belong here; it should be asked on StackOverflow site as this is a general programming question and is in no way Ubuntu-specific.
But the answer to your question is rather simple: you are manually creating paths to files in your code by using /
as the filename separator, like here:
f1=open("logs/out.txt","w")
f2=open("logs/error.txt","w")
out=subprocess.run([f"tesseract uploads/{filename}"+f" textresult/{filename}"],shell=True,stdout=f1,stderr=f2)
While this indeed works in Linux, it can't work in Windows, because the filename separator in Windows is \
and not /
. Windows does not recognize /
as filename separator and likewise Linux does not recognize \
.
If you want to have an OS-independent code, use os.path.join()
to join the parts of the pathname, so instead for example "logs/out.txt"
use os.path.join("logs","out.txt")
. os.path.join()
joins its arguments with a separator that is correct for the OS used.