Pyramid: what is the analog of php's $_FILES['Filedata']['file_name']? - python

I need to know it to correctly get filedata from POST dictionary.
I want to use Agile Uploader (resizes images on client side before upload on the server) in my project. It has process.php file as example of handling image on server. In that file:
$tmp_name = $_FILES["Filedata"]["file_name"]; // where "tmp_name" is file name
As Pyramid doesn't have FILES dictionary, I supose I have to find image in POST. But when I try to upload image POST is empty...
So where it send that image and how to find it on server side?
HTML (most part of html code taken from their demo):
<form action="/test" method="post" id="singularDemo" enctype="multipart/form-data">
<div id="single"></div>
</form>
Submit
<script type="text/javascript">
$('#single').agileUploaderSingle({
submitRedirect:'',
formId:'singularDemo',
progressBarColor:'#3b5998',
flashVars:{
firebug:true,
form_action:'/test'
}
});
</script>
Python (Pyramid code), just for testing - simple view:
def test(request):
if request.method == 'POST':
pass
return {}
Thanks!

Since the $_FILES global contains files submitted by a POST request, you can access them using request.POST:
# access the filename
filename = request.POST['Filedata'].filename
# access the actual file
input_file = request.POST['Filedata'].file
This is an exact equivalent of the PHP $_FILES variable, so if it doesn't work, something else must be wrong.
The Pyramid cookbook has more information about file uploads.

Related

tornado URL and HTML form

I'm using tornado and I want to Insert something to my MongoDB from values in a HTML form.
in the HTML file I have a form like this:
<form method="get" >
with 2 textbox and a submit button.
and I don't know what to set as "action"
I have a handler class with a function called "post" like bellow:
class MyHandler(tornado.web.RequestHandler):
def post(self):
name = self.get_argument("Name", "")
index = self.get_argument("Index","")
.... code for updating MongoDB
I have a file called BaseUrl.py that contains:
(/admin/edit[/]?',MyHandler )
but it seems that the "post" function in myHandler does not execute.
could you please give me some advice about how to properly set my URLs and form actions?
Change the form method to POST as you are handling in a POST request:
<form method="POST" >
You also need to provide an action if the form is served from different page, so your form should be:
<form method="POST" action="/admin/edit">
Your post method isn't called because your form specifies method="get". Change that to method="post" and it'll probably work.
If the action is empty the browser will submit the request to the current page, so if you have a get handler serving the form at the same URL you don't need to specify it.

Getting file location from an html form

EDIT: Added the solution to my code, as suggested by Martijn Pieters.
I'm writing a web application that should have an image upload feature. Actually it is uploading directly to imgur.com through their api. So far I can upload an image to imgur through the terminal by running my python script. But I want the user to be able to select an image through an html form. All I actually need (I think) is the path for the file, then I have a script that converts the image to base64. As I write this I realize that the script might only work when it's run locally, and not from a browser. I have been googling for two days. I get a lot of results about cgi.FieldStorage() but can't seem to get that to work as I get a KeyError.
This is the file input part of my form:
<div class="container">
<form role="form" class="form-horizontal form-inline" method="post" enctype="multipart/form-data">
<div class="col-md-12">
<div class="form-group">
<label for="image" class="control-label">Product image</label>
<input type="file" id="image" name="imageurl" value=""/>
</div>
</div>
And then I need to be able to handle the input in my python script:
class MainPage(BlogHandler):
def get(self):
self.render("front.html")
def post(self):
image = self.request.POST.get("imageurl")
logging.info(getUrl(image))
This is the code for sending the image to the imgur api:
def getUrl(image):
API_URL = "https://api.imgur.com/3/upload.json"
image_read = image.file.read()
b64 = base64.b64encode(image_read)
data = {
'image': b64,
'type': base64,
'title': 'testupload'
}
response = requests.post(API_URL, data, headers={'Authorization': 'Client-ID my-cient-id'})
url = response.json()['data']['link']
return url
I developing in Google App Engine and using Jinja2 as the templating engine.
I'm a beginner programmer so I hope to get some pointers on my problem. I feel like I'm stuck on searching for the answer. I've read that the browser does not know anything about the file system of the computer for security reasons, but websites exist where you can choose a file from your computer to upload, so I figure it must be possible to achieve. :)
EDIT: Added the solution to my code, as suggested by Martijn Pieters.
Uploading an image requires that you change the form encoding to multipart/form-data:
<form encoding="multipart/form-data" role="form" class="form-horizontal form-inline" method="post">
See application/x-www-form-urlencoded or multipart/form-data?
Because this is a POST request, you'll find the fields in request.POST:
def post(self):
imageurl = self.request.POST.get("imageurl")
logging.info(imageurl)
although request.get() will search both query parameters and POST form data.
A form upload is returned as a cgi.FieldStorage() object; this has a file attribute, which gives you a file-like interface. You could just read the data into memory:
image = self.request.POST.get("imageurl")
image_read = image.file.read()
b64 = base64.b64encode(image_read)

flask error sending POST and GET to same function,

This is a function which (in a GET request) receives a case_url and case_key and serves the corresponding case (using mongoDB) to a html template called detail_case.
Im trying to add a feature where when a form is filled(on this same page detail_case) and it is submitted, it should submit a POST request to the same function and the code under 'if request.method=="POST"' should get executed.
#app.route('/case/<case_url>/<case_key>', methods=["GET","POST"])
def serve_case(case_url,case_key):
"""for saving a comment in db.comments"""
if request.method == "POST":
text=request.form['comment_text']
#code which inserts it in the database
return redirect(url_for('serve_case', \
case_url=case_url,\
case_key="Highlights"))
"""
Function serves the case as per the key indicated in the URL
"""
#corresponding code here which fills values of variables and sends it to another page
return render_template('detail_case.html')
The problem is that I don't think the POST request is ever executed. This is the html code on the template page detail_case-
<textarea placeholder="Please enter your comments here" action="{{ url_for('serve_case',case_url=case_url,case_key=case_key)}}" method="POST" name="comment_text" rows="6"></textarea><br />
The problem i think is the action field. I don't know how should I send the variable comment_text to my function. Infact, the code under POST does not get executed when I submit.
Basically the issue is that during a GET request, it sends 2 variables which are needed in the parameters of the function serve_case. During my POST request, well, I don't know how to exactly frame the action field. If I send no parameters, its an error. If I don't send it to the same function, then how will it execute the POST code? Could someone please suggest sumthing?
i'm pretty new to flask, i'm editing someone else's code
You need to submit the POST request (for example through form) like below:
<form action="{{ url_for('serve_case',case_url=case_url,case_key=case_key)}}" method="POST">
<input type="text" placeholder="Please enter your comments here">
<input type="submit" name="comment_text" rows="6"><br />
</form>

get_serving_url in Google App Engine fails in Production Caught InvalidBlobKeyError while rendering

and thank you for taking the time to read my question.
I have successfully implemented user uploads in a form. I have also been successful at displaying the uploaded files (images) on my devserver.
However, I cannot get them to be displayed on production.
I am currently using the following filter for images:
#register.simple_tag
def media_file_url(file_obj):
file_location = file_obj.name.split('/')[0]
#gives just the key
return get_serving_url(str(file_location))
and in the template:
<img class='visual' src='{% media_file_url promotion.image %}'
alt='image description' width='70' height='88' />
I have tried the above without splitting the file_location.
I have tried a custom url handler as following in views.py:
def images(request, resource):
clean_key = urllib2.unquote(resource)
return HttpResponseRedirect(get_serving_url(clean_key))
All of the above work in dev, but not production.
Does anyone have any suggestions?
Thanks!!!
The blob info was stored in the file info of the model.
I was able to get the serving url in my filter as follows:
from google.appengine.api import images
...
#register.simple_tag
def media_file_url(file_obj):
try:
return images.get_serving_url(file_obj.file.blobstore_info)
except:
return None

How to use goog.net.IframeIo to upload a file to Blobstore in Python?

Here I am trying to upload a file asynchronously to the blobstore. Following is what I've done so far:
html file
<form id="my_form" enctype="multipart/form-data" method="POST"
action="/partner">
<input type="file" id="my_file" name="my_file"/>
</form>
js file
my.Project.prototype.onFileUpload = function(e) {
var uploadForm = /** #type {HTMLFormElement} */ (
goog.dom.getElement('my_form'));
var iframeIo = new goog.net.IframeIo();
goog.events.listen(iframeIo, goog.net.EventType.COMPLETE, function() { alert('request complete'); });
iframeIo.sendFromForm(uploadForm);
python code
class MyHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
logging.info(self.request) // I can see my file in this line's output
upload_files = self.get_uploads('my_file')
logging.info(upload_files) //upload_files come out to be an empty array
blob_info = upload_files[0]
self.redirect('/partner/serve/%s' % blob_info.key())
Any pointers on how to get the file to be uploaded fron the Request object.
The python code provided by google tutorial on blobstore can be found here.
Now I am stuck. I believe if I can get the file in python code I'll be able to upload it.
Any pointers will be very helpful.
Thanks,
Mohit
This isn't really a question about iframeio, but simply about uploading in AppEngine. What you're missing is that you're supposed to create a URL to upload to first, in your GET method, and use that as the action parameter for the form. See the sample application in the AppEngine docs.
So in your case, you'd do upload_url = blobstore.create_upload_url('/partner'), and in your template, <form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">, etc.

Categories

Resources