summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/stt.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/client/stt.py b/client/stt.py
index 86cc83b..9277cb6 100644
--- a/client/stt.py
+++ b/client/stt.py
@@ -413,6 +413,84 @@ class AttSTT(AbstractSTTEngine):
return diagnose.check_network_connection()
+class WitAiSTT(AbstractSTTEngine):
+ """
+ Speech-To-Text implementation which relies on the Wit.ai Speech API.
+
+ This implementation requires an Wit.ai Access Token to be present in
+ profile.yml. Please sign up at https://wit.ai and copy your instance
+ token, which can be found under Settings in the Wit console to your
+ profile.yml:
+ ...
+ stt_engine: witai
+ witai-stt:
+ access_token: ERJKGE86SOMERANDOMTOKEN23471AB
+ """
+
+ SLUG = "witai"
+
+ def __init__(self, access_token):
+ self._logger = logging.getLogger(__name__)
+ self._token = access_token
+
+ @classmethod
+ def get_config(cls):
+ # FIXME: Replace this as soon as we have a config module
+ config = {}
+ # Try to get wit.ai Auth token from config
+ profile_path = jasperpath.config('profile.yml')
+ if os.path.exists(profile_path):
+ with open(profile_path, 'r') as f:
+ profile = yaml.safe_load(f)
+ if 'witai-stt' in profile:
+ if 'access_token' in profile['witai-stt']:
+ config['access_token'] = \
+ profile['witai-stt']['access_token']
+ return config
+
+ @property
+ def token(self):
+ return self._token
+
+ def transcribe(self, fp):
+ data = fp.read()
+ headers = {'Authorization': 'Bearer %s' % self.token,
+ 'accept': 'application/json',
+ 'Content-Type': 'audio/wav'}
+ r = requests.post('https://api.wit.ai/speech?v=20140916',
+ data=data,
+ headers=headers)
+ try:
+ r.raise_for_status()
+ except requests.exceptions.HTTPError:
+ self._logger.critical('Request failed with response: %r',
+ r.text,
+ exc_info=True)
+ return []
+ except requests.exceptions.RequestException:
+ self._logger.critical('Request failed.', exc_info=True)
+ return []
+ else:
+ try:
+ text = r.json()['_text']
+ except ValueError as e:
+ self._logger.debug('Recognition failed with status: %s',
+ e.args[0])
+ return []
+ except KeyError:
+ self._logger.critical('Cannot parse response.',
+ exc_info=True)
+ return []
+ else:
+ transcribed = [text.upper()]
+ self._logger.info('Transcribed: %r', transcribed)
+ return transcribed
+
+ @classmethod
+ def is_available(cls):
+ return diagnose.check_network_connection()
+
+
def get_engine_by_slug(slug=None):
"""
Returns: