0

I am trying to convert this part into Python3 and just can't get it to work.

import urllib
import datetime
import urllib2
import httplib
import hmac
from hashlib import sha256

TIMEOUT=60

def getDimMetrics(options):
    now = datetime.datetime.now()
    
    # create a dictionary of the arguments to the API call
    post_dict = {}
    
    if options.group:
        post_dict['group'] = options.group
        
        # start and end are dates, the format will be specified on the command line
        # we will simply pass those along in the API
        
    if options.start:
        post_dict['start'] = options.start
        
    if options.end:
        post_dict['end'] = options.end
        
        # encode the data
        post_data = urllib.urlencode(post_dict)
        protocol = 'https'
        
    if 'localhost' in options.host:
        # for testing
        protocol = 'http'
        url = protocol + '://' + options.host + options.url + '.' + options.type.lower()
        
        # create the request
        request = urllib2.Request(url, post_data)
        
        # add a date header (optional)
        request.add_header('Date', str(now))

        # calculate the authorization header and add it
        hashString = 'POST' + request.get_selector() + request.get_header('Date') + 'application/x-www-form-urlencoded' + str(len(request.get_data()))
        calc_sig = hmac.new(str(options.secret), hashString,
        sha256).hexdigest()
        request.add_header('Authorization', 'Dimo %s:%s' %(options.key, calc_sig))

        print 'url=', url
        print 'post_data=', post_data
        print 'headers=', request.headers

This is what I have in Python3. When I run it I get an error message saying 400 Malformed Authorization header. How can I fix this error so that I can get this part running in python 3.

from requests_oauthlib import OAuth1Session

CONSUMER_KEY = "aaaaaaaaaaaaaaaaa"
CONSUMER_SECRET = "bbbbbbbbbbbbbbbbbbbb"
host = "api.dimo.com"
uri = "/api/Visits.json"

oauthRequest = OAuth1Session(CONSUMER_KEY,
                    client_secret=CONSUMER_SECRET)

url = 'https://' + host + uri

headers = {
        'Accept': "application/json",
        'Accept-Encoding': "application/x-www-form-urlencoded",
        'Authorization': "dimo bbbbbbbbbbbbbbb"
    }

response = oauthRequest.post(url, headers=headers)

print(response.status_code)
print(response.content)

ERROR 400 b'Malformed Authorization header.\n'

1 Answer 1

1

Problem

  1. You're experiencing issues converting python 2.7 code to python 3.x.
  2. Your authorization header in your original python 3 converted code isn't valid.

Solution

Run python 2to3 converter with some additional cleanup based on PEP 8 -- Style Guide for Python ( max line length, etc.).

Example

import datetime
import urllib.request
import urllib.error
import urllib.parse
import http.client
import hmac
from hashlib import sha256

TIMEOUT = 60


def getDimMetrics(options):
    now = datetime.datetime.now()

    # create a dictionary of the arguments to the API call
    post_dict = {}

    if options.group:
        post_dict['group'] = options.group

    # start and end are dates, the format will be specified on the command line
    # we will simply pass those along in the API
    if options.start:
        post_dict['start'] = options.start

    if options.end:
        post_dict['end'] = options.end

        # encode the data
        post_data = urllib.parse.urlencode(post_dict)
        protocol = 'https'

    if 'localhost' in options.host:
        # for testing
        protocol = 'http'
        url = f'{protocol}://{options.host}{options.url}.' \
              f'{options.type.lower()}'

        # create the request
        request = urllib.request.Request(url, post_data)

        # add a date header (optional)
        request.add_header('Date', str(now))

        # calculate the authorization header and add it
        hashString = f'POST{request.get_selector()}' \
                     f'{request.get_header('Date')}' \
                     f'application/x-www-form-urlencoded' \
                     f'{str(len(request.get_data()))}'

        calc_sig = hmac.new(
            str(options.secret), hashString, sha256).hexdigest()
        request.add_header('Authorization', 'Dimo {options.key}:{calc_sig}')

        print(f'url={url}')
        print(f'post_data={post_data}')
        print(f'headers={request.headers}')

References

Python 2to3: https://docs.python.org/3/library/2to3.html

Sign up to request clarification or add additional context in comments.

3 Comments

While code-only answers might answer the question, you could significantly improve the quality of your answer by providing context for your code, a reason for why this code works, and some references to documentation for further reading. From How to Answer: "Brevity is acceptable, but fuller explanations are better."
How would I call this script in python?
@Vel Call which script?

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.