Merge pull request #4 from IndicoDataSolutions/local-api

Local api
This commit is contained in:
Madison May
2014-09-25 17:10:32 -04:00
9 changed files with 139 additions and 16 deletions
+14 -2
View File
@@ -1,10 +1,22 @@
from functools import partial
from utils import config
JSON_HEADERS = {'Content-type': 'application/json', 'Accept': 'text/plain'} JSON_HEADERS = {'Content-type': 'application/json', 'Accept': 'text/plain'}
Version, version, __version__, VERSION = ('0.4.4',) * 4 Version, version, __version__, VERSION = ('0.4.5',) * 4
from text.sentiment import political, posneg from text.sentiment import political, posneg
from text.sentiment import posneg as sentiment from text.sentiment import posneg as sentiment
from text.lang import language from text.lang import language
from images.fer import fer from images.fer import fer
from images.features import facial_features from images.features import facial_features
from images.features import image_features from images.features import image_features
political = partial(political, config.api_root)
posneg = partial(posneg, config.api_root)
sentiment = partial(sentiment, config.api_root)
posneg = partial(sentiment, config.api_root)
language = partial(language, config.api_root)
fer = partial(fer, config.api_root)
facial_features = partial(facial_features, config.api_root)
image_features = partial(image_features, config.api_root)
+4 -4
View File
@@ -6,7 +6,7 @@ import numpy as np
from indicoio import JSON_HEADERS from indicoio import JSON_HEADERS
from indicoio.utils import image_preprocess from indicoio.utils import image_preprocess
def facial_features(image): def facial_features(api_root, image):
""" """
Given an grayscale input image of a face, returns a 48 dimensional feature vector explaining that face. Given an grayscale input image of a face, returns a 48 dimensional feature vector explaining that face.
Useful as a form of feature engineering for face oriented tasks. Useful as a form of feature engineering for face oriented tasks.
@@ -30,14 +30,14 @@ def facial_features(image):
""" """
data_dict = json.dumps({"face": image}) data_dict = json.dumps({"face": image})
response = requests.post("http://api.indico.io/facialfeatures", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "facialfeatures", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if 'response' not in response_dict: if 'response' not in response_dict:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
else: else:
return response_dict['response'] return response_dict['response']
def image_features(image): def image_features(api_root, image):
""" """
Given an input image, returns a 2048 dimensional sparse feature vector explaining that image. Given an input image, returns a 2048 dimensional sparse feature vector explaining that image.
Useful as a form of feature engineering for image oriented tasks. Useful as a form of feature engineering for image oriented tasks.
@@ -69,7 +69,7 @@ def image_features(image):
""" """
image = image_preprocess(image) image = image_preprocess(image)
data_dict = json.dumps({"image": image}) data_dict = json.dumps({"image": image})
response = requests.post("http://api.indico.io/imagefeatures", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "imagefeatures", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if 'Features' not in response_dict: if 'Features' not in response_dict:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
+2 -2
View File
@@ -4,7 +4,7 @@ import requests
import numpy as np import numpy as np
from indicoio import JSON_HEADERS from indicoio import JSON_HEADERS
def fer(image): def fer(api_root, image):
""" """
Given a grayscale input image of a face, returns a probability distribution over emotional state. Given a grayscale input image of a face, returns a probability distribution over emotional state.
Input should be in a list of list format, resizing will be attempted internally but for best Input should be in a list of list format, resizing will be attempted internally but for best
@@ -29,7 +29,7 @@ def fer(image):
""" """
data_dict = json.dumps({"face": image}) data_dict = json.dumps({"face": image})
response = requests.post("http://api.indico.io/fer", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "fer", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if len(response_dict) < 2: if len(response_dict) < 2:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
+20
View File
@@ -0,0 +1,20 @@
from functools import partial
from indicoio.utils import config
JSON_HEADERS = {'Content-type': 'application/json', 'Accept': 'text/plain'}
from indicoio.text.sentiment import political, posneg
from indicoio.text.sentiment import posneg as sentiment
from indicoio.text.lang import language
from indicoio.images.fer import fer
from indicoio.images.features import facial_features
from indicoio.images.features import image_features
political = partial(political, config.local_api_root)
posneg = partial(posneg, config.local_api_root)
sentiment = partial(sentiment, config.local_api_root)
posneg = partial(sentiment, config.local_api_root)
language = partial(language, config.local_api_root)
fer = partial(fer, config.local_api_root)
facial_features = partial(facial_features, config.local_api_root)
image_features = partial(image_features, config.local_api_root)
+2 -2
View File
@@ -3,7 +3,7 @@ import json
from indicoio import JSON_HEADERS from indicoio import JSON_HEADERS
def language(text): def language(api_root, text):
""" """
Given input text, returns a probability distribution over 33 possible Given input text, returns a probability distribution over 33 possible
languages of what language the text was written in. languages of what language the text was written in.
@@ -27,7 +27,7 @@ def language(text):
""" """
data_dict = json.dumps({'text': text}) data_dict = json.dumps({'text': text})
response = requests.post("http://api.indico.io/language", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "language", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if len(response_dict) < 2: if len(response_dict) < 2:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
+4 -4
View File
@@ -4,7 +4,7 @@ import json
from indicoio import JSON_HEADERS from indicoio import JSON_HEADERS
from indicoio.utils import normalize from indicoio.utils import normalize
def political(text): def political(api_root, text):
""" """
Given input text, returns a probability distribution over the political alignment of the speaker. Given input text, returns a probability distribution over the political alignment of the speaker.
@@ -31,14 +31,14 @@ def political(text):
""" """
data_dict = json.dumps({'text': text}) data_dict = json.dumps({'text': text})
response = requests.post("http://api.indico.io/political", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "political", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if len(response_dict) < 2: if len(response_dict) < 2:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
else: else:
return response_dict return response_dict
def posneg(text): def posneg(api_root, text):
""" """
Given input text, returns a scalar estimate of the sentiment of that text. Given input text, returns a scalar estimate of the sentiment of that text.
Values are roughly in the range 0 to 1 with 0.5 indicating neutral sentiment. Values are roughly in the range 0 to 1 with 0.5 indicating neutral sentiment.
@@ -60,7 +60,7 @@ def posneg(text):
""" """
data_dict = json.dumps({'text': text}) data_dict = json.dumps({'text': text})
response = requests.post("http://api.indico.io/sentiment", data=data_dict, headers=JSON_HEADERS) response = requests.post(api_root + "sentiment", data=data_dict, headers=JSON_HEADERS)
response_dict = response.json() response_dict = response.json()
if 'Sentiment' not in response_dict: if 'Sentiment' not in response_dict:
raise ValueError(response_dict.values()[0]) raise ValueError(response_dict.values()[0])
+2
View File
@@ -0,0 +1,2 @@
local_api_root = "http://localhost:9438/"
api_root = "http://api.indico.io/"
+90
View File
@@ -0,0 +1,90 @@
import unittest
import numpy as np
from indicoio.local import political, sentiment, fer, facial_features, language
class FullAPIRun(unittest.TestCase):
def test_political(self):
political_set = set(['Libertarian', 'Liberal', 'Conservative', 'Green'])
test_string = "Guns don't kill people, people kill people."
response = political(test_string)
self.assertTrue(isinstance(response, dict))
self.assertEqual(political_set, set(response.keys()))
def test_posneg(self):
posneg_set = set(['Sentiment'])
test_string = "Worst song ever."
response = sentiment(test_string)
self.assertTrue(isinstance(response, float))
def test_good_fer(self):
fer_set = set(['Angry', 'Sad', 'Neutral', 'Surprise', 'Fear', 'Happy'])
test_face = np.linspace(0,50,48*48).reshape(48,48).tolist()
response = fer(test_face)
self.assertTrue(isinstance(response, dict))
self.assertEqual(fer_set, set(response.keys()))
def test_bad_fer(self):
fer_set = set(['Angry', 'Sad', 'Neutral', 'Surprise', 'Fear', 'Happy'])
test_face = np.linspace(0,50,56*56).reshape(56,56).tolist()
response = fer(test_face)
self.assertTrue(isinstance(response, dict))
self.assertEqual(fer_set, set(response.keys()))
def test_good_facial_features(self):
test_face = np.linspace(0,50,48*48).reshape(48,48).tolist()
response = facial_features(test_face)
self.assertTrue(isinstance(response, list))
self.assertEqual(len(response), 48)
def test_language(self):
language_set = set([
'English',
'Spanish',
'Tagalog',
'Esperanto',
'French',
'Chinese',
'French',
'Bulgarian',
'Latin',
'Slovak',
'Hebrew',
'Russian',
'German',
'Japanese',
'Korean',
'Portuguese',
'Italian',
'Polish',
'Turkish',
'Dutch',
'Arabic',
'Persian (Farsi)',
'Czech',
'Swedish',
'Indonesian',
'Vietnamese',
'Romanian',
'Greek',
'Danish',
'Hungarian',
'Thai',
'Finnish',
'Norwegian',
'Lithuanian'
])
language_dict = language('clearly an english sentence')
self.assertEqual(language_set, set(language_dict.keys()))
if __name__ == "__main__":
unittest.main()
+1 -2
View File
@@ -20,8 +20,7 @@ class FullAPIRun(unittest.TestCase):
test_string = "Worst song ever." test_string = "Worst song ever."
response = sentiment(test_string) response = sentiment(test_string)
self.assertTrue(isinstance(response, dict)) self.assertTrue(isinstance(response, float))
self.assertEqual(posneg_set, set(response.keys()))
def test_good_fer(self): def test_good_fer(self):
fer_set = set(['Angry', 'Sad', 'Neutral', 'Surprise', 'Fear', 'Happy']) fer_set = set(['Angry', 'Sad', 'Neutral', 'Surprise', 'Fear', 'Happy'])