Python file upload "KeyError" - python

Whats wrong in this code?
Here is my HTML:
<html><body>
<form action="iindex.py" method="POST" enctype="multipart/form-data">
<p>File: <input type="file" name="ssfilename"></p>
<p><input type="submit" value="Upload" name="submit"></p>
</form>
</body></html>
This is my Python script:
#! /usr/bin/env python
import os, sys;
from mod_python import apache
import cgi
import cgitb; cgitb.enable()
form = cgi.FieldStorage(keep_blank_values=1)
fileitem = form["ssfilename"]
.....
This is the line where I get KeyError.
File "/Applications/MAMP/python/framework/Python.framework/Versions/2.6/lib/python2.6/cgi.py", line 541, in __getitem__
raise KeyError, key
KeyError: 'ssfilename'

Edit: Totally missed the part where you are doing keep_blank_values = 1; sorry, no idea what is wrong.
From http://docs.python.org/library/cgi.html:
Form fields containing empty strings are ignored and do not appear in the dictionary; to keep such values, provide a true value for the optional keep_blank_values keyword parameter when creating the FieldStorage instance.
Therefore, this is happening because this field was left blank.

I had the exact same problem, make sure you have the "enctype" set to "multipart/form-data" and use a default value in your field. So your form should look like this:
<form enctype="multipart/form-data" id="addFile" action="AddFile.py">
<input type="file" name="file" id="file" value=""/><br/>
<input type="submit" name="submit" value="Add File"/><br/>
</form>
I was also using a JQuery handler for my Form and was trying to serialize it and then posting it to my python handler, I bypassed that and it was going all fine, so you should try that also.

Check if you have no GET parameters in your form action URL.
If you need to pass on any data put it as form elements inside the form to be POSTed along with your upload file.
Then you find all your POSTed vars in cgi.FieldStorage.

Related

Python, Django: getting full path from file

Good evening,
I'm trying to select a file ("example.csv") via a input inside my template:
main.html
...
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myFile">
<button class="btn btn-success" type="submit">Choose</button>
</form>
...
After selecting and hitting the button I want to achieve the full path plus the name of the file itself as a string!
views.py
...
if request.method == 'POST' and request.FILES['myFile']:
myFile = request.FILES['myFile']
file_path = # getting the full file path
...
For example:
data_name = 'example.csv'
file_path = 'C:\Users\John Doe\Files'
So the string should look something like this: 'C:\Users\John Doe\Files\example.csv'
I tried it with os.path, but this doesn't seem to work or I'm doing something wrong here!?
Thanks for all your help!
It's not possible to get the user's local path of the file, the browser doesn't give such information. Usually the information you get is the Size, Type, Filename.
Check This, This and This

flask-wtforms field required

how i can add tag required on this flask code :
{{ form.youtube_href(type='url', class='form-control') }}
actual output is :
<input class="form-control" id="youtube_href" name="youtube_href" value="" type="url">
need this output bat give error :
<input class="form-control" id="youtube_href" name="youtube_href" value="" type="url" required>
im tried this bat give error :
{{ form.youtube_href(type='url', class='form-control', 'required') }}
As of WTForms 2.2 (June 2nd, 2018), fields now render the required attribute if they have a validator that sets the required flag, such as DataRequired and InputRequired. If for some reason you don't want to render the attribute, you can pass required=False. Or if you want to disable all browser validation, you can set the novalidate attribute in the form tag. In general you should prefer to leave browser validation enabled, because it prevents a request/response for simple validation, which is desirable.
You are passing a positional argument after keyword arguments, which is a syntax error. Instead, pass required=True, which will set a bare attribute on the tag. Check the flags on a field to see if a Required validator was set: field.flags.required is a boolean. Create a URLField rather than passing the type manually.
from flask_wtf import Form
from wtforms.fields.html5 import URLField
from wtforms.validators import InputRequired
class MyForm(Form):
youtube_href = URLField(validators=[InputRequired()])
form = MyForm()
print(form.youtube_href(required=form.youtube_href.flags.required))
# <input id="youtube_href" name="youtube_href" required type="url" value="">
To those who simply want to add the required attribute to their html input, this can be accomplished by following the comment mentioned by Raja Simon above. Simply call your field name in your template with required='required' Example:
<form>
...
{{myform.my_name_field(required='required')}}
{{myform.my_email_field(required='required')}}
...
</form>
The Above code will result in fields like so:
<input id="my_name_field" name="my_name_field" required="required" type="text" value="">

Processing POST request in Django

Hi I got a simple form for a POST request and it works when I'm only having one input, but not two inputs together. Can someone show me some light on this?
index.html
<form name="input" action="{% url 'sending' %}" method="post">
{% csrf_token %}
Recipient: <input type="text" name="recipient">
<br>
Message: <input type="text" name="content">
<br>
<input type="submit">
</form>
views.py
def sending(request):
recipient = request.POST.get('recipient','')
content = request.POST.get('content','') #not working when I am doing this...
someMethod(recipient, content)
return HttpResponseRedirect(reverse('results'))
Adding a "forms" portion to your setup will help you greatly... see the quickstart docs on forms here: https://docs.djangoproject.com/en/1.6/topics/forms/
In particular, check out "using a form in a view": https://docs.djangoproject.com/en/1.6/topics/forms/#using-a-form-in-a-view
Basically, you end up with a "forms.py" file which defines your form fields. Then, after it all processes, you get a simplier API into your form fields that looks like this:
form.cleaned_data['recipient']
form.cleaned_data['content']
etc.

Pyramid app: How can I pass values into my request.route_url?

I have this in my views.py file as the view config for my home page:
#view_config(route_name='home_page', renderer='templates/edit.pt')
def home_page(request):
if 'form.submitted' in request.params:
name= request.params['name']
body = request.params['body']
page=Page(name,body)
DBSession.add(page)
return HTTPFound(location=request.route_url('view_page',pagename=name))
return {}
Also, here is the form in the edit.pt template:
<form action="/view_page" method="post">
<div>
<input type="text" name="name"/>
</div>
<div>
<input type="text" name="body"/>
</div>
<label for="stl">Stl</label>
<input name="stl" type="file" value="" />
<input type="submit" name='form.submitted' value="Save"/>
</form>
Also in my init.py file I have
config.add_route('home_page', '/')
config.add_route('view_page', '/{pagename}')
right now when I submit the form it just tries to go to localhost:6543/view_page. This returns a 404 as there is no view_page resource or route leading to it. Instead I want it to go to localhost:6543/(the name of the page I just created aka the first input box in the form). How can I do this?
Edit: I am worried that something else may be telling it to route to view_page because I even tried changing it to
return HTTPFound(location=request.route_url('front_page',pagename=name))
And it still goes to /view_page. There is no route named front_page, so I would at least suspect it to throw an error.
Also, I would really appreciate it if you could tell me where you found the info. I have been looking at http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/api/request.html?highlight=request.route_url#pyramid.request.Request.route_url but can't seem to find use from it.
Edit: should I be using an asset specification instead of a path name? so
return HTTPFound(Location=request.route_url('tutorial:templates/view.pt','/{pagename}'))
Also, I am working through this article which seems very helpful with the syntax: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#urldispatch-chapter
I think your form should submit to "/", ie.
<!-- where your home_page route is waiting for the POST -->
<form action="/" method="post">
With the prior answers this now looks correct:
return HTTPFound(location=request.route_url('view_page', pagename=name))
My first guess is that it's location not Location as the argument to HTTPFound.
from the link you give
it's should be
return HTTPFound(location=request.route_url('view_page',pagename=name))
when you had add this route
config.add_route('view_page', '/{pagename}')
and set the variable name before
name= request.params['name']

How to upload a file with django (python) and s3?

I'm looking for a way to upload a file to s3. I am using django. I am currently using amazon's python library for uploading along with the following code:
View:
def submitpicture(request):
fuser = request.session["login"]
copied_data = request.POST.copy()
copied_data.update(request.FILES)
content_type = copied_data['file'].get('content-type')
ffile = copied_data['file']['content']
key = '%s-%s' % (fuser, ''.join(copied_data['file']['filename'].split(' ')))
site_s3.save_s3_data(key, ffile, content_type)
Template:
<form action="/submitpicture/" method="POST">
<input type="file" id="file" name="file" />
<input type="submit" value="submit" />
</form>
However, when I actually try to run it i get the following error:
"Key 'file' not found in <QueryDict: {}>"
#MultiValueDictKeyError
I really don't see what I'm doing wrong. Can someone point me in the right direction?
Edit: Just in case someone wonders, I am planning on adding some validation after I get the actual upload working.
You will have to provide the enctype attribute to the FORM element (I've been bitten by this before). For example, your FORM tag should look like:
<form action="/submitpicture/" method="POST" enctype="multipart/form-data" >
Without the enctype, you will find yourself with an empty request.FILES.
Instead of doing this manually I would take a look at the storage backend David Larlet has written for Django, django-storages
Adding enctype="multipart/form-data" seems like something that's worth mentioning in the "File Uploads" section of the django docs (http://docs.djangoproject.com/en/dev/topics/http/file-uploads/). Thoughts?

Categories

Resources