Problems of GET and POST methods in Python - python

File name mypage.py
Python code
form = cgi.FieldStorage()
name = form.getfirst('name', 'empty')
id = form.getfirst('id', 'empty')
print """\
Content-Type: text/html\n
<html>
<body>
<p>Name: "%s"</p>
<p>ID: "%s"</p>
</body>
</html>
""" % (name, id)
HTML inside the same file
<form name="frm" method="post" action="mypage.py?id=33">
<input type="text" name="name" value="MyName" />
<input type="Submit" id="btn" value="Send" />
After submitting the form (pressing Send button), I can see this URL with following output
localhost:8000/cgi-bin/mypage.py?id=33
Name: "empty"
ID: "33"
if I change the form method POST to GET
<form name="frm" method="get" action="mypage.py?id=33">
then I can see this URL with following output
localhost:8000/cgi-bin/mypage.py?name=MyName
Name: "MyName"
ID: "empty"
I don't understand why I am not receiving text field value with POST method ? And why I am unable to receive id value in query string with GET method ?
Its simple python page without any framework. BTW I am using "python-bugzilla 0.8.0" downloaded from here but i think my given code is just a simple page and has nothing to do with this package.
Any help would be appreciated.
Thanks in advance,

Your GET is proper:
<form name="frm" method="get" action="mypage.py?id=33">
But your POST is not:
<form name="frm" method="post" action="mypage.py?id=33">
You can't add a GET style variable (?id=33) to the action of your POST. It should be:
<form name="frm" method="post" action="mypage.py">
<input type="hidden" name="id" value="33">
See HTTP Methods: GET vs. POST: "Query strings (name/value pairs) are sent in the URL of a GET request" and "Query strings (name/value pairs) are sent in the HTTP message body of a POST request".
Not adhering to these rules would cause unexpected results such as you are seeing.

Technically, a POST target url should not have GET parameters, so the ?id=33 in the target is invalid. I'm also guessing that it's confusing to the FieldStorage module, that might be why you are getting unexpected results.

You should properly use POST and GET per my other answer. That said, I'm worried about your use of form.getfirst and variable names.
Per the documentation:
FieldStorage.getfirst(name[, default]) - This method always returns only one value associated with form field name. The method returns only the first value in case that more values were posted under such name.
You've named your name variable name which is a silly name. See, lots of names. And your form has a name. And it's a field. Same with ID. You should change your variable names as such:
<form name="MyForm" method="post" action="mypage.py">
<input type="text" name="FullName" value="MyName" />
<input type="text" name="FormID" value="33" />
<input type="Submit" id="btn" value="Send" />
and change your Python as follows:
form = cgi.FieldStorage()
FullName = form.getfirst('FullName', 'empty')
FormID = form.getfirst('FormID', 'empty')
print """\
Content-Type: text/html\n
<html>
<body>
<p>Name: "%s"</p>
<p>ID: "%s"</p>
</body>
</html>
""" % (FullName, FormID)
That's the code for a proper POST and printing of the variables. Does it work?

Thanks for the help.
problem was here.
form = cgi.FieldStorage()
As I've mentioned in comments of your answers that I've printed "form" and here is output: "FieldStorage(None, None, [])".
So, if FieldStorage doesn't have any value then it doesn't matter which function is being used to get the form value. But it was really good information and practical as well.
previously form = cgi.FieldStorage() was declared inside another function which was wrong, that's why FieldStorage was empty.
Here is WRONG code.
def myfunction ():
cgitb.enable()
form = cgi.FieldStorage()
Solution 1:
form = cgi.FieldStorage() shall define inside the run() function and pass this form as parameter of other function to get values of form.
i.e.
def run():
cgitb.enable()
form = cgi.FieldStorage()
myfunction(form)
Now its working
def myfunction (form):
name = form.getfirst('name', 'empty')
id = form.getfirst('id', 'empty')
Solution 2:
form = cgi.FieldStorage() shall define directly inside the main function then don't need to pass it as parameter .
i.e.
if __name__ == "__main__":
cgitb.enable()
form = cgi.FieldStorage()
Now its working too and form is accessible inside the myfunction.
def myfunction ():
name = form.getfirst('name', 'empty')
id = form.getfirst('id', 'empty')
Thanks everybody.

Related

Form Handling with Lambda-AWS

I am trying to build a Lambda that displays a simple html form, where you fill your name (Mary for example) and the output should be "welcome Mary" but I dont know how to do it without .php
some information:
1.i am using python.
2.the first if (==GET) works fine.
3.action="lambda's URL", omitted in the code below.
4.my problem is on the second if(==POST).I dont know how to collect form data after submitting my HTML form.
Thanks in advance;)
here is the code:
import json
def lambda_handler(event, context):
if event['requestContext']['http']['method'] == 'GET':
content='''
<html>
<body>
<form action="my lambda's URL here" method="POST">
Name: <input type="text" name="fname"><br>
<input type="submit">
</form>
</body>
</html>
'''
if event['requestContext']['http']['method'] == 'POST':
content='''
<html>
<body>
<p>
"I would like to see:"Welcome Mary" here but i don't know how!
</p>
</body>
</html>
'''
# TODO implement
response = {
"statusCode": 200,
"headers": {
'Content-Type': 'text/html',
},
If your code you're accessing parts of the request like the HTTP method.
The event actually holds a heap of different bits of information about the request. You can see an example in the Lambda developer guide.
I would suggest printing out the entire event to start with while you get used to the format. Then work out how to access the form data.

Making a post request when there are no attributes in the form element?

I'm looping through zip codes and retrieving information from this site http://www.airnow.gov/index.cfm?action=school_flag_program.sfp_createwidget
Here's the form and input elements:
<form name="groovyform">
<input type="text" name="Title" id="Title" size="20" maxlength="20" />
<input type="text" name="Zipcode" id="Zipcode" size="10" maxlength="10" />
My question is how do I make a post request if there are no attributes in the form element (such as action or method)?
My code (I've tried request.get with the params argument, and request.post with the data argument):
url = 'http://www.airnow.gov/index.cfm?action=school_flag_program.sfp_createwidget'
data_to_send = {'zipcode ':'37217',
'Title': 'ph'}
response = requests.get(url, params=data_to_send)
contents = response.text
print contents
just returns the HTML of the url but I want the HTML of the page I get when I post the data. In other words, I don't think request.get is submitting my data and I think it has something to do with there not being an action or method attribute.
Enlighten me!
Thanks!
That form isn't intended to be submitted anywhere. It's just there for the benefit of the Copy button:
<input type="button" value="Copy" onclick="copy(document.groovyform.simba.value)" />
There are also a number of references to document.groovyform in the buildCall Javascript function, which is run when you click on Build your widget.
This is an old style of Javascript programming. These days, most would assign IDs to these elements, and use document.getElementById() to access them, so there would be no need to wrap them in a form. But before that approach was developed, the way to access DOM elements depended on the fact that forms are automatically added as properties of document, and input elements are properties of the containing form.
Reading Comprehension, I could learn it.
Ok, so like Barmar stated, the <form> I posted isn't supposed to be submitted. The form I was supposed to be filling out (top of the page) contained the following:
<form name="frmZipSearch" method="get" style="width:178px; float:left;">
Zip Code:
<input name="zipcode" type="text" size="5" maxlength="5" height="20">
Now my code works.
url = 'http://www.airnow.gov/index.cfm?action=airnow.local_city&zipcode=37217&submit=Go'
data_to_send = {'zipcode':'37217'}
response = requests.get(url, data=data_to_send)
contents = response.text
print contents
Thanks, Barmar, for directing me to the right path.

Python webpage login error

I am trying to create create a kind of webserver withy python and cherrypy.
I wish to put the htmls into separate files and embedd them into my python script. The code i used to do that is.
#cherrypy.expose
def welcome(self, loginAttempt = None):
""" Prompt the user with a login form. The form will be submitted to /signin
as a POST request, with arguments "username", "password" and "signin"
Dispaly a login error above the form if there has been one attempted login already.
"""
#Debugging Process Check
print "welcome method called with loggedIn = %s" % (loginAttempt)
if loginAttempt == '1':
""" If the user has attempted to login once, return the original login page
with a error message"""
page = get_file("loginPageE.html")
return page
else:
page = """
<form action='/signin' method='post'>
Username: <input type='text' name='username' /> <br />
Password: <input type='password' name='password' />
<input type='submit' name='signin' value='Sign In'/>
</form>
"""
return page
where loginPageE.html is
<html>
<head>
<title>Failed Login Page</title>
</head>
<body>
<!-- header-wrap -->
<div id="header-wrap">
<header>
<hgroup>
<h1>Acebook</h1>
<h3>Not Just Another Social Networking Site</h3>
</hgroup>
<ul>
<form action='/signin' method='post'>
Username: <input type='text' name='username' />
Password: <input type='password' name='password' />
<input type='submit' name='signin' value='Sign In'/>
</form>
</ul>
</header>
</div>
</body>
</html>
However I keep on getting an error message that reads
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/cherrypy/_cprequest.py", line 606, in respond
cherrypy.response.body = self.handler()
File "/usr/lib/pymodules/python2.7/cherrypy/_cpdispatch.py", line 25, in __call__
return self.callable(*self.args, **self.kwargs)
File "proj1base.py", line 74, in welcome
page = get_file("loginPageE.html")
NameError: global name 'get_file' is not defined
I was wondering if anyone could please help?
Thanks in advance
Well, from the error, evidently python doesn't know what the get_file() function is. Are you sure that at that point of time where you invoke this function inside the welcome() function, get_file() has been defined?
get_file isn't one of the standard Python functions, so it must be a custom one you used to have. You can create a simple function to read a file and return its contents as a string like this:
def get_file(path):
f = open(path, 'r')
output = f.read()
f.close()
return output
You can read up on Python file management at http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files
def get_file(path):
with open(path, 'r') as f:
return f.read()
However, consider using a proper template engine. Jinja2 is really good and it allows you to use conditionals etc. in templates - something you'll certainly want at some point. Besides that, it does nice things such as variable autoescaping for you if you ask it to.

Python - posting checkbox to web form

i use this code in python to post something to a form in a web page.
but i dont just want to send some text as an input textbox, i also want to decide if a checkbox in the form is checked or not.
what value do i have to give to the 'checkbox' parameter in the "web_form"?
web_form = [('textbox', text),('checkbox', ?????)]
form_data = urllib.urlencode(web_form)
o = urllib2.build_opener(url)
res = o.open(url, form_data).read()
this is the html of the form:
<form action="?" method="POST" enctype="multipart/form-data">
<textarea name="textbox"></textarea> Checkbox <input type='checkbox' name='cb' > <input type="submit" value="submit" /></div>
</form>
You question is pretty broad since you did not mention with web framework you are using.
Application code could check either for the existence of the checkbox key in the request or check for a particular value...unless you provide further informations: try setting it to something like '1' and see what's happening.

Trouble with receiving data from <form>

HTML:
<form enctype="multipart/form-data" action="/convert_upl" method="post">
Name: <input type="text" name="file_name">
File: <input type="file" name="subs_file">
<input type="submit" value="Send">
</form>
Python (Google App Engine):
if self.request.get('file_name'):
file_name = self.request.get('file_name')
My problem is that I receive no data from file_name text input. I am aware that the trouble is because of it's existence within the form enctype="multipart/form-data" but I don't know how to solve it - I mean how to receive a file and the string from the input with one click of the submit button.
Thanks in advance.
The uploading example code works fine for me. Have you tried using that code exactly? Does it work for you, or what problems do you see?
As you'll see, that example has a form with the same encoding you're using:
<form action="/sign" enctype="multipart/form-data" method="post">
<div><label>Message:</label></div>
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><label>Avatar:</label></div>
<div><input type="file" name="img"/></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
it's just a bit more careful in the HTML to properly use label tags to display field labels, but that only affect the form's looks when rendered in the browser.
The Python code is also similar to what you show (for the tiny susbset that you do show):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get("content")
avatar = self.request.get("img")
greeting.avatar = db.Blob(avatar)
greeting.put()
self.redirect('/')
and of course the /sign URL is directed to the class whose do_post method we've just shown.
So, if this code works and yours doesn't, where is the difference? Not in the part you've shown us, so it must be in some parts you haven't shown... can you reproduce the part about this example code from Google working just fine?
You are using the POST method to send the data but then are trying to get it with the GET method.
instead of
self.request.get('file_name')
do something like
self.request.post('file_name')

Categories

Resources