I'm trying to use AjaxUpload with Python:
http://valums.com/ajax-upload/
I would like to know how to access the uploaded file with Python. On the web site, it says:
* PHP: $_FILES['userfile']
* Rails: params[:userfile]
What is the Syntax for Python?
request.params['userfile'] doesn't seem to work.
Thanks in advance! Here is my current code (using PIL imported as Image)
im = Image.open(request.params['myFile'].file)
import cgi
#This will give you the data of the file,
# but won't give you the filename, unfortunately.
# For that you have to do some other trick.
file_data = cgi.FieldStorage.getfirst('file')
#<IGNORE if you're not using mod_python>
#(If you're using mod_python you can also get the Request object
# by passing 'req' to the relevant function in 'index.py', like "def func(req):"
# Then you access it with req.form.getfirst('file') instead. NOTE that the
# first method will work even when using mod_python, but the first FieldStorage
# object called is the only one with relevant data, so if you pass 'req' to the
# function you have to use the method that uses 'req'.)
#</IGNORE>
#Then you can write it to a file like so...
file = open('example_filename.wtvr','w')#'w' is for 'write'
file.write(file_data)
file.close()
#Then access it like so...
file = open('example_filename.wtvr','r')#'r' is for 'read'
#And use file.read() or whatever else to do what you want.
I'm working with Pyramid, and I was trying to do the same thing. After some time I came up with this solution.
from cStringIO import StringIO
from cgi import FieldStorage
fs = FieldStorage(fp=request['wsgi.input'], environ=request)
f = StringIO(fs.value)
im = Image.open(f)
I'm not sure if it's the "right" one, but it seems to work.
in django, you can use:
request.FILES['file']
instead of:
request.POST['file']
i did not know how to do in pylons...maybe it is the same concept..
Related
I'm currently working on a simple proof of concept for a pdf-editor application. The example is supposed to be a simplified python script showcasing how we could use the pdfrw library to edit PDF files with forms in them.
So, here's the issue. I'm not interested in writing the edited PDF to a file.
The idea is that file opening and closing is going to most likely be handled by external code and so I want all the edits in my files to be done in memory. I don't want to write the edited filestream to a local file.
Let me specify what I mean by this. I currently have a piece of code like this:
class FormFiller:
def __fill_pdf__(input_pdf_filestream : bytes, data_dict : dict):
template_pdf : pdfrw.PdfReader = pdfrw.PdfReader(input_pdf_filestream)
# <some editing magic here>
return template_pdf
def fillForm(self,mapper : FieldMapper):
value_mapping : dict = mapper.getValues()
filled_pdf : pdfrw.PdfReader = self.__fill_pdf__(self.filesteam, value_mapping)
#<this point is crucial>
def __init__(self, filestream : bytes):
self.filesteam : bytes = filestream
So, as you see the FormFiller constructor receives an array of bytes. In fact, it's an io.BytesIO object. The template_pdf variable uses a PdfReader object from the pdfrw library. Now, when we get to the #<this point is crucial> marker, I have a filled_pdf variable which is a PdfReader object. I would like to convert it to a filestream (a bytes array, or an io.BytesIO object if you will), and return it in that form. I don't want to write it to a file. However, the writer class provided by pdfrw (pdfrw.PdfWriter) does not allow for such an operation. It only provides a write(<filename>) method, which saves the PdfReader object to a pdf output file.
How should I approach this? Do you recommend a workaround? Or perhaps I should use a completely different library to accomplish this?
Please help :-(
To save your altered PDF to memory in an object that can be passed around (instead of writing to a file), simply create an empty instance of io.BytesIO:
from io import BytesIO
new_bytes_object = BytesIO()
Then, use pdfrw's PdfWriter.write() method to write your data to the empty BytesIO object:
pdfrw.PdfWriter.write(new_bytes_object, filled_pdf)
# I'm not sure about the syntax, I haven't used this lib before
This works because io.BytesIO objects act like a file object, also known as a file-like object. It and related classes like io.StringIO behave like files in memory, such as the object f created with the built-in function open below:
with open("output.txt", "a") as f:
f.write(some_data)
Before you attempt to read from new_bytes_object, don't forget to seek(0) back to the beginning, or rewind it. Otherwise, the object seems empty.
new_bytes_object.seek(0)
Is this possible to pickle and unpickle data without creating a file for it? In the question that was suggested as duplicate I don't see how to unpickle this.
Pickle.dump to variable
I want to do this remotely so I can't create new files on the fly.
All examples with pickling and unpickling show use of pickle.dump, and pickle.load.
I read the docs, and the file argument can be a BytesIO object but when I try to use load() function, I get.
EOFError: Ran out of input
Can somebody give me some examples of how to do this?
What I currently have is:
a = A("some_random_string")
bio = BytesIO(b"some_bytes_data")
d = pickle.dump(a, bio)
f = pickle.Unpickler(bio).load()
The load gives me the above error. What am I doing wrong?
I was able to resolve it after all. Using dumps instead of dump made it possible for me.
An example of how it works in my case now:
from io import BytesIO
import pickle
a = b"asdf"
f = pickle.dumps(a)
file = BytesIO(f)
unpickled = pickle.load(file) # It is equal to initial value.
Maybe it helps someone else too.
I am trying to create a pickle file.
I have used the following piece of code to do it:
def pickler(input_nparray):
with open('/Users/username/Desktop/pklfilename.pkl', 'wb+') as f:
pickle.dump(input_nparray, f)
This method works perfectly. What this does is it takes in the numpy array and stores the contents into the pklfilename.pkl.
But the problem here is I have to specify the filename. This I tried to do in the following way, but failed.
def pickler(input_nparray, pklfilename):
with open('/Users/swaghccc/Desktop/' + pklfilename, 'wb+') as f:
pickle.dump(input_nparray, f)
pickler(input_nparray, 'file1.pkl')
Can someone tell me the correct alternative?
The username differs between the first and second example. Change it to username and use the filename pklfilename.pkl and see if you end up with a file in the second example.
Another tip is to save the filename in a variable a print it to try to figure out what goes on.
I'm using Reportlab to create PDFs. I'm creating two PDFs which I want to merge after I created them. Reportlab provides a way to save a pycanvas (source) (which is basically my pdf file in memory) as a python file, and calling the method doIt(filename) on that python file, will recreate the pdf file. This is great, since you can combine two PDFs on source code basis and create one merge pdf.
This is done like this:
from reportlab.pdfgen import canvas, pycanvas
#create your canvas
p = pycanvas.Canvas(buffer,pagesize=PAGESIZE)
#...instantiate your pdf...
# after that, close the PDF object cleanly.
p.showPage()
p.save()
#now create the string equivalent of your canvas
source_code_equiv = str(p)
source_code_equiv2 = str(p)
#merge the two files on str. basis
#not shown how it is exactly done, to make it more easy to read the source
#actually one just have to take the middle part of source_code_equiv2 and add it into source_code_equiv
final_pdf = source_code_equiv_part1 + source_code_equiv2_center_part + source_code_equiv_part2
#write the source-code equivalent of the pdf
open("n2.py","w").write(final_pdf)
from myproject import n2
p = n2.doIt(buffer)
# Get the value of the StringIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
This works fine, but I want to skip the step that I save the n2.py to the disk. Thus I'm looking for a way to instantiate from the final_pdf string the corresponding python class and use it directly in the source. Is this possible?
It should work somehow like this..
n2 = instantiate_python_class_from_source(final_pdf)
p = n2.doIt(buffer)
The reason for this is mainly that there is not really a need to save the source to the disk, and secondly that it is absolutely not thread save. I could name the created file at run time, but then I do not know what to import!? If there is no way to prevent the file saving, is there a way to define the import based on the name of the file, which is defined at runtime!?
One might ask why I do not create one pdf in advance, but this is not possible, since they are coming from different applications.
This seems like a really long way around to what you want. Doesn't Reportlab have a Canvas class from which you can pull the PDF document? I don't see why generated Python source code should be involved here.
But if for some reason it is necessary, then you can use StringIO to "write" the source to a string, then exec to execute it:
from cStringIO import StringIO
source_code = StringIO()
source_code.write(final_pdf)
exec(source_code)
p = doIt(buffer)
Ok, I guess you could use code module which provides standard interpreter’s interactive mode. The following would execute function doIt.
import code
import string
coded_data = """
def doIt():
print "XXXXX"
"""
script = coded_data + "\ndoIt()\n"
co = code.compile_command(script, "<stdin>", "exec")
if co:
exec co
Let me know, if this helped.
I'm running python 2.4 from cgi and I'm trying to upload to a cloud service using a python api. In php, the $_FILE array contains a "tmp" element which is where the file lives until you place it where you want it. What's the equivalent in python?
if I do this
fileitem = form['file']
fileitem.filename is the name of the file
if i print fileitem, the array simply contains the file name and what looks to be the file itself.
I am trying to stream things and it requires the tmp location when using the php api.
The file is a real file, but the cgi.FieldStorage unlinked it as soon as it was created so that it would exist only as long as you keep it open, and no longer has a real path on the file system.
You can, however, change this...
You can extend the cgi.FieldStorage and replace the make_file method to place the file wherever you want:
import os
import cgi
class MyFieldStorage(cgi.FieldStorage):
def make_file(self, binary=None):
return open(os.path.join('/tmp', self.filename), 'wb')
You must also keep in mind that the FieldStorage object only creates a real file if it recieves more than 1000B (otherwise it is a cStringIO.StringIO)
EDIT: The cgi module actually makes the file with the tempfile module, so check that out if you want lots of gooey details.
Here's a code snippet taken from my site:
h = open("user_uploaded_file", "wb")
while 1:
data = form["file"].file.read(4096)
if not data:
break
h.write(data)
h.close()
Hope this helps.