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()