Skip to content
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

Using glossaries with tts and vision tutorial sample code #2325

Merged
merged 28 commits into from
Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 257 additions & 0 deletions translate/cloud-client/hybrid_glossaries/hybrid_tutorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# Copyright 2019 Google Inc. All Rights Reserved.
crowdus marked this conversation as resolved.
Show resolved Hide resolved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# [START hybrid_imports]
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Imports the Google Cloud client libraries
from google.cloud import translate_v3beta1 as translate
from google.cloud import vision
from google.cloud import texttospeech

import io
crowdus marked this conversation as resolved.
Show resolved Hide resolved
import os
# [END hybrid_imports]

# [START hybrid_project_id]
# extract GCP project id
PROJECT_ID = os.environ['GCLOUD_PROJECT']
# [END hybrid_project_id]


# [START hybrid_vision]
def pic_to_text(infile):
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Detects text in an image file
crowdus marked this conversation as resolved.
Show resolved Hide resolved
#
# ARGS
# infile: path to image file
#
# RETURNS
# String of text detected in image

# Instantiates a client
client = vision.ImageAnnotatorClient()

# Opens the input image file
with io.open(infile, 'rb') as image_file:
content = image_file.read()

image = vision.types.Image(content=content)

# For dense text, use document_text_detection
# For less dense text, use text_detection
crowdus marked this conversation as resolved.
Show resolved Hide resolved
response = client.document_text_detection(image=image)
text = response.full_text_annotation.text

return text
# [END hybrid_vision]


# [START hybrid_create_glossary]
def create_glossary(languages, project_id, glossary_name, glossary_uri):
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Creates a GCP glossary resource
# Assumes you've already manually uploaded a glossary to Cloud Storage
#
# ARGS
# languages: list of languages in the glossary
# project_id: GCP project id
# glossary_name: name you want to give this glossary resource
# glossary_uri: the uri of the glossary you uploaded to Cloud Storage
#
# RETURNS
# nothing if glossary creation is successful

# Instantiates a client
client = translate.TranslationServiceClient()

# Defines the languages in the glossary
# This list must match the languages in the glossary
# Here, the glossary includes French and English
languages = ['fr', 'en']
# Set information to access
glossary_uri = 'gs://cloud-samples-data/translation/bistro_glossary.csv'
# Designates the data center location that you want to use
location = 'us-central1'

# Set glossary resource name
name = client.glossary_path(
project_id,
location,
glossary_name)

# Set language codes
language_codes_set = translate.types.Glossary.LanguageCodesSet(
language_codes=languages)

gcs_source = translate.types.GcsSource(
input_uri=glossary_uri)

input_config = translate.types.GlossaryInputConfig(
gcs_source=gcs_source)

# Set glossary resource information
glossary = translate.types.Glossary(
name=name,
language_codes_set=language_codes_set,
input_config=input_config)

resource = client.location_path(project_id, location)
crowdus marked this conversation as resolved.
Show resolved Hide resolved

# Create glossary resource
operation = client.create_glossary(parent=resource, glossary=glossary)

return operation.result(timeout=90)
crowdus marked this conversation as resolved.
Show resolved Hide resolved


# [START hybrid_translate]
def translate_text(text, prev_lang, new_lang, project_id, glossary_name):
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Translates text to a given language using a glossary
#
# ARGS
# text: String of text to translate
# prev_lang: language of input text
# new_lang: language of output text
# project_id: GCP project id
# glossary_name: name you gave your project's glossary
# resource when you created it
#
# RETURNS
# String of translated text

# Instantiates a client
client = translate.TranslationServiceClient()

# Designates the data center location that you want to use
location = 'us-central1'

glossary = client.glossary_path(
project_id,
location,
glossary_name)

glossary_config = translate.types.TranslateTextGlossaryConfig(
glossary=glossary)

resource = client.location_path(project_id, location)
crowdus marked this conversation as resolved.
Show resolved Hide resolved

result = client.translate_text(
parent=resource,
contents=[text],
mime_type='text/plain', # mime types: text/plain, text/html
source_language_code=prev_lang,
target_language_code=new_lang,
glossary_config=glossary_config)

# Returns translated text
return result.glossary_translations[0].translated_text
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# [END hybrid_translate]


# [START hybrid_glossary_delete]
def delete_glossary(project_id, glossary_name):
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Deletes a GCP glossary resource
#
# ARGS
# project_id: GCP project id
# glossary_name: name you gave your project's glossary
# resource when you created it
#
# RETURNS
# nothing

# Designates the data center location that you want to use
location = 'us-central1'

# Instantiates a client
client = translate.TranslationServiceClient()

resource = client.glossary_path(
project_id,
location,
glossary_name)

operation = client.delete_glossary(resource)
result = operation.result(timeout=90)

print('Deleted: {}'.format(result.name))
# [END hybrid_glossary_delete]


# [START hybrid_tts]
def text_to_speech(text, outfile):
crowdus marked this conversation as resolved.
Show resolved Hide resolved
# Generates synthetic audio from plaintext
#
# ARGS
# text: text to synthesize
# outfile: filename to use to store synthetic audio
#
# RETURNS
# nothing

# Instantiates a client
client = texttospeech.TextToSpeechClient()

# Sets the text input to be synthesized
synthesis_input = texttospeech.types.SynthesisInput(text=text)

# Builds the voice request, selects the language code ("en-US") and
# the SSML voice gender ("MALE")
voice = texttospeech.types.VoiceSelectionParams(
language_code='en-US',
ssml_gender=texttospeech.enums.SsmlVoiceGender.MALE)

# Selects the type of audio file to return
audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)

# Performs the text-to-speech request on the text input with the selected
# voice parameters and audio file type
response = client.synthesize_speech(synthesis_input, voice, audio_config)

# Writes the synthetic audio to the output file.
with open(outfile, 'wb') as out:
out.write(response.audio_content)
print('Audio content written to file ' + outfile)
# [END hybrid_tts]


# [START hybrid_integration]
def main():

# Photo from which to extract text
infile = "resources/example.png"
# Name of file that will hold synthetic speech
outfile = "resources/example.mp3"

# Name that will be assigned to your project's glossary resource
glossary_name = 'bistro-glossary'
# URI of glossary uploaded to Cloud Storage
glossary_uri = 'gs://cloud-samples-data/translation/bistro_glossary.csv'
# List of languages in the glossary
glossary_langs = ['fr', 'en']

# delete_glossary(PROJECT_ID, glossary_name)
crowdus marked this conversation as resolved.
Show resolved Hide resolved
create_glossary(glossary_langs, PROJECT_ID, glossary_name, glossary_uri)

# photo -> detected text
text_to_translate = pic_to_text(infile)
# detected text -> translated text
text_to_speak = translate_text(text_to_translate, 'fr', 'en',
PROJECT_ID, glossary_name)
# translated text -> synthetic audio
text_to_speech(text_to_speak, outfile)
# [END hybrid_integration]


if __name__ == '__main__':
main()
117 changes: 117 additions & 0 deletions translate/cloud-client/hybrid_glossaries/hybrid_tutorial_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from hybrid_tutorial import pic_to_text
from hybrid_tutorial import create_glossary
from hybrid_tutorial import delete_glossary
from hybrid_tutorial import translate_text
from hybrid_tutorial import text_to_speech

import filecmp
import os

PROJECT_ID = os.environ['GCLOUD_PROJECT']

# VISION TESTS


def test_vision_standard_format():

expected_text = 'This is\na test!\n'
alt_expected_text = 'This\nis\na test!\n'

# Generate text using Vision API
text = pic_to_text('resources/standard_format.jpeg')

assert (text == expected_text) or (text == alt_expected_text)


def test_vision_non_standard_format():

# Generate text
text = pic_to_text('resources/non_standard_format.png')

# Read expected text
with open('resources/non_standard_format.txt') as f:
expected_text = f.read()

assert text == expected_text


# TRANSLATE TESTS


def test_create_and_delete_glossary():
languages = ['fr', 'en']
glossary_name = 'test-glossary'
glossary_uri = 'gs://cloud-samples-data/translation/bistro_glossary.csv'

# create_glossary will raise an exception if creation fails
create_glossary(languages, PROJECT_ID, glossary_name,
glossary_uri)

# Delete glossary so that future tests will pass
# delete_glossary will raise an exception if deletion fails
delete_glossary(PROJECT_ID, glossary_name)


def test_translate_standard():

expected_text = 'Hello'

text = translate_text('Bonjour', 'fr', 'en', PROJECT_ID,
'bistro-glossary')

assert text == expected_text


def test_translate_glossary():

expected_text = 'I eat goat cheese'
input_text = 'Je mange du chevre'

text = translate_text(input_text, 'fr', 'en', PROJECT_ID,
'bistro-glossary')

assert text == expected_text


# TEXT-TO-SPEECH TESTS


def test_tts_standard(capsys):
outfile = 'resources/test_standard_text.mp3'
expected_outfile = 'resources/expected_standard_text.mp3'
textfile = 'resources/standard_format.txt'

with open(textfile, 'r') as f:
text = f.read()

text_to_speech(text, outfile)

# Assert audio file generated
assert os.path.isfile(outfile)

# Assert audio file generated correctly
assert filecmp.cmp(outfile,
expected_outfile,
shallow=True)

out, err = capsys.readouterr()

# Assert success message printed
assert 'Audio content written to file ' + outfile in out

# Delete test file
os.remove(outfile)
3 changes: 3 additions & 0 deletions translate/cloud-client/hybrid_glossaries/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
google-cloud-translate==1.4.0
google-cloud-vision==0.35.2
google-cloud-texttospeech==0.4.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fr,en,
chevre,goat cheese,
Chevre,Goat cheese,
chèvre,goat cheese,
Chèvre,Goat cheese,
crème brulée,crème brulée,
Crème brulée,Crème brulée,
Crème Brulée,Crème Brulée,
bouillabaisse,fish stew,
Bouillabaisse,Fish stew,
steak frites,steak with french fries,
Steak frites,Steak with french fries,
Steak Frites,Steak with French Fries,
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading