From b5d0aafc4e196a0ef81b8838a31a100df284cd51 Mon Sep 17 00:00:00 2001 From: jagreene Date: Thu, 11 Jun 2015 09:45:23 -0400 Subject: [PATCH] ADD: keywords api support --- indicoio/__init__.py | 2 ++ indicoio/config.py | 3 ++- indicoio/images/features.py | 6 +++-- indicoio/images/fer.py | 3 ++- indicoio/text/keywords.py | 24 ++++++++++++++++++ indicoio/text/lang.py | 4 +-- indicoio/text/sentiment.py | 12 ++++----- indicoio/text/tagging.py | 4 +-- indicoio/utils/api.py | 2 ++ tests/test_remote.py | 50 +++++++++++++++++++++++++------------ 10 files changed, 80 insertions(+), 30 deletions(-) create mode 100644 indicoio/text/keywords.py diff --git a/indicoio/__init__.py b/indicoio/__init__.py index 3c06929..50a3ea5 100644 --- a/indicoio/__init__.py +++ b/indicoio/__init__.py @@ -13,6 +13,7 @@ from indicoio.text.sentiment import political, posneg, sentiment_hq from indicoio.text.sentiment import posneg as sentiment from indicoio.text.lang import language from indicoio.text.tagging import text_tags +from indicoio.text.keywords import keywords from indicoio.images.fer import fer from indicoio.images.features import facial_features from indicoio.images.features import image_features @@ -20,6 +21,7 @@ from indicoio.utils.multi import predict_image, predict_text from indicoio.config import API_NAMES + apis = dict((api, globals().get(api)) for api in API_NAMES) for api in apis: diff --git a/indicoio/config.py b/indicoio/config.py index 0b24332..756f4b0 100644 --- a/indicoio/config.py +++ b/indicoio/config.py @@ -50,7 +50,8 @@ TEXT_APIS = [ 'political', 'sentiment', 'language', - 'sentiment_hq' + 'sentiment_hq', + 'keywords' ] IMAGE_APIS = [ diff --git a/indicoio/images/features.py b/indicoio/images/features.py index e1fc18b..75482bd 100644 --- a/indicoio/images/features.py +++ b/indicoio/images/features.py @@ -26,7 +26,8 @@ def facial_features(image, cloud=None, batch=False, api_key=None, **kwargs): :rtype: List containing feature responses """ image = image_preprocess(image, batch=batch) - return api_handler(image, cloud=cloud, api="facialfeatures", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(image, cloud=cloud, api="facialfeatures", url_params=url_params, **kwargs) def image_features(image, cloud=None, batch=False, api_key=None, **kwargs): """ @@ -59,4 +60,5 @@ def image_features(image, cloud=None, batch=False, api_key=None, **kwargs): :rtype: List containing features """ image = image_preprocess(image, batch=batch, size=(64,64)) - return api_handler(image, cloud=cloud, api="imagefeatures", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(image, cloud=cloud, api="imagefeatures", url_params=url_params, **kwargs) diff --git a/indicoio/images/fer.py b/indicoio/images/fer.py index b36d6ff..87612e2 100644 --- a/indicoio/images/fer.py +++ b/indicoio/images/fer.py @@ -28,4 +28,5 @@ def fer(image, cloud=None, batch=False, api_key=None, **kwargs): :rtype: Dictionary containing emotion probability pairs """ image = image_preprocess(image, batch=batch) - return api_handler(image, cloud=cloud, api="fer", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(image, cloud=cloud, api="fer", url_params=url_params, **kwargs) diff --git a/indicoio/text/keywords.py b/indicoio/text/keywords.py new file mode 100644 index 0000000..4293486 --- /dev/null +++ b/indicoio/text/keywords.py @@ -0,0 +1,24 @@ +from indicoio.utils.api import api_handler +import indicoio.config as config + +def keywords(text, cloud=None, batch=False, api_key=None, **kwargs): + """ + Given input text, returns series of keywords and associated scores + + Example usage: + + .. code-block:: python + + >>> import indicoio + >>> import numpy as np + >>> text = 'Monday: Delightful with mostly sunny skies. Highs in the low 70s.' + >>> keywords = indicoio.keywords(text, top_n=3) + >>> print "The keywords are: "+str(keywords.keys()) + u'The keywords are ['delightful', 'highs', 'skies'] + + :param text: The text to be analyzed. + :type text: str or unicode + :rtype: Dictionary of feature score pairs + """ + url_params = {'batch': batch, 'api_key': api_key} + return api_handler(text, cloud=cloud, api="keywords", url_params=url_params, **kwargs) diff --git a/indicoio/text/lang.py b/indicoio/text/lang.py index 9f0871f..fbc03a3 100644 --- a/indicoio/text/lang.py +++ b/indicoio/text/lang.py @@ -23,5 +23,5 @@ def language(text, cloud=None, batch=False, api_key=None, **kwargs): :type text: str or unicode :rtype: Dictionary of language probability pairs """ - - return api_handler(text, cloud=cloud, api="language", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(text, cloud=cloud, api="language", url_params=url_params, **kwargs) diff --git a/indicoio/text/sentiment.py b/indicoio/text/sentiment.py index 5172e40..64607f3 100644 --- a/indicoio/text/sentiment.py +++ b/indicoio/text/sentiment.py @@ -25,8 +25,8 @@ def political(text, cloud=None, batch=False, api_key=None, **kwargs): :type text: str or unicode :rtype: Dictionary of party probability pairs """ - - return api_handler(text, cloud=cloud, api="political", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(text, cloud=cloud, api="political", url_params=url_params, **kwargs) def posneg(text, cloud=None, batch=False, api_key=None, **kwargs): """ @@ -48,8 +48,8 @@ def posneg(text, cloud=None, batch=False, api_key=None, **kwargs): :type text: str or unicode :rtype: Float """ - - return api_handler(text, cloud=cloud, api="sentiment", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(text, cloud=cloud, api="sentiment", url_params=url_params, **kwargs) def sentiment_hq(text, cloud=None, batch=False, api_key=None, **kwargs): """ @@ -71,5 +71,5 @@ def sentiment_hq(text, cloud=None, batch=False, api_key=None, **kwargs): :type text: str or unicode :rtype: Float """ - - return api_handler(text, cloud=cloud, api="sentimenthq", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(text, cloud=cloud, api="sentimenthq", url_params=url_params, **kwargs) diff --git a/indicoio/text/tagging.py b/indicoio/text/tagging.py index e0f58de..87a1cdc 100644 --- a/indicoio/text/tagging.py +++ b/indicoio/text/tagging.py @@ -22,5 +22,5 @@ def text_tags(text, cloud=None, batch=False, api_key=None, **kwargs): :type text: str or unicode :rtype: Dictionary of class probability pairs """ - - return api_handler(text, cloud=cloud, api="texttags", url_params={"batch":batch, "api_key":api_key}, **kwargs) + url_params = {"batch": batch, "api_key": api_key} + return api_handler(text, cloud=cloud, api="texttags", url_params=url_params, **kwargs) diff --git a/indicoio/utils/api.py b/indicoio/utils/api.py index 836b243..f06e2fa 100644 --- a/indicoio/utils/api.py +++ b/indicoio/utils/api.py @@ -29,6 +29,8 @@ def api_handler(arg, cloud, api, url_params = {"batch":False, "api_key":None}, * if apis: url += "&apis=%s" % ",".join(apis) + print url + response = requests.post(url, data=json_data, headers=JSON_HEADERS) if response.status_code == 503 and cloud != None: raise IndicoError("Private cloud '%s' does not include api '%s'" % (cloud, api)) diff --git a/tests/test_remote.py b/tests/test_remote.py index b4b262d..18cfbba 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -9,6 +9,7 @@ from indicoio import config from indicoio import political, sentiment, fer, facial_features, language, image_features, text_tags from indicoio import batch_political, batch_sentiment, batch_fer, batch_facial_features from indicoio import batch_language, batch_image_features, batch_text_tags +from indicoio import keywords, batch_keywords from indicoio import sentiment_hq, batch_sentiment_hq from indicoio import predict_image, predict_text, batch_predict_image, batch_predict_text from indicoio.utils.errors import IndicoError @@ -32,18 +33,22 @@ class BatchAPIRun(unittest.TestCase): response = batch_text_tags(test_data, api_key=self.api_key) self.assertTrue(isinstance(response, list)) + def test_batch_keywords(self): + test_data = ["A working api is key to the success of our young company"] + response = batch_keywords(test_data, api_key=self.api_key) + self.assertTrue(isinstance(response, list)) + def test_batch_posneg(self): test_data = ['Worst song ever', 'Best song ever'] response = batch_sentiment(test_data, api_key=self.api_key) self.assertTrue(isinstance(response, list)) self.assertTrue(response[0] < 0.5) - # TODO: uncomment once the high quality sentiment API is publicly released - # def test_batch_sentiment_hq(self): - # test_data = ['Worst song ever', 'Best song ever'] - # response = batch_sentiment_hq(test_data, api_key=self.api_key) - # self.assertTrue(isinstance(response, list)) - # self.assertTrue(response[0] < 0.5) + def test_batch_sentiment_hq(self): + test_data = ['Worst song ever', 'Best song ever'] + response = batch_sentiment_hq(test_data, api_key=self.api_key) + self.assertTrue(isinstance(response, list)) + self.assertTrue(response[0] < 0.5) def test_batch_political(self): test_data = ["Guns don't kill people, people kill people."] @@ -202,6 +207,20 @@ class FullAPIRun(unittest.TestCase): for v in results.values(): assert v >= 0.1 + def test_keywords(self): + text = "A working api is key to the success of our young company" + + results = keywords(text) + assert 'api' in results.keys() + + results = keywords(text, top_n=3) + assert len(results) is 3 + + results = keywords(text, threshold=.1) + for v in results.values(): + assert v >= .1 + + def test_political(self): political_set = set(['Libertarian', 'Liberal', 'Conservative', 'Green']) test_string = "Guns don't kill people, people kill people." @@ -228,18 +247,17 @@ class FullAPIRun(unittest.TestCase): self.assertTrue(isinstance(response, float)) self.assertTrue(response > 0.5) - # TODO: uncomment when the high quality sentiment API is publicly released - # def test_sentiment_hq(self): - # test_string = "Worst song ever." - # response = sentiment_hq(test_string) + def test_sentiment_hq(self): + test_string = "Worst song ever." + response = sentiment_hq(test_string) - # self.assertTrue(isinstance(response, float)) - # self.assertTrue(response < 0.5) + self.assertTrue(isinstance(response, float)) + self.assertTrue(response < 0.5) - # test_string = "Best song ever." - # response = sentiment_hq(test_string) - # self.assertTrue(isinstance(response, float)) - # self.assertTrue(response > 0.5) + test_string = "Best song ever." + response = sentiment_hq(test_string) + self.assertTrue(isinstance(response, float)) + self.assertTrue(response > 0.5) def test_good_fer(self): fer_set = set(['Angry', 'Sad', 'Neutral', 'Surprise', 'Fear', 'Happy'])