Why Does My Put request fail? - python

Using Python 2.5 and httplib......
I am admittedly a python novice.....but this seems straight forward, why doesn't this work?
httpConn = HTTPConnection('127.0.0.1', 44789)
httpConn.request('PUT','/ShazaamMon/setmfgdata.cgi?serial=', hwSerialNum)
httpResp = httpConn.getresponse()
xmlResp = httpResp.read()
httpConn.close()
it returns the following response: <HTML><HEAD><TITLE>HTTP 404.......
Any clues anyone???

I think you should replace PUT with GET.
You should consider sanitizing the input, trye
httpConn.request('GET','/ShazaamMon/setmfgdata.cgi?serial=%s' % (urllib.quote(hwSerialNum)))

HTTP 404 means that the resource you requested does not exist. Are you sure that the URL is correct?
Moreover, you put in the body of the request (third parameter of request()) a variable that I think is a parameter of the request.
Try the following:
httpConn.request('PUT','/ShazaamMon/setmfgdata.cgi?serial=' + str(hwSerialNum))
or maybe (if GET is required instead of PUT):
httpConn.request('GET','/ShazaamMon/setmfgdata.cgi?serial=' + str(hwSerialNum))

#Angelom's answer is concise and correct. For a nice example-filled explanation of using PUT in urllib and urllib2 try http://www.voidspace.org.uk/python/articles/urllib2.shtml#data.

Related

GET parameters with inequalities

I'm trying to use the requests library to do some HTTP GET/POST work. I have to generate a URL that looks like:
http://mysite/mypage.php?myval=>10
I can't seem to find anything other than:
r = requests.get("http://mysite/mypage.php", params={"myval":10})
which will result in a URL with ?myval=10.
Is there a way to get the inequality in the URL? Fortunately I'm still exploring what packages to use so I'm not married to requests if this is something that just won't work.
Inequalities don't exist as a HTTP parameter concept.
The > may just need to be URL encoded.
HTTP Parameters are key=value pairs, so myval=>10 might actually mean myval = >10.
To send though >10, try %3E10 as > URL-encoded is %3E

Flask not recognising two URL parameters

I'm trying to send two parameters to a URL routed with Flask.
If I do:
curl -i http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell
Then my code which is:
#application.route('/api/journeys/count', methods=['GET'])
def journeys():
print request.args
startStationName = request.args.get('startStationName')
endStationName = request.args.get('endStationName')
Should print a dict with startStationName and endStationName defined.
However, instead, only the first parameter seems to be received:
ImmutableMultiDict([('startStationName', u'Hansard Mews, Shepherds Bush')])
Anybody got any idea what I'm doing wrong? I have a feeling there must be some kind of stupid mistake or misunderstanding somewhere but I've been looking for an hour and can't find it.
Your shell interprets the & as a put the command in the background character. To prevent this, quote the whole URL:
curl -i "http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell"

Parsing and appending a link

I have a link as input below,i need to parse this link and append "/#c/" as shown below,any inputs on how
this can be done?
INPUT:-https://link.com/617394/
OUTPUT:-https://link.com/#/c/617394/
Try something such as:
from urlparse import urlsplit, urlunsplit
s = 'https://link.com/617394/'
split = urlsplit(s)
new_url = urlunsplit(split._replace(path='/#/c' + split.path))
# https://link.com/#/c/617394/
"https://link.com/617394/".replace("m/6","m/#/c/6")
although I suspect your real problem is something else
"com/#/c/".join("https://link.com/617394/".split("com/"))
may be slightly more applicable to your actual problem statement (which I still dont know what that is)
my_link = "https://link.com/617394/"
print re.sub("\.(com|org|net)/",".\\1/#/c/",my_link)
maybe more of what your actually looking for ...
that urlsplit solution of #JonClements is pretty dang sweet too

How to make a request to the Intersango API

I'm trying to figure out what's the correct URL format for the Intersango API (which is poorly documented). I'm programming my client in C#, but I'm looking at the Python example and I'm a little confused as to what is actually being placed in the body of the request:
def make_request(self,call_name,params):
params.append(('api_key',self.api_key)) // <-- How does this get serialized?
body = urllib.urlencode(params)
self.connect()
try:
self.connection.putrequest('POST','/api/authenticated/v'+self.version+'/'+call_name+'.php')
self.connection.putheader('Connection','Keep-Alive')
self.connection.putheader('Keep-Alive','30')
self.connection.putheader('Content-type','application/x-www-form-urlencoded')
self.connection.putheader('Content-length',len(body))
self.connection.endheaders()
self.connection.send(body)
response = self.connection.getresponse()
return json.load(response)
//...
I can't figure out this piece of code: params.append(('api_key',self.api_key))
Is it some kind of a dictionary, something that gets serialized to JSON, comma delimited, or exactly how does it get serialized? What would the body look like when the parameters are encoded and assigned to it?
P.S. I don't have anything that I can run the code with so I can debug it, but I'm just hoping that this is simple enough to understand for somebody that knows Python and they would be able to tell me what's happening on that line of code.
params is a list of 2-element lists. The list would look like ((key1, value1), (key2, value2), ...)
params.append(('api_key',self.api_key)) adds another 2-element list to the existing params list.
Finally, urllib.urlencode takes this list and converts it into a propert urlencoded string. In this case, it will return a string key1=value1&key2=value2&api_key=23423. If there are any special characters in your keys or values, urlencode will %encode them. See documentation for urlencode
I tried to get the C# code working, and it kept failing with exception {"The remote server returned an error: (417) Expectation Failed."}. I finally found what the problem is. You could read about it in depth here
In short, the way to make C# access Intersango API is to add following code:
System.Net.ServicePointManager.Expect100Continue = false;
This code needs to only run once. This is a global setting, so it affects your full application, so beware that something else could break as a result.
Here's a sample code:
System.Net.ServicePointManager.Expect100Continue = false;
var address = "https://intersango.com/api/authenticated/v0.1/listAccounts.php";
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var postBytes = Encoding.UTF8.GetBytes("api_key=aa75***************fd65785");
request.ContentLength = postBytes.Length;
var dataStream = request.GetRequestStream();
dataStream.Write(postBytes, 0, postBytes.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Piece of cake
instead of params.append(('api_key',self.api_key))
just write:
params['api_key']=self.api_key

Using Python Web GET data

I'm trying to pass information to a python page via the url. I have the following link text:
"<a href='complete?id=%s'>" % (str(r[0]))
on the complete page, I have this:
import cgi
def complete():
form = cgi.FieldStorage()
db = MySQLdb.connect(user="", passwd="", db="todo")
c = db.cursor()
c.execute("delete from tasks where id =" + str(form["id"]))
return "<html><center>Task completed! Click <a href='/chris'>here</a> to go back!</center></html>"
The problem is that when i go to the complete page, i get a key error on "id". Does anyone know how to fix this?
EDIT
when i run cgi.test() it gives me nothing
I think something is wrong with the way i'm using the url because its not getting passed through.
its basically localhost/chris/complete?id=1
/chris/ is a folder and complete is a function within index.py
Am i formatting the url the wrong way?
The error means that form["id"] failed to find the key "id" in cgi.FieldStorage().
To test what keys are in the called URL, use cgi.test():
cgi.test()
Robust test CGI script, usable as main program. Writes minimal HTTP headers and formats all information provided to the script in HTML form.
EDIT: a basic test script (using the python cgi module with Linux path) is only 3 lines. Make sure you know how to run it on your system, then call it from a browser to check arguments are seen on the CGI side. You may also want to add traceback formatting with import cgitb; cgitb.enable().
#!/usr/bin/python
import cgi
cgi.test()
Have you tried printing out the value of form to make sure you're getting what you think you're getting? You do have a little problem with your code though... you should be doing form["id"].value to get the value of the item from FieldStorage. Another alternative is to just do it yourself, like so:
import os
import cgi
query_string = os.environ.get("QUERY_STRING", "")
form = cgi.parse_qs(query_string)
This should result in something like this:
{'id': ['123']}
First off, you should make dictionary lookups via
possibly_none = my_dict.get( "key_name" )
Because this assigns None to the variable, if the key is not in the dict. You can then use the
if key is not None:
do_stuff
idiom (yes, I'm a fan of null checks and defensive programming in general...). The python documentation suggests something along these lines as well.
Without digging into the code too much, I think you should reference
form.get( 'id' ).value
in order to extract the data you seem to be asking for.

Categories