Python: how to make HTTP request internally/localhost - php

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()

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)

Receive HTTP POST response by python

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?

duplicate HTTP POST from python script with Lua

I have a python script which succesfully posts a file to my localhost webserver running apache in <100ms. Now, I want to do exactly the same with Lua. I have come up with a script that posts that same image to my webserver but it takes a whopping ~24s to complete. The php running on the server receives and stores the file properly but for the Python script, the file comes in the $_FILES array whereas for the Lua script, I have to copy content from the php://input stream - also, looking at both POST requests with wireshark, I can see a 7667 POST from the Python script but not from the Lua, instead only a few TCP SYN & ACK frames. Any idea why my Lua script is missing the actual POST (incl. url) but it still seems to work (but really slow):
Some code is below:
Python
#!/usr/bin/python
import urllib2
import time
from binascii import hexlify, unhexlify
import MultipartPostHandler
fname="test.gif"
host = "localhost"
#host = "semioslive.com"
URI="/test.php"
#URI="/api/gateway.php"
nodemac ="AABBCC"
timestamp = int(time.time())
func="post_img"
url = "http://{0}{1}?f={2}&nodemac={3}&time={4}".format(host, URI,func,nodemac,timestamp)
opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)
data = {"data":open(fname,"rb")}
#r.get_method = lambda: 'PUT'
now = time.time()
response = opener.open(url, data, 120)
retval = response.read()
if "SUCCESS" in retval:
print "SUCCESS"
else:
print "RESPONSE sent at "+retval
print " Now "+str(time.time())
print "Request took "+str(time.time()-now)+"s to return"
Lua
#! /usr/bin/lua
http = require("socket.http")
ltn12 = require("ltn12")
local request_body = ltn12.source.file(io.open("test.gif"))
local response_body = {}
http.request{
url = "`http://localohst/test.php`",
method = "POST",
headers = {
["Content-Type"] = "multipart/form-data",
["Content-Length"] = 7333
},
-- source = ltn12.source.file(io.open("test.gif")),
source = request_body,
sink = ltn12.sink.table(response_body)
}
print(response_body[1]) --response to request
PHP
<?
if (isset($_FILES['data']))
move_uploaded_file($_FILES['data']['tmp_name'],"post(python).gif");
else
copy("php://input","post(lua).gif");
echo "SUCCESS!";
?>
Make sure your Lua script is sending the same HTTP headers. The important part for PHP is that the form with attached file upload is sent as "multipart/form-data", and the file must be properly embedded in the POST body of the HTTP request as a multipart mime message.
I cannot see if your Lua script actually does this, but I think no. Otherwise PHP would be happy.

Categories