diff --git a/google/cloud/texttospeech_v1beta1/__init__.py b/google/cloud/texttospeech_v1beta1/__init__.py index db38ed31..7528fdc2 100644 --- a/google/cloud/texttospeech_v1beta1/__init__.py +++ b/google/cloud/texttospeech_v1beta1/__init__.py @@ -18,6 +18,7 @@ from .services.text_to_speech import TextToSpeechAsyncClient from .types.cloud_tts import AudioConfig +from .types.cloud_tts import CustomVoiceParams from .types.cloud_tts import ListVoicesRequest from .types.cloud_tts import ListVoicesResponse from .types.cloud_tts import SynthesisInput @@ -33,6 +34,7 @@ "TextToSpeechAsyncClient", "AudioConfig", "AudioEncoding", + "CustomVoiceParams", "ListVoicesRequest", "ListVoicesResponse", "SsmlVoiceGender", diff --git a/google/cloud/texttospeech_v1beta1/services/text_to_speech/async_client.py b/google/cloud/texttospeech_v1beta1/services/text_to_speech/async_client.py index 7d20c2bc..68c02102 100644 --- a/google/cloud/texttospeech_v1beta1/services/text_to_speech/async_client.py +++ b/google/cloud/texttospeech_v1beta1/services/text_to_speech/async_client.py @@ -45,6 +45,8 @@ class TextToSpeechAsyncClient: DEFAULT_ENDPOINT = TextToSpeechClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = TextToSpeechClient.DEFAULT_MTLS_ENDPOINT + model_path = staticmethod(TextToSpeechClient.model_path) + parse_model_path = staticmethod(TextToSpeechClient.parse_model_path) common_billing_account_path = staticmethod( TextToSpeechClient.common_billing_account_path ) @@ -180,12 +182,13 @@ async def list_voices( language tag. If not specified, the API will return all supported voices. If specified, the ListVoices call will only return voices that can be used to synthesize this - language_code. E.g. when specifying "en-NZ", you will - get supported "en-NZ" voices; when specifying "no", you - will get supported "no-\*" (Norwegian) and "nb-\*" - (Norwegian Bokmal) voices; specifying "zh" will also get - supported "cmn-\*" voices; specifying "zh-hk" will also - get supported "yue-hk" voices. + language_code. E.g. when specifying ``"en-NZ"``, you + will get supported ``"en-NZ"`` voices; when specifying + ``"no"``, you will get supported ``"no-\*"`` (Norwegian) + and ``"nb-\*"`` (Norwegian Bokmal) voices; specifying + ``"zh"`` will also get supported ``"cmn-\*"`` voices; + specifying ``"zh-hk"`` will also get supported + ``"yue-hk"`` voices. This corresponds to the ``language_code`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/texttospeech_v1beta1/services/text_to_speech/client.py b/google/cloud/texttospeech_v1beta1/services/text_to_speech/client.py index 5e832926..a9139a4d 100644 --- a/google/cloud/texttospeech_v1beta1/services/text_to_speech/client.py +++ b/google/cloud/texttospeech_v1beta1/services/text_to_speech/client.py @@ -156,6 +156,22 @@ def transport(self) -> TextToSpeechTransport: """ return self._transport + @staticmethod + def model_path(project: str, location: str, model: str,) -> str: + """Returns a fully-qualified model string.""" + return "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str, str]: + """Parses a model path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path(billing_account: str,) -> str: """Returns a fully-qualified billing_account string.""" @@ -360,12 +376,13 @@ def list_voices( language tag. If not specified, the API will return all supported voices. If specified, the ListVoices call will only return voices that can be used to synthesize this - language_code. E.g. when specifying "en-NZ", you will - get supported "en-NZ" voices; when specifying "no", you - will get supported "no-\*" (Norwegian) and "nb-\*" - (Norwegian Bokmal) voices; specifying "zh" will also get - supported "cmn-\*" voices; specifying "zh-hk" will also - get supported "yue-hk" voices. + language_code. E.g. when specifying ``"en-NZ"``, you + will get supported ``"en-NZ"`` voices; when specifying + ``"no"``, you will get supported ``"no-\*"`` (Norwegian) + and ``"nb-\*"`` (Norwegian Bokmal) voices; specifying + ``"zh"`` will also get supported ``"cmn-\*"`` voices; + specifying ``"zh-hk"`` will also get supported + ``"yue-hk"`` voices. This corresponds to the ``language_code`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/texttospeech_v1beta1/types/__init__.py b/google/cloud/texttospeech_v1beta1/types/__init__.py index 34bfb0ec..b1b4c948 100644 --- a/google/cloud/texttospeech_v1beta1/types/__init__.py +++ b/google/cloud/texttospeech_v1beta1/types/__init__.py @@ -15,6 +15,7 @@ # from .cloud_tts import ( AudioConfig, + CustomVoiceParams, ListVoicesRequest, ListVoicesResponse, SynthesisInput, @@ -29,6 +30,7 @@ __all__ = ( "AudioConfig", + "CustomVoiceParams", "ListVoicesRequest", "ListVoicesResponse", "SynthesisInput", diff --git a/google/cloud/texttospeech_v1beta1/types/cloud_tts.py b/google/cloud/texttospeech_v1beta1/types/cloud_tts.py index 13f2af3a..bb4f3b50 100644 --- a/google/cloud/texttospeech_v1beta1/types/cloud_tts.py +++ b/google/cloud/texttospeech_v1beta1/types/cloud_tts.py @@ -28,6 +28,7 @@ "SynthesisInput", "VoiceSelectionParams", "AudioConfig", + "CustomVoiceParams", "SynthesizeSpeechResponse", "Timepoint", }, @@ -68,12 +69,12 @@ class ListVoicesRequest(proto.Message): language tag. If not specified, the API will return all supported voices. If specified, the ListVoices call will only return voices that can be used to synthesize this - language_code. E.g. when specifying "en-NZ", you will get - supported "en-NZ" voices; when specifying "no", you will get - supported "no-\*" (Norwegian) and "nb-\*" (Norwegian Bokmal) - voices; specifying "zh" will also get supported "cmn-\*" - voices; specifying "zh-hk" will also get supported "yue-hk" - voices. + language_code. E.g. when specifying ``"en-NZ"``, you will + get supported ``"en-NZ"`` voices; when specifying ``"no"``, + you will get supported ``"no-\*"`` (Norwegian) and + ``"nb-\*"`` (Norwegian Bokmal) voices; specifying ``"zh"`` + will also get supported ``"cmn-\*"`` voices; specifying + ``"zh-hk"`` will also get supported ``"yue-hk"`` voices. """ language_code = proto.Field(proto.STRING, number=1,) @@ -210,11 +211,16 @@ class VoiceSelectionParams(proto.Message): not requirement; if a voice of the appropriate gender is not available, the synthesizer should substitute a voice with a different gender rather than failing the request. + custom_voice (google.cloud.texttospeech_v1beta1.types.CustomVoiceParams): + The configuration for a custom voice. If + [CustomVoiceParams.model] is set, the service will choose + the custom voice matching the specified configuration. """ language_code = proto.Field(proto.STRING, number=1,) name = proto.Field(proto.STRING, number=2,) ssml_gender = proto.Field(proto.ENUM, number=3, enum="SsmlVoiceGender",) + custom_voice = proto.Field(proto.MESSAGE, number=4, message="CustomVoiceParams",) class AudioConfig(proto.Message): @@ -272,6 +278,31 @@ class AudioConfig(proto.Message): effects_profile_id = proto.RepeatedField(proto.STRING, number=6,) +class CustomVoiceParams(proto.Message): + r"""Description of the custom voice to be synthesized. + + Attributes: + model (str): + Required. The name of the AutoML model that + synthesizes the custom voice. + reported_usage (google.cloud.texttospeech_v1beta1.types.CustomVoiceParams.ReportedUsage): + Optional. The usage of the synthesized audio + to be reported. + """ + + class ReportedUsage(proto.Enum): + r"""The usage of the synthesized audio. You must report your + honest and correct usage of the service as it's regulated by + contract and will cause significant difference in billing. + """ + REPORTED_USAGE_UNSPECIFIED = 0 + REALTIME = 1 + OFFLINE = 2 + + model = proto.Field(proto.STRING, number=1,) + reported_usage = proto.Field(proto.ENUM, number=3, enum=ReportedUsage,) + + class SynthesizeSpeechResponse(proto.Message): r"""The message returned to the client by the ``SynthesizeSpeech`` method. diff --git a/tests/unit/gapic/texttospeech_v1beta1/test_text_to_speech.py b/tests/unit/gapic/texttospeech_v1beta1/test_text_to_speech.py index 232e83c5..4cdcc10e 100644 --- a/tests/unit/gapic/texttospeech_v1beta1/test_text_to_speech.py +++ b/tests/unit/gapic/texttospeech_v1beta1/test_text_to_speech.py @@ -1193,8 +1193,32 @@ def test_text_to_speech_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel +def test_model_path(): + project = "squid" + location = "clam" + model = "whelk" + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + actual = TextToSpeechClient.model_path(project, location, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "octopus", + "location": "oyster", + "model": "nudibranch", + } + path = TextToSpeechClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = TextToSpeechClient.parse_model_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "squid" + billing_account = "cuttlefish" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1204,7 +1228,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "clam", + "billing_account": "mussel", } path = TextToSpeechClient.common_billing_account_path(**expected) @@ -1214,7 +1238,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "whelk" + folder = "winkle" expected = "folders/{folder}".format(folder=folder,) actual = TextToSpeechClient.common_folder_path(folder) assert expected == actual @@ -1222,7 +1246,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "octopus", + "folder": "nautilus", } path = TextToSpeechClient.common_folder_path(**expected) @@ -1232,7 +1256,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "oyster" + organization = "scallop" expected = "organizations/{organization}".format(organization=organization,) actual = TextToSpeechClient.common_organization_path(organization) assert expected == actual @@ -1240,7 +1264,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nudibranch", + "organization": "abalone", } path = TextToSpeechClient.common_organization_path(**expected) @@ -1250,7 +1274,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "cuttlefish" + project = "squid" expected = "projects/{project}".format(project=project,) actual = TextToSpeechClient.common_project_path(project) assert expected == actual @@ -1258,7 +1282,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "mussel", + "project": "clam", } path = TextToSpeechClient.common_project_path(**expected) @@ -1268,8 +1292,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "winkle" - location = "nautilus" + project = "whelk" + location = "octopus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1279,8 +1303,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "scallop", - "location": "abalone", + "project": "oyster", + "location": "nudibranch", } path = TextToSpeechClient.common_location_path(**expected)