One way you could solve this is by separating the error handling logic into its own function, and then recursively calling a connection function:

    # Handles an error in the given response. Returns True if we should try connecting again
    def handle_error(response):
        if response["errors"][0]["type"] == 'INVALID_SESSION_ID':
            print("Session expired, initiating new session.")
            authorization = get_authorization(username, password)
            return True
        return False

    def connect():
        response = get_data(authorization)
        if response["responseStatus"] == "SUCCESS":
            process_data()
        elif response["responseStatus"] == "FAILURE":
            retry = handle_error(response)
            if retry:
                connect()
            else:
                print(response["errors"])

`handle_error` could, of course, be split up into more functions, one for each potential error. Depending on the response format, you may also want to check for each key in `response` before accessing it.

You could also specify `retry` as a number of times to reconnect before giving up, i.e if you were attempting to connect over multiple proxies. Then you would just decrement the counter after each failure, and print the error when the counter hits zero.