Merge pull request #38 from IndicoDataSolutions/madison/require-api-key

Require api keys
This commit is contained in:
Madison May
2015-04-07 19:20:06 -04:00
16 changed files with 182 additions and 253 deletions
+1
View File
@@ -20,3 +20,4 @@ v0.4.14, Sat Dec 20 -- Fix for batch image features preprocessing, increased tes
v0.4.15, Sat Dec 20 -- Bug fix release
v0.5.0, Friday Feb 27 -- Updated to support private cloud, allows for indicorc file to reduce redundant authorization calls, README updates
v0.5.1, Friday Feb 27 -- More README updates, fixed rst formatting issue, added classifiers
v0.5.2, Tue March 7 -- Required API keys, configuration settings
+33 -78
View File
@@ -1,29 +1,36 @@
indicoio-python
===============
A wrapper for a series of APIs made by indico.
A wrapper for the [indico API](http://indico.io).
Check out the main site on:
http://indico.io
Our APIs are totally free to use, and ready to be used in your application. No data or training required.
The indico API is free to use, and no training data is required.
Installation
------------
```
From PyPI:
```bash
pip install indicoio
```
Documentation
Installation
------------
Available at [indico.readme.io](http://indico.readme.io/v1.0/docs)
From source:
```bash
git clone https://github.com/IndicoDataSolutions/IndicoIo-python.git
python setup.py install
```
Current APIs
API Keys + Setup
----------------
For API key registration and setup, checkout our [quickstart guide](https://dash.readme.io/project/indico/v2.0/docs/api-keys).
Full Documentation
------------
Detailed documentation and further code examples are available at [indico.reame.io](http://indico.readme.io/v2.0/docs/python).
Right now this wrapper supports the following apps:
Supported APIs:
------------
- Positive/Negative Sentiment Analysis
- Political Sentiment Analysis
@@ -35,26 +42,21 @@ Right now this wrapper supports the following apps:
Examples
--------
```
>>> import numpy as np
```python
>>> from indicoio import political, sentiment, language, text_tags, fer, facial_features, image_features
>>> from indicoio import political, sentiment, fer, facial_features, language
>>> indicoio.config.api_key = "YOUR_API_KEY"
>>> political("Guns don't kill people. People kill people.")
{u'Libertarian': 0.47740164630834825, u'Green': 0.08454409540443657, u'Liberal': 0.16617097211030055, u'Conservative': 0.2718832861769146}
>>> sentiment('Worst movie ever.')
{u'Sentiment': 0.07062467665597527}
0.07062467665597527
>>> sentiment('Really enjoyed the movie.')
{u'Sentiment': 0.8105182526856075}
0.8105182526856075
>>> test_text = "Facebook blog posts about Android tech make better journalism than most news outlets."
>>> tag_dict = text_tags(test_text)
>>> sorted(tag_dict.keys(), key=lambda x: tag_dict[x], reverse=True)[:3]
[u'startups_and_entrepreneurship', u'investment', u'business']
>>> text_tags("Facebook blog posts about Android tech make better journalism than most news outlets.")
>>> text_tags(test_text, threshold=0.1) # return only keys with value > 0.1
{u'startups_and_entrepreneurship': 0.21888586688354486}
@@ -62,73 +64,26 @@ Examples
>>> text_tags(test_text, top_n=1) # return only keys with top_n values
{u'startups_and_entrepreneurship': 0.21888586688354486}
>>> import numpy as np
>>> test_face = np.linspace(0,50,48*48).reshape(48,48).tolist()
>>> fer(test_face)
{u'Angry': 0.08843749137458341, u'Sad': 0.39091163159204684, u'Neutral': 0.1947947999669361, u'Surprise': 0.03443785859010413, u'Fear': 0.17574534848440568, u'Happy': 0.11567286999192382}
>>> facial_features(test_face)
[0.0, -0.02568680526917187, 0.21645604230056517, -0.1519435786033145, -0.5648621854611555, 3.0607368045577226, 0.11434321880792693, -0.02163810928547493, -0.44224330594186484, 0.3024315632285246, -2.6068048934495276, 2.497798330306638, 3.040558335205844, 0.741045340525325, 0.37198135618478817, -0.33132377802172325, -0.9804190889833034, 0.5046575784709395, -0.5609132323152847, 1.679107064439151, 0.6825037853544341, -1.5977176226648016, 1.8959464303080562, -0.7812860715595836, -2.998394007543733, -0.22637273967347724, -0.9642457010679496, 1.4557274834236749, 2.412244419186633, 2.3151771738421965, 0.7881483386786367, 1.6622850935863422, 0.1304768990234367, 1.9344501393866649, 3.1271558035162914, -0.10250886439220543, 1.4921395116492966, 2.761645355670677, 1.6903473594991179, 1.009209807271491, 0.07273926986120445, -1.4941708135718021, -2.082786362439631, 1.0160924044870847, 2.5326580674673895, -0.8328208491083264, 2.0390177029762935, 3.0342637531932777]
[0.0, -0.02568680526917187, 0.21645604230056517, ..., 3.0342637531932777]
>>> language_dict = language('Quis custodiet ipsos custodes')
>>> sorted(language_dict.keys(), key=lambda x: language_dict[x], reverse=True)[:5]
[u'Latin', u'Dutch', u'Greek', u'Portuguese', u'Spanish']
>>> language_dict
>>> language('Quis custodiet ipsos custodes')
{u'Swedish': 0.00033330636691921914, u'Lithuanian': 0.007328693814717631, u'Vietnamese': 0.0002686116137658802, u'Romanian': 8.133913804076592e-06, ...}
```
Batch API Access
----------------
If you'd like to use our batch api interface, please check out the [pricing page](https://indico.io/pricing) on our website to find the right plan for you.
```
Each `indicoio` function has a corresponding batch function for analyzing many examples with a single request. Simply pass in a list of inputs and receive a list of results in return.
```python
>>> from indicoio import batch_sentiment
>>> batch_sentiment(['Text to analyze', 'More text'], auth=("example@example.com", "********"))
>>> batch_sentiment(['Best day ever', 'Worst day ever'])
[0.9899001220871786, 0.005709885173415242]
```
Authentication credentials can also be set as the environment variables `$INDICO_USERNAME` and `$INDICO_PASSWORD` or as `username` and `password` in the indicorc file.
Private cloud API Access
------------------------
If you're looking to use indico's API for high throughput applications, please check out the [pricing page](https://indico.io/pricing) on our website to find the right plan for you.
```
>>> from indicoio import sentiment
>>> sentiment("Text to analyze", cloud="example", auth=("example@example.com", "********"))
```
The `cloud` parameter redirects API calls to your private cloud hosted at `[cloud].indico.domains`
Private cloud subdomains can also be set as the environment variable `$INDICO_CLOUD` or as `cloud` in the indicorc file.
Configuration
------------------------
Indicoio-python will search ./.indicorc and $HOME/.indicorc for the optional configuration file. Values in the local configuration file (./.indicorc) take precedence over those found in a global configuration file ($HOME/.indicorc). The indicorc file can be used to set an authentication username and password or a private cloud subdomain, so these arguments don't need to be specified for every api call. All sections are optional.
Here is an example of a valid indicorc file:
```
[auth]
username = test@example.com
password = secret
[private_cloud]
cloud = example
```
Environment variables take precedence over any configuration found in the indicorc file.
The following environment variables are valid:
```
$INDICO_USERNAME
$INDICO_PASSWORD
$INDICO_CLOUD
```
Finally, any values explicitly passed in to an api call will override configuration options set in the indicorc file or in an environment variable.
+40 -93
View File
@@ -1,31 +1,40 @@
indicoio-python
===============
A wrapper for a series of APIs made by indico.
A wrapper for the `indico API <http://indico.io>`__.
Check out the main site on:
http://indico.io
Our APIs are totally free to use, and ready to be used in your
application. No data or training required.
The indico API is free to use, and no training data is required.
Installation
------------
::
From PyPI:
.. code:: bash
pip install indicoio
Documentation
-------------
From source:
Available at `indico.reame.io <http://indico.readme.io/v1.0/docs>`__
.. code:: bash
Current APIs
------------
git clone https://github.com/IndicoDataSolutions/IndicoIo-python.git
python setup.py install
Right now this wrapper supports the following apps:
API Keys + Setup
----------------
For API key registration and setup, checkout our `quickstart
guide <https://dash.readme.io/project/indico/v2.0/docs/api-keys>`__.
Full Documentation
------------------
Detailed documentation and further code examples are available at
`indico.reame.io <http://indico.readme.io/v2.0/docs/python>`__.
Supported APIs:
---------------
- Positive/Negative Sentiment Analysis
- Political Sentiment Analysis
@@ -38,27 +47,22 @@ Right now this wrapper supports the following apps:
Examples
--------
::
.. code:: python
>>> import numpy as np
>>> from indicoio import political, sentiment, language, text_tags, fer, facial_features, image_features
>>> from indicoio import political, sentiment, fer, facial_features, language
>>> indicoio.config.api_key = "YOUR_API_KEY"
>>> political("Guns don't kill people. People kill people.")
{u'Libertarian': 0.47740164630834825, u'Green': 0.08454409540443657, u'Liberal': 0.16617097211030055, u'Conservative': 0.2718832861769146}
>>> sentiment('Worst movie ever.')
{u'Sentiment': 0.07062467665597527}
0.07062467665597527
>>> sentiment('Really enjoyed the movie.')
{u'Sentiment': 0.8105182526856075}
0.8105182526856075
>>> test_text = "Facebook blog posts about Android tech make better journalism than most news outlets."
>>> tag_dict = text_tags(test_text)
>>> sorted(tag_dict.keys(), key=lambda x: tag_dict[x], reverse=True)[:3]
[u'startups_and_entrepreneurship', u'investment', u'business']
>>> text_tags("Facebook blog posts about Android tech make better journalism than most news outlets.")
>>> text_tags(test_text, threshold=0.1) # return only keys with value > 0.1
{u'startups_and_entrepreneurship': 0.21888586688354486}
@@ -66,87 +70,30 @@ Examples
>>> text_tags(test_text, top_n=1) # return only keys with top_n values
{u'startups_and_entrepreneurship': 0.21888586688354486}
>>> import numpy as np
>>> test_face = np.linspace(0,50,48*48).reshape(48,48).tolist()
>>> fer(test_face)
{u'Angry': 0.08843749137458341, u'Sad': 0.39091163159204684, u'Neutral': 0.1947947999669361, u'Surprise': 0.03443785859010413, u'Fear': 0.17574534848440568, u'Happy': 0.11567286999192382}
>>> facial_features(test_face)
[0.0, -0.02568680526917187, 0.21645604230056517, -0.1519435786033145, -0.5648621854611555, 3.0607368045577226, 0.11434321880792693, -0.02163810928547493, -0.44224330594186484, 0.3024315632285246, -2.6068048934495276, 2.497798330306638, 3.040558335205844, 0.741045340525325, 0.37198135618478817, -0.33132377802172325, -0.9804190889833034, 0.5046575784709395, -0.5609132323152847, 1.679107064439151, 0.6825037853544341, -1.5977176226648016, 1.8959464303080562, -0.7812860715595836, -2.998394007543733, -0.22637273967347724, -0.9642457010679496, 1.4557274834236749, 2.412244419186633, 2.3151771738421965, 0.7881483386786367, 1.6622850935863422, 0.1304768990234367, 1.9344501393866649, 3.1271558035162914, -0.10250886439220543, 1.4921395116492966, 2.761645355670677, 1.6903473594991179, 1.009209807271491, 0.07273926986120445, -1.4941708135718021, -2.082786362439631, 1.0160924044870847, 2.5326580674673895, -0.8328208491083264, 2.0390177029762935, 3.0342637531932777]
[0.0, -0.02568680526917187, 0.21645604230056517, ..., 3.0342637531932777]
>>> language_dict = language('Quis custodiet ipsos custodes')
>>> sorted(language_dict.keys(), key=lambda x: language_dict[x], reverse=True)[:5]
[u'Latin', u'Dutch', u'Greek', u'Portuguese', u'Spanish']
>>> language_dict
>>> language('Quis custodiet ipsos custodes')
{u'Swedish': 0.00033330636691921914, u'Lithuanian': 0.007328693814717631, u'Vietnamese': 0.0002686116137658802, u'Romanian': 8.133913804076592e-06, ...}
Batch API Access
----------------
If you'd like to use our batch api interface, please check out the
`pricing
page <https://github.com/IndicoDataSolutions/IndicoIo-python>`__ on our
website to find the right plan for you.
Each ``indicoio`` function has a corresponding batch function for
analyzing many examples with a single request. Simply pass in a list of
inputs and receive a list of results in return.
::
.. code:: python
>>> from indicio import batch_sentiment
>>> batch_sentiment(['Text to analyze', 'More text'], auth=("example@example.com", "********"))
>>> from indicoio import batch_sentiment
Authentication credentials can also be set as the environment variables
``$INDICO_USERNAME`` and ``$INDICO_PASSWORD`` or as ``username`` and
``password`` in the indicorc file.
>>> batch_sentiment(['Best day ever', 'Worst day ever'])
[0.9899001220871786, 0.005709885173415242]
Private cloud API Access
------------------------
If you're looking to use indico's API for high throughput applications,
please check out the `pricing
page <https://github.com/IndicoDataSolutions/IndicoIo-python>`__ on our
website to find the right plan for you.
::
>>> from indicio import sentiment
>>> sentiment("Text to analyze", cloud="example", auth=("example@example.com", "********"))
The ``cloud`` parameter redirects API calls to your private cloud hosted
at ``[cloud].indico.domains``
Private cloud subdomains can also be set as the environment variable
``$INDICO_CLOUD`` or as ``cloud`` in the indicorc file.
Configuration
-------------
Indicoio-python will search ./.indicorc and
HOME/.indicorc for the optional configuration file. Values in the local configuration file (./.indicorc) take precedence over those found in a global configuration file (`\ HOME/.indicorc).
The indicorc file can be used to set an authentication username and
password or a private cloud subdomain, so these arguments don't need to
be specified for every api call. All sections are optional.
Here is an example of a valid indicorc file:
::
[auth]
username = test@example.com
password = secret
[private_cloud]
cloud = example
Environment variables take precedence over any configuration found in
the indicorc file. The following environment variables are valid:
::
$INDICO_USERNAME
$INDICO_PASSWORD
$INDICO_CLOUD
Finally, any values explicitly passed in to an api call will override
configuration options set in the indicorc file or in an environment
variable.
+1 -1
View File
@@ -2,7 +2,7 @@ from functools import partial
JSON_HEADERS = {'Content-type': 'application/json', 'Accept': 'text/plain'}
Version, version, __version__, VERSION = ('0.5.1',) * 4
Version, version, __version__, VERSION = ('0.5.2',) * 4
from indicoio.text.sentiment import political, posneg
from indicoio.text.sentiment import posneg as sentiment
+12 -10
View File
@@ -16,7 +16,7 @@ class Settings(ConfigParser.ConfigParser):
for fd in self.files:
try:
self.readfp(fd)
except AttributeError:
except AttributeError:
self.read(fd)
self.auth_settings = self.get_section('auth')
@@ -33,22 +33,24 @@ class Settings(ConfigParser.ConfigParser):
def cloud(self):
return (
os.getenv("INDICO_CLOUD") or
self.private_cloud_settings.get('cloud') or
os.getenv("INDICO_CLOUD") or
self.private_cloud_settings.get('cloud') or
None
)
def auth(self):
def api_key(self):
return (
os.getenv("INDICO_USERNAME") or self.auth_settings.get('username'),
os.getenv("INDICO_PASSWORD") or self.auth_settings.get('password')
os.getenv("INDICO_API_KEY") or
self.auth_settings.get('api_key') or
None
)
SETTINGS = Settings(files=[
os.path.expanduser("~/.indicorc"),
os.path.join(os.getcwd(), '.indicorc')
])
AUTH = SETTINGS.auth()
CLOUD = SETTINGS.cloud()
PUBLIC_API_HOST = 'apiv1.indico.io'
api_key = SETTINGS.api_key()
cloud = SETTINGS.cloud()
PUBLIC_API_HOST = 'apiv2.indico.io'
url_protocol = "https:"
View File
+5 -6
View File
@@ -4,7 +4,7 @@ import numpy as np
from indicoio.utils import image_preprocess, api_handler, is_url
import indicoio.config as config
def facial_features(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def facial_features(image, cloud=None, batch=False, api_key=None, **kwargs):
"""
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.
@@ -26,9 +26,9 @@ def facial_features(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs)
:type image: list of lists
:rtype: List containing feature responses
"""
return api_handler(image, cloud=cloud, api="facialfeatures", batch=batch, auth=auth, **kwargs)
return api_handler(image, cloud=cloud, api="facialfeatures", batch=batch, api_key=api_key, **kwargs)
def image_features(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def image_features(image, cloud=None, batch=False, api_key=None, **kwargs):
"""
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.
@@ -58,6 +58,5 @@ def image_features(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:type image: numpy.ndarray
:rtype: List containing features
"""
if not is_url(image, batch=batch):
image = image_preprocess(image, batch=batch)
return api_handler(image, cloud=cloud, api="imagefeatures", batch=batch, auth=auth, **kwargs)
image = image_preprocess(image, batch=batch)
return api_handler(image, cloud=cloud, api="imagefeatures", batch=batch, api_key=api_key, **kwargs)
+2 -2
View File
@@ -4,7 +4,7 @@ import numpy as np
from indicoio.utils import api_handler
import indicoio.config as config
def fer(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def fer(image, cloud=None, batch=False, api_key=None, **kwargs):
"""
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
@@ -28,4 +28,4 @@ def fer(image, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:rtype: Dictionary containing emotion probability pairs
"""
return api_handler(image, cloud=cloud, api="fer", batch=batch, auth=auth, **kwargs)
return api_handler(image, cloud=cloud, api="fer", batch=batch, api_key=api_key, **kwargs)
View File
+2 -2
View File
@@ -1,7 +1,7 @@
from indicoio.utils import api_handler
import indicoio.config as config
def language(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def language(text, cloud=None, batch=False, api_key=None, **kwargs):
"""
Given input text, returns a probability distribution over 33 possible
languages of what language the text was written in.
@@ -24,4 +24,4 @@ def language(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:rtype: Dictionary of language probability pairs
"""
return api_handler(text, cloud=cloud, api="language", batch=batch, auth=auth, **kwargs)
return api_handler(text, cloud=cloud, api="language", batch=batch, api_key=api_key, **kwargs)
+4 -4
View File
@@ -2,7 +2,7 @@ from indicoio import JSON_HEADERS
from indicoio.utils import api_handler
import indicoio.config as config
def political(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def political(text, cloud=None, batch=False, api_key=None, **kwargs):
"""
Given input text, returns a probability distribution over the political alignment of the speaker.
@@ -28,9 +28,9 @@ def political(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:rtype: Dictionary of party probability pairs
"""
return api_handler(text, cloud=cloud, api="political", batch=batch, auth=auth, **kwargs)
return api_handler(text, cloud=cloud, api="political", batch=batch, api_key=api_key, **kwargs)
def posneg(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def posneg(text, cloud=None, batch=False, api_key=None, **kwargs):
"""
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.
@@ -51,4 +51,4 @@ def posneg(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:rtype: Float
"""
return api_handler(text, cloud=cloud, api="sentiment", batch=batch, auth=auth, **kwargs)
return api_handler(text, cloud=cloud, api="sentiment", batch=batch, api_key=api_key, **kwargs)
+2 -2
View File
@@ -1,7 +1,7 @@
from indicoio.utils import api_handler
import indicoio.config as config
def text_tags(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
def text_tags(text, cloud=None, batch=False, api_key=None, **kwargs):
"""
Given input text, returns a probability distribution over 100 document categories
@@ -23,4 +23,4 @@ def text_tags(text, cloud=config.CLOUD, batch=False, auth=None, **kwargs):
:rtype: Dictionary of class probability pairs
"""
return api_handler(text, cloud=cloud, api="texttags", batch=batch, auth=auth, **kwargs)
return api_handler(text, cloud=cloud, api="texttags", batch=batch, api_key=api_key, **kwargs)
+10 -8
View File
@@ -6,11 +6,12 @@ from skimage.transform import resize
from indicoio import JSON_HEADERS
from indicoio import config
def api_handler(arg, cloud, api, batch=False, auth=None, **kwargs):
def api_handler(arg, cloud, api, batch=False, api_key=None, **kwargs):
data = {'data': arg}
data.update(**kwargs)
json_data = json.dumps(data)
if not cloud:
cloud=config.cloud
if cloud:
host = "%s.indico.domains" % cloud
@@ -18,14 +19,15 @@ def api_handler(arg, cloud, api, batch=False, auth=None, **kwargs):
# default to indico public cloud
host = config.PUBLIC_API_HOST
url = "http://%s/%s" % (host, api)
if batch:
url += "/batch"
if not api_key:
api_key = config.api_key
if not auth:
auth = config.AUTH
url = config.url_protocol + "//%s/%s" % (host, api)
url = url + "/batch" if batch else url
url += "?key=%s" % api_key
response = requests.post(url, data=json_data, headers=JSON_HEADERS, auth=auth)
response = requests.post(url, data=json_data, headers=JSON_HEADERS)
if response.status_code == 503 and cloud != None:
raise Exception("Private cloud '%s' does not include api '%s'" % (cloud, api))
+1 -1
View File
@@ -8,7 +8,7 @@ except ImportError:
setup(
name="IndicoIo",
version='0.5.1',
version='0.5.2',
packages=[
"indicoio",
"indicoio.text",
+19 -33
View File
@@ -27,11 +27,9 @@ class TestConfigureEnv(unittest.TestCase):
"""
Ensure cloud authentication credentials are read in from environment variables
"""
username = "test"
password = "password"
os.environ["INDICO_USERNAME"] = username
os.environ["INDICO_PASSWORD"] = password
assert config.SETTINGS.auth() == (username, password)
api_key = "text"
os.environ["INDICO_API_KEY"] = api_key
assert config.SETTINGS.api_key() == api_key
class TestConfigurationFile(unittest.TestCase):
@@ -40,17 +38,15 @@ class TestConfigurationFile(unittest.TestCase):
"""
def setUp(self):
self.username = "test"
self.password = "password"
self.api_key = "test"
self.cloud = "localhost"
config = """
[auth]
username = %s
password = %s
api_key = %s
[private_cloud]
cloud = %s
""" % (self.username, self.password, self.cloud)
""" % (self.api_key, self.cloud)
config_file = StringIO(textwrap.dedent(config))
self.settings = Settings(files=[config_file])
@@ -66,7 +62,7 @@ class TestConfigurationFile(unittest.TestCase):
"""
Ensure cloud authentication credentials are read in from file
"""
assert self.settings.auth() == (self.username, self.password)
assert self.settings.api_key() == self.api_key
class TestPrecedence(unittest.TestCase):
@@ -75,27 +71,23 @@ class TestPrecedence(unittest.TestCase):
"""
def setUp(self):
self.file_username = "file-username"
self.file_password = "file-password"
self.file_api_key = "file-api-key"
self.file_cloud = "file-cloud"
self.env_username = "env-username"
self.env_password = "env-password"
self.env_api_key = "env-api-key"
self.env_cloud = "env-cloud"
config = """
[auth]
username = %s
password = %s
api_key = %s
[private_cloud]
cloud = %s
""" % (self.file_username, self.file_password, self.file_cloud)
""" % (self.file_api_key, self.file_cloud)
config_file = StringIO(textwrap.dedent(config))
os.environ = {
'INDICO_CLOUD': self.env_cloud,
'INDICO_USERNAME': self.env_username,
'INDICO_PASSWORD': self.env_password
'INDICO_API_KEY': self.env_api_key
}
self.settings = Settings(files=[config_file])
@@ -110,7 +102,7 @@ class TestPrecedence(unittest.TestCase):
Ensure cloud authentication credentials set in environment variables
are used over those in config files
"""
assert self.settings.auth() == (self.env_username, self.env_password)
assert self.settings.api_key() == self.env_api_key
class TestConfigFilePrecedence(unittest.TestCase):
@@ -119,37 +111,31 @@ class TestConfigFilePrecedence(unittest.TestCase):
"""
def setUp(self):
self.high_priority_username = "high-priority-username"
self.high_priority_password = "high-priority-password"
self.high_priority_api_key = "high-priority-api-key"
self.high_priority_cloud = "high-priority-cloud"
self.low_priority_username = "low-priority-username"
self.low_priority_password = "low-priority-password"
self.low_priority_api_key = "low-priority-api-key"
self.low_priority_cloud = "low-priority-cloud"
high_priority_config = """
[auth]
username = %s
password = %s
api_key = %s
[private_cloud]
cloud = %s
""" % (
self.high_priority_username,
self.high_priority_password,
self.high_priority_api_key,
self.high_priority_cloud
)
low_priority_config = """
[auth]
username = %s
password = %s
[private_cloud]
cloud = %s
""" % (
self.low_priority_username,
self.low_priority_password,
self.low_priority_api_key,
self.low_priority_cloud
)
@@ -172,4 +158,4 @@ class TestConfigFilePrecedence(unittest.TestCase):
"""
Ensure the cloud auth priority is handled properly
"""
assert self.settings.auth() == (self.high_priority_username, self.high_priority_password)
assert self.settings.api_key() == self.high_priority_api_key
+50 -13
View File
@@ -16,36 +16,40 @@ DIR = os.path.dirname(os.path.realpath(__file__))
class BatchAPIRun(unittest.TestCase):
def setUp(self):
self.auth = config.AUTH
self.api_key = config.api_key
config.url_protocol = "http:"
if not all(self.auth):
if not all(self.api_key):
raise SkipTest
def tearDown(self):
config.url_protocol = "https:"
def test_batch_texttags(self):
test_data = ["On Monday, president Barack Obama will be..."]
response = batch_text_tags(test_data, auth=self.auth)
response = batch_text_tags(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, auth=self.auth)
response = batch_sentiment(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."]
response = batch_political(test_data, auth=self.auth)
response = batch_political(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
def test_batch_fer(self):
test_data = [np.random.rand(48, 48).tolist()]
response = batch_fer(test_data, auth=self.auth)
response = batch_fer(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
self.assertTrue(isinstance(response[0], dict))
def test_batch_facial_features(self):
test_data = [np.random.rand(48, 48).tolist()]
response = batch_facial_features(test_data, auth=self.auth)
response = batch_facial_features(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
self.assertTrue(isinstance(response[0], list))
self.assertEqual(len(response[0]), 48)
@@ -65,21 +69,21 @@ class BatchAPIRun(unittest.TestCase):
def test_batch_image_features_greyscale(self):
test_data = [np.random.rand(64, 64).tolist()]
response = batch_image_features(test_data, auth=self.auth)
response = batch_image_features(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
self.assertTrue(isinstance(response[0], list))
self.assertEqual(len(response[0]), 2048)
def test_batch_image_features_rgb(self):
test_data = [np.random.rand(64, 64, 3).tolist()]
response = batch_image_features(test_data, auth=self.auth)
response = batch_image_features(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
self.assertTrue(isinstance(response[0], list))
self.assertEqual(len(response[0]), 2048)
def test_batch_language(self):
test_data = ['clearly an english sentence']
response = batch_language(test_data, auth=self.auth)
response = batch_language(test_data, api_key=self.api_key)
self.assertTrue(isinstance(response, list))
self.assertTrue(response[0]['English'] > 0.25)
@@ -88,7 +92,7 @@ class BatchAPIRun(unittest.TestCase):
self.assertRaises(ConnectionError,
batch_language,
test_data,
auth=self.auth,
api_key=self.api_key,
cloud='invalid/cloud')
@@ -124,11 +128,11 @@ class FullAPIRun(unittest.TestCase):
self.assertTrue(isinstance(response, dict))
self.assertEqual(political_set, set(response.keys()))
test_string = "Save the whales"
test_string = "pro-choice"
response = political(test_string)
self.assertTrue(isinstance(response, dict))
assert response['Green'] > 0.5
assert response['Liberal'] > 0.25
def test_posneg(self):
test_string = "Worst song ever."
@@ -252,6 +256,39 @@ class FullAPIRun(unittest.TestCase):
test_data,
cloud='invalid/cloud')
temp_cloud = config.cloud
config.cloud = 'invalid/cloud'
self.assertEqual(config.cloud, 'invalid/cloud')
self.assertRaises(ConnectionError,
language,
test_data)
config.cloud = temp_cloud
self.assertRaises(ConnectionError,
language,
test_data,
cloud='indico-test')
def test_set_api_key(self):
test_data = 'clearly an english sentence'
self.assertRaises(ValueError,
language,
test_data,
api_key ='invalid_api_key')
temp_api_key = config.api_key
config.api_key = 'invalid_api_key'
self.assertEqual(config.api_key, 'invalid_api_key')
self.assertRaises(ValueError,
language,
test_data)
config.api_key = temp_api_key
if __name__ == "__main__":
unittest.main()