1515"""Basic client for Google Cloud Speech API."""
1616
1717from base64 import b64encode
18+ import os
1819
20+ from google .cloud .client import Client as BaseClient
1921from google .cloud ._helpers import _to_bytes
2022from google .cloud ._helpers import _bytes_to_unicode
21- from google .cloud import client as client_module
23+ from google .cloud . environment_vars import DISABLE_GRPC
2224from google .cloud .speech .connection import Connection
2325from google .cloud .speech .encoding import Encoding
2426from google .cloud .speech .operation import Operation
2527from google .cloud .speech .sample import Sample
2628from google .cloud .speech .transcript import Transcript
2729
30+ try :
31+ from google .cloud .speech ._gax import GAPICSpeechAPI
32+ except ImportError : # pragma: NO COVER
33+ _HAVE_GAX = False
34+ GAPICSpeechAPI = None
35+ else :
36+ _HAVE_GAX = True
2837
29- class Client (client_module .Client ):
30- """Client to bundle configuration needed for API requests.
3138
32- :type project: str
33- :param project: The project which the client acts on behalf of. Will be
34- passed when creating a dataset / job. If not passed,
35- falls back to the default inferred from the environment.
39+ _DISABLE_GAX = os .getenv (DISABLE_GRPC , False )
40+ _USE_GAX = _HAVE_GAX and not _DISABLE_GAX
41+
42+
43+ class Client (BaseClient ):
44+ """Client to bundle configuration needed for API requests.
3645
3746 :type credentials: :class:`oauth2client.client.OAuth2Credentials` or
3847 :class:`NoneType`
@@ -45,9 +54,22 @@ class Client(client_module.Client):
4554 :param http: An optional HTTP object to make requests. If not passed, an
4655 ``http`` object is created that is bound to the
4756 ``credentials`` for the current object.
57+
58+ :type use_gax: bool
59+ :param use_gax: (Optional) Explicitly specifies whether
60+ to use the gRPC transport (via GAX) or HTTP. If unset,
61+ falls back to the ``GOOGLE_CLOUD_DISABLE_GRPC`` environment
62+ variable
4863 """
64+ def __init__ (self , credentials = None , http = None , use_gax = None ):
65+ super (Client , self ).__init__ (credentials = credentials , http = http )
66+ if use_gax is None :
67+ self ._use_gax = _USE_GAX
68+ else :
69+ self ._use_gax = use_gax
4970
5071 _connection_class = Connection
72+ _speech_api = None
5173
5274 def async_recognize (self , sample , language_code = None ,
5375 max_alternatives = None , profanity_filter = None ,
@@ -139,6 +161,16 @@ def sample(content=None, source_uri=None, encoding=None,
139161 return Sample (content = content , source_uri = source_uri ,
140162 encoding = encoding , sample_rate = sample_rate )
141163
164+ @property
165+ def speech_api (self ):
166+ """Helper for speech-related API calls."""
167+ if self ._speech_api is None :
168+ if self ._use_gax :
169+ self ._speech_api = GAPICSpeechAPI ()
170+ else :
171+ self ._speech_api = _JSONSpeechAPI (self )
172+ return self ._speech_api
173+
142174 def sync_recognize (self , sample , language_code = None ,
143175 max_alternatives = None , profanity_filter = None ,
144176 speech_context = None ):
@@ -188,19 +220,82 @@ def sync_recognize(self, sample, language_code=None,
188220 * ``confidence``: The confidence in language detection, float
189221 between 0 and 1.
190222 """
223+ api = self .speech_api
224+ return api .sync_recognize (sample , language_code , max_alternatives ,
225+ profanity_filter , speech_context )
226+
227+
228+ class _JSONSpeechAPI (object ):
229+ """Speech API for interacting with the JSON/REST version of the API.
230+
231+ :type client: :class:`google.cloud.core.client.Client`
232+ :param client: Instance of a ``Client`` object.
233+ """
234+ def __init__ (self , client ):
235+ self ._client = client
236+ self ._connection = client .connection
237+
238+ def sync_recognize (self , sample , language_code = None , max_alternatives = None ,
239+ profanity_filter = None , speech_context = None ):
240+ """Synchronous Speech Recognition.
241+
242+ .. _sync_recognize: https://cloud.google.com/speech/reference/\
243+ rest/v1beta1/speech/syncrecognize
244+
245+ See `sync_recognize`_.
246+
247+ :type sample: :class:`~google.cloud.speech.sample.Sample`
248+ :param sample: Instance of ``Sample`` containing audio information.
249+
250+ :type language_code: str
251+ :param language_code: (Optional) The language of the supplied audio as
252+ BCP-47 language tag. Example: ``'en-GB'``.
253+ If omitted, defaults to ``'en-US'``.
254+
255+ :type max_alternatives: int
256+ :param max_alternatives: (Optional) Maximum number of recognition
257+ hypotheses to be returned. The server may
258+ return fewer than maxAlternatives.
259+ Valid values are 0-30. A value of 0 or 1
260+ will return a maximum of 1. Defaults to 1
261+
262+ :type profanity_filter: bool
263+ :param profanity_filter: If True, the server will attempt to filter
264+ out profanities, replacing all but the
265+ initial character in each filtered word with
266+ asterisks, e.g. ``'f***'``. If False or
267+ omitted, profanities won't be filtered out.
268+
269+ :type speech_context: list
270+ :param speech_context: A list of strings (max 50) containing words and
271+ phrases "hints" so that the speech recognition
272+ is more likely to recognize them. This can be
273+ used to improve the accuracy for specific words
274+ and phrases. This can also be used to add new
275+ words to the vocabulary of the recognizer.
276+
277+ :rtype: list
278+ :returns: A list of dictionaries. One dict for each alternative. Each
279+ dictionary typically contains two keys (though not
280+ all will be present in all cases)
191281
282+ * ``transcript``: The detected text from the audio recording.
283+ * ``confidence``: The confidence in language detection, float
284+ between 0 and 1.
285+
286+ :raises: ValueError if more than one result is returned or no results.
287+ """
192288 data = _build_request_data (sample , language_code , max_alternatives ,
193289 profanity_filter , speech_context )
194-
195- api_response = self .connection .api_request (
290+ api_response = self ._connection .api_request (
196291 method = 'POST' , path = 'speech:syncrecognize' , data = data )
197292
198293 if len (api_response ['results' ]) == 1 :
199294 result = api_response ['results' ][0 ]
200295 return [Transcript .from_api_repr (alternative )
201296 for alternative in result ['alternatives' ]]
202297 else :
203- raise ValueError ('result in api should have length 1 ' )
298+ raise ValueError ('More than one result or none returned from API. ' )
204299
205300
206301def _build_request_data (sample , language_code = None , max_alternatives = None ,
0 commit comments