I am trying to convert this code snippet from PHP to Python (programming newbie) and am finding difficulty in doing so:
The PHP that I am trying to convert is as follows:
$fp = fsockopen($whmcsurl, 80, $errno, $errstr, 5);
if ($fp) {
$querystring = "";
foreach ($postfields AS $k=>$v) {
$querystring .= "$k=".urlencode($v)."&";
}
$header="POST ".$whmcsurl."modules/servers/licensing/verify.php HTTP/1.0\r\n";
$header.="Host: ".$whmcsurl."\r\n";
$header.="Content-type: application/x-www-form-urlencoded\r\n";
$header.="Content-length: ".@strlen($querystring)."\r\n";
$header.="Connection: close\r\n\r\n";
$header.=$querystring;
$data="";
@stream_set_timeout($fp, 20);
@fputs($fp, $header);
$status = @socket_get_status($fp);
while (!@feof($fp)&&$status) {
$data .= @fgets($fp, 1024);
$status = @socket_get_status($fp);
}
@fclose ($fp);
}
It corresponding Python code that I wrote is as follows:
fp = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
fp.connect(("my ip", 80))
if (fp):
querystring = ""
#print postfields
for key in postfields:
querystring = querystring+key+"="+urllib.quote(str(postfields[key]))+"&"
header = "POST "+whmcsurl+"modules/servers/licensing/verify.php HTTP/1.0\r\n"
header+="Content-type: application/x-www-form-urlencoded\r\n"
header+="Content-length: "+str(len(querystring))+"\r\n"
header+="Connection: close\r\n\r\n"
#header+=querystring
data=""
request = urllib2.Request(whmcsurl,querystring,header)
response = urllib2.urlopen(request)
data = response.read()
Here, I am faced with the following error:
request = urllib2.Request(whmcsurl,querystring,header)
File "/usr/lib64/python2.6/urllib2.py", line 200, in __init__
for key, value in headers.items():
AttributeError: 'str' object has no attribute 'items'
So I am guessing that Python is expecting a dictionary for the header. But the PHP sends it as a string.
May I know how to solve this issue?
Thanks in advance
You are overcomplicating things, by quite some distance. Python takes care of most of this for you. There is no need to open a socket yourself, nor do you need to build headers and the HTTP opening line.
Use the urllib.request
and urllib.parse
modules to do the work for you:
from urllib.parse import urlopen
from urllib.request import urlopen
params = urlencode(postfields)
url = whmcsurl + 'modules/servers/licensing/verify.php'
response = urlopen(url, params)
data = response.read()
urlopen()
takes a second parameter, the data to be sent in a POST
request; the library takes care of calculating the length of the body, and sets the appropriate headers. Most of all, under the hood it uses another library, httplib
, to take care of the socket connection and producing valid headers and a HTTP request line.
The POST body is encoded using urllib.parse.urlencode()
, which also takes care of proper quoting for you.
You may also want to look into the external requests
library, which provides an easier-to-use API still:
import requests
response = requests.post(whmcsurl + 'modules/servers/licensing/verify.php', params=params)
data = response.content # or response.text for decoded content, or response.json(), etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With