diff --git a/translation/samples/snippets/hybrid_glossaries/README.rst b/translation/samples/snippets/hybrid_glossaries/README.rst
new file mode 100644
index 000000000000..2c9866545dc6
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/README.rst
@@ -0,0 +1,97 @@
+.. This file is automatically generated. Do not edit this file directly.
+
+Google Translation API Python Samples
+===============================================================================
+
+.. image:: https://gstatic.com/cloudssh/images/open-btn.png
+ :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/README.rst
+
+
+This directory contains samples for Google Translation API. With `Google Translation API`, you can dynamically translate text between thousands of language pairs.
+
+
+
+
+.. _Google Translation API: https://cloud.google.com/translate/docs
+
+Setup
+-------------------------------------------------------------------------------
+
+
+Authentication
+++++++++++++++
+
+This sample requires you to have authentication setup. Refer to the
+`Authentication Getting Started Guide`_ for instructions on setting up
+credentials for applications.
+
+.. _Authentication Getting Started Guide:
+ https://cloud.google.com/docs/authentication/getting-started
+
+Install Dependencies
+++++++++++++++++++++
+
+#. Clone python-docs-samples and change directory to the sample directory you want to use.
+
+ .. code-block:: bash
+
+ $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
+
+#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions.
+
+ .. _Python Development Environment Setup Guide:
+ https://cloud.google.com/python/setup
+
+#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+.
+
+ .. code-block:: bash
+
+ $ virtualenv env
+ $ source env/bin/activate
+
+#. Install the dependencies needed to run the samples.
+
+ .. code-block:: bash
+
+ $ pip install -r requirements.txt
+
+.. _pip: https://pip.pypa.io/
+.. _virtualenv: https://virtualenv.pypa.io/
+
+Samples
+-------------------------------------------------------------------------------
+
+Using glossaries with vision and text-to-speech
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. image:: https://gstatic.com/cloudssh/images/open-btn.png
+ :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/hybrid_tutorial.py,/README.rst
+
+
+
+
+To run this sample:
+
+.. code-block:: bash
+
+ $ python hybrid_tutorial.py
+
+
+
+
+The client library
+-------------------------------------------------------------------------------
+
+This sample uses the `Google Cloud Client Library for Python`_.
+You can read the documentation for more details on API usage and use GitHub
+to `browse the source`_ and `report issues`_.
+
+.. _Google Cloud Client Library for Python:
+ https://googlecloudplatform.github.io/google-cloud-python/
+.. _browse the source:
+ https://github.com/GoogleCloudPlatform/google-cloud-python
+.. _report issues:
+ https://github.com/GoogleCloudPlatform/google-cloud-python/issues
+
+
+.. _Google Cloud SDK: https://cloud.google.com/sdk/
\ No newline at end of file
diff --git a/translation/samples/snippets/hybrid_glossaries/README.rst.in b/translation/samples/snippets/hybrid_glossaries/README.rst.in
new file mode 100644
index 000000000000..882f3666fc9f
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/README.rst.in
@@ -0,0 +1,22 @@
+
+
+# This file is used to generate README.rst
+
+product:
+ name: Google Translation API
+ short_name: Translation API
+ url: https://cloud.google.com/translate/docs
+ description: >
+ With `Google Translation API`, you can dynamically translate text between
+ thousands of language pairs.
+
+setup:
+- auth
+- install_deps
+
+samples:
+- name: Using glossaries with vision and text-to-speech
+ file: hybrid_tutorial.py
+
+cloud_client_library: true
+
diff --git a/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial.py b/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial.py
new file mode 100644
index 000000000000..be73960f64fb
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial.py
@@ -0,0 +1,249 @@
+# Copyright 2019 Google LLC
+#
+# 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 translate_hybrid_imports]
+import io
+import os
+import html
+
+# Imports the Google Cloud client libraries
+from google.api_core.exceptions import AlreadyExists
+from google.cloud import translate_v3beta1 as translate
+from google.cloud import vision
+from google.cloud import texttospeech
+# [END translate_hybrid_imports]
+
+
+# [START translate_hybrid_project_id]
+# extract GCP project id
+PROJECT_ID = os.environ['GCLOUD_PROJECT']
+# [END translate_hybrid_project_id]
+
+
+# [START translate_hybrid_vision]
+def pic_to_text(infile):
+ """Detects text in an image file
+
+ 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
+ response = client.document_text_detection(image=image)
+ text = response.full_text_annotation.text
+
+ return text
+ # [END translate_hybrid_vision]
+
+
+# [START translate_hybrid_create_glossary]
+def create_glossary(languages, project_id, glossary_name, glossary_uri):
+ """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
+ """
+
+ # Instantiates a client
+ client = translate.TranslationServiceClient()
+
+ # 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)
+
+ parent = client.location_path(project_id, location)
+
+ # Create glossary resource
+ # Handle exception for case in which a glossary
+ # with glossary_name already exists
+ try:
+ operation = client.create_glossary(parent=parent, glossary=glossary)
+ operation.result(timeout=90)
+ print('Created glossary ' + glossary_name + '.')
+ except AlreadyExists:
+ print('The glossary ' + glossary_name +
+ ' already exists. No new glossary was created.')
+ # [END translate_hybrid_create_glossary]
+
+
+# [START translate_hybrid_translate]
+def translate_text(text, source_language_code, target_language_code,
+ project_id, glossary_name):
+ """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)
+
+ parent = client.location_path(project_id, location)
+
+ result = client.translate_text(
+ parent=parent,
+ contents=[text],
+ mime_type='text/plain', # mime types: text/plain, text/html
+ source_language_code=source_language_code,
+ target_language_code=target_language_code,
+ glossary_config=glossary_config)
+
+ # Extract translated text from API response
+ return result.glossary_translations[0].translated_text
+ # [END translate_hybrid_translate]
+
+
+# [START translate_hybrid_tts]
+def text_to_speech(text, outfile):
+ """Converts plaintext to SSML and
+ generates synthetic audio from SSML
+
+ ARGS
+ text: text to synthesize
+ outfile: filename to use to store synthetic audio
+
+ RETURNS
+ nothing
+ """
+
+ # Replace special characters with HTML Ampersand Character Codes
+ # These Codes prevent the API from confusing text with
+ # SSML commands
+ # For example, '<' --> '<' and '&' --> '&'
+ escaped_lines = html.escape(text)
+
+ # Convert plaintext to SSML in order to wait two seconds
+ # between each line in synthetic speech
+ ssml = '{}'.format(
+ escaped_lines.replace('\n', '\n'))
+
+ # Instantiates a client
+ client = texttospeech.TextToSpeechClient()
+
+ # Sets the text input to be synthesized
+ synthesis_input = texttospeech.types.SynthesisInput(ssml=ssml)
+
+ # 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 translate_hybrid_tts]
+
+
+# [START translate_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'
+
+ # Defines the languages in the glossary
+ # This list must match the languages in the glossary
+ # Here, the glossary includes French and English
+ glossary_langs = ['fr', 'en']
+ # Name that will be assigned to your project's glossary resource
+ glossary_name = 'bistro-glossary'
+ # uri of .csv file uploaded to Cloud Storage
+ glossary_uri = 'gs://cloud-samples-data/translation/bistro_glossary.csv'
+
+ 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 transalte_hybrid_integration]
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial_tests.py b/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial_tests.py
new file mode 100644
index 000000000000..bdd8251ba865
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/hybrid_tutorial_tests.py
@@ -0,0 +1,122 @@
+# Copyright 2019 Google LLC
+#
+# 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.
+
+import filecmp
+import os
+import sys
+
+from hybrid_tutorial import pic_to_text
+from hybrid_tutorial import create_glossary
+from hybrid_tutorial import translate_text
+from hybrid_tutorial import text_to_speech
+
+
+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():
+ sys.path.insert(1, '../')
+ from beta_snippets import 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)
diff --git a/translation/samples/snippets/hybrid_glossaries/requirements.txt b/translation/samples/snippets/hybrid_glossaries/requirements.txt
new file mode 100644
index 000000000000..29c4261a7cf8
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/requirements.txt
@@ -0,0 +1,3 @@
+google-cloud-translate==1.4.0
+google-cloud-vision==0.35.2
+google-cloud-texttospeech==0.4.0
\ No newline at end of file
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/bistro_glossary.csv b/translation/samples/snippets/hybrid_glossaries/resources/bistro_glossary.csv
new file mode 100644
index 000000000000..99b451445529
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/resources/bistro_glossary.csv
@@ -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,
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/example.png b/translation/samples/snippets/hybrid_glossaries/resources/example.png
new file mode 100644
index 000000000000..a3ac25ab053b
Binary files /dev/null and b/translation/samples/snippets/hybrid_glossaries/resources/example.png differ
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/expected_standard_text.mp3 b/translation/samples/snippets/hybrid_glossaries/resources/expected_standard_text.mp3
new file mode 100644
index 000000000000..c731fbd787d3
Binary files /dev/null and b/translation/samples/snippets/hybrid_glossaries/resources/expected_standard_text.mp3 differ
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.png b/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.png
new file mode 100644
index 000000000000..eeee9c7f6a6f
Binary files /dev/null and b/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.png differ
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.txt b/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.txt
new file mode 100644
index 000000000000..8a6e3c113d18
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/resources/non_standard_format.txt
@@ -0,0 +1,30 @@
+MENU
+Google Cloud Bistro
+SALADS
+SANDWICHES
+GCP Green Salad
+Fresh Greens
+$5
+Kubernetes Sandwich
+ham and cheese sandwich
+$10
+Cloud Caprese
+Mozzarella, tomatoes, basil,
+balsamic reduction
+$8
+Dialogflow Panini
+chicken, pesto, and
+mozzarella panini
+$10
+Firebase Fruit Salad
+watermelon, honeydew melon,
+and pineapple
+Compute Engine Burger
+quarter-pound burger with
+cheddar cheese
+$10
+$6
+BigQuery BLT
+bacon, lettuce, and tomato
+sandwich
+$10
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/standard_format.jpeg b/translation/samples/snippets/hybrid_glossaries/resources/standard_format.jpeg
new file mode 100644
index 000000000000..f985a540dad9
Binary files /dev/null and b/translation/samples/snippets/hybrid_glossaries/resources/standard_format.jpeg differ
diff --git a/translation/samples/snippets/hybrid_glossaries/resources/standard_format.txt b/translation/samples/snippets/hybrid_glossaries/resources/standard_format.txt
new file mode 100644
index 000000000000..d91d49e8680b
--- /dev/null
+++ b/translation/samples/snippets/hybrid_glossaries/resources/standard_format.txt
@@ -0,0 +1,2 @@
+This is
+a test!