Receive HTTP POST response by python - php

I use the following example:
http://www.w3schools.com/php/php_forms.asp
When I run it from browser,
I see the results in the browser:
Welcome John
Your email address is john.doe#example.com
When I run python POST http request:
import httplib, urllib
params = urllib.urlencode({'#name': 'John','#email': 'John.doe#example.com'})
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/html"}
conn = httplib.HTTPConnection("10.0.0.201")
conn.request("POST","/welcome.php",params, headers)
response = conn.getresponse()
print "Status"
print response.status
print "Reason"
print response.reason
print "Read"
print response.read()
conn.close()
I see the following:
Status
200
Reason
OK
Read
<html>
<body>
Welcome <br>
Your email address is:
</body>
</html>
The question is:
How to receive POST request data in python?

You are using the wrong form names and the wrong HTTP method. There are no # characters at their starts:
params = urllib.urlencode({'name': 'John','email': 'John.doe#example.com'})
Next, the form you point to uses GET, not POST as the handling method, so you'll have to add these parameters to the URL instead:
conn.request("GET", "/welcome.php?" + params, '', headers)
You are doing yourself a disservice by trying to drive the HTTPConnection() manually. You could use urllib2.urlopen() instead for example:
from urllib2 import urlopen
from urllib import urlencode
params = urlencode({'name': 'John','email': 'John.doe#example.com'})
response = urlopen('http://10.0.0.201/welcome.php?' + params)
print response.read()
or you could make use of the requests library (separate install) to make it yourself much easier still:
import requests
params = {'name': 'John','email': 'John.doe#example.com'}
response = requests.get('http://10.0.0.201/welcome.php', params=params)
print response.content

Instead of using urllib, use the requests library as Martijn suggested. It will make things much simpler.
Check out the documentation: http://docs.python-requests.org/en/latest/user/quickstart/

I just removed the "#" and it works:
Status
200
Reason
OK
Read
<html>
<body>
Welcome John<br>
Your email address is: John.doe#example.com
</body>
</html>
Thank you Martijn Pieters.
As for POST method, i used the example for infrastructure testing purposes.
Finally i need to fill mysql database and retrieve data from it over php using python script.
What is the best method for it?
Why is HTTPConnection() not recommended?

Related

Reading JSON response from sever1 and returning the same JSON as response for server3

I have the following arrangement.
Server3 has a Codeigniter application runing on server3.S3 makes a call to s2 with some headers like this
$parse_auth = $this->parse->login($result->email, $this->input->post('password'));
now, on S2, I have a python script that makes a call an external Parse API, which returns JSON response;
Here is the complete code:
import SimpleHTTPServer
import SocketServer
import logging
import cgi
import urllib2
import json
PORT = 9500
headers = None
BASE_URL = 'https://api.parse.com'
class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
args = self.path
parse_url = BASE_URL+args
opener = urllib2.build_opener()
opener.addheaders = [('Accept', self.headers.getheader('Accept')),('X-Parse-Application-Id', self.headers.getheader('X-Parse-Application-Id')),('X-Parse-Client-Version', self.headers.getheader('X-Parse-Client-Version')),('X-Parse-REST-API-Key', self.headers.getheader('X-Parse-REST-API-Key'))]
response = opener.open(parse_url)
print response.read()
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(response.read()))// I tried without json.dumps, didn't work
def do_POST(self):
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD':'POST',
'CONTENT_TYPE':self.headers['Content-Type'],
})
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
Handler = ServerHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
when I print response from S1 on s2, It appears JSON.
But on S3 when I print the array $parse_auth I get
-1
Bad Request
I want S3 to receive proper JSON response. How to do it.
Thanks in advance.
Well to start you're always going to have to use either json.dumps() or jsonify() in order to format your outgoing JSON properly. But to your question, it looks like this should work, but on what route is your PHP server taking requests? It might have something to do with request headers.
Also, is there a reason you're using python urllib? These kinds of problems are exactly what the requests module was designed to prevent by having you not have to worry about things like request headers.
http://docs.python-requests.org/en/latest/
Sending your request could be as simple as this.
>>> import requests
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'private_gists': 419, u'total_private_repos': 77, ...}

Python request.post to php server

Different variants of this question litter google, but I am not finding a solution specific to my needs. I am trying to send a JSON string from a client running python to a web server that is using PHP. The JSON string contains the results from a select query.
I have found lots of examples and tutorials on how to generate the JSON in python and how to publish data from the server database to a user via the server's page.
What I am not finding is how to actually transfer the JSON from the Python script to the PHP script. I am using the Arduino YUN with Linino, and have tried a request.post() but get a "module not found" error.
A plain english explanation of how the data hand off should take place between the two devices would help greatly! Any suggestions on a good resource that actually shows an example of what I have described would be great too.
Python (Post):
#!/usr/bin/python
import requests
import json
url = 'http://xxx.xxx.x.xxx/reciever.php'
payload = {"device":"gabriel","data_type":"data","zone":1,"sample":4,"count":0,"time_stamp":"00:00"}
headers = {'content-type': 'application/json'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
PHP (Receiver):
<?php
print_r(json_decode($_POST['payload']));
?>
Maybe there is a totally different way that is better for posting a select query from a client to a server? Client will have dynamic IP's and the server will be web based.
Library requests isn't installed in Python by default. You need to get it first via pip or another package manager:
pip install requests
After that, you can use it.
There is also library, that is built in: urllib2. Example:
import urllib
import urllib2
url = 'http://xxx.xxx.x.xxx/reciever.php'
payload = {"device":"gabriel","data_type":"data","zone":1,"sample":4,"count":0,"time_stamp":"00:00"}
headers = {'content-type': 'application/json'}
data = urllib.urlencode(payload)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

403 status code while trying to access webpage from Python

I've already tried using JSON but can't really read this page.
This is my python code. I've tried it on other websites and it works, but on this website it returns a 403.
import urllib2
req = urllib2.Request('http://www.taringa.net/envivo/ajax.php')
response = urllib2.urlopen(req)
the_page = response.read()
print the_page
Better use requests. I tried your script and got the status of 403. This means that access to it is closed, for whatever reason, I do not know.
You have to add the 'User-Agent' header in order to make this work.
Urllib code:
req = urllib2.Request('http://www.taringa.net/envivo/ajax.php')
req.add_header('User-Agent', 'Mozilla')
resp = urllib2.urlopen(req)
print resp.code # Gives 200.
print resp.read() # Gives the HTML of the page.
I would recommend that you use requests mainly because it makes this kind of stuff very easy.
Requests code:
h = {'User-Agent':'Mozilla'}
requests.get('http://www.taringa.net/envivo/ajax.php', headers=h)

Python: how to make HTTP request internally/localhost

I want to send some parameters from a python script on my server to a php script on my server using HTTP. Suggestions?
This is pretty easy using urllib:
import urllib
myurl = 'http://localhost/script.php?var1=foo&var2=bar'
# GET is the default action
response = urllib.urlopen(myurl)
# Output from the GET assuming response code was 200
data = response.read()

How do I send a HTTP POST value to a (PHP) page using Python?

I have a PHP page that has 1 textbox and when I press on the submit button. My SQL is going to store this product name into my database. My question is; is it possible to send/post the product name using Python script that asks for 1 value and then use my PHP page to send it to my database? Thanks!
Check out the urllib and urllib2 modules.
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/urllib.html
Simply create a Request object with the needed data. Then read the response from your PHP service.
http://docs.python.org/library/urllib2.html#urllib2.Request
When testing, or automating websites using python, I enjoy using twill. Twill is a tool that automatically handles cookies and can read HTML forms and submit them.
For instance, if you had a form on a webpage you could conceivably use the following code:
from twill import commands
commands.go('http://example.com/create_product')
commands.formvalue('formname', 'product', 'new value')
commands.submit()
This would load the form, fill in the value, and submit it.
Yes. urllib2 is a nice Python way to form/send HTTP requests.
I find http://www.voidspace.org.uk/python/articles/urllib2.shtml to be a good source of information about urllib2, which is probably the best tool for the job.
import urllib
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
The encoding is actually done using urllib, and this supports HTTP POST. There is also a way to use GET, where you have to pass the data into urlencode.
Don't forget to call read() though, otherwise the request won't be completed.
Personally i prefer to use Requests. As its summary, this is a HTTP library for Python, built for human beings.
To quickly solve problems, rather than study deeply in HTTP, Requests will be a better choice. (Yeah, i mean compared to urllib or socket)
For example,
A python file which send a POST request with userdata:
import requests
userdata = {"firstname": "Smith", "lastname": "Ayasaki", "password": "123456"}
resp = requests.post('http://example.com/test.php', data = userdata)
And the following text.php treating this request:
$firstname = htmlspecialchars($_POST["firstname"]);
$lastname = htmlspecialchars($_POST["lastname"]);
$password = htmlspecialchars($_POST["password"]);
echo "FIRSTNAME: $firstname LASTNAME: $lastname PW: $password";
Finally, the response text (resp.content in python) will be like:
FIRSTNAME: Smith LASTNAME: Ayasaki PW: 123456
A simple Quickstart: http://docs.python-requests.org/en/latest/user/quickstart/
Another answer recommending Requests: Sending data using POST in Python to PHP
Just an addendum to #antileet's procedure, it works similarly if you're trying to do a HTTP POST request with a web-service-like payload, except you just omit the urlencode step; i.e.
import urllib, urllib2
payload = """
<?xml version='1.0'?>
<web_service_request>
<short_order>Spam</short_order>
<short_order>Eggs</short_order>
</web_service_request>
""".strip()
query_string_values = {'test': 1}
uri = 'http://example.com'
# You can still encode values in the query string, even though
# it's a POST request. Nice to have this when your payload is
# a chunk of text.
if query_string_values:
uri = ''.join([uri, '/?', urllib.urlencode(query_string_values)])
req = urllib2.Request(uri, data=payload)
assert req.get_method() == 'POST'
response = urllib2.urlopen(req)
print 'Response:', response.read()

Categories