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
Related
I am using an API I found online for one of my scripts, and I am wondering if I can change one word from the API to something else. My code is:
import requests
people = requests.get('https://insult.mattbas.org/api/insult')
print("Welcome to the insult machine!\nType somebody you want to insult!")
b = input()
print(people.replace("You", b))
Is replace not a command? If so, what plugin and/or commands would I need to do it? Thanks!
The value returned from requests.get isn’t a string, it’s a response object and that class has no replace method.
Have a look at the structure of that class. For example, you can do r = requests.get(...) and r.text.replace(...).
In other words, you need to operate on the text part of the response object.
I'm want to make a CloudStack API call 'uploadVolume' as described in here.
I'm using python and my code works for all others API calls, excepted uploadVolume.
secretkey = 'EdKz8Po3zmFWacumfxirauUBPVcLEWKq0qRox1iqhzAsrmLnJaEJxL2IsyDfyPE2Oh5AODJG3ZGKZf6A08xQAw'
apikey = 'YIShhcJ1PaGF5awJlci46qyAqhEN8WYdtUodHAT2wp7-zpN21_fJpcy1POTiMXOlFH-f-rO3zAs3tYRGcFqxwg'
request['command']='uploadVolume'
request['format']='QCOW2'
request['name']='test'
request['url']='http://192.168.122.100/image.qcow2'
request['zoneid']='959416fc-71f0-461c-99f0-28449e098036'
request['response']='json'
request['apikey']= apikey
baseurl='http://192.168.122.250:8080/client/api?'
request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()])
sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())])
sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip())
url=baseurl+request_str+'&signature='+sig
The generated URL looks like this:
http://192.168.122.250:8080/client/api?apikey=YIShhcJ1PaGF5awJlci46qyAqhEN8WYdtUodHAT2wp7-zpN21_fJpcy1POTiMXOlFH-f-rO3zAs3tYRGcFqxwg&name=test&format=QCOW2&url=http%3A%2F%2F192.168.122.100%2Fimage.qcow2&zoneid=959416fc-71f0-461c-99f0-28449e098036&command=uploadVolume&response=json&signature=EKhoEWKIG3QcmFM9k6sVRruZvFs%3D
Response indicates that there is a signature problem:
{"uploadvolumeresponse":{"uuidList":[],"errorcode":401,"errortext":"unable to verify user credentials and/or request signature"}}
After some tests, I have identified that the signature error occurs because of the url parameter. If I replace the url with any string in this parameter the signature is done correctly, but (obviously) the command fails (since CloudStack will not find the image).
I think the problem is in the special characters that make up the url, but I'm not sure.
Does anyone have any idea how to solve this?
When sending data through python-requests a GET request, I have a need to specifically add something at the beginning of the query string. I have tried passing the data in through dicts and json strings with no luck.
The request as it appears when produced by requests:
/apply/.../explain?%7B%22......
The request as it appears when produced by their interactive API documentation (Swagger):
/apply/.../explain?record=%7B%22....
Where the key-value pairs of my data follow the excerpt above.
Ultimately, I think the missing piece is the record= that gets produced by their documentation. It is the only piece that is different from what is produced by Requests.
At the moment I've got it set up something like this:
import requests
s = requests.Session()
s.auth = requests.auth.HTTPBasicAuth(username,password)
s.verify = certificate_path
# with data below being a dictionary of the values I need to pass.
r = s.get(url,data=data)
I am trying to include an image of the documentation below, but don't yet have enough reputation to do so:
apply/model/explain documentation
'GET' requests don't have data, that's for 'POST' and friends.
You can send the query string arguments using params kwarg instead:
>>> params = {'record': '{"'}
>>> response = requests.get('http://www.example.com/explain', params=params)
>>> response.request.url
'http://www.example.com/explain?record=%7B%22'
From the comments i felt the need to explain this.
http://example.com/sth?key=value&anotherkey=anothervalue
Let's assume you have a url like the above in order to call with python requests you only have to write
response = requests.get('http://example.com/sth', params={
'key':'value',
'anotherkey':'anothervalue'
})
Have in mind that if your value or your keys have any special character in them they will be escaped thats the reason for the %7B%2 part of url in your question.
how do I get the whole raw http request in the python framework bottle?
I need something like this:
GET\n
myurl.com\n
/\n
attribute=value
&att2=value2
I need this to sign my http api requests
As far as I can tell from the docs you can't get the data in raw format.
What you can do is reconstruct it using bottle.request.data and bottle.request.headers. That may be enough for your purposes.
If you just want to print the request you can do the following:
headers_string = ['{}: {}'.format(h, request.headers.get(h)) for h in request.headers.keys()]
print('URL={}, method={}\nheaders:\n{}'.format(request.url, request.method, '\n'.join(headers_string)))
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.