I am quite a newby with python. I am asking why python does not run the main function in my case. I put a printing function at the beginning of the main function but it never prints. Although I manage to run the rest of the code to create my html upload form on the internet so I do manage to upload files on it. Can you please help?
This part of the code always runs,dont ask me how :(
import web
import csv
urls = ('/upload', 'Upload')
class Upload:
def GET(self):
web.header("Content-Type","text/html; charset=utf-8")
return """<html><head></head><body>
<form method="POST" enctype="multipart/form-data" action="">
<input type="file" name="myfile" />
<br/>
<input type="submit" />
</form>
</body></html>"""
def POST(self):
x = web.input(myfile={})
outfile_errors = open('C:\Python27\csv_results\errors.csv', 'a')
outfile_errors.write("in the post " + "\n " + str(x) + "\n " )
filedir = "C:\Python27\csv_results\\"# change this to the directory you want to store the file in.
if 'myfile' in x: # to check if the file-object is created
filepath=x.myfile.filename.replace('\\','/') # replaces the windows-style slashes with linux ones.
outfile_denumire_fisier = open('C:\Python27\csv_results\denumire_fisier.csv', 'a')
outfile_denumire_fisier.write(filepath + ";" )
outfile_denumire_fisier.close()
filename=filepath.split('/')[-1] # splits the and chooses the last part (the filename with extension)
fout = open(filedir +'/'+ filename,'w') # creates the file where the uploaded file should be stored
fout.write(x.myfile.file.read()) # writes the uploaded file to the newly created file.
fout.close() # closes the file, upload complete.
raise web.seeother('/upload')
#transform()
outfile_errors.close()
This part of the code doesnt work, at least not together with the previous. Separately, it does work.
def transform():
outfile_errors = open('C:\Python27\csv_results\errors.txt', 'a')
outfile_errors.write("in the transform ")
outfile_errors.close()
#bla bla
This is the main, where i put a printing-to-file function that never works, although somehow the program runs the first function and generates my html format and allows me to upload files like i want. strange, right?
if __name__ == "__main__":
outfile_errors = open('C:\Python27\csv_results\errors.csv', 'a')
outfile_errors.write("in the main beginning" + "\n " )
app = web.application(urls, globals())
app.run()
outfile_errors.write("in the main middle" + "\n " )
transform()
outfile_errors.write("in the main end " + "\n " )
outfile_errors.close()
Can you please help?
you are not telling the program to write to the correct variable. Change outfile.write to Outfile_errors.write in the second half of your main fucntion
Related
I have a project which allows users to upload files, they will eventually get processed and then serve a result file.
I've just realised, now that I am trying to implement the processing part of the system, that the files are empty when uploaded and I'm not sure where this is going wrong. The files are successfully named and put in the directories, but are empty.
Any help would be much appreciated.
The html form for uploads:
<div class="tile is-vertical is-parent coach" id='fileUploadTile'>
<div class="tile is-child box has-background-light">
<form action='/' method='POST' enctype="multipart/form-data">
<div class='drop-zone'>
<span class='drop-zone__prompt is-family-monospace'>Drag and drop or click here to upload files</span>
<input class="drop-zone__input" type="file" multiple name="uploaded_file" id='fileLoader'>
</div> <!-- end of drop-zone-->
<div class='buttons are-medium' id='fileButtons'>
<input type='submit' class="button is-success is-light is-outlined is-family-monospace" id='submitFiles' value='Process file(s)'>
</form>
<button class='button is-danger is-light is-outlined is-family-monospace' name='resetFiles' id='resetFiles'>Reset File(s)</button>
</div> <!-- end of buttons -->
</div> <!-- end of tile is-child -->
</div> <!-- end of tile is-vertical -->
The code which attempts to validate the files (check extensions, file size, name, etc) and then save:
def file_upload():
if session:
session_name = session.get('public_user')
print("New request from " + str(session_name))
# update when last request was sent
active_sessions[session_name] = datetime.now()
else:
session_token = generate_session_token()
print("Generating new session... " + session_token)
session['public_user'] = session_token # session = key, last request = value
active_sessions[session_token] = datetime.now()
os.mkdir('uploads/'+session['public_user']) #create directory for uploaded files
if request.method == "POST":
if request.files:
files_processed = True
files = request.files.getlist("uploaded_file")
upload_path = app.config['UPLOAD_FOLDER'] + \
str(session['public_user'])
# loop, as possibility of multiple file uploads
for file_to_upload in files:
file_to_upload.seek(0, os.SEEK_END)
file_length = file_to_upload.tell()
file_name = check_existing_file_name(file_to_upload.filename)
# Secures file name against user input
file_name = secure_filename(file_name)
# Checks the file name isn't blank
if file_to_upload.filename == "":
print("Error with file" + file_to_upload.filename +
" - name must not be blank")
files_processed = False
continue
# Checks the file has an allowed extension
elif not allowed_ext(file_to_upload.filename):
print("Error with file" + file_to_upload.filename +
" - extension not supported")
files_processed = False
continue
# Checks file size
elif file_length > app.config['MAX_FILE_SIZE']:
print("Error with file" +
file_to_upload.filename + " file too big")
files_processed = False
continue
else: # Else, passes all validation and is saved.
file_path = upload_path + "/" + file_name
file_to_upload.save(file_path)
# If files have been processed, return a render with success message
if files_processed is True:
return render_template('index.html', is_home='yes', succ="Now processing your files...")
else: # Else, normal redirect.
return redirect(request.url)
else: # If no files request, redirect to index.
return redirect(request.url)
else: # If not a POST request, load page as normal.
return render_template('index.html', is_home='yes')
Sorry if this is something easy or silly I've missed - this is my first project in Python and my first time using Flask.
This all looks pretty ok.
Unrelated: I would do the check for the empty file name against file_name - not file_to_upload.filename.
About your problem:
The only sensible answer could be that with any of your many actions you put the file pointer at the end of the file, and save cannot handle it.
Unfortunately, I have no time to try this on my pc, so please do a seek 0 again - this time just before you call the save method.
I will try this later and update my answer accordingly.
Another way to find out what is going is using a debugger. That is not too complicated.
I made a 5 min video - just for debugging Flask: https://www.youtube.com/watch?v=DB4peJ1Lm2M
I was having the same issue and the recommended fix above helped me! From what I understand it is because you file pointer at the end of the file when you grab the file size. This just has to be undone with another file_to_upload.seek(0).
Just for clarity, your code should now look like:
file_path = upload_path + "/" + file_name
file_to_upload.seek(0)
file_to_upload.save(file_path)
On our flask website we implemented a "Download" button. This button invokes a function in flask which is providing the user with an zipped file via send_file(). The first time everything works fine. After clicking the button the second time, the user receives the exact same file again. Seems fine, but in the time the button is clicked again, the file that flask should send is changed and the old one is not existing anymore.
I tried to understand why this is happening with the PyCharm Debugger and noticed, that after pressing the download button a second time, the download routine is not even evoked anymore. So I think there is some kind of caching going on in the background. I even deleted the file to be send from the file system and then pressed the Download button a second time... I got the original file back.
Maybe you guys experienced something similar and can help me with your knowledge. Thank you in advance.
The download code:
#app.route('/download/<expID>')
def download(expID):
experiment = dbc.getExperiment(int(expID))
# only execute, if owner of experiment calls it AND experiment is NOT running or in queue
if experiment.getOwner() == cas.username and experiment.getStatus() != 1 and experiment.getStatus() != 2:
ownerPath = dbc.getUser(experiment.getOwner()).getPath()
fileName = cas.username + "_" + expID
# remove old zip (if existing)
try:
os.remove(experiment.getPath() + "/" + fileName + ".zip")
except FileNotFoundError:
pass
# create zip in owner folder to work around recursion problem
make_archive(ownerPath + "/" + fileName, 'zip', root_dir=experiment.getPath(), base_dir=None)
# move from owner folder to owner/experiment folder
shutil.move(ownerPath + "/" + fileName + ".zip", experiment.getPath() + "/" + fileName + ".zip");
# trigger download
return send_file(
experiment.getPath()+"/"+fileName + ".zip", as_attachment=True)
return redirect('/dashboard')
the button:
<form action="/download/{{experiments[i][0]}}">
<input type="submit" id="download" value="download" />
</form>
I found a solution in the documentation of send_file.
Flask indeed caches files that you send via send_file and does not access the function you called previously for a certain amount of time. To limit this behavior you can use the cache_timeout argument. For me it looks like this:
return send_file(
experiment.getPath()+"/"+fileName + ".zip", as_attachment=True, cache_timeout=0)
I am attempting to upload a CSV file, process it, create a new CSV response file and send it back (download to browser). I have this almost working, the end part of the code is:-
flash('Statement Processed, please check returned file for status','success')
path = 'static/' + name + '.csv'
f.close()
# return send_file(path, as_attachment=True)
return redirect(url_for('main.treasurer'))
This code does everything I need except the download (send_file commented out)
flash('Statement Processed, please check returned file for status','success')
path = 'static/' + name + '.csv'
f.close()
return send_file(path, as_attachment=True)
return redirect(url_for('main.treasurer'))
This code does the download but does not return me to the main.treasurer screen and does not display the flashed message.
My question therefore is can I execute the send_file function without using it within a "Return" statement? If I can't then I guess I'll just need to add a back button to the current screen.
I am currently learning HTML in my Python class. My assignment is to ask the user for their name and a short bio of themselves and print it on a web-page.
I believe my code is correct, I'm not too confused on that, but after I've created everything how do I see if it actually worked? When I try to open the file location with google chrome nothing happens.
def main():
f = open('Userbio', 'w')
f.write("<html>" + "\n")
f.write("<heads>" + "\n")
name = input("What is your name?")
bio = input ("Please write a sentence about yourself!")
f.write("<naming>" + "\n")
f.write(name)
f.write("/naming>" + "\n")
fout.write("</heads>" + "\n")
fout.write("</body>" + "\n")
fout.write("</html>" + "\n")
fout.close()
f.close()
main()
Basically after this program is written and the user inputs their information I'm trying to figure out how to open the web page.
This method works when I use a regular writer like notepad, I just save it and open it with chrome and I can see my webpage. But not Python?
Change f = open('Userbio', 'w') to f = open('Userbio.html', 'w').
You need to rename <heads> to <head> and add the <body> tag.
You will also need to move the <naming> tag out of the <head> and into the <body> tag in order to see any text inside of the naming tag.
As python does not have a built in web browser, you will be able to open the .html file with a browser like Chrome.
If you want to be able to parse and manipulate the html before writing to file, there are several libraries, like BeautifulSoup, that can do that for you.
So i am following the web.py uploading and storing guide to test it out but i keep geting a
error stating that [Errno 2] No such file or directory :< help
this is my code
import web
urls = (
'/hello', 'index',
'/hello/upload', 'upload'
)
app = web.application(urls, globals()) # handels http request that aks for urls
# the base ells lpthw.web to use the templates/layout.html file as the base template for all the other templates
render = web.template.render('templates/', base="layout")
# must use port 127.0.0.1:5000
class index(object):
def GET(self):
return render.hello_form()
def POST(self):
form = web.input(name="Nobody", greet="Hello")
greeting = "%s, %s" % (form.greet, form.name)
return render.index(greeting = greeting)
class upload(object):
def POST(self):
x = web.input(files={})
filedir = '/project/webtest/templates' # directory were you want to save the file
if 'files' in x: # check if the file -object is created
filepath=x.files.filename.replace('\\','/') # replace the windows -style slashes with linux ones
filename=filepath.split('/')[-1] #splits the and chooses the last part (the filename with extension
fout = open(filedir +'/'+ filename,'w') # creates the file where the uploaded file should be stored
fout.write(x.files.file.read()) #writes the uploaded file to the newly created file.
fout.close() #closes the file
else:
return "Error no file"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
help thx
import web
urls = ('/upload', 'Upload')
class Upload:
def GET(self):
web.header("Content-Type","text/html; charset=utf-8")
return view.upload()
def POST(self):
x = web.input(myfile={})
filedir = '/path/where/you/want/to/save' # change this to the directory you want to store the file in.
if 'myfile' in x: # to check if the file-object is created
filepath=x.myfile.filename.replace('\\','/')
filename=filepath.split('/')[-1]
fout = open(filedir +'/'+ filename,'w')
fout.write(x.myfile.file.read()) # writes the uploaded file to the newly created file.
fout.close() # closes the file, upload complete.
raise web.seeother('/upload')
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
upload.html
<html>
<head>
<title>File upload</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data" action="">
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
</body>
</html>
for your reference http://webpy.org/cookbook/storeupload/
I met the same problem myself, and tried to ask that here. But nobody answers.
Finally, I figured it out what's the problem and would like to share with you!
This part: filedir = '/project/webtest/templates' should be an absolute path.
And it should be an existing directory (at least in my trail it should be an existing directory, otherwise it would prompt the same error as you posted)! The file need not to be exciting since we are going to create it by copying the uploaded file.
For example in my mac, it's '/Users/J/pythonex/projects/gothonweb/docs', and it's an existing directory. If it's not an existing directory, you will get the same error message.
Last, the most tricky part. Im my mac, the uploaded files are actually stored in my disk in that exact directory. But I can't see them in my finder until I relaunch the finder. I don't know why is that. But for my computer, that's the case.