1
\$\begingroup\$

My first attempt at writing a Python application to solve a real problem is a one way connector between ERPNext and MYOB AccountRight.

This is the module I have written to connect to the API and get all the tokens. The user fills out a form in ERPNext containing the relevant keys, authorization code, redirect URI etc. which this module reads in and then sends requests for the tokens.

I'm sure it's a terribly primitive approach, but so far I'm happy.

I have a few questions. I seem to find I'm repeating myself quite a bit with the requests, and now that I've also started making other modules that will POST the various documents. I'm wondering if there is some way that I should approach refactoring the requests?

My other question is about the exceptions. I've never used them in a practical setting. Do I have the right idea? Should I be trying to catch the 400 error and inform the user? Are there other request exceptions I should try to catch?

import json

import requests

import frappe


TOKEN_URL = "https://secure.myob.com/oauth2/v1/authorize/"

# Retrieve the API settings saved by the user
client_id = frappe.db.get_single_value('MYOB Settings', 'api_key')
client_secret = frappe.db.get_single_value('MYOB Settings', 'api_secret')
redirect_uri = frappe.db.get_single_value('MYOB Settings', 'redirect_uri')


def get_tokens(doc, method):

    # Get the authorization code saved by the user
    auth_url = frappe.db.get_single_value('MYOB Settings', 
                                          'authorization_url')

    # split the authorization code from the url
    separator = "code="
    try:
        auth_code = auth_url.split(separator, 1)[1]

    except IndexError as e:
        frappe.log_error(frappe.get_traceback(), 'MYOB Authentication '
                                                 'Failed')
        raise IndexError("Invalid url entered. Check entire url has been paste"
                         "d.") from e

    payload = 'client_id=' + client_id + '&client_secret=' + client_secret +\
              '&scope=CompanyFile&grant_type=authorization_code&code='\
              + auth_code + '&redirect_uri=' + redirect_uri

    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': 'Bearer ' + auth_code
    }

    # Send request for tokens
    try:
        response = requests.request("POST", TOKEN_URL, headers=headers,
                                    data=payload)
        response.raise_for_status()

    except Exception as e:
        if e.args and e.args[0].startswith("400"):
            frappe.msgprint("400 Error: Bad Request. You may have entered "
                            "incorrect settings")

        else:
            frappe.msgprint("An unexpected error occurred. Check Error Log.")
            frappe.log_error(frappe.get_traceback(), 'MYOB Authentication '
                                                     'Failed')

    # Save tokens to database
    frappe.db.set_value('MYOB Settings',
                        'MYOB Settings', 'access_token',
                        response.json()['access_token'])
    frappe.db.set_value('MYOB Settings', 'MYOB Settings', 'refresh_token',
                        response.json()['refresh_token'])


def refresh_tokens(doc, method):

    # Get the refresh token from the database
    refresh_token = frappe.db.get_single_value('MYOB Settings',
                                               'refresh_token')

    payload = 'client_id=' + client_id + '&client_secret=' + client_secret + \
              '&grant_type=refresh_token&refresh_token=' + refresh_token
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    # Send request for new tokens
    try:
        response = requests.request("POST", TOKEN_URL, headers=headers,
                                    data=payload)
    except Exception as e:
        if e.args and e.args[0].startswith("400"):
            frappe.msgprint("400 Error: Bad Request. You may have entered "
                            "incorrect settings")

        else:
            frappe.msgprint("An unexpected error occurred. Check Error Log.")
            frappe.log_error(frappe.get_traceback(), 'MYOB Refreshing Tokens '
                                                     'Failed')

    # Save tokens to database
    frappe.db.set_value('MYOB Settings', 'MYOB Settings', 'access_token',
                        response.json()['access_token'])
    frappe.db.set_value('MYOB Settings', 'MYOB Settings', 'refresh_token',
                        response.json()['refresh_token'])
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.