Upload file with framework Zope - python

I would like that users of my ZOPE/Plone website can upload (big) file (>1Gb) on a server.
I have a form in html :
<form enctype="multipart/form-data" action="upload.py" method="post">
<p>File: <input type="file" name="file"></p>
<p><input type="submit" value="Upload"></p>
</form>
I have an external script with ZOPE : upload.py
def get(self, REQUEST):
filename = REQUEST.file['file']
Unfortunately I don't know what to do with this file..
I found some tutorial but I think I'm on wrong way (because these methods can't work with ZOPE ?):
CGI : http://webpython.codepoint.net/cgi_file_upload
ftplib : Python Script Uploading files via FTP
Thanks for your advices,

It depends on how and where you want to store it.
The REQUEST.file is a file object where you can read, seek, tell etc the contents from.
You can store it like a blob:
from ZODB.blob import Blob
blob = Blob()
bfile = blob.open('w')
bfile.write(REQUEST.file)
bfile.close()
# save the blob somewhere now
context.myfile = blob

Related

Blacksheep - can't use FromFiles and FromForm in same request

For some reason, I can't seem to be able to perform both a multi-file upload with additional data on the same form.
Specs:
Python 3.10.4 (inside virtual environment)
blacksheep 1.2.5
Ubuntu 20.04
Here is my html code (simplified):
<form action='/upload_files_with_additional_data' method="post" enctype='multipart/form-data'>
<input type="file" name="files" multiple>
<label for="checkbox1" class="checkbox">Checkbox 1</label>
<input type="checkbox" name="checkbox1">
<label for="checkbox2" class="checkbox">Checkbox 2</label>
<input type="checkbox" name="checkbox2">
<label for="textfield">Text field</label>
<input type="text" id="textfield" name="textfield">
<input type="submit" value="Submit">
</form>
Here's what I've tried (but didn't work) and what I expect would work:
#post('/upload_files_with_additional_data')
async def upload_files_with_additional_data(self, files: FromFiles, form_data: FromForm):
for file in Files:
# do something with each file
# do something with additional form data
I've also tried using FromForm[FormData] with the following FormData:
class FormData:
checkbox1: bool
checkbo2: bool
files: list # also tried with type hint FromFIles (and without setting files alltogether
# def __init__(self, checkbox1: str, checkbox2: str, files): # also tried with files: FromFiles and without entire __init__ (but that didn't work at all)
# self.checkbox1 = bool(checkbox1)
# self.checkbox2 = bool(checkbox2)
# self.files = files # also tried with FromFiles(files)
Either I can upload files, without sending additional form data (using only files: FromFiles), or I can use the form data without the files (using only form: FromForm). Combining the two doesn't work.
When using async def upload_files_with_additional_data(self, request: Request): I can get also get the form data from there using form = await request.form(), but that only works for additional data, not the files. When I try to upload files I get:
form = await request.form()
File "blacksheep/messages.pyx", line 172, in form
File "blacksheep/contents.pyx", line 163, in blacksheep.contents.multiparts_to_dictionary
AttributeError: 'bytes' object has no attribute 'append'
I've also tried using async def upload_files_with_additional_data(self, bytes: FromBytes): which does seem to contain all the data, but as bytes, and I've tried a few ways to convert these to what I want, but no success there either.
Is there a way of uploading both multiple files, alongside other form data (I'm fairly confident there is, but I just haven't figured it out)? If so: how should this be achieved?

Trouble uploading json file with flask

For some reason, this won't accept json files.
#app.route('/get_data', methods=['POST'])
def get_data():
dataFile = request.files['file_path']
dataFileName = dataFile.filename
dataFile.save(os.path.join(uploads_dir, dataFileName))
I keep getting this error:
You seem to have json set as an file ending in your template by <input type="file" accept="json">. (The template is not supplied so I can't pinpoint the line. This is not an error of the backend (flask) but of the your template code (jinja/html). It would be nice if you could supply a MRE for such issues.
For more information about <input type="file"> take a look at the MDN Documentation.
Example of correct accept:
<input type="file" accept=".json">
This will only allow *.json file but keep in mind that users may supply other files manually and create a fallback or validation when parsing/ saving the file.

Flask vs Web.py: Served files processed differently

A .tar.bz2 file served from web.py is saved as .tar.bz2 from the browser. However when served by flask, the .bz2 extension is removed (but running file against the file still identifies it as a .bz2 file).
I have both frameworks running (web.py on python 2.7 and flask on python 3.7).
I manually put the same .tar.bz2 file in a directory and serve it from the web page.
Web.py:
=======
<form method="get" action="$fName">
<div id="formsubmitbutton">
<input type="submit" name="Retrieve File" value="Retrieve File" class="button3" />
</div>
</form>
Flask:
======
<form method="get" action="{{ fName }}">
<div id="formsubmitbutton">
<input type="submit" name="Retrieve File" value="Retrieve File" class="button3" />
</div>
</form>
I would expect both setups to return fName.tar.bz2. Chrome is returning the following and I have no clue why, but suspect it has something to do with my problem:
"Resource interpreted as Document but transferred with MIME type application/x-tar"
UPDATE
Thanks for the tip. From Chrome though, that was the entire error message, minus the actual file name since there is customer information in there. Here is is edited error:
Resource interpreted as Document but transferred with MIME type application/x-tar: "http://foo.example.com:5000/static/1564445156.7369618/filename.tar.bz2?Retrieve+SSD=Retrieve+SSD".
Also, there is no traceback from web.py or Flask, because there is no error. it's just that when you click on retrieve file, web.py returns the full filename with .bz2 extenstion, and Flask returns the file without the .bz2 extension.
The .bz2 files I am trying to serve are in the /static directory. By adding an app.route('/static') function, I was able to serve the file as a .bz2 without it being stripped of the .bz2 suffix:
#main.route('/static')
def sendfile():
for key,val in request.values.items():
filedir = '/home/admin/Flask/httsTools'+os.path.dirname(key)
filename = os.path.basename(key)
return send_from_directory(filedir, filename, as_attachment=True)
Whether or not this is the recommended way to do it I'm not sure, but it works.
Thank you for your help.

Uploading file to GAE Datastore with Python [duplicate]

This question already has answers here:
Displaying uploaded file in GAE Appengine with Python
(3 answers)
Closed 8 years ago.
I'm uploading a small pdf file to be stored as a blob in the Datastore.
Here's the uploading html, getting the PDF from the user:
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="pdf">
<input type="submit" value="Upload">
</form>
Here's the handler, storing the PDF to the Datastore:
def post(self):
p = self.request.POST['pdf']
if p:
person.pdf = p.value
Here's the view, showing the user the contents of the PDF:
<embed src="{{ person.pdf }}" width="500"
height="375" type="application/pdf">
According to all the information I have found, the content of the PDF should reside in p.value. However, the person.pdf attribute is None, and, of course, nothing is displayed.
The most basic way that this appears to be wrong is that:
<embed src="{{ person.pdf }}">
should contain the URL to download the pdf file. However, you're uploading a file via your upload form, and presumably storing the file data.
There's at least a few things that can go wrong, you should debug through and at the very least, isolate where something is going wrong:
Are you actually uploading the file?
How is the file encoded as it's uploaded?
How is the file decoded when you get it from the POST data?
How are you storing the actual file in person.pdf?
And finally, are you actually saving person after you modify it? It's generally more helpful to show all your code rather than snippets. And if that's all your code, where on earth is person coming from? It's not actually being initialized anywhere.

Handle HTML Form Data with Python?

I'm trying to use Python and HTML together. What I'm trying to do is create an HTML Form that will submit data to a python file and that python file will then handle the data. But I'm not getting it to work.
Here is my python code:
form = cgi.FieldStorage() # instantiate only once!
name = form['Sample Name'].value
and this is my HTML code:
<form method='POST' action='/functionGen.py'>
Name: <input type='text' name='Sample Name'>
<input type='submit' value='Begin Storing'>
</form>
What ends up happening is I just see my python code in the browser, the file doesn't begin handling the data.
What can I do?
You should know, that you are getting plain python source document via http protocol now. If you want to use CGI mechanism, you should place youre .py in cgi-enabled directory. It means that you need http server.
related questions
How to run Python CGI script
How do I set up a Python CGI server?

Categories

Resources