2

I am trying to access a REST api and need to call it with a line of XML for a filter condition. My apologies for providing code that others cannot access. When I execute this code, I get the error message listed below.

import urllib2
import urllib
import hashlib
import hmac
import time
import random
import base64

def MakeRequest():
  url = 'https://api01.marketingstudio.com/API/Gateway/9'
  publickey = ''
  privatekey = ''
  method = 'Query'
  nonce = random.randrange(123400, 9999999)
  age = int(time.time())
  final = str(age) + '&' + str(nonce) + '&' + method.lower() + '&' + url.lower()  

  converted = hmac.new(privatekey, final, hashlib.sha1).digest()
  authorization = 'AMS ' + publickey + ':' + base64.b64encode(converted)

  xml_string = "<list><FilterItems><FilterItem attribute='pageNumber' value='1'/></FilterItems></list>"
  form = {'XML':xml_string}
  data = urllib.urlencode(form)
  headers = {'Content-Type': 'application/xml'}
  req = urllib2.Request(url,data,headers)
  req.add_header('ams-method', method)
  req.add_header('ams-nonce', nonce)
  req.add_header('ams-age', age)
  req.add_header('Authorization', authorization)  
  r = urllib2.urlopen(req)

  print r.read()

MakeRequest();  

Here is the error message.

Data at the root level is invalid. Line 1, position 1.
   at Aprimo.REST.Core.RESTService.GetRequest(String URI, HttpRequest req)
   at Aprimo.REST.RESTHandler.GetRequest(String apiUrl, HttpContext context)
   at Aprimo.REST.RESTHandler.ProcessRequest(HttpContext context)

I think this has the correct logic and filter conditions, what should I look at to get this to work. Thanks.

Per @Mark's suggestion I removed the urlencode for the XML string and got the following TraceBack:

Traceback (most recent call last):
  File "file.py", line 36, in <module>
    MakeRequest(); 
  File "file.py", line 32, in MakeRequest
    r = urllib2.urlopen(req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 126, in urlopen
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 392, in open
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 410, in _open
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 370, in _call_chain
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1194, in https_open
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1155, in do_open
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 801, in _send_output
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 773, in send
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 207, in sendall
TypeError: unhashable type
3
  • Is that error message returned from the server? It is a .NET XML parsing error. I am guessing the remote server does not like your xml_string. Are you sure you should be urlencoding it? Commented Aug 11, 2011 at 18:09
  • @Mark I removed the urlencode and got a different error: TypeError: unhashable type. I posted the entire traceback above. Any advice? Commented Aug 11, 2011 at 19:06
  • do you have any documentation on what the service is expecting? How you had it originally, you set the headers to 'applicaiton/xml', but then encoded the xml as a form which is usually sent 'application/x-www-form-urlencoded'. A lot of this implementation is dependent on what they expect. That said I am not sure about the "unhashable type", I tried formatting the request with just headers = {'Content-Type': 'application/xml'}; req = urllib2.Request(url,xml_string,headers) and did not get any errors Commented Aug 12, 2011 at 16:02

1 Answer 1

5

So the problem was with the formatting of the form variable and the encoding I was trying to do. Revising the following lines gets the call to work. I did not need to specify the headers.

 xml_string = "<list><FilterItems><FilterItem attribute='pageNumber' value='1'/></FilterItems></list>"
 data = (xml_string)
 req = urllib2.Request(url,data)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I had a XML string that gave me a server error. Had to put the parentheses around it for it to work!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.