Source code for schrodinger.application.licensing.netsuiteapi
# A Python module to perform Licensing API HTTPS REST calls to Schrodinger's
# NetSuite instance.
# Perform a version/compatibility check for now, since this code is not
# compatible with all Python versions.
import json
import requests
# Disable SSL security warnings until we upgrade to Python 2.7.9
requests.packages.urllib3.disable_warnings()
#############
# CONSTANTS #
#############
# Define the base, constant URL for the custom Schrodinger Licensing API hosted
# inside of NetSuite.
SCHRODINGER_NETSUITE_LICENSING_API_URL = \
    'https://websvc.schrodinger.com/licensing/api/api.php'
HTTP_STATUS_CODE_OK = 200
# Response fields
LICENSE_TYPE = 'license_type'
LICENSE_STRING = 'license_key'
# License types
NODELOCKED = 'Node-locked'
SERVER = 'Floating'
# Default port numbers for server licenses
DEFAULT_LMGRD_PORT = 27008
DEFAULT_SCHROD_PORT = 53000
# Info reply fields
LICENSE_REMAINING = 'licenses_remaining_count'
MAX_COUNT = 'licenses_total_count'
ERROR_CODE = 'error_code'
ERROR_MSG = 'error_message'
###############
# End Constants#
###############
[docs]def get_license_request_info(netsuite_license_hash_key):
    """
    This is an API call to the Schrodinger NetSuite instance in order to get
    the database data associated with a Schrodinger License Request Hash Key.
    NetSuite allows its customers to write custom code and deploy it within the
    NetSuite domain/environment. Therefore, we can construct and support
    arbitrary API calls within forms.netsuite.com. On the NetSuite side, we are
    simply reading Licensing data stored in our database (the same database
    currently used to track, store, and modify Licenses issued to customers of
    Schrodinger).
    :param str netsuite_license_hash_key: The unique NetSuite License Request
        hash key associated with a License Request stored in the Schrodinger
        NetSuite database.
    :returns: A dict (parsed from JSON) containing the meta-data for a license,
        or more specifically the corresponding License Request record fields
        and values stored in NetSuite.
    """
    # Append the Hash Key as an *additional* URL parameter.  The other
    # URL parameters are constant so there is no need to programmatically
    # concatenate them (they are included in constant).
    getRequestURLParameters = {'hashkey': netsuite_license_hash_key}
    # Perform a requests-based REST GET call to NetSuite (which should always
    # be over HTTPS).
    responseFromNetSuite = requests.get(SCHRODINGER_NETSUITE_LICENSING_API_URL,
                                        params=getRequestURLParameters,
                                        verify=False)
    if (responseFromNetSuite.status_code == HTTP_STATUS_CODE_OK):
        # If communication with NetSuite was successful, attempt to parse the
        # response as JSON using the built-in requests module JSON parser
        # If this response is not valid JSON, this parsing attempt should
        # raise an exception.
        try:
            jsonResponseFromNetSuite = responseFromNetSuite.json()
        except ValueError as err:
            # Add additional information to this error.
            msg = "Data returned from NetSuite, which should always be JSON formatted, failed to get parsed as JSON. JSON Parser Error: "
            msg += err.args[0]
            msg += "  The raw response data was: "
            msg += responseFromNetSuite.text
            err.args = (msg,)
            # Re-raise current exception with the expanded exception message
            raise
        return jsonResponseFromNetSuite
    else:
        responseFromNetSuite.raise_for_status() 
[docs]def retrieve_license_file(netsuite_license_hash_key,
                          machine_name_list,
                          host_id_list,
                          lmgrdport=None,
                          schrodport=None):
    """
    This is an API call to the Schrodinger NetSuite instance in order
    to process a License Key Retrieval request associated with a License
    Request Hash Key using machine data input provided from the user.
    Args:
        netsuite_license_hash_key (str): The unique NetSuite License
        Request hash key associated with a License Request stored in the
        Schrodinger NetSuite database.  machine_name_list (str list): The
        machine names describing the computers which will be running the
        FlexLM software.  host_id_list (str list): The 12 digit hexadecimal
        Host ID/MAC address strings for the servers or nodes which will
        be running the FlexLM software.
    Returns:
        str: A string containing the license key generated by the Licensing
        Server and processed through NetSuite for the given License Request
        and parameters.
    """
    if lmgrdport is None:
        lmgrdport = DEFAULT_LMGRD_PORT
    if schrodport is None:
        schrodport = DEFAULT_SCHROD_PORT
    # Append the Hash Key as an *additional* URL parameter.  The other URL
    # parameters are constant so there is no need to programmatically
    # concatenate them (they are included in constant).
    getRequestURLParameters = {'hashkey': netsuite_license_hash_key}
    postData = {
        'machine_names': machine_name_list,
        'host_ids': host_id_list,
        'lmgrdport': lmgrdport,
        'schrodport': schrodport
    }
    # If we allow Python to provide the default User Agent value, for example:
    # User-Agent: python-requests/2.4.3 CPython/2.7.6 Windows/7
    # Then we will be rejected with 405 Client Error: Method Not Allowed, so we have to pretend to be a browser.
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36',
        #'From': 'youremail@domain.com'  # This is another valid field
    }
    # Perform a requests-based REST POST call to NetSuite (which should always be over HTTPS).
    responseFromNetSuite = requests.post(SCHRODINGER_NETSUITE_LICENSING_API_URL,
                                         params=getRequestURLParameters,
                                         data=json.dumps(postData),
                                         headers=headers,
                                         verify=False)
    if (responseFromNetSuite.status_code == HTTP_STATUS_CODE_OK):
        # If communication with NetSuite was successful, attempt to parse the
        # response as JSON using the built-in requests module JSON parser
        # If response is not valid JSON, this parsing attempt should raise an exception.
        try:
            jsonResponseFromNetSuite = responseFromNetSuite.json()
        except ValueError as err:
            # Add additional information to this error.
            err.args = (
                "Data returned from NetSuite, which should always be JSON formatted, failed to get parsed as JSON. JSON Parser Error: "
                + err.args[0] + "  The raw response data was: " +
                responseFromNetSuite.text,)
            # Re-raise current exception with the expanded exception message
            raise
        return jsonResponseFromNetSuite
    else:
        # If we did not get an OK response, raise an exception!
        responseFromNetSuite.raise_for_status()