diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 30c3973a..9cd0a337 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,4 +8,4 @@ * @googleapis/yoshi-python # The python-samples-reviewers team is the default owner for samples changes -/samples/ @googleapis/python-samples-owners \ No newline at end of file +/samples/ @googleapis/python-samples-owners @wuyuexin \ No newline at end of file diff --git a/.github/snippet-bot.yml b/.github/snippet-bot.yml new file mode 100644 index 00000000..e69de29b diff --git a/samples/AUTHORING_GUIDE.md b/samples/AUTHORING_GUIDE.md new file mode 100644 index 00000000..55c97b32 --- /dev/null +++ b/samples/AUTHORING_GUIDE.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/samples/CONTRIBUTING.md b/samples/CONTRIBUTING.md new file mode 100644 index 00000000..34c882b6 --- /dev/null +++ b/samples/CONTRIBUTING.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/CONTRIBUTING.md \ No newline at end of file diff --git a/samples/snippets/README.rst b/samples/snippets/README.rst new file mode 100644 index 00000000..7c403a4d --- /dev/null +++ b/samples/snippets/README.rst @@ -0,0 +1,221 @@ + +.. This file is automatically generated. Do not edit this file directly. + +Dialogflow CX 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 Dialogflow CX API. The `Dialogflow CX API`_ enables you to create conversational experiences across devices and platforms. + + + + +.. _Dialogflow CX API: https://cloud.google.com/dialogflow/cx/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 3.6+. + + .. 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 +------------------------------------------------------------------------------- + + +Detect Intent Text ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. 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=/detect_intent_texts.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_texts.py + + + usage: detect_intent_texts.py [-h] --agent AGENT [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + texts [texts ...] + + DialogFlow API Detect Intent Python sample with text inputs. + + Examples: + python detect_intent_texts.py -h + python detect_intent_texts.py --agent AGENT --session-id SESSION_ID "hello" "book a meeting room" "Mountain View" + python detect_intent_texts.py --agent AGENT --session-id SESSION_ID "tomorrow" "10 AM" "2 hours" "10 people" "A" "yes" + + positional arguments: + texts Text inputs. + + optional arguments: + -h, --help show this help message and exit + --agent AGENT Agent resource name. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + + + + + +Detect Intent Audio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. 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=/detect_intent_audio.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_audio.py + + + usage: detect_intent_audio.py [-h] --agent AGENT [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --audio-file-path AUDIO_FILE_PATH + + DialogFlow API Detect Intent Python sample with audio file. + + Examples: + python detect_intent_audio.py -h + python detect_intent_audio.py --agent AGENT --session-id SESSION_ID --audio-file-path resources/hello.wav + + optional arguments: + -h, --help show this help message and exit + --agent AGENT Agent resource name. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --audio-file-path AUDIO_FILE_PATH + Path to the audio file. + + + + + +Detect Intent Stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. 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=/detect_intent_stream.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_stream.py + + + usage: detect_intent_stream.py [-h] --agent AGENT [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --audio-file-path AUDIO_FILE_PATH + + DialogFlow API Detect Intent Python sample with audio files processed as an audio stream. + + Examples: + python detect_intent_stream.py -h + python detect_intent_stream.py --agent AGENT --session-id SESSION_ID --audio-file-path resources/hello.wav + + optional arguments: + -h, --help show this help message and exit + --agent AGENT Agent resource name. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --audio-file-path AUDIO_FILE_PATH + Path to the audio file. + + + + + + + + + +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/ diff --git a/samples/snippets/README.rst.in b/samples/snippets/README.rst.in new file mode 100644 index 00000000..043c9b77 --- /dev/null +++ b/samples/snippets/README.rst.in @@ -0,0 +1,25 @@ +# This file is used to generate README.rst + +product: + name: Dialogflow CX API + short_name: Dialogflow CX API + url: https://cloud.google.com/dialogflow/cx/docs/ + description: > + The `Dialogflow CX API`_ enables you to create conversational experiences across devices and platforms. + +setup: +- auth +- install_deps + +samples: +- name: Detect Intent Text + file: detect_intent_texts.py + show_help: True +- name: Detect Intent Audio + file: detect_intent_audio.py + show_help: True +- name: Detect Intent Stream + file: detect_intent_stream.py + show_help: True + +cloud_client_library: true diff --git a/samples/snippets/detect_intent_audio.py b/samples/snippets/detect_intent_audio.py new file mode 100644 index 00000000..2bb1fa1e --- /dev/null +++ b/samples/snippets/detect_intent_audio.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +# Copyright 2020 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. + +"""DialogFlow API Detect Intent Python sample with audio file. + +Examples: + python detect_intent_audio.py -h + python detect_intent_audio.py --agent AGENT \ + --session-id SESSION_ID --audio-file-path resources/hello.wav +""" + +import argparse +import uuid + +from google.cloud.dialogflowcx_v3beta1.services.sessions import SessionsClient +from google.cloud.dialogflowcx_v3beta1.types import audio_config +from google.cloud.dialogflowcx_v3beta1.types import session + + +# [START dialogflow_detect_intent_audio] +def run_sample(): + # TODO(developer): Replace these values when running the function + project_id = "YOUR-PROJECT-ID" + location_id = "YOUR-LOCATION-ID" + # For more info on agents see https://cloud.google.com/dialogflow/cx/docs/concept/agent + agent_id = "YOUR-AGENT-ID" + agent = f"projects/{project_id}/locations/{location_id}/agents/{agent_id}" + # For more information on sessions see https://cloud.google.com/dialogflow/cx/docs/concept/session + session_id = str(uuid.uuid4()) + audio_file_path = "YOUR-AUDIO-FILE-PATH" + # For more supported languages see https://cloud.google.com/dialogflow/es/docs/reference/language + language_code = "en-us" + + detect_intent_audio(agent, session_id, audio_file_path, language_code) + + +def detect_intent_audio(agent, session_id, audio_file_path, language_code): + """Returns the result of detect intent with an audio file as input. + + Using the same `session_id` between requests allows continuation + of the conversation.""" + session_client = SessionsClient() + session_path = f"{agent}/sessions/{session_id}" + print(f"Session path: {session_path}\n") + + input_audio_config = audio_config.InputAudioConfig( + audio_encoding=audio_config.AudioEncoding.AUDIO_ENCODING_LINEAR_16, + sample_rate_hertz=24000, + ) + + with open(audio_file_path, "rb") as audio_file: + input_audio = audio_file.read() + + audio_input = session.AudioInput(config=input_audio_config, audio=input_audio) + query_input = session.QueryInput(audio=audio_input, language_code=language_code) + request = session.DetectIntentRequest(session=session_path, query_input=query_input) + response = session_client.detect_intent(request=request) + + print("=" * 20) + print(f"Query text: {response.query_result.transcript}") + response_messages = [ + " ".join(msg.text.text) for msg in response.query_result.response_messages + ] + print(f"Response text: {' '.join(response_messages)}\n") + + +# [END dialogflow_detect_intent_audio] + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "--agent", help="Agent resource name. Required.", required=True + ) + parser.add_argument( + "--session-id", + help="Identifier of the DetectIntent session. " "Defaults to a random UUID.", + default=str(uuid.uuid4()), + ) + parser.add_argument( + "--language-code", + help='Language code of the query. Defaults to "en-US".', + default="en-US", + ) + parser.add_argument( + "--audio-file-path", help="Path to the audio file.", required=True + ) + + args = parser.parse_args() + + detect_intent_audio( + args.agent, args.session_id, args.audio_file_path, args.language_code + ) diff --git a/samples/snippets/detect_intent_audio_test.py b/samples/snippets/detect_intent_audio_test.py new file mode 100644 index 00000000..720bf68c --- /dev/null +++ b/samples/snippets/detect_intent_audio_test.py @@ -0,0 +1,37 @@ +# Copyright 2020, 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. + +"""Tests for detect_intent_texts.""" + +from __future__ import absolute_import + +import os +import uuid + + +from detect_intent_audio import detect_intent_audio + +DIRNAME = os.path.realpath(os.path.dirname(__file__)) +PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT") +AGENT_ID = os.getenv("AGENT_ID") +AGENT = f"projects/{PROJECT_ID}/locations/global/agents/{AGENT_ID}" +SESSION_ID = uuid.uuid4() +AUDIO_PATH = os.getenv("AUDIO_PATH") +AUDIO = f"{DIRNAME}/{AUDIO_PATH}" + + +def test_detect_intent_texts(capsys): + detect_intent_audio(AGENT, SESSION_ID, AUDIO, "en-US") + out, _ = capsys.readouterr() + + assert "Response text: Hi! I'm the virtual flights agent." in out diff --git a/samples/snippets/detect_intent_stream.py b/samples/snippets/detect_intent_stream.py new file mode 100644 index 00000000..ecf1ea53 --- /dev/null +++ b/samples/snippets/detect_intent_stream.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +# Copyright 2020 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. + +"""DialogFlow API Detect Intent Python sample with audio files processed as an audio stream. + +Examples: + python detect_intent_stream.py -h + python detect_intent_stream.py --agent AGENT \ + --session-id SESSION_ID --audio-file-path resources/hello.wav +""" + +import argparse +import uuid + +from google.cloud.dialogflowcx_v3beta1.services.sessions import SessionsClient +from google.cloud.dialogflowcx_v3beta1.types import audio_config +from google.cloud.dialogflowcx_v3beta1.types import session + + +# [START dialogflow_detect_intent_stream] +def run_sample(): + # TODO(developer): Replace these values when running the function + project_id = "YOUR-PROJECT-ID" + location_id = "YOUR-LOCATION-ID" + # For more info on agents see https://cloud.google.com/dialogflow/cx/docs/concept/agent + agent_id = "YOUR-AGENT-ID" + agent = f"projects/{project_id}/locations/{location_id}/agents/{agent_id}" + # For more information on sessions see https://cloud.google.com/dialogflow/cx/docs/concept/session + session_id = uuid.uuid4() + audio_file_path = "YOUR-AUDIO-FILE-PATH" + # For more supported languages see https://cloud.google.com/dialogflow/es/docs/reference/language + language_code = "en-us" + + detect_intent_stream(agent, session_id, audio_file_path, language_code) + + +def detect_intent_stream(agent, session_id, audio_file_path, language_code): + """Returns the result of detect intent with streaming audio as input. + + Using the same `session_id` between requests allows continuation + of the conversation.""" + session_client = SessionsClient() + session_path = f"{agent}/sessions/{session_id}" + print(f"Session path: {session_path}\n") + + input_audio_config = audio_config.InputAudioConfig( + audio_encoding=audio_config.AudioEncoding.AUDIO_ENCODING_LINEAR_16, + sample_rate_hertz=24000, + ) + + def request_generator(): + audio_input = session.AudioInput(config=input_audio_config) + query_input = session.QueryInput(audio=audio_input, language_code=language_code) + + # The first request contains the configuration. + yield session.StreamingDetectIntentRequest( + session=session_path, query_input=query_input + ) + + # Here we are reading small chunks of audio data from a local + # audio file. In practice these chunks should come from + # an audio input device. + with open(audio_file_path, "rb") as audio_file: + while True: + chunk = audio_file.read(4096) + if not chunk: + break + # The later requests contains audio data. + audio_input = session.AudioInput(audio=chunk) + query_input = session.QueryInput(audio=audio_input) + yield session.StreamingDetectIntentRequest(query_input=query_input) + + responses = session_client.streaming_detect_intent(requests=request_generator()) + + print("=" * 20) + for response in responses: + print(f'Intermediate transcript: "{response.recognition_result.transcript}".') + + # Note: The result from the last response is the final transcript along + # with the detected content. + response = response.detect_intent_response + print(f"Query text: {response.query_result.transcript}") + response_messages = [ + " ".join(msg.text.text) for msg in response.query_result.response_messages + ] + print(f"Response text: {' '.join(response_messages)}\n") + + +# [END dialogflow_detect_intent_stream] + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "--agent", help="Agent resource name. Required.", required=True + ) + parser.add_argument( + "--session-id", + help="Identifier of the DetectIntent session. " "Defaults to a random UUID.", + default=str(uuid.uuid4()), + ) + parser.add_argument( + "--language-code", + help='Language code of the query. Defaults to "en-US".', + default="en-US", + ) + parser.add_argument( + "--audio-file-path", help="Path to the audio file.", required=True + ) + + args = parser.parse_args() + + detect_intent_stream( + args.agent, args.session_id, args.audio_file_path, args.language_code + ) diff --git a/samples/snippets/detect_intent_stream_test.py b/samples/snippets/detect_intent_stream_test.py new file mode 100644 index 00000000..7501cfc1 --- /dev/null +++ b/samples/snippets/detect_intent_stream_test.py @@ -0,0 +1,38 @@ +# Copyright 2020, 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. + +"""Tests for detect_intent_texts.""" + +from __future__ import absolute_import + +import os +import uuid + + +from detect_intent_stream import detect_intent_stream + +DIRNAME = os.path.realpath(os.path.dirname(__file__)) +PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT") +AGENT_ID = os.getenv("AGENT_ID") +AGENT = f"projects/{PROJECT_ID}/locations/global/agents/{AGENT_ID}" +SESSION_ID = uuid.uuid4() +AUDIO_PATH = os.getenv("AUDIO_PATH") +AUDIO = f"{DIRNAME}/{AUDIO_PATH}" + + +def test_detect_intent_texts(capsys): + detect_intent_stream(AGENT, SESSION_ID, AUDIO, "en-US") + out, _ = capsys.readouterr() + + assert "Intermediate transcript:" in out + assert "Response text: Hi! I'm the virtual flights agent." in out diff --git a/samples/snippets/detect_intent_texts.py b/samples/snippets/detect_intent_texts.py new file mode 100644 index 00000000..b55f4bf2 --- /dev/null +++ b/samples/snippets/detect_intent_texts.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +# Copyright 2020 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. + +"""DialogFlow API Detect Intent Python sample with text inputs. + +Examples: + python detect_intent_texts.py -h + python detect_intent_texts.py --agent AGENT \ + --session-id SESSION_ID \ + "hello" "book a meeting room" "Mountain View" + python detect_intent_texts.py --agent AGENT \ + --session-id SESSION_ID \ + "tomorrow" "10 AM" "2 hours" "10 people" "A" "yes" +""" + +import argparse +import uuid + +from google.cloud.dialogflowcx_v3beta1.services.sessions import SessionsClient +from google.cloud.dialogflowcx_v3beta1.types import session + + +# [START dialogflow_detect_intent_text] +def run_sample(): + # TODO(developer): Replace these values when running the function + project_id = "YOUR-PROJECT-ID" + location_id = "YOUR-LOCATION-ID" + # For more info on agents see https://cloud.google.com/dialogflow/cx/docs/concept/agent + agent_id = "YOUR-AGENT-ID" + agent = f"projects/{project_id}/locations/{location_id}/agents/{agent_id}" + # For more information on sessions see https://cloud.google.com/dialogflow/cx/docs/concept/session + session_id = uuid.uuid4() + texts = ["Hello"] + # For more supported languages see https://cloud.google.com/dialogflow/es/docs/reference/language + language_code = "en-us" + + detect_intent_texts(agent, session_id, texts, language_code) + + +def detect_intent_texts(agent, session_id, texts, language_code): + """Returns the result of detect intent with texts as inputs. + + Using the same `session_id` between requests allows continuation + of the conversation.""" + session_client = SessionsClient() + session_path = f"{agent}/sessions/{session_id}" + print(f"Session path: {session_path}\n") + + for text in texts: + text_input = session.TextInput(text=text) + query_input = session.QueryInput(text=text_input, language_code=language_code) + request = session.DetectIntentRequest( + session=session_path, query_input=query_input + ) + response = session_client.detect_intent(request=request) + + print("=" * 20) + print(f"Query text: {response.query_result.text}") + response_messages = [ + " ".join(msg.text.text) for msg in response.query_result.response_messages + ] + print(f"Response text: {' '.join(response_messages)}\n") + + +# [END dialogflow_detect_intent_text] + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "--agent", help="Agent resource name. Required.", required=True + ) + parser.add_argument( + "--session-id", + help="Identifier of the DetectIntent session. " "Defaults to a random UUID.", + default=str(uuid.uuid4()), + ) + parser.add_argument( + "--language-code", + help='Language code of the query. Defaults to "en-US".', + default="en-US", + ) + parser.add_argument("texts", nargs="+", type=str, help="Text inputs.") + + args = parser.parse_args() + + detect_intent_texts(args.agent, args.session_id, args.texts, args.language_code) diff --git a/samples/snippets/detect_intent_texts_test.py b/samples/snippets/detect_intent_texts_test.py new file mode 100644 index 00000000..0cc263ae --- /dev/null +++ b/samples/snippets/detect_intent_texts_test.py @@ -0,0 +1,35 @@ +# Copyright 2020, 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. + +"""Tests for detect_intent_texts.""" + +from __future__ import absolute_import + +import os +import uuid + + +from detect_intent_texts import detect_intent_texts + +PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT") +AGENT_ID = os.getenv("AGENT_ID") +AGENT = f"projects/{PROJECT_ID}/locations/global/agents/{AGENT_ID}" +SESSION_ID = uuid.uuid4() +TEXTS = ["hello", "book a flight"] + + +def test_detect_intent_texts(capsys): + detect_intent_texts(AGENT, SESSION_ID, TEXTS, "en-US") + out, _ = capsys.readouterr() + + assert "Response text: I can help you find a ticket" in out diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py new file mode 100644 index 00000000..ba55d7ce --- /dev/null +++ b/samples/snippets/noxfile.py @@ -0,0 +1,224 @@ +# 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. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/samples/snippets/noxfile_config.py b/samples/snippets/noxfile_config.py new file mode 100644 index 00000000..edded193 --- /dev/null +++ b/samples/snippets/noxfile_config.py @@ -0,0 +1,40 @@ +# Copyright 2020 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": { + "AGENT_ID": "53516802-3e2a-4016-80b6-a3df0d240240", + "AUDIO_PATH": "resources/hello.wav", + }, +} \ No newline at end of file diff --git a/samples/snippets/requirements-test.txt b/samples/snippets/requirements-test.txt new file mode 100644 index 00000000..3413ad1c --- /dev/null +++ b/samples/snippets/requirements-test.txt @@ -0,0 +1 @@ +pytest==6.0.1 \ No newline at end of file diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt new file mode 100644 index 00000000..9123af57 --- /dev/null +++ b/samples/snippets/requirements.txt @@ -0,0 +1 @@ +google-cloud-dialogflow-cx==0.1.0 diff --git a/samples/snippets/resources/hello.wav b/samples/snippets/resources/hello.wav new file mode 100644 index 00000000..0aadf16c Binary files /dev/null and b/samples/snippets/resources/hello.wav differ