Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "region" and "use production slot" to clients #15

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ lib64

# Installer logs
pip-log.txt

# IDEs
.idea
.vscode
2 changes: 1 addition & 1 deletion python2/luis_sdk/luis_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def get_name(self):
def get_triggered(self):
'''
A getter for the action's triggered flag.
:return: A boolean that expresses whether the action was trigerred or not.
:return: A boolean that expresses whether the action was triggered or not.
'''
return self._triggered

Expand Down
37 changes: 23 additions & 14 deletions python2/luis_sdk/luis_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,21 @@
class LUISClient(object):
'''
This is the interface of the LUIS
Constructs a LUISClient with the corresponding user's App Id and Subscription Keys
Constructs a LUISClient with the corresponding user's App Id, region Subscription Keys
Starts the prediction procedure for the user's text, and accepts a callback function
'''
_LUISURL = u'westus.api.cognitive.microsoft.com'
_PredictMask = u'/luis/v2.0/apps/%s?subscription-key=%s&q=%s&verbose=%s'
_ReplyMask = u'/luis/v2.0/apps/%s?subscription-key=%s&q=%s&contextid=%s&verbose=%s'
_LUISURLMASK = u'%s.api.cognitive.microsoft.com'
_PredictMask = u'/luis/v2.0/apps/%s?subscription-key=%s&q=%s&verbose=%s&staging=%s'
_ReplyMask = u'/luis/v2.0/apps/%s?subscription-key=%s&q=%s&contextid=%s&verbose=%s&staging=%s'

def __init__(self, app_id, app_key, verbose=True):
def __init__(self, app_id, app_key, region, verbose=True, use_production_slot=True):
'''
A constructor for the LUISClient class.
:param app_id: A string containing the application id.
:param app_key: A string containing the subscription key.
:param region: A string containing the region of the subscription.
:param verbose: A boolean to indicate whether the verbose version should used or not.
:param use_production_slot: A boolean to indicate whether to use the production slot.
'''
if app_id is None:
raise TypeError(u'NULL App Id')
Expand All @@ -65,15 +67,23 @@ def __init__(self, app_id, app_key, verbose=True):
raise ValueError(u'Empty Subscription Key')
if u' ' in app_key:
raise ValueError(u'Invalid Subscription Key')
if region is None:
raise TypeError(u'NULL Region')
if not region:
raise ValueError(u'Empty Region')
if ' ' in region:
raise ValueError(u'Invalid Region')

self._app_id = app_id
self._app_key = app_key
self._region = region
self._verbose = u'true' if verbose else u'false'
self._use_staging_slot = u'false' if use_production_slot else u'true'

def predict(self, text, response_handlers=None, daemon=False):
'''
Routes the prediction routine to either sync or async
based on the presence or absence of a callback fucntion.
based on the presence or absence of a callback function.
:param text: the text to be analysed and predicted.
:param response_handlers: a dictionary that contains two keys on_success and on_failure,
whose values are two functions to be executed if async.
Expand All @@ -97,7 +107,7 @@ def predict_sync(self, text):
:return: A LUISResponse object containing the response data.
'''
try:
conn = httplib.HTTPSConnection(self._LUISURL)
conn = httplib.HTTPSConnection(self._LUISURLMASK % self._region)
conn.request(u'GET', self._predict_url_gen(text))
res = conn.getresponse()
return LUISResponse(res.read().decode(u'UTF-8'))
Expand Down Expand Up @@ -127,16 +137,15 @@ def _predict_url_gen(self, text):
'''
Returns the suitable LUIS API predict url.
:param text: The text to be analysed and predicted.
:return: LUIS API predicton url.
:return: LUIS API prediction url.
'''
return self._PredictMask%(self._app_id, self._app_key, quote(text), self._verbose)
return self._PredictMask%(self._app_id, self._app_key, quote(text), self._verbose, self._use_staging_slot)

def _predict_async_helper(self, text, response_handlers):
'''
A wrapper function to be executed asynchronously in an external thread.
It executes the predict routine and then executes a callback function.
:param text: The text to be analysed and predicted.
:param response: A LUISResponse that contains the context Id.
:param response_handlers: A dictionary that contains two keys on_success and on_failure,
whose values are two functions to be executed if async.
:return: None.
Expand All @@ -152,7 +161,7 @@ def _predict_async_helper(self, text, response_handlers):
def reply(self, text, response, response_handlers=None, force_set_parameter_name=None, daemon=False):
'''
Routes the reply routine to either sync or async
based on the presence or absence of a callback fucntion.
based on the presence or absence of a callback function.
:param text: The text to be analysed and predicted.
:param response: A LUISResponse object that contains the context Id.
:param response_handlers: A dictionary that contains two keys on_success and on_failure,
Expand All @@ -178,10 +187,10 @@ def reply_sync(self, text, response, force_set_parameter_name=None):
:param text: The text to be analysed and predicted.
:param response: A LUISResponse object that contains the context Id.
:param force_set_parameter_name: The name of a parameter the needs to be reset in dialog.
:return: A LUISResponse object containg the response data.
:return: A LUISResponse object containing the response data.
'''
try:
conn = httplib.HTTPSConnection(self._LUISURL)
conn = httplib.HTTPSConnection(self._LUISURLMASK % self._region)
conn.request(u'GET', self._reply_url_gen(text, response, force_set_parameter_name))
res = conn.getresponse()
return LUISResponse(res.read().decode(u'UTF-8'))
Expand Down Expand Up @@ -219,7 +228,7 @@ def _reply_url_gen(self, text, response, force_set_parameter_name):
:return: LUIS API reply url.
'''
url = self._ReplyMask%(self._app_id, self._app_key, quote(text)
, response.get_dialog().get_context_id(), self._verbose)
, response.get_dialog().get_context_id(), self._verbose, self._use_staging_slot)
if force_set_parameter_name is not None:
url += u'&forceset=%s'%(force_set_parameter_name)
return url
Expand Down
2 changes: 1 addition & 1 deletion python2/luis_sdk/luis_composite_entity_child.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LUISCompositeEntityChild:
def __init__(self, composite_entity_child):
'''
A constructor for the LUISCompositeEntityChild class.
:param composite_entity: A dictionary containing the composite entity child data.
:param composite_entity_child: A dictionary containing the composite entity child data.
'''
self._type = composite_entity_child['type']
self._value = composite_entity_child['value']
Expand Down
2 changes: 1 addition & 1 deletion python2/luis_sdk/luis_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LUISDialog(object):
def __init__(self, dialog):
'''
A constructor for the LUISDialog class.
:param action: A dictionary containing the dialog data.
:param dialog: A dictionary containing the dialog data.
'''
if u'prompt' in dialog:
self._prompt = dialog[u'prompt']
Expand Down
4 changes: 2 additions & 2 deletions python2/luis_sdk/luis_parametervalue.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

class LUISParameterValue(object):
'''
LUIS Paramater Value Class.
Describes the LUIS Paramter Value structure.
LUIS Parameter Value Class.
Describes the LUIS Parameter Value structure.
'''

def __init__(self, parameter_value):
Expand Down
2 changes: 1 addition & 1 deletion python2/luis_sdk/luis_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(self, JSONResponse):
try:
response = json.loads(JSONResponse)
except Exception:
raise Exception(u'Error in parsing json')
raise Exception(u'Error in parsing json "%s"' % JSONResponse)
else:
response = JSONResponse

Expand Down
3 changes: 2 additions & 1 deletion python2/sample_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ def process_res(res):
try:
APPID = raw_input(u'Please enter your app Id:\n')
APPKEY = raw_input(u'Please input your subscription key:\n')
REGION = raw_input(u'Please input your region:\n')
TEXT = raw_input(u'Please input the text to predict:\n')
CLIENT = LUISClient(APPID, APPKEY, True)
CLIENT = LUISClient(APPID, APPKEY, REGION, True, True)
res = CLIENT.predict(TEXT)
while res.get_dialog() is not None and not res.get_dialog().is_finished():
TEXT = raw_input(u'%s\n'%res.get_dialog().get_prompt())
Expand Down
3 changes: 2 additions & 1 deletion python2/sample_app_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def on_failure(err):
try:
APPID = raw_input(u'Please enter your app Id:\n')
APPKEY = raw_input(u'Please input your subscription key:\n')
REGION = raw_input(u'Please input your region:\n')
TEXT = raw_input(u'Please input the text to predict:\n')
CLIENT = LUISClient(APPID, APPKEY, True)
CLIENT = LUISClient(APPID, APPKEY, REGION, True, True)
CLIENT.predict(TEXT, {u'on_success': on_success, u'on_failure': on_failure})
print u'-------\nMain thread finishing!!\n-------'
except Exception, exc:
Expand Down
2 changes: 1 addition & 1 deletion python3/luis_sdk/luis_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def get_name(self):
def get_triggered(self):
'''
A getter for the action's triggered flag.
:return: A boolean that expresses whether the action was trigerred or not.
:return: A boolean that expresses whether the action was triggered or not.
'''
return self._triggered

Expand Down
39 changes: 24 additions & 15 deletions python3/luis_sdk/luis_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,21 @@
class LUISClient:
'''
This is the interface of the LUIS
Constructs a LUISClient with the corresponding user's App Id and Subscription Keys
Constructs a LUISClient with the corresponding user's App Id, region and Subscription Keys
Starts the prediction procedure for the user's text, and accepts a callback function
'''
_LUISURL = 'westus.api.cognitive.microsoft.com'
_PredictMask = '/luis/v2.0/apps/%s?subscription-key=%s&q=%s&verbose=%s'
_ReplyMask = '/luis/v2.0/apps/%s?subscription-key=%s&q=%s&contextid=%s&verbose=%s'
_LUISURLMASK = '%s.api.cognitive.microsoft.com'
_PredictMask = '/luis/v2.0/apps/%s?subscription-key=%s&q=%s&verbose=%s&staging=%s'
_ReplyMask = '/luis/v2.0/apps/%s?subscription-key=%s&q=%s&contextid=%s&verbose=%s&staging=%s'

def __init__(self, app_id, app_key, verbose=True):
def __init__(self, app_id, app_key, region, verbose=True, use_production_slot=True):
'''
A constructor for the LUISClient class.
:param app_id: A string containing the application id.
:param app_key: A string containing the subscription key.
:param region: A string containing the region of the subscription.
:param verbose: A boolean to indicate whether the verbose version should used or not.
:param use_production_slot: A boolean to indicate whether to use the production slot.
'''
if app_id is None:
raise TypeError('NULL App Id')
Expand All @@ -65,15 +67,23 @@ def __init__(self, app_id, app_key, verbose=True):
raise ValueError('Empty Subscription Key')
if ' ' in app_key:
raise ValueError('Invalid Subscription Key')
if region is None:
raise TypeError('NULL Region')
if not region:
raise ValueError('Empty Region')
if ' ' in region:
raise ValueError('Invalid Region')

self._app_id = app_id
self._app_key = app_key
self._region = region
self._verbose = 'true' if verbose else 'false'
self._use_staging_slot = 'false' if use_production_slot else 'true'

def predict(self, text, response_handlers=None, daemon=False):
'''
Routes the prediction routine to either sync or async
based on the presence or absence of a callback fucntion.
based on the presence or absence of a callback function.
:param text: the text to be analysed and predicted.
:param response_handlers: a dictionary that contains two keys on_success and on_failure,
whose values are two functions to be executed if async.
Expand All @@ -97,7 +107,7 @@ def predict_sync(self, text):
:return: A LUISResponse object containing the response data.
'''
try:
conn = http.client.HTTPSConnection(self._LUISURL)
conn = http.client.HTTPSConnection(self._LUISURLMASK % self._region)
conn.request('GET', self._predict_url_gen(text))
res = conn.getresponse()
return LUISResponse(res.read().decode('UTF-8'))
Expand Down Expand Up @@ -127,16 +137,15 @@ def _predict_url_gen(self, text):
'''
Returns the suitable LUIS API predict url.
:param text: The text to be analysed and predicted.
:return: LUIS API predicton url.
:return: LUIS API prediction url.
'''
return self._PredictMask%(self._app_id, self._app_key, quote(text), self._verbose)
return self._PredictMask%(self._app_id, self._app_key, quote(text), self._verbose, self._use_staging_slot)

def _predict_async_helper(self, text, response_handlers):
'''
A wrapper function to be executed asynchronously in an external thread.
It executes the predict routine and then executes a callback function.
:param text: The text to be analysed and predicted.
:param response: A LUISResponse object that contains the context Id.
:param response_handlers: A dictionary that contains two keys on_success and on_failure,
whose values are two functions to be executed if async.
:return: None.
Expand All @@ -152,7 +161,7 @@ def _predict_async_helper(self, text, response_handlers):
def reply(self, text, response, response_handlers=None, force_set_parameter_name=None, daemon=False):
'''
Routes the reply routine to either sync or async
based on the presence or absence of a callback fucntion.
based on the presence or absence of a callback function.
:param text: The text to be analysed and predicted.
:param response: A LUISResponse object that contains the context Id.
:param response_handlers: A dictionary that contains two keys on_success and on_failure,
Expand All @@ -178,10 +187,10 @@ def reply_sync(self, text, response, force_set_parameter_name):
:param text: The text to be analysed and predicted.
:param response: A LUISResponse object that contains the context Id.
:param force_set_parameter_name: The name of a parameter the needs to be reset in dialog.
:return: A LUISResponse object containg the response data.
:return: A LUISResponse object containing the response data.
'''
try:
conn = http.client.HTTPSConnection(self._LUISURL)
conn = http.client.HTTPSConnection(self._LUISURLMASK % self._region)
conn.request('GET', self._reply_url_gen(text, response, force_set_parameter_name))
res = conn.getresponse()
return LUISResponse(res.read().decode('UTF-8'))
Expand Down Expand Up @@ -219,12 +228,12 @@ def _reply_url_gen(self, text, response, force_set_parameter_name):
:return: LUIS API reply url.
'''
url = self._ReplyMask%(self._app_id, self._app_key, quote(text)
, response.get_dialog().get_context_id(), self._verbose)
, response.get_dialog().get_context_id(), self._verbose, self._use_staging_slot)
if force_set_parameter_name is not None:
url += '&forceset=%s'%(force_set_parameter_name)
return url

def _reply_async_helper(self, text, response, response_handlers):
def _reply_async_helper(self, text, response, response_handlers, force_set_parameter_name):
'''
A wrapper function to be executed asynchronously in an external thread.
It executes the reply routine and then executes a callback function.
Expand Down
2 changes: 1 addition & 1 deletion python3/luis_sdk/luis_composite_entity_child.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LUISCompositeEntityChild:
def __init__(self, composite_entity_child):
'''
A constructor for the LUISCompositeEntityChild class.
:param composite_entity: A dictionary containing the composite entity child data.
:param composite_entity_child: A dictionary containing the composite entity child data.
'''
self._type = composite_entity_child['type']
self._value = composite_entity_child['value']
Expand Down
2 changes: 1 addition & 1 deletion python3/luis_sdk/luis_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LUISDialog:
def __init__(self, dialog):
'''
A constructor for the LUISDialog class.
:param action: A dictionary containing the dialog data.
:param dialog: A dictionary containing the dialog data.
'''
if 'prompt' in dialog:
self._prompt = dialog['prompt']
Expand Down
4 changes: 2 additions & 2 deletions python3/luis_sdk/luis_parametervalue.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

class LUISParameterValue:
'''
LUIS Paramater Value Class.
Describes the LUIS Paramter Value structure.
LUIS Parameter Value Class.
Describes the LUIS Parameter Value structure.
'''

def __init__(self, parameter_value):
Expand Down
2 changes: 1 addition & 1 deletion python3/luis_sdk/luis_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(self, JSONResponse):
try:
response = json.loads(JSONResponse)
except Exception:
raise Exception('Error in parsing json')
raise Exception('Error in parsing json "%s"' % JSONResponse)
else:
response = JSONResponse

Expand Down
3 changes: 2 additions & 1 deletion python3/sample_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ def process_res(res):
try:
APPID = input('Please enter your app Id:\n')
APPKEY = input('Please input your subscription key:\n')
REGION = input('Please input your region:\n')
TEXT = input('Please input the text to predict:\n')
CLIENT = LUISClient(APPID, APPKEY, True)
CLIENT = LUISClient(APPID, APPKEY, REGION, True, True)
res = CLIENT.predict(TEXT)
while res.get_dialog() is not None and not res.get_dialog().is_finished():
TEXT = input('%s\n'%res.get_dialog().get_prompt())
Expand Down
3 changes: 2 additions & 1 deletion python3/sample_app_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def on_failure(err):
try:
APPID = input('Please enter your app Id:\n')
APPKEY = input('Please input your subscription key:\n')
REGION = input('Please input your region:\n')
TEXT = input('Please input the text to predict:\n')
CLIENT = LUISClient(APPID, APPKEY, True)
CLIENT = LUISClient(APPID, APPKEY, REGION, True, True)
CLIENT.predict(TEXT, {'on_success': on_success, 'on_failure': on_failure})
print('-------\nMain thread finishing!!\n-------')
except Exception as exc:
Expand Down