4

I'm encountering this error message:

TypeError: add_header() takes exactly 3 arguments (2 given)

when using these parameters:

testService("SomeServiceName", "POST", "[redacted valid url]", ('Content-type','application/json'), [redacted valid json])

Normally this error means I'm not passing "self" as a parameter, but seeing as this method is not being called in a class, I'm not sure what to do. I've tried passing self in as a parameter in both the parameters and inside the method. And I've tried wrapping the header in brackets and parentheses. When I pass "self" I get the error message that self is undefined, and when I use the brackets instead of parentheses, I get the same error as above.

Anyone with magical Python debugging skills out there? Thanks so much for taking the time to check this out!

def testService(name, verb, url, header="", requestBody=""):

#Log out the name of the request we're testing
if (name is not None) or (name.strip() is not ""):
    print "Checking  " + name + "\n\n"

    # Make URL with StoreNumber
    if (url is not None) or (url is not ""):
        testUrl = url

        # If specified verb is GET
        if verb.strip().upper() == "GET":

            # Create request
            req = urllib2.Request(testUrl)
            print "Making request with URL: " + testUrl + "\n\n"

            # Send request
            try:
                response = urllib2.urlopen(req)

                # If service returns 200 Okay
                print "Connection to " + name + " Service successful. Returned with code " + str(response.code) + "\n\n"

                # Log response
                print "Response: " + response.read() + "\n\n"


                # Handle exceptions
                # If HTTP Error
            except HTTPError as e:
                if hasattr(e, 'reason'):
                    print name + ' failed to reach a server.'
                    print 'Reason: ', e.reason

                elif hasattr(e, 'code'):
                    print e.code

                elif hasattr(e, 'message'):
                    print e.message
                pass 

            # If URL was the problem
            except URLError as e:
                if hasattr(e, 'reason'):
                    print name + ' failed to reach a server.'

                    if str(e.reason) == "[Errno 11004] getaddrinfo failed":
                        print "[Errno 11004] getaddrinfo failed with bad url: " + testUrl + "\n\n"

                    else:
                        print 'Reason: ', e.reason

                elif hasattr(e, 'code'):
                    print 'Error code: ', e.code

                elif hasattr(e, 'message'):
                    print e.message
                pass 


        # If specified verb was POST
        elif verb.strip().upper() == "POST":

            # Check for None requestBody
            if (requestBody is not None) or (requestBody.strip() is not ""):
                data = urllib.urlencode(requestBody)

                # Create request
                req = urllib2.Request(testUrl, data)

                # Check for header
                if (header is not None) or (header.strip() is not ""):
                    req.add_header(header)

                    # YO YO THE BELOW CODE IS INCOMPLETE PLEASE FINISH
                    # Log request with URL and Data
                    print "Making request with URL: " + testUrl + " and data: THIS PART IS UNFINISHED PLEASE FINISH ME \n\n" 

                    try: 
                        response = urllib2.urlopen(req)

                        # If service returns 200 Okay
                        print "Connection to " + name + " Service successful. Returned with code " + str(response.code) + "\n\n"

                        # Log response
                        print "Response: " + response.read() + "\n\n"


                    # Handle exceptions
                    # If HTTP Error
                    except HTTPError as e:
                        if hasattr(e, 'code'):
                            print e.code
                        elif hasattr(e, 'message'):
                            print e.message
                        elif hasattr(e, 'reason'):
                            print name + ' failed to reach a server.'
                            print 'Reason: ', e.reason
                        pass 

                    except URLError as e:
                        if hasattr(e, 'reason'):
                            print name + ' failed to reach a server.'

                            if str(e.reason) == "[Errno 11004] getaddrinfo failed":
                                print "[Errno 11004] getaddrinfo failed with bad url: " + url + "\n\n"
                            else:
                                print 'Reason: ', e.reason                
                        elif hasattr(e, 'code'):
                            print 'Error code: ', e.code

                        elif hasattr(e, 'message'):
                            print e.message
                        pass 

                # Header non-existent in testService call
                else: 
                    print "Service header not provided. Exiting program"
                    sys.exit() 

            # Requesty Body not present in testService call
            else:
                print "Service request body not provided in code. Exiting program"
                sys.exit()

        # If specified verb is not supported (Currently only GET and POST are supported)    
        else:
            print name + " Service written with HTTP verb other than GET or POST. Exiting program"
            sys.exit()

    else:
        print "Service url not provided in code. Exiting program"
        sys.exit() 


else: 
    print "Service name not provided in code. Exiting program"
    sys.exit()
gtgaxiola
  • 9,241
  • 5
  • 42
  • 64
Iammesol
  • 144
  • 1
  • 2
  • 12

3 Answers3

7

From the documentation, add_header takes two arguments. You are calling it with one argument, a tuple with two values.

What you should do:

req.add_header(key, value)

What you are currently doing because you are getting the header as a tuple:

req.add_header((key, value,))    # aka passing a tuple with both arguments to the key parameter

You need to unpack the tuple:

req.add_header(header[0], header[1])

Or even better, using the splat operator (*):

req.add_header(*header)      # Does the same thing as above

Also, you are using an empty string as the default argument for header, when when it is supplied it is a tuple. You should probably change the default value to a tuple or None.

Community
  • 1
  • 1
rlms
  • 10,650
  • 8
  • 44
  • 61
4

Your header is a 2-tuple:

('Content-Type', 'application/json')

You're trying to do this:

req.add_header('Content-Type', 'application/json')

But in reality you're doing this:

req.add_header(('Content-Type', 'application/json'))

Notice that you're only passing one argument - a tuple - instead of two, a key and a value.

To fix, unpack your header when you pass it with the * (informally, 'splat') operator:

req.add_header(*header)
roippi
  • 25,533
  • 4
  • 48
  • 73
1

Take a look at the documentation: http://docs.python.org/2/library/urllib2.html#urllib2.Request.add_header.

While the function expects a key and a value, you're passing only a single object. Since you're calling this on the req object, that is the implicit "self" that's being passed as well.

You could call this function in two ways:

req.add_header(key, value)
urllib2.Request.add_header(req, key, value) # explicitly passing the reference instead of self

I'm not sure whether you're expecting the string you pass to be treated as the key or the value, but adding another paramater (or making the header parameter take a dict and then splitting appropriately in a for loop) should solve the issue. For example (with irrelevant code removed):

def testService(name, verb, url, header=None, requestBody=""):

    if header is None:
         header = {}

    for key, value in header.iteritems():
        req.add_header(key, value)
Chris Arena
  • 1,602
  • 15
  • 17