-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic implementation of Speech API. #2344
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for the patch -- it is very well done!
@@ -230,3 +238,4 @@ Cloud Storage | |||
bucket = client.get_bucket('<your-bucket-name>') | |||
blob = bucket.blob('my-test-file.txt') | |||
blob.upload_from_string('this is test content!') | |||
|
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
At this moment we only support one method of the Speech API: | ||
|
||
- `syncrecognize`_ |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
- `syncrecognize`_ | ||
|
||
Synchronous Recognize |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
--------------------- | ||
|
||
The :meth:`~google.cloud.speech.Client.syncrecognize` method | ||
does speech to text on a file and returns the text |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
The :meth:`~google.cloud.speech.Client.syncrecognize` method | ||
does speech to text on a file and returns the text | ||
as a :class:`list` of tuples dicts (each containing a transcript an a confidence value). |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
for param_name, param in required_params: | ||
if param is None: | ||
message = '%r cannot be None' % (param_name) | ||
raise ValueError(message) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
if param is None: | ||
message = '%r cannot be None' % (param_name) | ||
raise ValueError(message) | ||
config = dict(required_params) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
('maxAlternatives', max_alternatives), | ||
('profanityFilter', profanity_filter)]: | ||
if param is not None: | ||
config[param_name] = param |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
sample_rate, | ||
max_alternatives=2, | ||
speech_context=hints) | ||
self.assertEqual(speechrecognition_result[0]["transcript"], 'hello') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
with self.assertRaises(ValueError): | ||
client.syncrecognize(None, None, None, None) | ||
with self.assertRaises(ValueError): | ||
client.syncrecognize(None, "uri", None, None) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Thank you for your feedback! I have implemented your suggestions, except for the additional examples with extra arguments in the docs. I will try to finish this tomorrow. |
supported, which must be specified in the following | ||
format: gs://bucket_name/object_name | ||
:type content: bytes | ||
:param content: Byte stream of audio. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Thank you!
"""Client to bundle configuration needed for API requests. | ||
|
||
:type project: str | ||
:param project: the project which the client acts on behalf of. Will be |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Basic client for Google Cloud Speech API.""" |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@@ -229,4 +237,4 @@ Cloud Storage | |||
client = storage.Client() | |||
bucket = client.get_bucket('<your-bucket-name>') | |||
blob = bucket.blob('my-test-file.txt') | |||
blob.upload_from_string('this is test content!') | |||
blob.upload_from_string('this is test content!') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
.. code-block:: python | ||
|
||
>>> alternatives = client.sync_recognize(None,"gs://my-bucket/recording.flac", | ||
... "FLAC", 16000, max_alternatives=2): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
>>> for alternative in alternatives: | ||
... print('=' * 20) | ||
... print(' transcript: %s' % (alternative["transcript"],)) | ||
... print(' confidence: %s' % (alternative["confidence"],)) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
... print(' confidence: %s' % (alternative["confidence"],)) | ||
==================== | ||
transcript: Hello, this is a test | ||
confidence: 0.81 |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
"""Google Cloud Speech API wrapper.""" | ||
|
||
from google.cloud.speech.client import Client, Encoding |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
response = client.sync_recognize(_AUDIO_CONTENT, | ||
encoding, | ||
self.SAMPLE_RATE, | ||
language_code="EN", |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
self.assertEqual(REQUEST, | ||
client.connection._requested[0]['data']) | ||
self.assertEqual(response[0]["transcript"], 'hello') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
}, | ||
"audio": { | ||
"content": _B64_AUDIO_CONTENT | ||
} |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
self.assertEqual(REQUEST, | ||
client.connection._requested[0]['data']) | ||
self.assertEqual(response[0]["transcript"], 'hello') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
class _Credentials(object): | ||
|
||
_scopes = ('https://www.googleapis.com/auth/cloud-platform') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@Fematich Really great work! Especially impressed that you have Travis 100% green on your first try! |
I have updated the code (included source_uri again and updated formatting/unit_tests). |
|
||
:type source_uri: str | ||
:param source_uri: URI that points to a file that contains audio | ||
data bytes as specified in RecognitionConfig. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
between 0 and 1. | ||
""" | ||
|
||
if (content is None) and (source_uri is None): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
raise ValueError('content and source_uri cannot be both equal to\ | ||
None') | ||
|
||
if (content is not None) and (source_uri is not None): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
""" | ||
|
||
if (content is None) and (source_uri is None): | ||
raise ValueError('content and source_uri cannot be both equal to\ |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
None') | ||
|
||
if (content is not None) and (source_uri is not None): | ||
raise ValueError('content and source_uri cannot be both different from\ |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
if sample_rate is None: | ||
raise ValueError('sample_rate cannot be None') | ||
|
||
if content is not None: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
} | ||
|
||
SYNC_RECOGNIZE_EMPTY_RESPONSE = { | ||
'results': [] |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
import unittest | ||
|
||
_AUDIO_SOURCE_URI = 'gs://sample-bucket/sample-recording.flac' |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
I'm going to merge as-is. I'll send a PR addressing most of my concerns. Remaining issues outside of that PR will be: |
@Fematich Thanks for your great work! We decided to go ahead and merge to speed up the process. We'd like to get this library feature-complete ASAP so we didn't want the review cycle to slow us down on getting the first chunks in. From here, a person working on this library full-time will take it to the finish line. You were great! |
Thank you it was a pleasure :-)! |
Updates from #2344 for speech API.
Updates from googleapis#2344 for speech API.
I have made a basic implementation of Speech API.
This currently only supports
syncrecognize
from the REST-API.I think I followed all the contribution guidelines:
However, this is my first contribution, so in case I missed something, please let me know and I will see how to fix it!