Home > Mobile >  AttributeError: module 'urllib3' has no attribute 'HTTPHeaderDict'
AttributeError: module 'urllib3' has no attribute 'HTTPHeaderDict'

Time:11-28

I am trying to send headers from lambda into an API.I have taken HTTPHeaderDict from https://urllib3.readthedocs.io/en/latest/user-guide.html .

import urllib3
import os
import json

# Get environment variable
api_url = os.getenv('API_URL')


def lambda_handler(event, context):
    #print("Received event: "   json.dumps(event, indent=2))
    request = json.loads(json.dumps(event))
    print(json.dumps(request['headers']))
    headers = request['headers']
    
    request_headers = urllib3.HTTPHeaderDict()
    for key in headers:
        request_headers.add(key, headers[key])
    
    http = urllib3.PoolManager()
    response = http.request('GET', api_url   '/', headers=request_headers, timeout=10)

    
    return {
        'statusCode': response.status,
        'headers': response.headers,
        'body': response.data
    }

I see the error in cloudwatch

[ERROR] AttributeError: module 'urllib3' has no attribute 'HTTPHeaderDict'

CodePudding user response:

What version of urllib3 are you using? If you are using the latest pip installed package which is version 1.26.7 it won't have it exposed at the package import level. If you look at the docs for the latest stable release you'll see that it isn't mentioned as an import level Class.

The link you linked too is for 2.0.0dev0 version which you'll have to install from the github repo itself. If you can't install from the repo you should be able to access the HTTPHeaderDict class from the _collections module like from urllib3._collections import HTTPHeaderDict and then call it as request_headers = HTTPHeaderDict().

CodePudding user response:

The HTTPHeaderDict seems to be not serializable and the error was in the way i was sending the response.

import urllib3
import os
import json
#from urllib3._collections import HTTPHeaderDict

# Get environment variable
api_url = os.getenv('API_URL')


def lambda_handler(event, context):
    #print("Received event: "   json.dumps(event, indent=2))
    request = json.loads(json.dumps(event))
    
    http = urllib3.PoolManager()
    response = http.request('GET', api_url   '/', headers=request['headers'], timeout=10)
    response_headers = {}
    for header_key in response.headers:
        response_headers[header_key] = response.headers[header_key] 
    
    return {
        'statusCode': response.status,
        'headers' : response_headers,
        'body': json.dumps('Hello from Lambda!')
    }

I had to loop through the HTTPHeaderDict and put the value in another dictionary.As pointed by @mata request['headers'] can be used directly.

P.S I couldn't find aws docs that indicate which version of urllib3 is used for AWS Lambda functions

  • Related