├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── google-assistant-grpc ├── CHANGELOG.rst ├── LICENSE ├── MAINTAINER.md ├── MANIFEST.in ├── README.rst ├── google │ ├── __init__.py │ └── assistant │ │ ├── __init__.py │ │ └── embedded │ │ ├── __init__.py │ │ ├── v1alpha1 │ │ ├── __init__.py │ │ ├── embedded_assistant_pb2.py │ │ └── embedded_assistant_pb2_grpc.py │ │ └── v1alpha2 │ │ ├── __init__.py │ │ ├── embedded_assistant_pb2.py │ │ └── embedded_assistant_pb2_grpc.py ├── noxfile.py ├── setup.cfg └── setup.py └── google-assistant-sdk ├── CHANGELOG.rst ├── LICENSE ├── MAINTAINER.md ├── MANIFEST.in ├── README.rst ├── actions.json ├── googlesamples ├── __init__.py └── assistant │ ├── __init__.py │ └── grpc │ ├── README.rst │ ├── __init__.py │ ├── assistant_helpers.py │ ├── audio_helpers.py │ ├── audiofileinput.py │ ├── browser_helpers.py │ ├── device_helpers.py │ ├── devicetool.py │ ├── pushtotalk.py │ ├── requirements.txt │ └── textinput.py ├── noxfile.py ├── setup.cfg ├── setup.py └── tests ├── data ├── grapefruit.riff └── whattimeisit.riff ├── test_audio_helpers.py ├── test_device_helpers.py ├── test_devicetool.py └── test_endtoend.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | env/ 3 | env2/ 4 | *~ 5 | *.pyc 6 | .embedded_assistant_credentials.json 7 | client_secret_*.googleusercontent.com.json 8 | dist/ 9 | build/ 10 | google_assistant.egg-info/ 11 | *.egg 12 | .eggs/ 13 | *.egg-info/ 14 | .nox/ 15 | .tox/ 16 | .cache/ 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | before_install: 5 | - sudo apt-get -qq update 6 | - sudo apt-get install -y portaudio19-dev libffi-dev libssl-dev 7 | install: 8 | - pip install nox 9 | script: 10 | - nox -f google-assistant-grpc/noxfile.py -s lint 11 | - nox -f google-assistant-sdk/noxfile.py -s lint unittest 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | ## Contributor License Agreements 4 | 5 | We'd love to accept your sample apps and patches! Before we can take them, we 6 | have to jump a couple of legal hurdles. 7 | 8 | Please fill out either the individual or corporate Contributor License Agreement (CLA). 9 | 10 | * If you are an individual writing original source code and you're sure you 11 | own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). 12 | * If you work for a company that wants to allow you to contribute your work, 13 | then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). 14 | 15 | Follow either of the two links above to access the appropriate CLA and 16 | instructions for how to sign and return it. Once we receive it, we'll be able to 17 | accept your pull requests. 18 | 19 | ## Contributing A Patch 20 | 21 | 1. Submit an issue describing your proposed change to the repo in question. 22 | 1. The repo owner will respond to your issue promptly. 23 | 1. If your proposed change is accepted, and you haven't already done so, sign a 24 | Contributor License Agreement (see details above). 25 | 1. Fork the desired repo, develop and test your code changes. 26 | 1. Ensure that your code adheres to the existing style in the sample to which 27 | you are contributing. Refer to 28 | the [PEP-8](https://www.python.org/dev/peps/pep-0008/) style guide for the 29 | recommended coding standards for this project. 30 | 1. Ensure that your code has an appropriate set of unit tests which all pass. 31 | 1. Submit a pull request. 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2014 The Android Open Source Project 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Assistant SDK for devices - Python 2 | 3 | This repository contains the [Python][python] packages for the [Google Assistant SDK][google-assistant-sdk]. 4 | 5 | To get started, see the following developer guides: 6 | - [Introduction to the Google Assistant Service][getting-started-python]. 7 | 8 | ## Content 9 | 10 | - [google-assistant-grpc](google-assistant-grpc): autogenerated Python bindings to communicate with the [Google Assistant Service][google-assistant-api] *available for non-commercial use* 11 | - ~~google-assistant-library: Python bindings for the Google Assistant Library~~ *deprecated* 12 | - [google-assistant-sdk](google-assistant-sdk): tools and python samples to help developers get started with the [Google Assistant SDK][google-assistant-sdk] 13 | - [googlesamples/assistant/grpc](google-assistant-sdk/googlesamples/assistant/grpc): reference sample for the [Google Assistant Service][google-assistant-api] 14 | - ~~googlesamples/assistant/library: reference sample for the Google Assistant library~~ *deprecated* 15 | 16 | ## Contributing 17 | 18 | Contributions to this repository are always welcome and highly encouraged. 19 | 20 | See [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to get started. 21 | 22 | ## License 23 | 24 | Copyright (C) 2017 Google Inc. 25 | 26 | Licensed to the Apache Software Foundation (ASF) under one or more contributor 27 | license agreements. See the NOTICE file distributed with this work for 28 | additional information regarding copyright ownership. The ASF licenses this 29 | file to you under the Apache License, Version 2.0 (the "License"); you may not 30 | use this file except in compliance with the License. You may obtain a copy of 31 | the License at 32 | 33 | http://www.apache.org/licenses/LICENSE-2.0 34 | 35 | Unless required by applicable law or agreed to in writing, software 36 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 37 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 38 | License for the specific language governing permissions and limitations under 39 | the License. 40 | 41 | [python]: https://www.python.org 42 | [google-assistant-api]: https://developers.google.com/assistant/sdk/reference/rpc 43 | [google-assistant-sdk]: https://developers.google.com/assistant/sdk 44 | [getting-started-python]: https://developers.google.com/assistant/sdk/guides/service/python/ 45 | -------------------------------------------------------------------------------- /google-assistant-grpc/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.3.0 5 | ----- 6 | - Update Google Assistant Service usage restriction: non-commercial use. 7 | 8 | 9 | 0.2.1 10 | ----- 11 | - Update ``v1alpha2`` gRPC service definition: 12 | - Add new fields for AoG testing/debugging. 13 | 14 | 15 | 0.2.0 16 | ----- 17 | - Update ``v1alpha2`` gRPC service definition: 18 | - Add ScreenOut/ScreenOutConfig message. 19 | - Add is_new_conversation field. 20 | 21 | 22 | 0.1.0 23 | ----- 24 | - Add ``v1alpha2`` gRPC service definition. 25 | 26 | 27 | 0.0.2 28 | ----- 29 | - Bump ``grpcio`` dependency to use binary wheels (faster install on ``armv7l``). 30 | 31 | 32 | 0.0.1 33 | ----- 34 | - Initial release. 35 | -------------------------------------------------------------------------------- /google-assistant-grpc/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2014 The Android Open Source Project 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /google-assistant-grpc/MAINTAINER.md: -------------------------------------------------------------------------------- 1 | Maintainer guide 2 | ================ 3 | 4 | ## Prerequisites 5 | 6 | - Install automation tools 7 | 8 | pip install --upgrade nox 9 | 10 | ## Tasks 11 | 12 | - Install package with local modifications 13 | 14 | pip install -e . 15 | 16 | - Regenerate the python gRPC stubs 17 | 18 | git clone https://github.com/googleapis/googleapis 19 | nox -s protoc 20 | 21 | - Create a new `google_assistant_grpc` release in `dist` 22 | 23 | nox -s release 24 | -------------------------------------------------------------------------------- /google-assistant-grpc/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst LICENSE 2 | -------------------------------------------------------------------------------- /google-assistant-grpc/README.rst: -------------------------------------------------------------------------------- 1 | Google Assistant Service Bindings for Python 2 | ============================================= 3 | 4 | This package contains the generated Python_ bindings for the `Google Assistant Service`_. 5 | It is part of the `Google Assistant SDK`_. 6 | 7 | This package should be compatible with POSIX platforms supporting gRPC_ and Python_. 8 | 9 | .. note:: The Google Assistant Service is available for `non-commercial use`_. 10 | 11 | .. _Python: https://www.python.org/ 12 | .. _gRPC: https://www.grpc.io 13 | .. _Google Assistant Service: https://developers.google.com/assistant/sdk/guides/service/python/ 14 | .. _Google Assistant SDK: https://developers.google.com/assistant/sdk 15 | .. _non-commercial use: https://developers.google.com/assistant/sdk/terms-of-service 16 | 17 | Installing 18 | ---------- 19 | 20 | - You can install using `pip `_.:: 21 | 22 | pip install --upgrade google-assistant-grpc 23 | 24 | Authorization 25 | ------------- 26 | 27 | - Follow the steps to `configure the Actions Console project and the Google account `_. 28 | - Follow the steps to `register a new device model and download the client secrets file `_. 29 | - Generate device credentials using ``google-oauthlib-tool``: 30 | 31 | pip install --upgrade google-auth-oauthlib[tool] 32 | google-oauthlib-tool --client-secrets path/to/client_secret_.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype --save --headless 33 | 34 | - Load the device credentials using `google.oauth2.credentials `_.:: 35 | 36 | import io 37 | import google.oauth2.credentials 38 | 39 | with io.open('/path/to/credentials.json', 'r') as f: 40 | credentials = google.oauth2.credentials.Credentials(token=None, 41 | **json.load(f)) 42 | 43 | - Initialize the gRPC channel using `google.auth.transport.grpc `_. 44 | 45 | Usage 46 | ----- 47 | 48 | - Initialize the gRPC stubs using ``google.assistant.embedded.v1alpha1.embedded_assistant_pb2_grpc``.:: 49 | 50 | import google.assistant.embedded.v1alpha1.embedded_assistant_pb2_grpc 51 | assistant = embedded_assistant_pb2.EmbeddedAssistantStub(channel) 52 | 53 | - Call the `Assist`_ streaming method. It takes a generator of `AssistRequest`_ and returns a generator of `AssistResponse`_.:: 54 | 55 | assist_responses_generator = assistant.Assist(assist_requests_generator) 56 | start_acquiring_audio() 57 | 58 | - Send a `AssistRequest`_ message with audio configuration parameters followed by multiple outgoing `AssistRequest`_ messages containing the audio data of the Assistant request.:: 59 | 60 | import google.assistant.embedded.v1alpha1.embedded_assistant_pb2 61 | 62 | def generate_assist_requests(): 63 | yield embedded_assistant_pb2.AssistConfig( 64 | audio_in_config=embedded_assistant_pb2.AudioInConfig( 65 | encoding='LINEAR16', 66 | sample_rate_hertz=16000, 67 | ), 68 | audio_out_config=embedded_assistant_pb2.AudioOutConfig( 69 | encoding='LINEAR16', 70 | sample_rate_hertz=16000, 71 | ), 72 | device_config=embedded_assistant_pb2.DeviceConfig( 73 | device_id=device_id, 74 | device_model_id=device_model_id, 75 | ) 76 | ) 77 | for data in acquire_audio_data(): 78 | yield embedded_assistant_pb2.AssistRequest(audio_in=data) 79 | 80 | - Handle the incoming stream of `AssistResponse`_ messages: 81 | 82 | - Stop recording when receiving a `AssistResponse`_ with the `EventType`_ message set to ``END_OF_UTTERANCE``. 83 | - Get transcription of the user query from the `SpeechRecognitionResult`_ field. 84 | - Get conversation metadata like supplemental display text from the Assistant from the `DialogStateOut`_ field. 85 | - Extract the audio data of the Assistant response from the `AudioOut`_ field. 86 | 87 | :: 88 | 89 | for assist_response in assist_response_generator: 90 | if resp.event_type == END_OF_UTTERANCE: 91 | stop_acquiring_audio() 92 | if resp.speech_results: 93 | print(' '.join(r.transcript for r in resp.speech_results) 94 | if resp.dialog_state_out.supplemental_display_text: 95 | print(resp.dialog_state_out.supplemental_display_text) 96 | if len(resp.audio_out.audio_data) > 0: 97 | playback_audio_data(resp.audio_out.audio_data) 98 | 99 | 100 | .. _Assist: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#embeddedassistant 101 | .. _AssistRequest: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#google.assistant.embedded.v1alpha2.AssistRequest 102 | .. _AssistResponse: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#google.assistant.embedded.v1alpha2.AssistResponse 103 | .. _EventType: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#eventtype 104 | .. _AudioOut: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#google.assistant.embedded.v1alpha2.AudioOut 105 | .. _SpeechRecognitionResult: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#speechrecognitionresult 106 | .. _DialogStateOut: https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2#dialogstateout 107 | 108 | Reference 109 | --------- 110 | 111 | - `gRPC reference sample `_. 112 | - `Google Assistant Service reference `_. 113 | 114 | For Maintainers 115 | --------------- 116 | 117 | See `MAINTAINER.md `_ for more documentation on the 118 | development, maintainance and release of the Python package itself. 119 | 120 | License 121 | ------- 122 | 123 | Copyright (C) 2017 Google Inc. 124 | 125 | Licensed to the Apache Software Foundation (ASF) under one or more contributor 126 | license agreements. See the NOTICE file distributed with this work for 127 | additional information regarding copyright ownership. The ASF licenses this 128 | file to you under the Apache License, Version 2.0 (the "License"); you may not 129 | use this file except in compliance with the License. You may obtain a copy of 130 | the License at 131 | 132 | http://www.apache.org/licenses/LICENSE-2.0 133 | 134 | Unless required by applicable law or agreed to in writing, software 135 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 136 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 137 | License for the specific language governing permissions and limitations under 138 | the License. 139 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """google namespace package.""" 16 | 17 | try: 18 | import pkg_resources 19 | pkg_resources.declare_namespace(__name__) 20 | except ImportError: 21 | import pkgutil 22 | __path__ = pkgutil.extend_path(__path__, __name__) 23 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """google.assistant namespace package.""" 16 | 17 | try: 18 | import pkg_resources 19 | pkg_resources.declare_namespace(__name__) 20 | except ImportError: 21 | import pkgutil 22 | __path__ = pkgutil.extend_path(__path__, __name__) 23 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """google.assistant.embedded namespace package.""" 16 | 17 | try: 18 | import pkg_resources 19 | pkg_resources.declare_namespace(__name__) 20 | except ImportError: 21 | import pkgutil 22 | __path__ = pkgutil.extend_path(__path__, __name__) 23 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/v1alpha1/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/v1alpha1/embedded_assistant_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: google/assistant/embedded/v1alpha1/embedded_assistant.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 17 | from google.rpc import status_pb2 as google_dot_rpc_dot_status__pb2 18 | 19 | 20 | DESCRIPTOR = _descriptor.FileDescriptor( 21 | name='google/assistant/embedded/v1alpha1/embedded_assistant.proto', 22 | package='google.assistant.embedded.v1alpha1', 23 | syntax='proto3', 24 | serialized_pb=_b('\n;google/assistant/embedded/v1alpha1/embedded_assistant.proto\x12\"google.assistant.embedded.v1alpha1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/rpc/status.proto\"\xbe\x02\n\x0e\x43onverseConfig\x12J\n\x0f\x61udio_in_config\x18\x01 \x01(\x0b\x32\x31.google.assistant.embedded.v1alpha1.AudioInConfig\x12L\n\x10\x61udio_out_config\x18\x02 \x01(\x0b\x32\x32.google.assistant.embedded.v1alpha1.AudioOutConfig\x12I\n\x0e\x63onverse_state\x18\x03 \x01(\x0b\x32\x31.google.assistant.embedded.v1alpha1.ConverseState\x12G\n\rdevice_config\x18\x04 \x01(\x0b\x32\x30.google.assistant.embedded.v1alpha1.DeviceConfig\"\xb6\x01\n\rAudioInConfig\x12L\n\x08\x65ncoding\x18\x01 \x01(\x0e\x32:.google.assistant.embedded.v1alpha1.AudioInConfig.Encoding\x12\x19\n\x11sample_rate_hertz\x18\x02 \x01(\x05\"<\n\x08\x45ncoding\x12\x18\n\x14\x45NCODING_UNSPECIFIED\x10\x00\x12\x0c\n\x08LINEAR16\x10\x01\x12\x08\n\x04\x46LAC\x10\x02\"\xe3\x01\n\x0e\x41udioOutConfig\x12M\n\x08\x65ncoding\x18\x01 \x01(\x0e\x32;.google.assistant.embedded.v1alpha1.AudioOutConfig.Encoding\x12\x19\n\x11sample_rate_hertz\x18\x02 \x01(\x05\x12\x19\n\x11volume_percentage\x18\x03 \x01(\x05\"L\n\x08\x45ncoding\x12\x18\n\x14\x45NCODING_UNSPECIFIED\x10\x00\x12\x0c\n\x08LINEAR16\x10\x01\x12\x07\n\x03MP3\x10\x02\x12\x0f\n\x0bOPUS_IN_OGG\x10\x03\"+\n\rConverseState\x12\x1a\n\x12\x63onversation_state\x18\x01 \x01(\x0c\"\x1e\n\x08\x41udioOut\x12\x12\n\naudio_data\x18\x01 \x01(\x0c\"\xbd\x02\n\x0e\x43onverseResult\x12\x1b\n\x13spoken_request_text\x18\x01 \x01(\t\x12\x1c\n\x14spoken_response_text\x18\x02 \x01(\t\x12\x1a\n\x12\x63onversation_state\x18\x03 \x01(\x0c\x12Z\n\x0fmicrophone_mode\x18\x04 \x01(\x0e\x32\x41.google.assistant.embedded.v1alpha1.ConverseResult.MicrophoneMode\x12\x19\n\x11volume_percentage\x18\x05 \x01(\x05\"]\n\x0eMicrophoneMode\x12\x1f\n\x1bMICROPHONE_MODE_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43LOSE_MICROPHONE\x10\x01\x12\x14\n\x10\x44IALOG_FOLLOW_ON\x10\x02\"\x7f\n\x0f\x43onverseRequest\x12\x44\n\x06\x63onfig\x18\x01 \x01(\x0b\x32\x32.google.assistant.embedded.v1alpha1.ConverseConfigH\x00\x12\x12\n\x08\x61udio_in\x18\x02 \x01(\x0cH\x00\x42\x12\n\x10\x63onverse_request\"\xb5\x03\n\x10\x43onverseResponse\x12#\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x12.google.rpc.StatusH\x00\x12T\n\nevent_type\x18\x02 \x01(\x0e\x32>.google.assistant.embedded.v1alpha1.ConverseResponse.EventTypeH\x00\x12\x41\n\taudio_out\x18\x03 \x01(\x0b\x32,.google.assistant.embedded.v1alpha1.AudioOutH\x00\x12I\n\rdevice_action\x18\t \x01(\x0b\x32\x30.google.assistant.embedded.v1alpha1.DeviceActionH\x00\x12\x44\n\x06result\x18\x05 \x01(\x0b\x32\x32.google.assistant.embedded.v1alpha1.ConverseResultH\x00\"=\n\tEventType\x12\x1a\n\x16\x45VENT_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10\x45ND_OF_UTTERANCE\x10\x01\x42\x13\n\x11\x63onverse_response\":\n\x0c\x44\x65viceConfig\x12\x11\n\tdevice_id\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_model_id\x18\x03 \x01(\t\"+\n\x0c\x44\x65viceAction\x12\x1b\n\x13\x64\x65vice_request_json\x18\x02 \x01(\t2\x8e\x01\n\x11\x45mbeddedAssistant\x12y\n\x08\x43onverse\x12\x33.google.assistant.embedded.v1alpha1.ConverseRequest\x1a\x34.google.assistant.embedded.v1alpha1.ConverseResponse(\x01\x30\x01\x42\x86\x01\n&com.google.assistant.embedded.v1alpha1B\x0e\x41ssistantProtoP\x01ZJgoogle.golang.org/genproto/googleapis/assistant/embedded/v1alpha1;embeddedb\x06proto3') 25 | , 26 | dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_rpc_dot_status__pb2.DESCRIPTOR,]) 27 | 28 | 29 | 30 | _AUDIOINCONFIG_ENCODING = _descriptor.EnumDescriptor( 31 | name='Encoding', 32 | full_name='google.assistant.embedded.v1alpha1.AudioInConfig.Encoding', 33 | filename=None, 34 | file=DESCRIPTOR, 35 | values=[ 36 | _descriptor.EnumValueDescriptor( 37 | name='ENCODING_UNSPECIFIED', index=0, number=0, 38 | options=None, 39 | type=None), 40 | _descriptor.EnumValueDescriptor( 41 | name='LINEAR16', index=1, number=1, 42 | options=None, 43 | type=None), 44 | _descriptor.EnumValueDescriptor( 45 | name='FLAC', index=2, number=2, 46 | options=None, 47 | type=None), 48 | ], 49 | containing_type=None, 50 | options=None, 51 | serialized_start=598, 52 | serialized_end=658, 53 | ) 54 | _sym_db.RegisterEnumDescriptor(_AUDIOINCONFIG_ENCODING) 55 | 56 | _AUDIOOUTCONFIG_ENCODING = _descriptor.EnumDescriptor( 57 | name='Encoding', 58 | full_name='google.assistant.embedded.v1alpha1.AudioOutConfig.Encoding', 59 | filename=None, 60 | file=DESCRIPTOR, 61 | values=[ 62 | _descriptor.EnumValueDescriptor( 63 | name='ENCODING_UNSPECIFIED', index=0, number=0, 64 | options=None, 65 | type=None), 66 | _descriptor.EnumValueDescriptor( 67 | name='LINEAR16', index=1, number=1, 68 | options=None, 69 | type=None), 70 | _descriptor.EnumValueDescriptor( 71 | name='MP3', index=2, number=2, 72 | options=None, 73 | type=None), 74 | _descriptor.EnumValueDescriptor( 75 | name='OPUS_IN_OGG', index=3, number=3, 76 | options=None, 77 | type=None), 78 | ], 79 | containing_type=None, 80 | options=None, 81 | serialized_start=812, 82 | serialized_end=888, 83 | ) 84 | _sym_db.RegisterEnumDescriptor(_AUDIOOUTCONFIG_ENCODING) 85 | 86 | _CONVERSERESULT_MICROPHONEMODE = _descriptor.EnumDescriptor( 87 | name='MicrophoneMode', 88 | full_name='google.assistant.embedded.v1alpha1.ConverseResult.MicrophoneMode', 89 | filename=None, 90 | file=DESCRIPTOR, 91 | values=[ 92 | _descriptor.EnumValueDescriptor( 93 | name='MICROPHONE_MODE_UNSPECIFIED', index=0, number=0, 94 | options=None, 95 | type=None), 96 | _descriptor.EnumValueDescriptor( 97 | name='CLOSE_MICROPHONE', index=1, number=1, 98 | options=None, 99 | type=None), 100 | _descriptor.EnumValueDescriptor( 101 | name='DIALOG_FOLLOW_ON', index=2, number=2, 102 | options=None, 103 | type=None), 104 | ], 105 | containing_type=None, 106 | options=None, 107 | serialized_start=1192, 108 | serialized_end=1285, 109 | ) 110 | _sym_db.RegisterEnumDescriptor(_CONVERSERESULT_MICROPHONEMODE) 111 | 112 | _CONVERSERESPONSE_EVENTTYPE = _descriptor.EnumDescriptor( 113 | name='EventType', 114 | full_name='google.assistant.embedded.v1alpha1.ConverseResponse.EventType', 115 | filename=None, 116 | file=DESCRIPTOR, 117 | values=[ 118 | _descriptor.EnumValueDescriptor( 119 | name='EVENT_TYPE_UNSPECIFIED', index=0, number=0, 120 | options=None, 121 | type=None), 122 | _descriptor.EnumValueDescriptor( 123 | name='END_OF_UTTERANCE', index=1, number=1, 124 | options=None, 125 | type=None), 126 | ], 127 | containing_type=None, 128 | options=None, 129 | serialized_start=1772, 130 | serialized_end=1833, 131 | ) 132 | _sym_db.RegisterEnumDescriptor(_CONVERSERESPONSE_EVENTTYPE) 133 | 134 | 135 | _CONVERSECONFIG = _descriptor.Descriptor( 136 | name='ConverseConfig', 137 | full_name='google.assistant.embedded.v1alpha1.ConverseConfig', 138 | filename=None, 139 | file=DESCRIPTOR, 140 | containing_type=None, 141 | fields=[ 142 | _descriptor.FieldDescriptor( 143 | name='audio_in_config', full_name='google.assistant.embedded.v1alpha1.ConverseConfig.audio_in_config', index=0, 144 | number=1, type=11, cpp_type=10, label=1, 145 | has_default_value=False, default_value=None, 146 | message_type=None, enum_type=None, containing_type=None, 147 | is_extension=False, extension_scope=None, 148 | options=None), 149 | _descriptor.FieldDescriptor( 150 | name='audio_out_config', full_name='google.assistant.embedded.v1alpha1.ConverseConfig.audio_out_config', index=1, 151 | number=2, type=11, cpp_type=10, label=1, 152 | has_default_value=False, default_value=None, 153 | message_type=None, enum_type=None, containing_type=None, 154 | is_extension=False, extension_scope=None, 155 | options=None), 156 | _descriptor.FieldDescriptor( 157 | name='converse_state', full_name='google.assistant.embedded.v1alpha1.ConverseConfig.converse_state', index=2, 158 | number=3, type=11, cpp_type=10, label=1, 159 | has_default_value=False, default_value=None, 160 | message_type=None, enum_type=None, containing_type=None, 161 | is_extension=False, extension_scope=None, 162 | options=None), 163 | _descriptor.FieldDescriptor( 164 | name='device_config', full_name='google.assistant.embedded.v1alpha1.ConverseConfig.device_config', index=3, 165 | number=4, type=11, cpp_type=10, label=1, 166 | has_default_value=False, default_value=None, 167 | message_type=None, enum_type=None, containing_type=None, 168 | is_extension=False, extension_scope=None, 169 | options=None), 170 | ], 171 | extensions=[ 172 | ], 173 | nested_types=[], 174 | enum_types=[ 175 | ], 176 | options=None, 177 | is_extendable=False, 178 | syntax='proto3', 179 | extension_ranges=[], 180 | oneofs=[ 181 | ], 182 | serialized_start=155, 183 | serialized_end=473, 184 | ) 185 | 186 | 187 | _AUDIOINCONFIG = _descriptor.Descriptor( 188 | name='AudioInConfig', 189 | full_name='google.assistant.embedded.v1alpha1.AudioInConfig', 190 | filename=None, 191 | file=DESCRIPTOR, 192 | containing_type=None, 193 | fields=[ 194 | _descriptor.FieldDescriptor( 195 | name='encoding', full_name='google.assistant.embedded.v1alpha1.AudioInConfig.encoding', index=0, 196 | number=1, type=14, cpp_type=8, label=1, 197 | has_default_value=False, default_value=0, 198 | message_type=None, enum_type=None, containing_type=None, 199 | is_extension=False, extension_scope=None, 200 | options=None), 201 | _descriptor.FieldDescriptor( 202 | name='sample_rate_hertz', full_name='google.assistant.embedded.v1alpha1.AudioInConfig.sample_rate_hertz', index=1, 203 | number=2, type=5, cpp_type=1, label=1, 204 | has_default_value=False, default_value=0, 205 | message_type=None, enum_type=None, containing_type=None, 206 | is_extension=False, extension_scope=None, 207 | options=None), 208 | ], 209 | extensions=[ 210 | ], 211 | nested_types=[], 212 | enum_types=[ 213 | _AUDIOINCONFIG_ENCODING, 214 | ], 215 | options=None, 216 | is_extendable=False, 217 | syntax='proto3', 218 | extension_ranges=[], 219 | oneofs=[ 220 | ], 221 | serialized_start=476, 222 | serialized_end=658, 223 | ) 224 | 225 | 226 | _AUDIOOUTCONFIG = _descriptor.Descriptor( 227 | name='AudioOutConfig', 228 | full_name='google.assistant.embedded.v1alpha1.AudioOutConfig', 229 | filename=None, 230 | file=DESCRIPTOR, 231 | containing_type=None, 232 | fields=[ 233 | _descriptor.FieldDescriptor( 234 | name='encoding', full_name='google.assistant.embedded.v1alpha1.AudioOutConfig.encoding', index=0, 235 | number=1, type=14, cpp_type=8, label=1, 236 | has_default_value=False, default_value=0, 237 | message_type=None, enum_type=None, containing_type=None, 238 | is_extension=False, extension_scope=None, 239 | options=None), 240 | _descriptor.FieldDescriptor( 241 | name='sample_rate_hertz', full_name='google.assistant.embedded.v1alpha1.AudioOutConfig.sample_rate_hertz', index=1, 242 | number=2, type=5, cpp_type=1, label=1, 243 | has_default_value=False, default_value=0, 244 | message_type=None, enum_type=None, containing_type=None, 245 | is_extension=False, extension_scope=None, 246 | options=None), 247 | _descriptor.FieldDescriptor( 248 | name='volume_percentage', full_name='google.assistant.embedded.v1alpha1.AudioOutConfig.volume_percentage', index=2, 249 | number=3, type=5, cpp_type=1, label=1, 250 | has_default_value=False, default_value=0, 251 | message_type=None, enum_type=None, containing_type=None, 252 | is_extension=False, extension_scope=None, 253 | options=None), 254 | ], 255 | extensions=[ 256 | ], 257 | nested_types=[], 258 | enum_types=[ 259 | _AUDIOOUTCONFIG_ENCODING, 260 | ], 261 | options=None, 262 | is_extendable=False, 263 | syntax='proto3', 264 | extension_ranges=[], 265 | oneofs=[ 266 | ], 267 | serialized_start=661, 268 | serialized_end=888, 269 | ) 270 | 271 | 272 | _CONVERSESTATE = _descriptor.Descriptor( 273 | name='ConverseState', 274 | full_name='google.assistant.embedded.v1alpha1.ConverseState', 275 | filename=None, 276 | file=DESCRIPTOR, 277 | containing_type=None, 278 | fields=[ 279 | _descriptor.FieldDescriptor( 280 | name='conversation_state', full_name='google.assistant.embedded.v1alpha1.ConverseState.conversation_state', index=0, 281 | number=1, type=12, cpp_type=9, label=1, 282 | has_default_value=False, default_value=_b(""), 283 | message_type=None, enum_type=None, containing_type=None, 284 | is_extension=False, extension_scope=None, 285 | options=None), 286 | ], 287 | extensions=[ 288 | ], 289 | nested_types=[], 290 | enum_types=[ 291 | ], 292 | options=None, 293 | is_extendable=False, 294 | syntax='proto3', 295 | extension_ranges=[], 296 | oneofs=[ 297 | ], 298 | serialized_start=890, 299 | serialized_end=933, 300 | ) 301 | 302 | 303 | _AUDIOOUT = _descriptor.Descriptor( 304 | name='AudioOut', 305 | full_name='google.assistant.embedded.v1alpha1.AudioOut', 306 | filename=None, 307 | file=DESCRIPTOR, 308 | containing_type=None, 309 | fields=[ 310 | _descriptor.FieldDescriptor( 311 | name='audio_data', full_name='google.assistant.embedded.v1alpha1.AudioOut.audio_data', index=0, 312 | number=1, type=12, cpp_type=9, label=1, 313 | has_default_value=False, default_value=_b(""), 314 | message_type=None, enum_type=None, containing_type=None, 315 | is_extension=False, extension_scope=None, 316 | options=None), 317 | ], 318 | extensions=[ 319 | ], 320 | nested_types=[], 321 | enum_types=[ 322 | ], 323 | options=None, 324 | is_extendable=False, 325 | syntax='proto3', 326 | extension_ranges=[], 327 | oneofs=[ 328 | ], 329 | serialized_start=935, 330 | serialized_end=965, 331 | ) 332 | 333 | 334 | _CONVERSERESULT = _descriptor.Descriptor( 335 | name='ConverseResult', 336 | full_name='google.assistant.embedded.v1alpha1.ConverseResult', 337 | filename=None, 338 | file=DESCRIPTOR, 339 | containing_type=None, 340 | fields=[ 341 | _descriptor.FieldDescriptor( 342 | name='spoken_request_text', full_name='google.assistant.embedded.v1alpha1.ConverseResult.spoken_request_text', index=0, 343 | number=1, type=9, cpp_type=9, label=1, 344 | has_default_value=False, default_value=_b("").decode('utf-8'), 345 | message_type=None, enum_type=None, containing_type=None, 346 | is_extension=False, extension_scope=None, 347 | options=None), 348 | _descriptor.FieldDescriptor( 349 | name='spoken_response_text', full_name='google.assistant.embedded.v1alpha1.ConverseResult.spoken_response_text', index=1, 350 | number=2, type=9, cpp_type=9, label=1, 351 | has_default_value=False, default_value=_b("").decode('utf-8'), 352 | message_type=None, enum_type=None, containing_type=None, 353 | is_extension=False, extension_scope=None, 354 | options=None), 355 | _descriptor.FieldDescriptor( 356 | name='conversation_state', full_name='google.assistant.embedded.v1alpha1.ConverseResult.conversation_state', index=2, 357 | number=3, type=12, cpp_type=9, label=1, 358 | has_default_value=False, default_value=_b(""), 359 | message_type=None, enum_type=None, containing_type=None, 360 | is_extension=False, extension_scope=None, 361 | options=None), 362 | _descriptor.FieldDescriptor( 363 | name='microphone_mode', full_name='google.assistant.embedded.v1alpha1.ConverseResult.microphone_mode', index=3, 364 | number=4, type=14, cpp_type=8, label=1, 365 | has_default_value=False, default_value=0, 366 | message_type=None, enum_type=None, containing_type=None, 367 | is_extension=False, extension_scope=None, 368 | options=None), 369 | _descriptor.FieldDescriptor( 370 | name='volume_percentage', full_name='google.assistant.embedded.v1alpha1.ConverseResult.volume_percentage', index=4, 371 | number=5, type=5, cpp_type=1, label=1, 372 | has_default_value=False, default_value=0, 373 | message_type=None, enum_type=None, containing_type=None, 374 | is_extension=False, extension_scope=None, 375 | options=None), 376 | ], 377 | extensions=[ 378 | ], 379 | nested_types=[], 380 | enum_types=[ 381 | _CONVERSERESULT_MICROPHONEMODE, 382 | ], 383 | options=None, 384 | is_extendable=False, 385 | syntax='proto3', 386 | extension_ranges=[], 387 | oneofs=[ 388 | ], 389 | serialized_start=968, 390 | serialized_end=1285, 391 | ) 392 | 393 | 394 | _CONVERSEREQUEST = _descriptor.Descriptor( 395 | name='ConverseRequest', 396 | full_name='google.assistant.embedded.v1alpha1.ConverseRequest', 397 | filename=None, 398 | file=DESCRIPTOR, 399 | containing_type=None, 400 | fields=[ 401 | _descriptor.FieldDescriptor( 402 | name='config', full_name='google.assistant.embedded.v1alpha1.ConverseRequest.config', index=0, 403 | number=1, type=11, cpp_type=10, label=1, 404 | has_default_value=False, default_value=None, 405 | message_type=None, enum_type=None, containing_type=None, 406 | is_extension=False, extension_scope=None, 407 | options=None), 408 | _descriptor.FieldDescriptor( 409 | name='audio_in', full_name='google.assistant.embedded.v1alpha1.ConverseRequest.audio_in', index=1, 410 | number=2, type=12, cpp_type=9, label=1, 411 | has_default_value=False, default_value=_b(""), 412 | message_type=None, enum_type=None, containing_type=None, 413 | is_extension=False, extension_scope=None, 414 | options=None), 415 | ], 416 | extensions=[ 417 | ], 418 | nested_types=[], 419 | enum_types=[ 420 | ], 421 | options=None, 422 | is_extendable=False, 423 | syntax='proto3', 424 | extension_ranges=[], 425 | oneofs=[ 426 | _descriptor.OneofDescriptor( 427 | name='converse_request', full_name='google.assistant.embedded.v1alpha1.ConverseRequest.converse_request', 428 | index=0, containing_type=None, fields=[]), 429 | ], 430 | serialized_start=1287, 431 | serialized_end=1414, 432 | ) 433 | 434 | 435 | _CONVERSERESPONSE = _descriptor.Descriptor( 436 | name='ConverseResponse', 437 | full_name='google.assistant.embedded.v1alpha1.ConverseResponse', 438 | filename=None, 439 | file=DESCRIPTOR, 440 | containing_type=None, 441 | fields=[ 442 | _descriptor.FieldDescriptor( 443 | name='error', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.error', index=0, 444 | number=1, type=11, cpp_type=10, label=1, 445 | has_default_value=False, default_value=None, 446 | message_type=None, enum_type=None, containing_type=None, 447 | is_extension=False, extension_scope=None, 448 | options=None), 449 | _descriptor.FieldDescriptor( 450 | name='event_type', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.event_type', index=1, 451 | number=2, type=14, cpp_type=8, label=1, 452 | has_default_value=False, default_value=0, 453 | message_type=None, enum_type=None, containing_type=None, 454 | is_extension=False, extension_scope=None, 455 | options=None), 456 | _descriptor.FieldDescriptor( 457 | name='audio_out', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.audio_out', index=2, 458 | number=3, type=11, cpp_type=10, label=1, 459 | has_default_value=False, default_value=None, 460 | message_type=None, enum_type=None, containing_type=None, 461 | is_extension=False, extension_scope=None, 462 | options=None), 463 | _descriptor.FieldDescriptor( 464 | name='device_action', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.device_action', index=3, 465 | number=9, type=11, cpp_type=10, label=1, 466 | has_default_value=False, default_value=None, 467 | message_type=None, enum_type=None, containing_type=None, 468 | is_extension=False, extension_scope=None, 469 | options=None), 470 | _descriptor.FieldDescriptor( 471 | name='result', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.result', index=4, 472 | number=5, type=11, cpp_type=10, label=1, 473 | has_default_value=False, default_value=None, 474 | message_type=None, enum_type=None, containing_type=None, 475 | is_extension=False, extension_scope=None, 476 | options=None), 477 | ], 478 | extensions=[ 479 | ], 480 | nested_types=[], 481 | enum_types=[ 482 | _CONVERSERESPONSE_EVENTTYPE, 483 | ], 484 | options=None, 485 | is_extendable=False, 486 | syntax='proto3', 487 | extension_ranges=[], 488 | oneofs=[ 489 | _descriptor.OneofDescriptor( 490 | name='converse_response', full_name='google.assistant.embedded.v1alpha1.ConverseResponse.converse_response', 491 | index=0, containing_type=None, fields=[]), 492 | ], 493 | serialized_start=1417, 494 | serialized_end=1854, 495 | ) 496 | 497 | 498 | _DEVICECONFIG = _descriptor.Descriptor( 499 | name='DeviceConfig', 500 | full_name='google.assistant.embedded.v1alpha1.DeviceConfig', 501 | filename=None, 502 | file=DESCRIPTOR, 503 | containing_type=None, 504 | fields=[ 505 | _descriptor.FieldDescriptor( 506 | name='device_id', full_name='google.assistant.embedded.v1alpha1.DeviceConfig.device_id', index=0, 507 | number=1, type=9, cpp_type=9, label=1, 508 | has_default_value=False, default_value=_b("").decode('utf-8'), 509 | message_type=None, enum_type=None, containing_type=None, 510 | is_extension=False, extension_scope=None, 511 | options=None), 512 | _descriptor.FieldDescriptor( 513 | name='device_model_id', full_name='google.assistant.embedded.v1alpha1.DeviceConfig.device_model_id', index=1, 514 | number=3, type=9, cpp_type=9, label=1, 515 | has_default_value=False, default_value=_b("").decode('utf-8'), 516 | message_type=None, enum_type=None, containing_type=None, 517 | is_extension=False, extension_scope=None, 518 | options=None), 519 | ], 520 | extensions=[ 521 | ], 522 | nested_types=[], 523 | enum_types=[ 524 | ], 525 | options=None, 526 | is_extendable=False, 527 | syntax='proto3', 528 | extension_ranges=[], 529 | oneofs=[ 530 | ], 531 | serialized_start=1856, 532 | serialized_end=1914, 533 | ) 534 | 535 | 536 | _DEVICEACTION = _descriptor.Descriptor( 537 | name='DeviceAction', 538 | full_name='google.assistant.embedded.v1alpha1.DeviceAction', 539 | filename=None, 540 | file=DESCRIPTOR, 541 | containing_type=None, 542 | fields=[ 543 | _descriptor.FieldDescriptor( 544 | name='device_request_json', full_name='google.assistant.embedded.v1alpha1.DeviceAction.device_request_json', index=0, 545 | number=2, type=9, cpp_type=9, label=1, 546 | has_default_value=False, default_value=_b("").decode('utf-8'), 547 | message_type=None, enum_type=None, containing_type=None, 548 | is_extension=False, extension_scope=None, 549 | options=None), 550 | ], 551 | extensions=[ 552 | ], 553 | nested_types=[], 554 | enum_types=[ 555 | ], 556 | options=None, 557 | is_extendable=False, 558 | syntax='proto3', 559 | extension_ranges=[], 560 | oneofs=[ 561 | ], 562 | serialized_start=1916, 563 | serialized_end=1959, 564 | ) 565 | 566 | _CONVERSECONFIG.fields_by_name['audio_in_config'].message_type = _AUDIOINCONFIG 567 | _CONVERSECONFIG.fields_by_name['audio_out_config'].message_type = _AUDIOOUTCONFIG 568 | _CONVERSECONFIG.fields_by_name['converse_state'].message_type = _CONVERSESTATE 569 | _CONVERSECONFIG.fields_by_name['device_config'].message_type = _DEVICECONFIG 570 | _AUDIOINCONFIG.fields_by_name['encoding'].enum_type = _AUDIOINCONFIG_ENCODING 571 | _AUDIOINCONFIG_ENCODING.containing_type = _AUDIOINCONFIG 572 | _AUDIOOUTCONFIG.fields_by_name['encoding'].enum_type = _AUDIOOUTCONFIG_ENCODING 573 | _AUDIOOUTCONFIG_ENCODING.containing_type = _AUDIOOUTCONFIG 574 | _CONVERSERESULT.fields_by_name['microphone_mode'].enum_type = _CONVERSERESULT_MICROPHONEMODE 575 | _CONVERSERESULT_MICROPHONEMODE.containing_type = _CONVERSERESULT 576 | _CONVERSEREQUEST.fields_by_name['config'].message_type = _CONVERSECONFIG 577 | _CONVERSEREQUEST.oneofs_by_name['converse_request'].fields.append( 578 | _CONVERSEREQUEST.fields_by_name['config']) 579 | _CONVERSEREQUEST.fields_by_name['config'].containing_oneof = _CONVERSEREQUEST.oneofs_by_name['converse_request'] 580 | _CONVERSEREQUEST.oneofs_by_name['converse_request'].fields.append( 581 | _CONVERSEREQUEST.fields_by_name['audio_in']) 582 | _CONVERSEREQUEST.fields_by_name['audio_in'].containing_oneof = _CONVERSEREQUEST.oneofs_by_name['converse_request'] 583 | _CONVERSERESPONSE.fields_by_name['error'].message_type = google_dot_rpc_dot_status__pb2._STATUS 584 | _CONVERSERESPONSE.fields_by_name['event_type'].enum_type = _CONVERSERESPONSE_EVENTTYPE 585 | _CONVERSERESPONSE.fields_by_name['audio_out'].message_type = _AUDIOOUT 586 | _CONVERSERESPONSE.fields_by_name['device_action'].message_type = _DEVICEACTION 587 | _CONVERSERESPONSE.fields_by_name['result'].message_type = _CONVERSERESULT 588 | _CONVERSERESPONSE_EVENTTYPE.containing_type = _CONVERSERESPONSE 589 | _CONVERSERESPONSE.oneofs_by_name['converse_response'].fields.append( 590 | _CONVERSERESPONSE.fields_by_name['error']) 591 | _CONVERSERESPONSE.fields_by_name['error'].containing_oneof = _CONVERSERESPONSE.oneofs_by_name['converse_response'] 592 | _CONVERSERESPONSE.oneofs_by_name['converse_response'].fields.append( 593 | _CONVERSERESPONSE.fields_by_name['event_type']) 594 | _CONVERSERESPONSE.fields_by_name['event_type'].containing_oneof = _CONVERSERESPONSE.oneofs_by_name['converse_response'] 595 | _CONVERSERESPONSE.oneofs_by_name['converse_response'].fields.append( 596 | _CONVERSERESPONSE.fields_by_name['audio_out']) 597 | _CONVERSERESPONSE.fields_by_name['audio_out'].containing_oneof = _CONVERSERESPONSE.oneofs_by_name['converse_response'] 598 | _CONVERSERESPONSE.oneofs_by_name['converse_response'].fields.append( 599 | _CONVERSERESPONSE.fields_by_name['device_action']) 600 | _CONVERSERESPONSE.fields_by_name['device_action'].containing_oneof = _CONVERSERESPONSE.oneofs_by_name['converse_response'] 601 | _CONVERSERESPONSE.oneofs_by_name['converse_response'].fields.append( 602 | _CONVERSERESPONSE.fields_by_name['result']) 603 | _CONVERSERESPONSE.fields_by_name['result'].containing_oneof = _CONVERSERESPONSE.oneofs_by_name['converse_response'] 604 | DESCRIPTOR.message_types_by_name['ConverseConfig'] = _CONVERSECONFIG 605 | DESCRIPTOR.message_types_by_name['AudioInConfig'] = _AUDIOINCONFIG 606 | DESCRIPTOR.message_types_by_name['AudioOutConfig'] = _AUDIOOUTCONFIG 607 | DESCRIPTOR.message_types_by_name['ConverseState'] = _CONVERSESTATE 608 | DESCRIPTOR.message_types_by_name['AudioOut'] = _AUDIOOUT 609 | DESCRIPTOR.message_types_by_name['ConverseResult'] = _CONVERSERESULT 610 | DESCRIPTOR.message_types_by_name['ConverseRequest'] = _CONVERSEREQUEST 611 | DESCRIPTOR.message_types_by_name['ConverseResponse'] = _CONVERSERESPONSE 612 | DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG 613 | DESCRIPTOR.message_types_by_name['DeviceAction'] = _DEVICEACTION 614 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 615 | 616 | ConverseConfig = _reflection.GeneratedProtocolMessageType('ConverseConfig', (_message.Message,), dict( 617 | DESCRIPTOR = _CONVERSECONFIG, 618 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 619 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.ConverseConfig) 620 | )) 621 | _sym_db.RegisterMessage(ConverseConfig) 622 | 623 | AudioInConfig = _reflection.GeneratedProtocolMessageType('AudioInConfig', (_message.Message,), dict( 624 | DESCRIPTOR = _AUDIOINCONFIG, 625 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 626 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.AudioInConfig) 627 | )) 628 | _sym_db.RegisterMessage(AudioInConfig) 629 | 630 | AudioOutConfig = _reflection.GeneratedProtocolMessageType('AudioOutConfig', (_message.Message,), dict( 631 | DESCRIPTOR = _AUDIOOUTCONFIG, 632 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 633 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.AudioOutConfig) 634 | )) 635 | _sym_db.RegisterMessage(AudioOutConfig) 636 | 637 | ConverseState = _reflection.GeneratedProtocolMessageType('ConverseState', (_message.Message,), dict( 638 | DESCRIPTOR = _CONVERSESTATE, 639 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 640 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.ConverseState) 641 | )) 642 | _sym_db.RegisterMessage(ConverseState) 643 | 644 | AudioOut = _reflection.GeneratedProtocolMessageType('AudioOut', (_message.Message,), dict( 645 | DESCRIPTOR = _AUDIOOUT, 646 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 647 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.AudioOut) 648 | )) 649 | _sym_db.RegisterMessage(AudioOut) 650 | 651 | ConverseResult = _reflection.GeneratedProtocolMessageType('ConverseResult', (_message.Message,), dict( 652 | DESCRIPTOR = _CONVERSERESULT, 653 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 654 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.ConverseResult) 655 | )) 656 | _sym_db.RegisterMessage(ConverseResult) 657 | 658 | ConverseRequest = _reflection.GeneratedProtocolMessageType('ConverseRequest', (_message.Message,), dict( 659 | DESCRIPTOR = _CONVERSEREQUEST, 660 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 661 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.ConverseRequest) 662 | )) 663 | _sym_db.RegisterMessage(ConverseRequest) 664 | 665 | ConverseResponse = _reflection.GeneratedProtocolMessageType('ConverseResponse', (_message.Message,), dict( 666 | DESCRIPTOR = _CONVERSERESPONSE, 667 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 668 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.ConverseResponse) 669 | )) 670 | _sym_db.RegisterMessage(ConverseResponse) 671 | 672 | DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), dict( 673 | DESCRIPTOR = _DEVICECONFIG, 674 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 675 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.DeviceConfig) 676 | )) 677 | _sym_db.RegisterMessage(DeviceConfig) 678 | 679 | DeviceAction = _reflection.GeneratedProtocolMessageType('DeviceAction', (_message.Message,), dict( 680 | DESCRIPTOR = _DEVICEACTION, 681 | __module__ = 'google.assistant.embedded.v1alpha1.embedded_assistant_pb2' 682 | # @@protoc_insertion_point(class_scope:google.assistant.embedded.v1alpha1.DeviceAction) 683 | )) 684 | _sym_db.RegisterMessage(DeviceAction) 685 | 686 | 687 | DESCRIPTOR.has_options = True 688 | DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n&com.google.assistant.embedded.v1alpha1B\016AssistantProtoP\001ZJgoogle.golang.org/genproto/googleapis/assistant/embedded/v1alpha1;embedded')) 689 | 690 | _EMBEDDEDASSISTANT = _descriptor.ServiceDescriptor( 691 | name='EmbeddedAssistant', 692 | full_name='google.assistant.embedded.v1alpha1.EmbeddedAssistant', 693 | file=DESCRIPTOR, 694 | index=0, 695 | options=None, 696 | serialized_start=1962, 697 | serialized_end=2104, 698 | methods=[ 699 | _descriptor.MethodDescriptor( 700 | name='Converse', 701 | full_name='google.assistant.embedded.v1alpha1.EmbeddedAssistant.Converse', 702 | index=0, 703 | containing_service=None, 704 | input_type=_CONVERSEREQUEST, 705 | output_type=_CONVERSERESPONSE, 706 | options=None, 707 | ), 708 | ]) 709 | _sym_db.RegisterServiceDescriptor(_EMBEDDEDASSISTANT) 710 | 711 | DESCRIPTOR.services_by_name['EmbeddedAssistant'] = _EMBEDDEDASSISTANT 712 | 713 | # @@protoc_insertion_point(module_scope) 714 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/v1alpha1/embedded_assistant_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | from google.assistant.embedded.v1alpha1 import embedded_assistant_pb2 as google_dot_assistant_dot_embedded_dot_v1alpha1_dot_embedded__assistant__pb2 5 | 6 | 7 | class EmbeddedAssistantStub(object): 8 | """Service that implements Google Assistant API. 9 | """ 10 | 11 | def __init__(self, channel): 12 | """Constructor. 13 | 14 | Args: 15 | channel: A grpc.Channel. 16 | """ 17 | self.Converse = channel.stream_stream( 18 | '/google.assistant.embedded.v1alpha1.EmbeddedAssistant/Converse', 19 | request_serializer=google_dot_assistant_dot_embedded_dot_v1alpha1_dot_embedded__assistant__pb2.ConverseRequest.SerializeToString, 20 | response_deserializer=google_dot_assistant_dot_embedded_dot_v1alpha1_dot_embedded__assistant__pb2.ConverseResponse.FromString, 21 | ) 22 | 23 | 24 | class EmbeddedAssistantServicer(object): 25 | """Service that implements Google Assistant API. 26 | """ 27 | 28 | def Converse(self, request_iterator, context): 29 | """Initiates or continues a conversation with the embedded assistant service. 30 | Each call performs one round-trip, sending an audio request to the service 31 | and receiving the audio response. Uses bidirectional streaming to receive 32 | results, such as the `END_OF_UTTERANCE` event, while sending audio. 33 | 34 | A conversation is one or more gRPC connections, each consisting of several 35 | streamed requests and responses. 36 | For example, the user says *Add to my shopping list* and the assistant 37 | responds *What do you want to add?*. The sequence of streamed requests and 38 | responses in the first gRPC message could be: 39 | 40 | * ConverseRequest.config 41 | * ConverseRequest.audio_in 42 | * ConverseRequest.audio_in 43 | * ConverseRequest.audio_in 44 | * ConverseRequest.audio_in 45 | * ConverseResponse.event_type.END_OF_UTTERANCE 46 | * ConverseResponse.result.spoken_request_text "add to my shopping list" 47 | * ConverseResponse.result.microphone_mode.DIALOG_FOLLOW_ON 48 | * ConverseResponse.audio_out 49 | * ConverseResponse.audio_out 50 | * ConverseResponse.audio_out 51 | 52 | 53 | The user then says *bagels* and the assistant responds 54 | *OK, I've added bagels to your shopping list*. This is sent as another gRPC 55 | connection call to the `Converse` method, again with streamed requests and 56 | responses, such as: 57 | 58 | * ConverseRequest.config 59 | * ConverseRequest.audio_in 60 | * ConverseRequest.audio_in 61 | * ConverseRequest.audio_in 62 | * ConverseResponse.event_type.END_OF_UTTERANCE 63 | * ConverseResponse.result.microphone_mode.CLOSE_MICROPHONE 64 | * ConverseResponse.audio_out 65 | * ConverseResponse.audio_out 66 | * ConverseResponse.audio_out 67 | * ConverseResponse.audio_out 68 | 69 | Although the precise order of responses is not guaranteed, sequential 70 | ConverseResponse.audio_out messages will always contain sequential portions 71 | of audio. 72 | """ 73 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 74 | context.set_details('Method not implemented!') 75 | raise NotImplementedError('Method not implemented!') 76 | 77 | 78 | def add_EmbeddedAssistantServicer_to_server(servicer, server): 79 | rpc_method_handlers = { 80 | 'Converse': grpc.stream_stream_rpc_method_handler( 81 | servicer.Converse, 82 | request_deserializer=google_dot_assistant_dot_embedded_dot_v1alpha1_dot_embedded__assistant__pb2.ConverseRequest.FromString, 83 | response_serializer=google_dot_assistant_dot_embedded_dot_v1alpha1_dot_embedded__assistant__pb2.ConverseResponse.SerializeToString, 84 | ), 85 | } 86 | generic_handler = grpc.method_handlers_generic_handler( 87 | 'google.assistant.embedded.v1alpha1.EmbeddedAssistant', rpc_method_handlers) 88 | server.add_generic_rpc_handlers((generic_handler,)) 89 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/v1alpha2/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /google-assistant-grpc/google/assistant/embedded/v1alpha2/embedded_assistant_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | from google.assistant.embedded.v1alpha2 import embedded_assistant_pb2 as google_dot_assistant_dot_embedded_dot_v1alpha2_dot_embedded__assistant__pb2 5 | 6 | 7 | class EmbeddedAssistantStub(object): 8 | """Service that implements the Google Assistant API. 9 | """ 10 | 11 | def __init__(self, channel): 12 | """Constructor. 13 | 14 | Args: 15 | channel: A grpc.Channel. 16 | """ 17 | self.Assist = channel.stream_stream( 18 | '/google.assistant.embedded.v1alpha2.EmbeddedAssistant/Assist', 19 | request_serializer=google_dot_assistant_dot_embedded_dot_v1alpha2_dot_embedded__assistant__pb2.AssistRequest.SerializeToString, 20 | response_deserializer=google_dot_assistant_dot_embedded_dot_v1alpha2_dot_embedded__assistant__pb2.AssistResponse.FromString, 21 | ) 22 | 23 | 24 | class EmbeddedAssistantServicer(object): 25 | """Service that implements the Google Assistant API. 26 | """ 27 | 28 | def Assist(self, request_iterator, context): 29 | """Initiates or continues a conversation with the embedded Assistant Service. 30 | Each call performs one round-trip, sending an audio request to the service 31 | and receiving the audio response. Uses bidirectional streaming to receive 32 | results, such as the `END_OF_UTTERANCE` event, while sending audio. 33 | 34 | A conversation is one or more gRPC connections, each consisting of several 35 | streamed requests and responses. 36 | For example, the user says *Add to my shopping list* and the Assistant 37 | responds *What do you want to add?*. The sequence of streamed requests and 38 | responses in the first gRPC message could be: 39 | 40 | * AssistRequest.config 41 | * AssistRequest.audio_in 42 | * AssistRequest.audio_in 43 | * AssistRequest.audio_in 44 | * AssistRequest.audio_in 45 | * AssistResponse.event_type.END_OF_UTTERANCE 46 | * AssistResponse.speech_results.transcript "add to my shopping list" 47 | * AssistResponse.dialog_state_out.microphone_mode.DIALOG_FOLLOW_ON 48 | * AssistResponse.audio_out 49 | * AssistResponse.audio_out 50 | * AssistResponse.audio_out 51 | 52 | 53 | The user then says *bagels* and the Assistant responds 54 | *OK, I've added bagels to your shopping list*. This is sent as another gRPC 55 | connection call to the `Assist` method, again with streamed requests and 56 | responses, such as: 57 | 58 | * AssistRequest.config 59 | * AssistRequest.audio_in 60 | * AssistRequest.audio_in 61 | * AssistRequest.audio_in 62 | * AssistResponse.event_type.END_OF_UTTERANCE 63 | * AssistResponse.dialog_state_out.microphone_mode.CLOSE_MICROPHONE 64 | * AssistResponse.audio_out 65 | * AssistResponse.audio_out 66 | * AssistResponse.audio_out 67 | * AssistResponse.audio_out 68 | 69 | Although the precise order of responses is not guaranteed, sequential 70 | `AssistResponse.audio_out` messages will always contain sequential portions 71 | of audio. 72 | """ 73 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 74 | context.set_details('Method not implemented!') 75 | raise NotImplementedError('Method not implemented!') 76 | 77 | 78 | def add_EmbeddedAssistantServicer_to_server(servicer, server): 79 | rpc_method_handlers = { 80 | 'Assist': grpc.stream_stream_rpc_method_handler( 81 | servicer.Assist, 82 | request_deserializer=google_dot_assistant_dot_embedded_dot_v1alpha2_dot_embedded__assistant__pb2.AssistRequest.FromString, 83 | response_serializer=google_dot_assistant_dot_embedded_dot_v1alpha2_dot_embedded__assistant__pb2.AssistResponse.SerializeToString, 84 | ), 85 | } 86 | generic_handler = grpc.method_handlers_generic_handler( 87 | 'google.assistant.embedded.v1alpha2.EmbeddedAssistant', rpc_method_handlers) 88 | server.add_generic_rpc_handlers((generic_handler,)) 89 | -------------------------------------------------------------------------------- /google-assistant-grpc/noxfile.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | import nox 18 | 19 | 20 | @nox.session(python=["3"]) 21 | def lint(session): 22 | session.install('pip', 'setuptools') 23 | session.install('docutils', 'flake8', 'readme_renderer') 24 | session.run('flake8', 'nox.py', 'setup.py') 25 | session.run('python', 'setup.py', 'check', 26 | '--restructuredtext', '--strict') 27 | 28 | 29 | @nox.session 30 | def protoc(session): 31 | session.install('pip', 'setuptools') 32 | session.install('grpcio-tools') 33 | if os.path.exists('proto'): 34 | session.run('python', '-m', 'grpc_tools.protoc', 35 | '--proto_path=proto', 36 | '--proto_path=googleapis', 37 | '--python_out=.', 38 | '--grpc_python_out=.', 39 | 'proto/google/assistant/embedded/v1alpha2/' 40 | 'embedded_assistant.proto',) 41 | else: 42 | session.run('python', '-m', 'grpc_tools.protoc', 43 | '--proto_path=googleapis', 44 | '--python_out=.', 45 | '--grpc_python_out=.', 46 | 'googleapis/google/assistant/embedded/v1alpha2/' 47 | 'embedded_assistant.proto') 48 | 49 | 50 | @nox.session 51 | def release(session): 52 | session.install('pip', 'setuptools', 'wheel') 53 | session.run('python', 'setup.py', 'sdist', 'bdist_wheel') 54 | session.run('python', 'setup.py', 'sdist', 'bdist_wheel') 55 | -------------------------------------------------------------------------------- /google-assistant-grpc/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | 4 | [flake8] 5 | show-source = 1 6 | exclude = google/assistant/embedded/v1alpha1 7 | -------------------------------------------------------------------------------- /google-assistant-grpc/setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from setuptools import setup, find_packages 16 | import io 17 | 18 | install_requires = [ 19 | 'googleapis-common-protos>=1.5.2', 20 | 'grpcio>=1.3.5', 21 | ] 22 | 23 | with io.open('README.rst', 'r') as fh: 24 | long_description = fh.read() 25 | 26 | setup( 27 | name='google-assistant-grpc', 28 | version='0.3.0', 29 | author='Google Assistant SDK team', 30 | author_email='proppy+assistant-sdk@google.com', 31 | description='Google Assistant API gRPC bindings', 32 | long_description=long_description, 33 | url='https://github.com/googlesamples/assistant-sdk-python', 34 | packages=find_packages(), 35 | namespace_packages=[ 36 | 'google', 37 | 'google.assistant', 38 | 'google.assistant.embedded', 39 | ], 40 | install_requires=install_requires, 41 | license='Apache 2.0', 42 | keywords='google assistant api grpc', 43 | classifiers=( 44 | 'Programming Language :: Python :: 2', 45 | 'Programming Language :: Python :: 2.7', 46 | 'Programming Language :: Python :: 3', 47 | 'Programming Language :: Python :: 3.4', 48 | 'Programming Language :: Python :: 3.5', 49 | 'Development Status :: 4 - Beta', 50 | 'Intended Audience :: Developers', 51 | 'License :: OSI Approved :: Apache Software License', 52 | 'Operating System :: POSIX', 53 | 'Operating System :: Microsoft :: Windows', 54 | 'Operating System :: MacOS :: MacOS X', 55 | 'Operating System :: OS Independent', 56 | 'Topic :: Internet :: WWW/HTTP', 57 | ), 58 | ) 59 | -------------------------------------------------------------------------------- /google-assistant-sdk/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.6.0 5 | ----- 6 | - Deprecate Google Assistant Library. 7 | - Update Google Assistant Service usage restriction: non-commercial use. 8 | 9 | 10 | 0.5.1 11 | ----- 12 | - Fix Python generator termination. 13 | - Lint/Fix README.rst. 14 | - Make device action keys uppercase. 15 | - Add `query` and `nickname` flag to library sample. 16 | 17 | 18 | 0.5.0 19 | ----- 20 | - Add HTML output. 21 | - Add simpler file i/o sample. 22 | - Fix crash with empty audio query. 23 | 24 | 25 | 0.4.4 26 | ----- 27 | - Fix DeviceHandler initialization issue. 28 | - Add example action packages for custom device actions. 29 | - Better feedback on device registration. 30 | 31 | 32 | 0.4.3 33 | ----- 34 | - Fix Python 2.7/3.6 compatibility for ``pushtotalk`` and ``hotword`` sample. 35 | 36 | 37 | 0.4.2 38 | ----- 39 | - Add client type for ``pushtotalk`` registration. 40 | 41 | 42 | 0.4.1 43 | ----- 44 | - Update outdated ``hotword`` sample. 45 | 46 | 47 | 0.4.0 48 | ----- 49 | - Add Device actions handling to samples. 50 | - Update ``pushtotalk`` sample to ``v1alpha2`` of Google Assistant Service. 51 | - Add language selection to ``pushtotalk`` sample. 52 | - New ``textinput`` sample for the Google Assistant Service. 53 | - New ``devicetool`` tool for device registration. 54 | 55 | 56 | 0.3.3 57 | ----- 58 | - Update Google Assistant Library from 0.0.2 to 0.0.3 59 | 60 | 61 | 0.3.2 62 | ----- 63 | - Bump urllib3 dependency. 64 | 65 | 66 | 0.3.1 67 | ----- 68 | - Bump dependencies to use new ``google-assistant-grpc`` package (faster install). 69 | 70 | 71 | 0.3.0 72 | ----- 73 | - Move grpc bindings to the `google-assistant-grpc `_ package. 74 | - Moved reference grpc sample to ``googlesamples.assistant.grpc.pushtotalk`` with `updated instructions `_. 75 | - Replaced ``auth_helpers`` with ``google-oauthlibtool``: 76 | 77 | - Follow the `updated instructions `_ to generate and use new credentials. 78 | 79 | - Add ``--once`` flag to pushtotalk grpc sample (@r-clancy). 80 | - Fix typo in IFTTT handling in pushtotalk grpc sample (@kadeve). 81 | - Add ``google-assistant-library`` package `installation instructions `_ and `sample `_. 82 | 83 | 84 | 0.2.1 85 | ----- 86 | - Fix audio helpers. 87 | 88 | 89 | 0.2.0 90 | ----- 91 | - Add basic travis config. 92 | - Add retry logic. 93 | - Implement volume control. 94 | 95 | 96 | 0.1.0 97 | ----- 98 | - Initial release. 99 | -------------------------------------------------------------------------------- /google-assistant-sdk/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2014 The Android Open Source Project 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /google-assistant-sdk/MAINTAINER.md: -------------------------------------------------------------------------------- 1 | Maintainer guide 2 | ================ 3 | 4 | ## Prerequisites 5 | 6 | - Install automation tools 7 | 8 | pip install --upgrade nox 9 | 10 | ## Tasks 11 | 12 | - Install package with local modifications 13 | 14 | pip install -e .[samples] 15 | 16 | - Run lint tool 17 | 18 | nox -s lint 19 | 20 | - Run unit tests 21 | 22 | nox -s unittest 23 | 24 | - Create a new `google_assistant_sdk` release in `dist` 25 | 26 | nox -s release 27 | -------------------------------------------------------------------------------- /google-assistant-sdk/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst CHANGELOG.rst LICENSE 2 | recursive-include tests * 3 | -------------------------------------------------------------------------------- /google-assistant-sdk/README.rst: -------------------------------------------------------------------------------- 1 | Google Assistant SDK for devices - Python 2 | ========================================= 3 | 4 | This package contains a collection of samples and tools to help you 5 | get started with the `Google Assistant SDK`_ using `Python`_. 6 | 7 | Installing 8 | ---------- 9 | 10 | - You can install using `pip`_:: 11 | 12 | pip install --upgrade google-assistant-sdk[samples] 13 | 14 | Usage 15 | ----- 16 | 17 | google-oauthlib-tool 18 | ~~~~~~~~~~~~~~~~~~~~ 19 | 20 | This tool creates test credentials to authorize devices to call the 21 | Google Assistant Service when prototyping. 22 | 23 | - Follow the steps to `configure the Actions Console project and the Google account `_. 24 | - Follow the steps to `register a new device model and download the client secrets file `_. 25 | - Generate device credentials using ``google-oauthlib-tool``: 26 | 27 | pip install --upgrade google-auth-oauthlib[tool] 28 | google-oauthlib-tool --client-secrets path/to/client_secret_.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype --save --headless 29 | 30 | googlesamples-assistant-audiotest 31 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 | 33 | This tool verifies device setup for audio recording and playback. 34 | 35 | - Install the sample's dependencies:: 36 | 37 | sudo apt-get install portaudio19-dev libffi-dev libssl-dev 38 | pip install --upgrade google-assistant-sdk[samples] 39 | 40 | - Record 10 seconds of audio samples and play them back:: 41 | 42 | googlesamples-assistant-audiotest --record-time 10 43 | 44 | - Adjust the sound device block size and flush size for a soundcard with limited throughput:: 45 | 46 | googlesamples-assistant-audiotest --record-time 10 --audio-block-size=3200 --audio-flush-size=6400 47 | 48 | The same ``--audio-block-size`` and ``--audio-flush-size`` options can 49 | be used on the ``gRPC`` samples included in the SDK. 50 | 51 | googlesamples-assistant-devicetool 52 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 53 | 54 | This tool allows you to register Google Assistant device models and 55 | instances and associate them with Device Actions traits. 56 | 57 | - Install the sample's dependencies:: 58 | 59 | sudo apt-get install portaudio19-dev libffi-dev libssl-dev 60 | pip install --upgrade google-assistant-sdk[samples] 61 | 62 | - Show the CLI tool usage:: 63 | 64 | googlesamples-assistant-devicetool --help 65 | 66 | - Register a new device model and new device instance (after replacing the 'placeholder values' between quotes):: 67 | 68 | googlesamples-assistant-devicetool --project-id PROJECT_ID register --model 'my-model-identifier' \ 69 | --type LIGHT --trait action.devices.traits.OnOff \ 70 | --manufacturer 'Assistant SDK developer' \ 71 | --product-name 'Assistant SDK light' \ 72 | --description 'Assistant SDK light device' \ 73 | --device 'my-device-identifier' \ 74 | --nickname 'My Assistant Light' 75 | 76 | - Register or overwrite the device model with the supported traits (after replacing the 'placeholder values' between quotes):: 77 | 78 | googlesamples-assistant-devicetool --project-id PROJECT_ID register-model --model 'my-model-identifier' \ 79 | --type LIGHT --trait action.devices.traits.OnOff \ 80 | --manufacturer 'Assistant SDK developer' \ 81 | --product-name 'Assistant SDK light' \ 82 | --description 'Assistant SDK light device' 83 | 84 | *Note: The model identifier must be globally unique.* 85 | 86 | - Register or overwrite the device instance using the device model (after replacing the 'placeholder values' between quotes):: 87 | 88 | googlesamples-assistant-devicetool --project-id PROJECT_ID register-device --device 'my-device-identifier' \ 89 | --model 'my-model-identifier' \ 90 | --nickname 'My Assistant Light' 91 | 92 | *Note: The device instance identifier should be unique within the Google Developer Project associated with the device.* 93 | 94 | - Verify that the device model and instance have been registered correctly:: 95 | 96 | googlesamples-assistant-devicetool --project-id PROJECT_ID get --model 'my-model-identifier' 97 | googlesamples-assistant-devicetool --project-id PROJECT_ID get --device 'my-device-identifier' 98 | 99 | - List all device models and instances:: 100 | 101 | googlesamples-assistant-devicetool --project-id PROJECT_ID list --model 102 | googlesamples-assistant-devicetool --project-id PROJECT_ID list --device 103 | 104 | googlesamples-assistant-pushtotalk 105 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 | 107 | This reference sample implements a simple but functional client for the `Google Assistant Service`_. 108 | 109 | - Install the sample's dependencies:: 110 | 111 | sudo apt-get install portaudio19-dev libffi-dev libssl-dev 112 | pip install --upgrade google-assistant-sdk[samples] 113 | 114 | - Run the push to talk sample. The sample records a voice query after a key press and plays back the Google Assistant's answer:: 115 | 116 | googlesamples-assistant-pushtotalk --device-model-id 'my-device-model' --device-id 'my-device-identifier' 117 | 118 | - Try some Google Assistant voice query like "What time is it?" or "Who am I?". 119 | 120 | - Try a device action query like "Turn on". 121 | 122 | - Run in verbose mode to see the gRPC communication with the Google Assistant Service:: 123 | 124 | googlesamples-assistant-pushtotalk --device-model-id 'my-device-model' --device-id 'my-device-identifier' -v 125 | 126 | Also see the `grpc sample README `_. 127 | 128 | For Maintainers 129 | --------------- 130 | 131 | See `MAINTAINER.md `_ for more documentation on the 132 | development, maintainance and release of the Python package itself. 133 | 134 | Contributing 135 | ------------ 136 | 137 | Contributions to this repository are always welcome and highly encouraged. 138 | 139 | See `CONTRIBUTING.md `_ for more information on how to get started. 140 | 141 | License 142 | ------- 143 | 144 | Copyright (C) 2017 Google Inc. 145 | 146 | Licensed to the Apache Software Foundation (ASF) under one or more contributor 147 | license agreements. See the NOTICE file distributed with this work for 148 | additional information regarding copyright ownership. The ASF licenses this 149 | file to you under the Apache License, Version 2.0 (the "License"); you may not 150 | use this file except in compliance with the License. You may obtain a copy of 151 | the License at 152 | 153 | http://www.apache.org/licenses/LICENSE-2.0 154 | 155 | Unless required by applicable law or agreed to in writing, software 156 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 157 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 158 | License for the specific language governing permissions and limitations under 159 | the License. 160 | 161 | .. _Python: https://python.org/ 162 | .. _pip: https://pip.pypa.io/ 163 | .. _Google Assistant SDK: https://developers.google.com/assistant/sdk 164 | .. _Google Assistant Service: https://developers.google.com/assistant/sdk/reference/rpc 165 | -------------------------------------------------------------------------------- /google-assistant-sdk/actions.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest": { 3 | "displayName": "Blinky light", 4 | "invocationName": "Blinky light", 5 | "category": "PRODUCTIVITY" 6 | }, 7 | "actions": [ 8 | { 9 | "name": "com.example.actions.BlinkLight", 10 | "availability": { 11 | "deviceClasses": [ 12 | { 13 | "assistantSdkDevice": {} 14 | } 15 | ] 16 | }, 17 | "intent": { 18 | "name": "com.example.intents.BlinkLight", 19 | "parameters": [ 20 | { 21 | "name": "number", 22 | "type": "SchemaOrg_Number" 23 | }, 24 | { 25 | "name": "speed", 26 | "type": "Speed" 27 | } 28 | ], 29 | "trigger": { 30 | "queryPatterns": [ 31 | "blink ($Speed:speed)? $SchemaOrg_Number:number times", 32 | "blink $SchemaOrg_Number:number times ($Speed:speed)?" 33 | ] 34 | } 35 | }, 36 | "fulfillment": { 37 | "staticFulfillment": { 38 | "templatedResponse": { 39 | "items": [ 40 | { 41 | "simpleResponse": { 42 | "textToSpeech": "Blinking $number times" 43 | } 44 | }, 45 | { 46 | "deviceExecution": { 47 | "command": "com.example.commands.BlinkLight", 48 | "params": { 49 | "speed": "$speed", 50 | "number": "$number" 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | } 57 | } 58 | } 59 | ], 60 | "types": [ 61 | { 62 | "name": "$Speed", 63 | "entities": [ 64 | { 65 | "key": "SLOWLY", 66 | "synonyms": [ 67 | "slowly", 68 | "slow" 69 | ] 70 | }, 71 | { 72 | "key": "NORMALLY", 73 | "synonyms": [ 74 | "normally", 75 | "regular" 76 | ] 77 | }, 78 | { 79 | "key": "QUICKLY", 80 | "synonyms": [ 81 | "quickly", 82 | "fast", 83 | "quick" 84 | ] 85 | } 86 | ] 87 | } 88 | ] 89 | } -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """googlesamples namespace package.""" 16 | 17 | try: 18 | import pkg_resources 19 | pkg_resources.declare_namespace(__name__) 20 | except ImportError: 21 | import pkgutil 22 | __path__ = pkgutil.extend_path(__path__, __name__) 23 | -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/assistant/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """googlesamples.assistant namespace package.""" 16 | 17 | try: 18 | import pkg_resources 19 | pkg_resources.declare_namespace(__name__) 20 | except ImportError: 21 | import pkgutil 22 | __path__ = pkgutil.extend_path(__path__, __name__) 23 | -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/assistant/grpc/README.rst: -------------------------------------------------------------------------------- 1 | Python Samples for the Google Assistant gRPC API 2 | ================================================ 3 | 4 | This repository contains a reference sample for the ``google-assistant-grpc`` Python package_. 5 | 6 | It implements the following features: 7 | 8 | - Triggering a conversation using a key press 9 | - Audio recording of user queries (single or multiple consecutive queries) 10 | - Playback of the Assistant response 11 | - Conversation state management 12 | - Volume control 13 | 14 | .. _package: https://pypi.python.org/pypi/google-assistant-grpc 15 | 16 | Prerequisites 17 | ------------- 18 | 19 | - `Python `_ (>= 3.4 recommended) 20 | - An `Actions Console Project `_ 21 | - A `Google account `_ 22 | 23 | Setup 24 | ----- 25 | 26 | - Install Python 3 27 | 28 | - Ubuntu/Debian GNU/Linux:: 29 | 30 | sudo apt-get update 31 | sudo apt-get install python3 python3-venv 32 | 33 | - `MacOSX, Windows, Other `_ 34 | 35 | - Create a new virtual environment (recommended):: 36 | 37 | python3 -m venv env 38 | env/bin/python -m pip install --upgrade pip setuptools wheel 39 | source env/bin/activate 40 | 41 | Authorization 42 | ------------- 43 | 44 | - Follow the steps to `configure the Actions Console project and the Google account `_. 45 | - Follow the steps to `register a new device model and download the client secrets file `_. 46 | - Generate device credentials using ``google-oauthlib-tool``: 47 | 48 | pip install --upgrade google-auth-oauthlib[tool] 49 | google-oauthlib-tool --client-secrets path/to/client_secret_.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype --save --headless 50 | 51 | Run the samples 52 | --------------- 53 | 54 | - Install the sample dependencies:: 55 | 56 | sudo apt-get install portaudio19-dev libffi-dev libssl-dev 57 | pip install --upgrade -r requirements.txt 58 | 59 | - Verify audio setup:: 60 | 61 | # Record a 5 sec sample and play it back 62 | python -m audio_helpers 63 | 64 | - Run the push to talk sample. The sample records a voice query after a key press and plays back the Google Assistant's answer:: 65 | 66 | python -m pushtotalk --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' 67 | 68 | - Try some Google Assistant voice query like "What time is it?" or "Who am I?". 69 | 70 | - Try a device action query like "Turn on". 71 | 72 | - Run in verbose mode to see the gRPC communication with the Google Assistant API:: 73 | 74 | python -m pushtotalk --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' -v 75 | 76 | - Send a pre-recorded request to the Assistant:: 77 | 78 | python -m pushtotalk --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' -i in.wav 79 | 80 | - Save the Assistant response to a file:: 81 | 82 | python -m pushtotalk --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' -o out.wav 83 | 84 | - Send text requests to the Assistant:: 85 | 86 | python -m textinput --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' 87 | 88 | - Send a request to the Assistant from a local audio file and write the Assistant audio response to another file:: 89 | 90 | python -m audiofileinput --device-id 'my-device-identifier' --device-model-id 'my-model-identifier' -i in.wav -o out.wav 91 | 92 | Troubleshooting 93 | --------------- 94 | 95 | - Verify ALSA setup:: 96 | 97 | # Play a test sound 98 | speaker-test -t wav 99 | 100 | # Record and play back some audio using ALSA command-line tools 101 | arecord --format=S16_LE --duration=5 --rate=16000 --file-type=raw out.raw 102 | aplay --format=S16_LE --rate=16000 --file-type=raw out.raw 103 | 104 | - If Assistant audio is choppy, try adjusting the sound device's block size:: 105 | 106 | # If using a USB speaker or dedicated soundcard, set block size to "0" 107 | # to automatically adjust the buffer size 108 | python -m audio_helpers --audio-block-size=0 109 | 110 | # If using the line-out 3.5mm audio jack on the device, set block size 111 | # to a value larger than the `ConverseResponse` audio payload size 112 | python -m audio_helpers --audio-block-size=3200 113 | 114 | # Run the Assistant sample using the best block size value found above 115 | python -m pushtotalk --audio-block-size=value 116 | 117 | - If Assistant audio is truncated, try adjusting the sound device's flush size:: 118 | 119 | # Set flush size to a value larger than the audio block size. You can 120 | # run the sample using the --audio-flush-size flag as well. 121 | python -m audio_helpers --audio-block-size=3200 --audio-flush-size=6400 122 | 123 | See also the `troubleshooting section `_ of the official documentation. 124 | 125 | License 126 | ------- 127 | 128 | Copyright (C) 2017 Google Inc. 129 | 130 | Licensed to the Apache Software Foundation (ASF) under one or more contributor 131 | license agreements. See the NOTICE file distributed with this work for 132 | additional information regarding copyright ownership. The ASF licenses this 133 | file to you under the Apache License, Version 2.0 (the "License"); you may not 134 | use this file except in compliance with the License. You may obtain a copy of 135 | the License at 136 | 137 | http://www.apache.org/licenses/LICENSE-2.0 138 | 139 | Unless required by applicable law or agreed to in writing, software 140 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 141 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 142 | License for the specific language governing permissions and limitations under 143 | the License. 144 | -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/assistant/grpc/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Samples for Google Assistant gRPC API.""" 16 | -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/assistant/grpc/assistant_helpers.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Helper functions for the Google Assistant API.""" 16 | 17 | import logging 18 | 19 | from google.assistant.embedded.v1alpha2 import embedded_assistant_pb2 20 | 21 | 22 | def log_assist_request_without_audio(assist_request): 23 | """Log AssistRequest fields without audio data.""" 24 | if logging.getLogger().isEnabledFor(logging.DEBUG): 25 | resp_copy = embedded_assistant_pb2.AssistRequest() 26 | resp_copy.CopyFrom(assist_request) 27 | if len(resp_copy.audio_in) > 0: 28 | size = len(resp_copy.audio_in) 29 | resp_copy.ClearField('audio_in') 30 | logging.debug('AssistRequest: audio_in (%d bytes)', 31 | size) 32 | return 33 | logging.debug('AssistRequest: %s', resp_copy) 34 | 35 | 36 | def log_assist_response_without_audio(assist_response): 37 | """Log AssistResponse fields without audio data.""" 38 | if logging.getLogger().isEnabledFor(logging.DEBUG): 39 | resp_copy = embedded_assistant_pb2.AssistResponse() 40 | resp_copy.CopyFrom(assist_response) 41 | has_audio_data = (resp_copy.HasField('audio_out') and 42 | len(resp_copy.audio_out.audio_data) > 0) 43 | if has_audio_data: 44 | size = len(resp_copy.audio_out.audio_data) 45 | resp_copy.audio_out.ClearField('audio_data') 46 | if resp_copy.audio_out.ListFields(): 47 | logging.debug('AssistResponse: %s audio_data (%d bytes)', 48 | resp_copy, 49 | size) 50 | else: 51 | logging.debug('AssistResponse: audio_data (%d bytes)', 52 | size) 53 | return 54 | logging.debug('AssistResponse: %s', resp_copy) 55 | -------------------------------------------------------------------------------- /google-assistant-sdk/googlesamples/assistant/grpc/audio_helpers.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Helper functions for audio streams.""" 16 | 17 | import array 18 | import logging 19 | import math 20 | import time 21 | import threading 22 | import wave 23 | 24 | import click 25 | import sounddevice as sd 26 | 27 | 28 | DEFAULT_AUDIO_SAMPLE_RATE = 16000 29 | DEFAULT_AUDIO_SAMPLE_WIDTH = 2 30 | DEFAULT_AUDIO_ITER_SIZE = 3200 31 | DEFAULT_AUDIO_DEVICE_BLOCK_SIZE = 6400 32 | DEFAULT_AUDIO_DEVICE_FLUSH_SIZE = 25600 33 | 34 | 35 | def normalize_audio_buffer(buf, volume_percentage, sample_width=2): 36 | """Adjusts the loudness of the audio data in the given buffer. 37 | 38 | Volume normalization is done by scaling the amplitude of the audio 39 | in the buffer by a scale factor of 2^(volume_percentage/100)-1. 40 | For example, 50% volume scales the amplitude by a factor of 0.414, 41 | and 75% volume scales the amplitude by a factor of 0.681. 42 | For now we only sample_width 2. 43 | 44 | Args: 45 | buf: byte string containing audio data to normalize. 46 | volume_percentage: volume setting as an integer percentage (1-100). 47 | sample_width: size of a single sample in bytes. 48 | """ 49 | if sample_width != 2: 50 | raise Exception('unsupported sample width:', sample_width) 51 | scale = math.pow(2, 1.0*volume_percentage/100)-1 52 | # Construct array from bytes based on sample_width, multiply by scale 53 | # and convert it back to bytes 54 | arr = array.array('h', buf) 55 | for idx in range(0, len(arr)): 56 | arr[idx] = int(arr[idx]*scale) 57 | buf = arr.tostring() 58 | return buf 59 | 60 | 61 | def align_buf(buf, sample_width): 62 | """In case of buffer size not aligned to sample_width pad it with 0s""" 63 | remainder = len(buf) % sample_width 64 | if remainder != 0: 65 | buf += b'\0' * (sample_width - remainder) 66 | return buf 67 | 68 | 69 | class WaveSource(object): 70 | """Audio source that reads audio data from a WAV file. 71 | 72 | Reads are throttled to emulate the given sample rate and silence 73 | is returned when the end of the file is reached. 74 | 75 | Args: 76 | fp: file-like stream object to read from. 77 | sample_rate: sample rate in hertz. 78 | sample_width: size of a single sample in bytes. 79 | """ 80 | def __init__(self, fp, sample_rate, sample_width): 81 | self._fp = fp 82 | try: 83 | self._wavep = wave.open(self._fp, 'r') 84 | except wave.Error as e: 85 | logging.warning('error opening WAV file: %s, ' 86 | 'falling back to RAW format', e) 87 | self._fp.seek(0) 88 | self._wavep = None 89 | self._sample_rate = sample_rate 90 | self._sample_width = sample_width 91 | self._sleep_until = 0 92 | 93 | def read(self, size): 94 | """Read bytes from the stream and block until sample rate is achieved. 95 | 96 | Args: 97 | size: number of bytes to read from the stream. 98 | """ 99 | now = time.time() 100 | missing_dt = self._sleep_until - now 101 | if missing_dt > 0: 102 | time.sleep(missing_dt) 103 | self._sleep_until = time.time() + self._sleep_time(size) 104 | data = (self._wavep.readframes(size) 105 | if self._wavep 106 | else self._fp.read(size)) 107 | # When reach end of audio stream, pad remainder with silence (zeros). 108 | if not data: 109 | return b'\x00' * size 110 | return data 111 | 112 | def close(self): 113 | """Close the underlying stream.""" 114 | if self._wavep: 115 | self._wavep.close() 116 | self._fp.close() 117 | 118 | def _sleep_time(self, size): 119 | sample_count = size / float(self._sample_width) 120 | sample_rate_dt = sample_count / float(self._sample_rate) 121 | return sample_rate_dt 122 | 123 | def start(self): 124 | pass 125 | 126 | def stop(self): 127 | pass 128 | 129 | @property 130 | def sample_rate(self): 131 | return self._sample_rate 132 | 133 | 134 | class WaveSink(object): 135 | """Audio sink that writes audio data to a WAV file. 136 | 137 | Args: 138 | fp: file-like stream object to write data to. 139 | sample_rate: sample rate in hertz. 140 | sample_width: size of a single sample in bytes. 141 | """ 142 | def __init__(self, fp, sample_rate, sample_width): 143 | self._fp = fp 144 | self._wavep = wave.open(self._fp, 'wb') 145 | self._wavep.setsampwidth(sample_width) 146 | self._wavep.setnchannels(1) 147 | self._wavep.setframerate(sample_rate) 148 | 149 | def write(self, data): 150 | """Write bytes to the stream. 151 | 152 | Args: 153 | data: frame data to write. 154 | """ 155 | self._wavep.writeframes(data) 156 | 157 | def close(self): 158 | """Close the underlying stream.""" 159 | self._wavep.close() 160 | self._fp.close() 161 | 162 | def start(self): 163 | pass 164 | 165 | def stop(self): 166 | pass 167 | 168 | def flush(self): 169 | pass 170 | 171 | 172 | class SoundDeviceStream(object): 173 | """Audio stream based on an underlying sound device. 174 | 175 | It can be used as an audio source (read) and a audio sink (write). 176 | 177 | Args: 178 | sample_rate: sample rate in hertz. 179 | sample_width: size of a single sample in bytes. 180 | block_size: size in bytes of each read and write operation. 181 | flush_size: size in bytes of silence data written during flush operation. 182 | """ 183 | def __init__(self, sample_rate, sample_width, block_size, flush_size): 184 | if sample_width == 2: 185 | audio_format = 'int16' 186 | else: 187 | raise Exception('unsupported sample width:', sample_width) 188 | self._audio_stream = sd.RawStream( 189 | samplerate=sample_rate, dtype=audio_format, channels=1, 190 | blocksize=int(block_size/2), # blocksize is in number of frames. 191 | ) 192 | self._block_size = block_size 193 | self._flush_size = flush_size 194 | self._sample_rate = sample_rate 195 | 196 | def read(self, size): 197 | """Read bytes from the stream.""" 198 | buf, overflow = self._audio_stream.read(size) 199 | if overflow: 200 | logging.warning('SoundDeviceStream read overflow (%d, %d)', 201 | size, len(buf)) 202 | return bytes(buf) 203 | 204 | def write(self, buf): 205 | """Write bytes to the stream.""" 206 | underflow = self._audio_stream.write(buf) 207 | if underflow: 208 | logging.warning('SoundDeviceStream write underflow (size: %d)', 209 | len(buf)) 210 | return len(buf) 211 | 212 | def flush(self): 213 | if self._audio_stream.active and self._flush_size > 0: 214 | self._audio_stream.write(b'\x00' * self._flush_size) 215 | 216 | def start(self): 217 | """Start the underlying stream.""" 218 | if not self._audio_stream.active: 219 | self._audio_stream.start() 220 | 221 | def stop(self): 222 | """Stop the underlying stream.""" 223 | if self._audio_stream.active: 224 | self._audio_stream.stop() 225 | 226 | def close(self): 227 | """Close the underlying stream and audio interface.""" 228 | if self._audio_stream: 229 | self.stop() 230 | self._audio_stream.close() 231 | self._audio_stream = None 232 | 233 | @property 234 | def sample_rate(self): 235 | return self._sample_rate 236 | 237 | 238 | class ConversationStream(object): 239 | """Audio stream that supports half-duplex conversation. 240 | 241 | A conversation is the alternance of: 242 | - a recording operation 243 | - a playback operation 244 | 245 | Excepted usage: 246 | 247 | For each conversation: 248 | - start_recording() 249 | - read() or iter() 250 | - stop_recording() 251 | - start_playback() 252 | - write() 253 | - stop_playback() 254 | 255 | When conversations are finished: 256 | - close() 257 | 258 | Args: 259 | source: file-like stream object to read input audio bytes from. 260 | sink: file-like stream object to write output audio bytes to. 261 | iter_size: read size in bytes for each iteration. 262 | sample_width: size of a single sample in bytes. 263 | """ 264 | def __init__(self, source, sink, iter_size, sample_width): 265 | self._source = source 266 | self._sink = sink 267 | self._iter_size = iter_size 268 | self._sample_width = sample_width 269 | self._volume_percentage = 50 270 | self._stop_recording = threading.Event() 271 | self._source_lock = threading.RLock() 272 | self._recording = False 273 | self._playing = False 274 | 275 | def start_recording(self): 276 | """Start recording from the audio source.""" 277 | self._recording = True 278 | self._stop_recording.clear() 279 | self._source.start() 280 | 281 | def stop_recording(self): 282 | """Stop recording from the audio source.""" 283 | self._stop_recording.set() 284 | with self._source_lock: 285 | self._source.stop() 286 | self._recording = False 287 | 288 | def start_playback(self): 289 | """Start playback to the audio sink.""" 290 | self._playing = True 291 | self._sink.start() 292 | 293 | def stop_playback(self): 294 | """Stop playback from the audio sink.""" 295 | self._sink.flush() 296 | self._sink.stop() 297 | self._playing = False 298 | 299 | @property 300 | def recording(self): 301 | return self._recording 302 | 303 | @property 304 | def playing(self): 305 | return self._playing 306 | 307 | @property 308 | def volume_percentage(self): 309 | """The current volume setting as an integer percentage (1-100).""" 310 | return self._volume_percentage 311 | 312 | @volume_percentage.setter 313 | def volume_percentage(self, new_volume_percentage): 314 | self._volume_percentage = new_volume_percentage 315 | 316 | def read(self, size): 317 | """Read bytes from the source (if currently recording). 318 | """ 319 | with self._source_lock: 320 | return self._source.read(size) 321 | 322 | def write(self, buf): 323 | """Write bytes to the sink (if currently playing). 324 | """ 325 | buf = align_buf(buf, self._sample_width) 326 | buf = normalize_audio_buffer(buf, self.volume_percentage) 327 | return self._sink.write(buf) 328 | 329 | def close(self): 330 | """Close source and sink.""" 331 | self._source.close() 332 | self._sink.close() 333 | 334 | def __iter__(self): 335 | """Returns a generator reading data from the stream.""" 336 | while True: 337 | if self._stop_recording.is_set(): 338 | return 339 | yield self.read(self._iter_size) 340 | 341 | @property 342 | def sample_rate(self): 343 | return self._source._sample_rate 344 | 345 | 346 | @click.command() 347 | @click.option('--record-time', default=5, 348 | metavar='', show_default=True, 349 | help='Record time in secs') 350 | @click.option('--audio-sample-rate', 351 | default=DEFAULT_AUDIO_SAMPLE_RATE, 352 | metavar='