├── .YANDEX_PRIVATE_KEY.txt.gpg
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── publish-to-pypi.yml
│ └── python-package.yml
├── .gitignore
├── .pyup.yml
├── .readthedocs.yaml
├── LICENSE.txt
├── README.md
├── docs
├── Makefile
├── make.bat
├── requirements.txt
└── source
│ ├── auth.rst
│ ├── conf.py
│ ├── exceptions.rst
│ ├── index.rst
│ ├── speechkit.rst
│ └── utils.rst
├── examples
├── long_audio_recognition.py
└── streaming_recognize.py
├── pyproject.toml
├── requirements.txt
├── setup.cfg
└── src
├── speechkit
├── __init__.py
├── _auth.py
├── _recognition
│ ├── __init__.py
│ ├── google
│ │ ├── __init__.py
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── annotations_pb2.py
│ │ │ ├── annotations_pb2_grpc.py
│ │ │ ├── http_pb2.py
│ │ │ └── http_pb2_grpc.py
│ │ └── rpc
│ │ │ ├── __init__.py
│ │ │ ├── status_pb2.py
│ │ │ └── status_pb2_grpc.py
│ ├── streaming_recognition.py
│ ├── sync_recognition.py
│ └── yandex
│ │ ├── __init__.py
│ │ └── cloud
│ │ ├── __init__.py
│ │ ├── ai
│ │ ├── __init__.py
│ │ └── stt
│ │ │ ├── __init__.py
│ │ │ └── v2
│ │ │ ├── __init__.py
│ │ │ ├── stt_service_pb2.py
│ │ │ └── stt_service_pb2_grpc.py
│ │ ├── api
│ │ ├── __init__.py
│ │ ├── operation_pb2.py
│ │ └── operation_pb2_grpc.py
│ │ └── operation
│ │ ├── __init__.py
│ │ ├── operation_pb2.py
│ │ └── operation_pb2_grpc.py
├── _synthesis.py
├── auth.py
├── exceptions.py
└── utils.py
└── tests
├── __init__.py
├── test_auth.py
├── test_exceptions.py
├── test_long_audio_recognition.py
├── test_short_audio_recognition.py
├── test_speech_synthesis.py
├── test_streaming_recognition.py
└── test_utils.py
/.YANDEX_PRIVATE_KEY.txt.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/.YANDEX_PRIVATE_KEY.txt.gpg
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/publish-to-pypi.yml:
--------------------------------------------------------------------------------
1 | name: Publish Python 🐍 distributions 📦 to PyPI
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | permissions:
8 | contents: read
9 |
10 | jobs:
11 | build-n-publish:
12 | name: Build and publish Python 🐍 distributions 📦 to PyPI
13 |
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 |
19 | - name: Set up Python
20 | uses: actions/setup-python@v4
21 | with:
22 | python-version: "3.x"
23 |
24 | - name: Install pypa/build
25 | run: >-
26 | python -m
27 | pip install
28 | build
29 | --user
30 |
31 | - name: Build a binary wheel and a source tarball
32 | run: >-
33 | python -m
34 | build
35 | --sdist
36 | --wheel
37 | --outdir dist/
38 | .
39 |
40 | - name: Publish distribution 📦 to PyPI
41 | uses: pypa/gh-action-pypi-publish@release/v1
42 | with:
43 | password: ${{ secrets.PYPI_API_TOKEN }}
44 |
--------------------------------------------------------------------------------
/.github/workflows/python-package.yml:
--------------------------------------------------------------------------------
1 | name: Speechkit python package
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | -master
10 |
11 | jobs:
12 | build:
13 | name: Build and test Python 🐍 package
14 |
15 | runs-on: ubuntu-latest
16 | strategy:
17 | fail-fast: false
18 | matrix:
19 | python-version: [ "3.8", "3.9", "3.10" ]
20 |
21 | steps:
22 | - uses: actions/checkout@v3
23 |
24 | - name: Set up Python ${{ matrix.python-version }}
25 | uses: actions/setup-python@v3
26 | with:
27 | python-version: ${{ matrix.python-version }}
28 |
29 | - name: Install dependencies
30 | run: |
31 | python -m pip install --upgrade pip
32 | python -m pip install flake8 codecov
33 | pip install -r requirements.txt
34 |
35 | - name: Install package
36 | run: |
37 | pip install ".[test]" .
38 |
39 | - name: Lint with flake8
40 | run: |
41 | # stop the build if there are Python syntax errors or undefined names
42 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
43 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
44 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
45 |
46 | - name: Test with unittest
47 | run: |
48 | gpg --quiet --batch --yes --decrypt --passphrase="$YANDEX_PRIVATE_KEY_PASSPHRASE" \
49 | --output .YANDEX_PRIVATE_KEY.txt .YANDEX_PRIVATE_KEY.txt.gpg
50 | cd src
51 | coverage run -m unittest discover && coverage report
52 | codecov
53 | env:
54 | BUCKET_NAME: ${{ secrets.BUCKET_NAME }}
55 | CATALOG: ${{ secrets.CATALOG }}
56 | SERVICE_ACCOUNT_ID: ${{ secrets.SERVICE_ACCOUNT_ID }}
57 | SERVICE_API_KEY: ${{ secrets.SERVICE_API_KEY }}
58 | YANDEX_KEY_ID: ${{ secrets.YANDEX_KEY_ID }}
59 | YANDEX_OAUTH: ${{ secrets.YANDEX_OAUTH }}
60 | YANDEX_PRIVATE_KEY_PASSPHRASE: ${{ secrets.YANDEX_PRIVATE_KEY_PASSPHRASE }}
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 |
132 | *.DS_Store
133 | *.swp
134 | .idea/
135 | bash_profile
136 | /.YANDEX_PRIVATE_KEY.txt
137 | /src/tests/test_rec.wav
138 | /src/tests/test_synth.wav
139 |
--------------------------------------------------------------------------------
/.pyup.yml:
--------------------------------------------------------------------------------
1 | # autogenerated pyup.io config file
2 | # see https://pyup.io/docs/configuration/ for all available options
3 |
4 | schedule: ''
5 | update: false
6 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | os: "ubuntu-22.04"
5 | tools:
6 | python: "3.10"
7 |
8 | sphinx:
9 | builder: html
10 | configuration: docs/source/conf.py
11 | fail_on_warning: true
12 |
13 | formats:
14 | - pdf
15 |
16 | python:
17 | install:
18 | - requirements: docs/requirements.txt
19 | - requirements: requirements.txt
20 | - method: pip
21 | path: .
22 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Tikhon Petrishchev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
🎙 Yandex SpeechKit Python SDK
4 |
5 | 
6 | 
7 | 
8 | [](https://codecov.io/gh/tikhonp/yandex-speechkit-lib-python)
9 | [](https://pip.pypa.io/en/stable/?badge=stable)
10 | [](https://pepy.tech/project/speechkit)
11 |
12 |
13 | Python SDK for Yandex SpeechKit API. This SDK allows you to use the cloud API for speech recognition and synthesis from Yandex.
14 |
15 | For more information please visit [Yandex Speechkit API Docs](https://cloud.yandex.com/en/docs/speechkit/). This lib
16 | supports short and long audio recognition with speechkit
17 |
18 | ## 🛠 Getting Started
19 |
20 | Assuming that you have Python and `virtualenv` installed, set up your environment and install the required dependencies
21 | like this, or you can install the library using `pip`:
22 |
23 | ```sh
24 | $ git clone https://github.com/TikhonP/yandex-speechkit-lib-python.git
25 | $ cd yandex-speechkit-lib-python
26 | $ virtualenv venv
27 | ...
28 | $ . venv/bin/activate
29 | $ python -m pip install -r requirements.txt
30 | $ python -m pip install .
31 | ```
32 |
33 | ```sh
34 | python -m pip install speechkit
35 | ```
36 |
37 | ## 📑 Speechkit documentation
38 |
39 | Check out [speechkit docs](https://yandex-speechkit-lib-python.readthedocs.io/en/latest/index.html) for more
40 | info. [PDF docs](https://yandex-speechkit-lib-python.readthedocs.io/_/downloads/en/latest/pdf/)
41 |
42 | ## 🔮 Using speechkit
43 |
44 | There are support of recognizing long and short audio and synthesis. For more information please read docs below.
45 |
46 | First you need create session for authorisation:
47 |
48 | ```python3
49 | from speechkit import Session
50 |
51 | oauth_token = str('')
52 | folder_id = str('')
53 | api_key = str('')
54 | jwt_token = str('')
55 |
56 | oauth_session = Session.from_yandex_passport_oauth_token(oauth_token, folder_id)
57 | api_key_session = Session.from_api_key(api_key, x_client_request_id_header=True, x_data_logging_enabled=True)
58 | # You can use `x_client_request_id_header` and `x_data_logging_enabled` params to troubleshoot yandex recognition
59 | # Use `Session.get_x_client_request_id()` method to get x_client_request_id value.
60 | jwt_session = Session.from_jwt(jwt_token)
61 | ```
62 |
63 | Use created session to make other requests.
64 |
65 | There are also functions for getting credentials (read [Documentation](https://yandex-speechkit-lib-python.readthedocs.io/en/latest/index.html) for more info):
66 | `Speechkit.auth.generate_jwt`, `speechkit.auth.get_iam_token`, `speechkit.auth.get_api_key`
67 |
68 | ### For audio recognition
69 |
70 | Short audio:
71 |
72 | ```python3
73 | from speechkit import ShortAudioRecognition
74 |
75 | recognizeShortAudio = ShortAudioRecognition(session)
76 | with open(str('/Users/tikhon/Desktop/out.wav'), str('rb')) as f:
77 | data = f.read()
78 |
79 | print(recognizeShortAudio.recognize(data, format='lpcm', sampleRateHertz='48000'))
80 |
81 | # Will be printed: 'text that need to be recognized'
82 | ```
83 |
84 | Look at example with long
85 | audio [long_audio_recognition.py](https://github.com/TikhonP/yandex-speechkit-lib-python/blob/master/examples/long_audio_recognition.py)
86 | .
87 |
88 | Look at example with streaming
89 | audio [streaming_recognize.py](https://github.com/TikhonP/yandex-speechkit-lib-python/blob/master/examples/streaming_recognize.py)
90 |
91 | ### For synthesis
92 |
93 | ```python3
94 | from speechkit import SpeechSynthesis
95 |
96 | synthesizeAudio = SpeechSynthesis(session)
97 | synthesizeAudio.synthesize(
98 | str('/Users/tikhon/Desktop/out.wav'), text='Text that will be synthesised',
99 | voice='oksana', format='lpcm', sampleRateHertz='16000'
100 | )
101 | ```
102 |
103 | ## 🔗 Links
104 |
105 | - [Readthedocs Documentation for this package](https://yandex-speechkit-lib-python.readthedocs.io/en/latest/index.html)
106 | - [Yandex Speechkit Documentation](https://cloud.yandex.com/en/docs/speechkit/)
107 | - [Статья на хабре](https://habr.com/ru/post/681566/)
108 |
109 | ## 💼 License
110 |
111 | [MIT](LICENSE)
112 |
113 | In other words, you can use the code for private and commercial purposes with an author attribution (by including the original license file).
114 |
115 | ❤️
116 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx>=4.1.2
2 | sphinx_markdown_builder>=0.5.4
3 | sphinx-rtd-theme>=0.5.2
4 |
--------------------------------------------------------------------------------
/docs/source/auth.rst:
--------------------------------------------------------------------------------
1 | speechkit.auth module
2 | ---------------------
3 |
4 | .. automodule:: speechkit.auth
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os
14 | import sys
15 |
16 | sys.path.insert(0, os.path.abspath('../../src'))
17 |
18 |
19 | # -- Project information -----------------------------------------------------
20 |
21 | project = 'Yandex Speechkit SDK'
22 | copyright = '2021, Tikhon Petrishchev'
23 | author = 'Tikhon Petrishchev'
24 |
25 | # The full version, including alpha/beta/rc tags
26 | release = '1.3.0'
27 |
28 |
29 | # -- General configuration ---------------------------------------------------
30 |
31 | # Add any Sphinx extension module names here, as strings. They can be
32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33 | # ones.
34 | extensions = [
35 | 'sphinx.ext.autodoc',
36 | 'sphinx.ext.viewcode',
37 | 'sphinx_markdown_builder'
38 | ]
39 |
40 | # Add any paths that contain templates here, relative to this directory.
41 | templates_path = ['_templates']
42 | autoclass_content = 'both'
43 |
44 | # List of patterns, relative to source directory, that match files and
45 | # directories to ignore when looking for source files.
46 | # This pattern also affects html_static_path and html_extra_path.
47 | exclude_patterns = []
48 |
49 |
50 | # -- Options for HTML _recognition -------------------------------------------------
51 |
52 | # The theme to use for HTML and HTML Help pages. See the documentation for
53 | # a list of builtin themes.
54 | #
55 | html_theme = "sphinx_rtd_theme"
56 |
57 | # Add any paths that contain custom static files (such as style sheets) here,
58 | # relative to this directory. They are copied after the builtin static files,
59 | # so a file named "default.css" will overwrite the builtin "default.css".
60 | html_static_path = []
61 |
--------------------------------------------------------------------------------
/docs/source/exceptions.rst:
--------------------------------------------------------------------------------
1 | speechkit.exceptions module
2 | ---------------------------
3 |
4 | .. automodule:: speechkit.exceptions
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. speechkit documentation master file, created by
2 | sphinx-quickstart on Tue Jul 20 03:54:03 2021.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to speechkit's documentation!
7 | =====================================
8 |
9 | Speechkit is python SDK for Yandex SpeechKit API.
10 |
11 | Installation
12 | ------------
13 |
14 | Assuming that you have Python and virtualenv installed, set up your environment and install the required dependencies
15 | like this::
16 |
17 |
18 | $ git clone https://github.com/TikhonP/yandex-speechkit-lib-python.git
19 | $ cd yandex-speechkit-lib-python
20 | $ virtualenv venv
21 | ...
22 | $ . venv/bin/activate
23 | $ python -m pip install -r requirements.txt
24 | $ python -m pip install .
25 |
26 | Or you can install the library using pip::
27 |
28 | python -m pip install speechkit
29 |
30 | Api Reference
31 | -------------
32 |
33 | .. toctree::
34 | :maxdepth: 2
35 | :caption: Contents:
36 |
37 | speechkit
38 |
39 | auth
40 |
41 | utils
42 |
43 | exceptions
44 |
45 | Some Shortcuts dor YC console tool
46 | ----------------------------------
47 |
48 | Get FOLDER_ID: FOLDER_ID=$(yc config get folder-id)
49 |
50 | Create service-account: yc iam service-account create --name admin
51 |
52 | Get id of service-account: SA_ID=$(yc iam service-account get --name admin --format json | jq .id -r)
53 |
54 | Assign a role to the admin service account using its ID: yc resource-manager folder add-access-binding --id $FOLDER_ID --role admin --subject serviceAccount:$SA_ID
55 |
56 | Indices and tables
57 | ==================
58 |
59 | * :ref:`genindex`
60 | * :ref:`modindex`
61 | * :ref:`search`
62 |
--------------------------------------------------------------------------------
/docs/source/speechkit.rst:
--------------------------------------------------------------------------------
1 | speechkit package
2 | =================
3 |
4 | .. automodule:: speechkit
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/utils.rst:
--------------------------------------------------------------------------------
1 | speechkit.utils module
2 | ----------------------
3 |
4 | .. automodule:: speechkit.utils
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
--------------------------------------------------------------------------------
/examples/long_audio_recognition.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | from sys import argv
4 |
5 | from speechkit import RecognitionLongAudio, Session
6 | from speechkit.auth import generate_jwt
7 |
8 | _, filename = argv
9 |
10 | bucket_name = os.environ.get('BUCKET_NAME')
11 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
12 | key_id = os.environ.get('YANDEX_KEY_ID')
13 | private_key = os.environ.get('YANDEX_PRIVATE_KEY').replace('\\n', '\n').encode()
14 |
15 | if not key_id or not service_account_id or not bucket_name or not private_key:
16 | print("Specify `YANDEX_KEY_ID`, `SERVICE_ACCOUNT_ID`, `BUCKET_NAME`, `private_key` environment variables.")
17 | exit()
18 |
19 | jwt = generate_jwt(service_account_id, key_id, private_key)
20 | session = Session.from_jwt(jwt)
21 |
22 | # Maybe you want to create aws s3 key only once
23 | # In that case from version 2.2.0 you can do:
24 | access_key_id, secret = RecognitionLongAudio.get_aws_credentials(session, service_account_id)
25 |
26 | # And then use it:
27 | recognize_long_audio = RecognitionLongAudio(session, service_account_id, bucket_name, aws_access_key_id=access_key_id,
28 | aws_secret=secret)
29 |
30 | # Or you can do it automatically
31 | # recognize_long_audio = RecognitionLongAudio(session, service_account_id, bucket_name)
32 |
33 | print("Sending file for recognition...")
34 | recognize_long_audio.send_for_recognition(
35 | filename, audioEncoding='LINEAR16_PCM', sampleRateHertz='48000',
36 | audioChannelCount=1, rawResults=False
37 | )
38 | while True:
39 | time.sleep(2)
40 | if recognize_long_audio.get_recognition_results():
41 | break
42 | print("Recognizing...")
43 |
44 | data = recognize_long_audio.get_data()
45 | print("DATA:\n\n", data)
46 |
47 | text = recognize_long_audio.get_raw_text()
48 | print("TEXT:\n\n", text)
49 |
--------------------------------------------------------------------------------
/examples/streaming_recognize.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 |
4 | import pyaudio
5 | from iterators import TimeoutIterator
6 |
7 | from speechkit import DataStreamingRecognition, Session
8 | from speechkit.auth import generate_jwt
9 |
10 | CHUNK_SIZE = 4000
11 |
12 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
13 | key_id = os.environ.get('YANDEX_KEY_ID')
14 | private_key = os.environ.get('YANDEX_PRIVATE_KEY').replace('\\n', '\n').encode()
15 |
16 | jwt = generate_jwt(service_account_id, key_id, private_key)
17 | session = Session.from_jwt(jwt)
18 | data_streaming_recognition = DataStreamingRecognition(
19 | session,
20 | language_code='ru-RU',
21 | audio_encoding='LINEAR16_PCM',
22 | sample_rate_hertz=8000,
23 | partial_results=False,
24 | single_utterance=True,
25 | )
26 |
27 |
28 | def gen_audio_from_file_function():
29 | with open('/Users/tikhon/Downloads/speech.pcm', 'rb') as f:
30 | data = f.read(CHUNK_SIZE)
31 | while data != b'':
32 | yield data
33 | data = f.read(CHUNK_SIZE)
34 |
35 |
36 | def gen_audio_capture_function(chunk_size=1024):
37 | p = pyaudio.PyAudio()
38 | stream = p.open(
39 | format=pyaudio.paInt16,
40 | channels=1,
41 | rate=8000,
42 | input=True,
43 | frames_per_buffer=chunk_size
44 | )
45 | try:
46 | while True:
47 | yield stream.read(chunk_size)
48 | finally:
49 | stream.stop_stream()
50 | stream.close()
51 | p.terminate()
52 |
53 |
54 | for text, final, end_of_utterance in data_streaming_recognition.recognize(
55 | gen_audio_capture_function, chunk_size=CHUNK_SIZE
56 | ):
57 | print(text[0]) # text is list of alternatives
58 |
59 | if final: # Stop when final_flag set
60 | break
61 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools>=42",
4 | "wheel"
5 | ]
6 | build-backend = "setuptools.build_meta"
7 |
8 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | boto3
2 | requests
3 | grpcio-tools>=1.39.0
4 | protobuf~=3.19.6
5 | pyjwt>=2.1.0
6 | cryptography
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = speechkit
3 | version = 2.2.3
4 | author = Tikhon Petrishchev
5 | author_email = tikhon.petrishchev@gmail.com
6 | description = Python SDK for Yandex Speechkit API.
7 | long_description = file: README.md
8 | long_description_content_type = text/markdown
9 | url = https://github.com/TikhonP/yandex-speechkit-lib-python
10 | project_urls =
11 | Bug Tracker = https://github.com/TikhonP/yandex-speechkit-lib-python/issues
12 | Documentation = https://yandex-speechkit-lib-python.readthedocs.io/en/latest/index.html
13 | GitHub = https://github.com/TikhonP/yandex-speechkit-lib-python
14 | classifiers =
15 | Development Status :: 5 - Production/Stable
16 | Intended Audience :: Developers
17 | Natural Language :: English
18 | Programming Language :: Python
19 | Programming Language :: Python :: 3
20 | Programming Language :: Python :: 3.6
21 | Programming Language :: Python :: 3.7
22 | Programming Language :: Python :: 3.8
23 | Programming Language :: Python :: 3.9
24 | Programming Language :: Python :: 3.10
25 | License :: OSI Approved :: MIT License
26 | Operating System :: OS Independent
27 |
28 | [options]
29 | packages = find:
30 | install_requires =
31 | boto3
32 | requests
33 | grpcio-tools >=1.39.0
34 | protobuf ~=3.19.6
35 | pyjwt >=2.1.0
36 | cryptography
37 | package_dir =
38 | =src
39 | python_requires = >=3.6
40 |
41 | [options.packages.find]
42 | where = src
43 |
--------------------------------------------------------------------------------
/src/speechkit/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | speechkit
3 | Python SDK for using Yandex Speech recognition and synthesis.
4 | """
5 |
6 | __author__ = 'Tikhon Petrishchev'
7 | __version__ = '2.2.3'
8 |
9 | from speechkit._auth import Session
10 | from speechkit._recognition.streaming_recognition import DataStreamingRecognition
11 | from speechkit._recognition.sync_recognition import ShortAudioRecognition, RecognitionLongAudio
12 | from speechkit._synthesis import SpeechSynthesis
13 |
14 | __all__ = ['Session', 'SpeechSynthesis', 'ShortAudioRecognition', 'RecognitionLongAudio', 'DataStreamingRecognition']
15 |
--------------------------------------------------------------------------------
/src/speechkit/_auth.py:
--------------------------------------------------------------------------------
1 | import time
2 | import uuid
3 |
4 | import jwt
5 | import requests
6 |
7 | from speechkit.exceptions import RequestError
8 |
9 |
10 | def generate_jwt(service_account_id, key_id, private_key, exp_time=360):
11 | """
12 | Generating JWT token for authorisation
13 |
14 | :param string service_account_id: The ID of the service account whose key the JWT is signed with.
15 | :param string key_id: The ID of the Key resource belonging to the service account.
16 | :param bytes private_key: Private key given from Yandex Cloud console in bytes
17 | :param integer exp_time: Optional. The token expiration time delta in seconds. The expiration
18 | time must not exceed the issue time by more than one hour, meaning exp_time ≤ 3600. Default 360
19 | :return: JWT token
20 | :rtype: string
21 | """
22 | if not isinstance(service_account_id, str) or not isinstance(key_id, str):
23 | raise ValueError("service_account_id, key_id, must be strings.")
24 | if 0 in (len(service_account_id), len(key_id)):
25 | raise ValueError("service_account_id, key_id, can't be empty.")
26 | if not isinstance(private_key, bytes):
27 | raise ValueError("private_key must be bytes string, but got {}".format(type(private_key)))
28 | if not isinstance(exp_time, int):
29 | raise ValueError("exp_time must be int, but got {}".format(type(exp_time)))
30 | if exp_time > 3600:
31 | raise ValueError("exp_time ≤ 3600, but got {}".format(exp_time))
32 |
33 | now = int(time.time())
34 | payload = {
35 | 'aud': 'https://iam.api.cloud.yandex.net/iam/v1/tokens',
36 | 'iss': service_account_id,
37 | 'iat': now,
38 | 'exp': now + exp_time
39 | }
40 | return jwt.encode(
41 | payload,
42 | private_key,
43 | algorithm='PS256',
44 | headers={'kid': key_id}
45 | )
46 |
47 |
48 | def get_iam_token(yandex_passport_oauth_token=None, jwt_token=None):
49 | """
50 | Creates an IAM token for the specified identity.
51 | `Getting IAM for Yandex account `_
52 |
53 | :param string yandex_passport_oauth_token: OAuth token from Yandex OAuth
54 | :param string jwt_token: Json Web Token, can be generated by :py:meth:`speechkit.generate_jwt`
55 | :return: IAM token
56 | :rtype: string
57 | """
58 | if not type(yandex_passport_oauth_token) in (str, type(None)):
59 | raise TypeError("__init__() yandex_passport_oauth_token: got {} but expected \
60 | type is str or None".format(type(yandex_passport_oauth_token).__name__))
61 |
62 | if not type(jwt_token) in (str, type(None)):
63 | raise TypeError("__init__() jwt_token: got {} but expected \
64 | type is str or None".format(type(jwt_token).__name__))
65 |
66 | if (not yandex_passport_oauth_token and not jwt_token) or (yandex_passport_oauth_token and jwt_token):
67 | raise ValueError("Includes only one of the fields `yandex_passport_oauth_token`, `jwt_token`")
68 |
69 | if yandex_passport_oauth_token:
70 | data = {'yandexPassportOauthToken': str(yandex_passport_oauth_token)}
71 | else:
72 | data = {'jwt': str(jwt_token)}
73 |
74 | url = "https://iam.api.cloud.yandex.net/iam/v1/tokens"
75 | answer = requests.post(url, json=data)
76 |
77 | if answer.ok:
78 | return answer.json().get('iamToken')
79 | else:
80 | raise RequestError(answer.json())
81 |
82 |
83 | def get_api_key(yandex_passport_oauth_token=None, service_account_id=None,
84 | description='Default Api-Key created by `speechkit` python SDK'):
85 | """
86 | Creates an API key for the specified service account.
87 |
88 | :param string yandex_passport_oauth_token: OAuth token from Yandex OAuth
89 | :param string service_account_id: The ID of the service account whose key the Api-Key is signed with.
90 | :param string description: Description for api-key. Optional.
91 | :return: Api-Key
92 | :rtype: string
93 | """
94 | if not yandex_passport_oauth_token or not service_account_id:
95 | raise ValueError("`yandex_passport_oauth_token` and `service_account_id` required.")
96 |
97 | url = 'https://iam.api.cloud.yandex.net/iam/v1/apiKeys'
98 | headers = {
99 | 'Authorization': 'Bearer {}'.format(get_iam_token(yandex_passport_oauth_token=yandex_passport_oauth_token))
100 | }
101 | data = {'serviceAccountId': service_account_id, 'description': description}
102 |
103 | answer = requests.post(url, headers=headers, json=data)
104 | if answer.ok:
105 | return answer.json().get('secret')
106 | else:
107 | raise RequestError(answer.json())
108 |
109 |
110 | class Session:
111 | """Class provides yandex API authentication."""
112 |
113 | IAM_TOKEN = 'iam_token'
114 | """Iam_token if iam auth, value: 'iam_token'"""
115 |
116 | API_KEY = 'api_key'
117 | """Api key if api-key auth, value: 'api_key'"""
118 |
119 | def __init__(self, auth_type, credential, folder_id, x_client_request_id_header=False,
120 | x_data_logging_enabled=False):
121 | """
122 | Stores credentials for given auth method
123 |
124 | :param string auth_type: Type of auth may be :py:meth:`Session.IAM_TOKEN` or :py:meth:`Session.API_KEY`
125 | :param string | None folder_id: Id of the folder that you have access to. Don't specify this field if
126 | you make a request on behalf of a service account.
127 | :param string credential: Auth key iam or api key
128 | :param boolean x_client_request_id_header: include x-client-request-id. `x-client-request-id` is a unique
129 | request ID. It is generated using uuid. Send this ID to the technical support team to help us find
130 | a specific request in the system and assist you. To get x_client_request_id_header use
131 | `Session.get_x_client_request_id()` method.
132 | :param boolean x_data_logging_enabled: A flag that allows data passed by the user in the request to be saved.
133 | By default, we do not save any audio or text that you send. If you pass the true value in this header,
134 | your data is saved. This data, along with the request ID, will help the Yandex technical support team solve
135 | your problem.
136 | """
137 | if auth_type not in (self.IAM_TOKEN, self.API_KEY):
138 | raise ValueError(
139 | "auth_type must be `Session.IAM_TOKEN` or `Session.API_KEY`, but given {}".format(auth_type)
140 | )
141 |
142 | self._auth_method = auth_type
143 |
144 | if not isinstance(credential, str):
145 | raise ValueError("_credential must be string, but got {}".format(type(credential)))
146 |
147 | self._credential = credential
148 | self.folder_id = folder_id
149 |
150 | self._x_client_request_id = str(uuid.uuid4()) if x_client_request_id_header else None
151 | self._x_data_logging_enabled = x_data_logging_enabled
152 |
153 | @classmethod
154 | def from_api_key(cls, api_key, folder_id=None, x_client_request_id_header=False, x_data_logging_enabled=False):
155 | """
156 | Creates session from api key
157 |
158 | :param string api_key: Yandex Cloud Api-Key
159 | :param string | None folder_id: Id of the folder that you have access to. Don't specify this field if
160 | you make a request on behalf of a service account.
161 | :param boolean x_client_request_id_header: include x-client-request-id. `x-client-request-id` is a unique
162 | request ID. It is generated using uuid. Send this ID to the technical support team to help us find
163 | a specific request in the system and assist you. To get x_client_request_id_header use
164 | `Session.get_x_client_request_id()` method.
165 | :param boolean x_data_logging_enabled: A flag that allows data passed by the user in the request to be saved.
166 | By default, we do not save any audio or text that you send. If you pass the true value in this header,
167 | your data is saved. This data, along with the request ID, will help the Yandex technical support team solve
168 | your problem.
169 | :return: Session instance
170 | :rtype: Session
171 | """
172 | if not isinstance(api_key, str):
173 | raise ValueError("Api-Key must be string, but got {}".format(type(api_key)))
174 | if len(api_key) == 0:
175 | raise ValueError("Api-Key can not be empty.")
176 |
177 | if folder_id:
178 | if not isinstance(folder_id, str):
179 | raise ValueError("folder_id must be string, but got {}".format(type(folder_id)))
180 | if len(folder_id) == 0:
181 | raise ValueError("folder_id must not be empty.")
182 |
183 | return cls(cls.API_KEY, api_key, folder_id=folder_id, x_client_request_id_header=x_client_request_id_header,
184 | x_data_logging_enabled=x_data_logging_enabled)
185 |
186 | @classmethod
187 | def from_yandex_passport_oauth_token(cls, yandex_passport_oauth_token, folder_id, x_client_request_id_header=False,
188 | x_data_logging_enabled=False):
189 | """
190 | Creates Session from oauth token Yandex account
191 |
192 | :param string yandex_passport_oauth_token: OAuth token from Yandex.OAuth
193 | :param string folder_id: Id of the folder that you have access to. Don't specify this field if
194 | you make a request on behalf of a service account.
195 | :param boolean x_client_request_id_header: include x-client-request-id. `x-client-request-id` is a unique
196 | request ID. It is generated using uuid. Send this ID to the technical support team to help us find
197 | a specific request in the system and assist you. To get x_client_request_id_header use
198 | `Session.get_x_client_request_id()` method.
199 | :param boolean x_data_logging_enabled: A flag that allows data passed by the user in the request to be saved.
200 | By default, we do not save any audio or text that you send. If you pass the true value in this header,
201 | your data is saved. This data, along with the request ID, will help the Yandex technical support team solve
202 | your problem.
203 | :return: Session instance
204 | :rtype: Session
205 | """
206 | if not isinstance(yandex_passport_oauth_token, str):
207 | raise ValueError(
208 | "yandex_passport_oauth_token must be string, but got {}".format(type(yandex_passport_oauth_token))
209 | )
210 | if len(yandex_passport_oauth_token) == 0:
211 | raise ValueError("yandex_passport_oauth_token can not be empty.")
212 |
213 | if not isinstance(folder_id, str):
214 | raise ValueError("folder_id must be string, but got {}".format(type(folder_id)))
215 | if len(folder_id) == 0:
216 | raise ValueError("folder_id must not be empty.")
217 |
218 | iam_token = get_iam_token(yandex_passport_oauth_token=yandex_passport_oauth_token)
219 |
220 | return cls(cls.IAM_TOKEN, iam_token, folder_id=folder_id, x_client_request_id_header=x_client_request_id_header,
221 | x_data_logging_enabled=x_data_logging_enabled)
222 |
223 | @classmethod
224 | def from_jwt(cls, jwt_token, folder_id=None, x_client_request_id_header=False, x_data_logging_enabled=False):
225 | """
226 | Creates Session from JWT token
227 |
228 | :param string jwt_token: JWT
229 | :param string | None folder_id: Id of the folder that you have access to. Don't specify this field if
230 | you make a request on behalf of a service account.
231 | :param boolean x_client_request_id_header: include x-client-request-id. `x-client-request-id` is a unique
232 | request ID. It is generated using uuid. Send this ID to the technical support team to help us find
233 | a specific request in the system and assist you. To get x_client_request_id_header use
234 | `Session.get_x_client_request_id()` method.
235 | :param boolean x_data_logging_enabled: A flag that allows data passed by the user in the request to be saved.
236 | By default, we do not save any audio or text that you send. If you pass the true value in this header,
237 | your data is saved. This data, along with the request ID, will help the Yandex technical support team solve
238 | your problem.
239 | :return: Session instance
240 | :rtype: Session
241 | """
242 | if not isinstance(jwt_token, str):
243 | raise ValueError("jwt_token must be string, but got {}".format(type(jwt_token)))
244 | if len(jwt_token) == 0:
245 | raise ValueError("jwt_token can not be empty.")
246 |
247 | if folder_id:
248 | if not isinstance(folder_id, str):
249 | raise ValueError("folder_id must be string, but got {}".format(type(folder_id)))
250 | if len(folder_id) == 0:
251 | raise ValueError("folder_id must not be empty.")
252 |
253 | iam_token = get_iam_token(jwt_token=jwt_token)
254 |
255 | return cls(cls.IAM_TOKEN, iam_token, folder_id=folder_id, x_client_request_id_header=x_client_request_id_header,
256 | x_data_logging_enabled=x_data_logging_enabled)
257 |
258 | @property
259 | def header(self):
260 | """
261 | Authentication header.
262 |
263 | :return: Dict in format `{'Authorization': 'Bearer or Api-Key {iam or api_key}'}`
264 | :rtype: dict
265 | """
266 | if self._auth_method == self.IAM_TOKEN:
267 | h = {'Authorization': 'Bearer {iam}'.format(iam=self._credential)}
268 | elif self._auth_method == self.API_KEY:
269 | h = {'Authorization': 'Api-Key {api_key}'.format(api_key=self._credential)}
270 | else:
271 | return
272 | if self._x_client_request_id is not None:
273 | h.update({'x-client-request-id': self._x_client_request_id})
274 | if self._x_data_logging_enabled:
275 | h.update({'x-data-logging-enabled': 'true'})
276 | return h
277 |
278 | @property
279 | def streaming_recognition_header(self):
280 | """
281 | Authentication header for streaming recognition
282 |
283 | :return: Tuple in format `('authorization', 'Bearer or Api-Key {iam or api_key}')`
284 | :rtype: tuple
285 | """
286 |
287 | if self._auth_method == self.IAM_TOKEN:
288 | h = tuple(('authorization', 'Bearer {iam}'.format(iam=self._credential),))
289 | elif self._auth_method == self.API_KEY:
290 | h = tuple(('authorization', 'Api-Key {api_key}'.format(api_key=self._credential),))
291 | else:
292 | return
293 |
294 | if self._x_client_request_id is not None:
295 | h = h + tuple(('x-client-request-id', self._x_client_request_id,))
296 | if self._x_data_logging_enabled:
297 | h = h + tuple(('x-data-logging-enabled', 'true',))
298 | return h
299 |
300 | @property
301 | def auth_method(self):
302 | """Get auth method it may be `Session.IAM_TOKEN` or `Session.API_KEY`"""
303 |
304 | return self._auth_method
305 |
306 | def get_x_client_request_id(self):
307 | """Get generated x_client_request_id value, if enabled on init, else `None`"""
308 |
309 | return self._x_client_request_id
310 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/google/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/google/api/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/api/annotations_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: google/api/annotations.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 | from speechkit._recognition.google.api import http_pb2 as google_dot_api_dot_http__pb2
15 | from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
16 |
17 |
18 | DESCRIPTOR = _descriptor.FileDescriptor(
19 | name='google/api/annotations.proto',
20 | package='google.api',
21 | syntax='proto3',
22 | serialized_options=b'\n\016com.google.apiB\020AnnotationsProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI',
23 | create_key=_descriptor._internal_create_key,
24 | serialized_pb=b'\n\x1cgoogle/api/annotations.proto\x12\ngoogle.api\x1a\x15google/api/http.proto\x1a google/protobuf/descriptor.proto:E\n\x04http\x12\x1e.google.protobuf.MethodOptions\x18\xb0\xca\xbc\" \x01(\x0b\x32\x14.google.api.HttpRuleBn\n\x0e\x63om.google.apiB\x10\x41nnotationsProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3'
25 | ,
26 | dependencies=[google_dot_api_dot_http__pb2.DESCRIPTOR,google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
27 |
28 |
29 | HTTP_FIELD_NUMBER = 72295728
30 | http = _descriptor.FieldDescriptor(
31 | name='http', full_name='google.api.http', index=0,
32 | number=72295728, type=11, cpp_type=10, label=1,
33 | has_default_value=False, default_value=None,
34 | message_type=None, enum_type=None, containing_type=None,
35 | is_extension=True, extension_scope=None,
36 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
37 |
38 | DESCRIPTOR.extensions_by_name['http'] = http
39 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
40 |
41 | http.message_type = google_dot_api_dot_http__pb2._HTTPRULE
42 | google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(http)
43 |
44 | DESCRIPTOR._options = None
45 | # @@protoc_insertion_point(module_scope)
46 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/api/annotations_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/api/http_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: google/api/http.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 |
15 |
16 | DESCRIPTOR = _descriptor.FileDescriptor(
17 | name='google/api/http.proto',
18 | package='google.api',
19 | syntax='proto3',
20 | serialized_options=b'\n\016com.google.apiB\tHttpProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\370\001\001\242\002\004GAPI',
21 | create_key=_descriptor._internal_create_key,
22 | serialized_pb=b'\n\x15google/api/http.proto\x12\ngoogle.api\"+\n\x04Http\x12#\n\x05rules\x18\x01 \x03(\x0b\x32\x14.google.api.HttpRule\"\xea\x01\n\x08HttpRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\r\n\x03get\x18\x02 \x01(\tH\x00\x12\r\n\x03put\x18\x03 \x01(\tH\x00\x12\x0e\n\x04post\x18\x04 \x01(\tH\x00\x12\x10\n\x06\x64\x65lete\x18\x05 \x01(\tH\x00\x12\x0f\n\x05patch\x18\x06 \x01(\tH\x00\x12/\n\x06\x63ustom\x18\x08 \x01(\x0b\x32\x1d.google.api.CustomHttpPatternH\x00\x12\x0c\n\x04\x62ody\x18\x07 \x01(\t\x12\x31\n\x13\x61\x64\x64itional_bindings\x18\x0b \x03(\x0b\x32\x14.google.api.HttpRuleB\t\n\x07pattern\"/\n\x11\x43ustomHttpPattern\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\tBj\n\x0e\x63om.google.apiB\tHttpProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xf8\x01\x01\xa2\x02\x04GAPIb\x06proto3'
23 | )
24 |
25 |
26 |
27 |
28 | _HTTP = _descriptor.Descriptor(
29 | name='Http',
30 | full_name='google.api.Http',
31 | filename=None,
32 | file=DESCRIPTOR,
33 | containing_type=None,
34 | create_key=_descriptor._internal_create_key,
35 | fields=[
36 | _descriptor.FieldDescriptor(
37 | name='rules', full_name='google.api.Http.rules', index=0,
38 | number=1, type=11, cpp_type=10, label=3,
39 | has_default_value=False, default_value=[],
40 | message_type=None, enum_type=None, containing_type=None,
41 | is_extension=False, extension_scope=None,
42 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
43 | ],
44 | extensions=[
45 | ],
46 | nested_types=[],
47 | enum_types=[
48 | ],
49 | serialized_options=None,
50 | is_extendable=False,
51 | syntax='proto3',
52 | extension_ranges=[],
53 | oneofs=[
54 | ],
55 | serialized_start=37,
56 | serialized_end=80,
57 | )
58 |
59 |
60 | _HTTPRULE = _descriptor.Descriptor(
61 | name='HttpRule',
62 | full_name='google.api.HttpRule',
63 | filename=None,
64 | file=DESCRIPTOR,
65 | containing_type=None,
66 | create_key=_descriptor._internal_create_key,
67 | fields=[
68 | _descriptor.FieldDescriptor(
69 | name='selector', full_name='google.api.HttpRule.selector', index=0,
70 | number=1, type=9, cpp_type=9, label=1,
71 | has_default_value=False, default_value=b"".decode('utf-8'),
72 | message_type=None, enum_type=None, containing_type=None,
73 | is_extension=False, extension_scope=None,
74 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
75 | _descriptor.FieldDescriptor(
76 | name='get', full_name='google.api.HttpRule.get', index=1,
77 | number=2, type=9, cpp_type=9, label=1,
78 | has_default_value=False, default_value=b"".decode('utf-8'),
79 | message_type=None, enum_type=None, containing_type=None,
80 | is_extension=False, extension_scope=None,
81 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
82 | _descriptor.FieldDescriptor(
83 | name='put', full_name='google.api.HttpRule.put', index=2,
84 | number=3, type=9, cpp_type=9, label=1,
85 | has_default_value=False, default_value=b"".decode('utf-8'),
86 | message_type=None, enum_type=None, containing_type=None,
87 | is_extension=False, extension_scope=None,
88 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
89 | _descriptor.FieldDescriptor(
90 | name='post', full_name='google.api.HttpRule.post', index=3,
91 | number=4, type=9, cpp_type=9, label=1,
92 | has_default_value=False, default_value=b"".decode('utf-8'),
93 | message_type=None, enum_type=None, containing_type=None,
94 | is_extension=False, extension_scope=None,
95 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
96 | _descriptor.FieldDescriptor(
97 | name='delete', full_name='google.api.HttpRule.delete', index=4,
98 | number=5, type=9, cpp_type=9, label=1,
99 | has_default_value=False, default_value=b"".decode('utf-8'),
100 | message_type=None, enum_type=None, containing_type=None,
101 | is_extension=False, extension_scope=None,
102 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
103 | _descriptor.FieldDescriptor(
104 | name='patch', full_name='google.api.HttpRule.patch', index=5,
105 | number=6, type=9, cpp_type=9, label=1,
106 | has_default_value=False, default_value=b"".decode('utf-8'),
107 | message_type=None, enum_type=None, containing_type=None,
108 | is_extension=False, extension_scope=None,
109 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
110 | _descriptor.FieldDescriptor(
111 | name='custom', full_name='google.api.HttpRule.custom', index=6,
112 | number=8, type=11, cpp_type=10, label=1,
113 | has_default_value=False, default_value=None,
114 | message_type=None, enum_type=None, containing_type=None,
115 | is_extension=False, extension_scope=None,
116 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
117 | _descriptor.FieldDescriptor(
118 | name='body', full_name='google.api.HttpRule.body', index=7,
119 | number=7, type=9, cpp_type=9, label=1,
120 | has_default_value=False, default_value=b"".decode('utf-8'),
121 | message_type=None, enum_type=None, containing_type=None,
122 | is_extension=False, extension_scope=None,
123 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
124 | _descriptor.FieldDescriptor(
125 | name='additional_bindings', full_name='google.api.HttpRule.additional_bindings', index=8,
126 | number=11, type=11, cpp_type=10, label=3,
127 | has_default_value=False, default_value=[],
128 | message_type=None, enum_type=None, containing_type=None,
129 | is_extension=False, extension_scope=None,
130 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
131 | ],
132 | extensions=[
133 | ],
134 | nested_types=[],
135 | enum_types=[
136 | ],
137 | serialized_options=None,
138 | is_extendable=False,
139 | syntax='proto3',
140 | extension_ranges=[],
141 | oneofs=[
142 | _descriptor.OneofDescriptor(
143 | name='pattern', full_name='google.api.HttpRule.pattern',
144 | index=0, containing_type=None,
145 | create_key=_descriptor._internal_create_key,
146 | fields=[]),
147 | ],
148 | serialized_start=83,
149 | serialized_end=317,
150 | )
151 |
152 |
153 | _CUSTOMHTTPPATTERN = _descriptor.Descriptor(
154 | name='CustomHttpPattern',
155 | full_name='google.api.CustomHttpPattern',
156 | filename=None,
157 | file=DESCRIPTOR,
158 | containing_type=None,
159 | create_key=_descriptor._internal_create_key,
160 | fields=[
161 | _descriptor.FieldDescriptor(
162 | name='kind', full_name='google.api.CustomHttpPattern.kind', index=0,
163 | number=1, type=9, cpp_type=9, label=1,
164 | has_default_value=False, default_value=b"".decode('utf-8'),
165 | message_type=None, enum_type=None, containing_type=None,
166 | is_extension=False, extension_scope=None,
167 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
168 | _descriptor.FieldDescriptor(
169 | name='path', full_name='google.api.CustomHttpPattern.path', index=1,
170 | number=2, type=9, cpp_type=9, label=1,
171 | has_default_value=False, default_value=b"".decode('utf-8'),
172 | message_type=None, enum_type=None, containing_type=None,
173 | is_extension=False, extension_scope=None,
174 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
175 | ],
176 | extensions=[
177 | ],
178 | nested_types=[],
179 | enum_types=[
180 | ],
181 | serialized_options=None,
182 | is_extendable=False,
183 | syntax='proto3',
184 | extension_ranges=[],
185 | oneofs=[
186 | ],
187 | serialized_start=319,
188 | serialized_end=366,
189 | )
190 |
191 | _HTTP.fields_by_name['rules'].message_type = _HTTPRULE
192 | _HTTPRULE.fields_by_name['custom'].message_type = _CUSTOMHTTPPATTERN
193 | _HTTPRULE.fields_by_name['additional_bindings'].message_type = _HTTPRULE
194 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
195 | _HTTPRULE.fields_by_name['get'])
196 | _HTTPRULE.fields_by_name['get'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
197 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
198 | _HTTPRULE.fields_by_name['put'])
199 | _HTTPRULE.fields_by_name['put'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
200 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
201 | _HTTPRULE.fields_by_name['post'])
202 | _HTTPRULE.fields_by_name['post'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
203 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
204 | _HTTPRULE.fields_by_name['delete'])
205 | _HTTPRULE.fields_by_name['delete'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
206 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
207 | _HTTPRULE.fields_by_name['patch'])
208 | _HTTPRULE.fields_by_name['patch'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
209 | _HTTPRULE.oneofs_by_name['pattern'].fields.append(
210 | _HTTPRULE.fields_by_name['custom'])
211 | _HTTPRULE.fields_by_name['custom'].containing_oneof = _HTTPRULE.oneofs_by_name['pattern']
212 | DESCRIPTOR.message_types_by_name['Http'] = _HTTP
213 | DESCRIPTOR.message_types_by_name['HttpRule'] = _HTTPRULE
214 | DESCRIPTOR.message_types_by_name['CustomHttpPattern'] = _CUSTOMHTTPPATTERN
215 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
216 |
217 | Http = _reflection.GeneratedProtocolMessageType('Http', (_message.Message,), {
218 | 'DESCRIPTOR' : _HTTP,
219 | '__module__' : 'google.api.http_pb2'
220 | # @@protoc_insertion_point(class_scope:google.api.Http)
221 | })
222 | _sym_db.RegisterMessage(Http)
223 |
224 | HttpRule = _reflection.GeneratedProtocolMessageType('HttpRule', (_message.Message,), {
225 | 'DESCRIPTOR' : _HTTPRULE,
226 | '__module__' : 'google.api.http_pb2'
227 | # @@protoc_insertion_point(class_scope:google.api.HttpRule)
228 | })
229 | _sym_db.RegisterMessage(HttpRule)
230 |
231 | CustomHttpPattern = _reflection.GeneratedProtocolMessageType('CustomHttpPattern', (_message.Message,), {
232 | 'DESCRIPTOR' : _CUSTOMHTTPPATTERN,
233 | '__module__' : 'google.api.http_pb2'
234 | # @@protoc_insertion_point(class_scope:google.api.CustomHttpPattern)
235 | })
236 | _sym_db.RegisterMessage(CustomHttpPattern)
237 |
238 |
239 | DESCRIPTOR._options = None
240 | # @@protoc_insertion_point(module_scope)
241 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/api/http_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/rpc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/google/rpc/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/rpc/status_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: google/rpc/status.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 | from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
15 |
16 |
17 | DESCRIPTOR = _descriptor.FileDescriptor(
18 | name='google/rpc/status.proto',
19 | package='google.rpc',
20 | syntax='proto3',
21 | serialized_options=b'\n\016com.google.rpcB\013StatusProtoP\001Z7google.golang.org/genproto/googleapis/rpc/status;status\242\002\003RPC',
22 | create_key=_descriptor._internal_create_key,
23 | serialized_pb=b'\n\x17google/rpc/status.proto\x12\ngoogle.rpc\x1a\x19google/protobuf/any.proto\"N\n\x06Status\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12%\n\x07\x64\x65tails\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyB^\n\x0e\x63om.google.rpcB\x0bStatusProtoP\x01Z7google.golang.org/genproto/googleapis/rpc/status;status\xa2\x02\x03RPCb\x06proto3'
24 | ,
25 | dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,])
26 |
27 |
28 |
29 |
30 | _STATUS = _descriptor.Descriptor(
31 | name='Status',
32 | full_name='google.rpc.Status',
33 | filename=None,
34 | file=DESCRIPTOR,
35 | containing_type=None,
36 | create_key=_descriptor._internal_create_key,
37 | fields=[
38 | _descriptor.FieldDescriptor(
39 | name='code', full_name='google.rpc.Status.code', index=0,
40 | number=1, type=5, cpp_type=1, label=1,
41 | has_default_value=False, default_value=0,
42 | message_type=None, enum_type=None, containing_type=None,
43 | is_extension=False, extension_scope=None,
44 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
45 | _descriptor.FieldDescriptor(
46 | name='message', full_name='google.rpc.Status.message', index=1,
47 | number=2, type=9, cpp_type=9, label=1,
48 | has_default_value=False, default_value=b"".decode('utf-8'),
49 | message_type=None, enum_type=None, containing_type=None,
50 | is_extension=False, extension_scope=None,
51 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
52 | _descriptor.FieldDescriptor(
53 | name='details', full_name='google.rpc.Status.details', index=2,
54 | number=3, type=11, cpp_type=10, label=3,
55 | has_default_value=False, default_value=[],
56 | message_type=None, enum_type=None, containing_type=None,
57 | is_extension=False, extension_scope=None,
58 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
59 | ],
60 | extensions=[
61 | ],
62 | nested_types=[],
63 | enum_types=[
64 | ],
65 | serialized_options=None,
66 | is_extendable=False,
67 | syntax='proto3',
68 | extension_ranges=[],
69 | oneofs=[
70 | ],
71 | serialized_start=66,
72 | serialized_end=144,
73 | )
74 |
75 | _STATUS.fields_by_name['details'].message_type = google_dot_protobuf_dot_any__pb2._ANY
76 | DESCRIPTOR.message_types_by_name['Status'] = _STATUS
77 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
78 |
79 | Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), {
80 | 'DESCRIPTOR' : _STATUS,
81 | '__module__' : 'google.rpc.status_pb2'
82 | # @@protoc_insertion_point(class_scope:google.rpc.Status)
83 | })
84 | _sym_db.RegisterMessage(Status)
85 |
86 |
87 | DESCRIPTOR._options = None
88 | # @@protoc_insertion_point(module_scope)
89 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/google/rpc/status_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/streaming_recognition.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | import grpc
4 |
5 | import speechkit._recognition.yandex.cloud.ai.stt.v2.stt_service_pb2 as stt_service_pb2
6 | import speechkit._recognition.yandex.cloud.ai.stt.v2.stt_service_pb2_grpc as stt_service_pb2_grpc
7 |
8 |
9 | class DataStreamingRecognition:
10 | """
11 | Data streaming mode allows you to simultaneously send audio for recognition and
12 | get recognition results over the same connection.
13 |
14 | Unlike other recognition methods, you can get intermediate results while speech
15 | is in progress. After a pause, the service returns final results and starts recognizing the next utterance.
16 |
17 | After receiving the message with the recognition settings, the service starts a recognition session.
18 | The following limitations apply to each session:
19 |
20 | 1. You can't send audio fragments too often or too rarely. The time between messages to the service should be
21 | approximately the same as the duration of the audio fragments you send, but no more than 5 seconds.
22 | For example, send 400 ms of audio for recognition every 400 ms.
23 |
24 | 2. Maximum duration of transmitted audio for the entire session: 5 minutes.
25 |
26 | 3. Maximum size of transmitted audio data: 10 MB.
27 |
28 | To use this type of recognition, you need to create function that yields bytes data
29 |
30 | :Example:
31 |
32 | >>> chunk_size = 4000
33 | >>> session = Session.from_jwt("jwt")
34 | >>> data_streaming_recognition = DataStreamingRecognition(
35 | ... session,
36 | ... language_code='ru-RU',
37 | ... audio_encoding='LINEAR16_PCM',
38 | ... session=8000,
39 | ... partial_results=False,
40 | ... single_utterance=True,
41 | ... )
42 | ...
43 | >>> def gen_audio_from_file_function():
44 | ... with open('/path/to/pcm_data/speech.pcm', 'rb') as f:
45 | ... data = f.read(chunk_size)
46 | ... while data != b'':
47 | ... yield data
48 | ... data = f.read(chunk_size)
49 | ...
50 | >>> for i in data_streaming_recognition.recognize(gen_audio_capture_function):
51 | ... print(i) # (['text'], final_flag, end_of_utterance_flag)
52 | ...
53 |
54 | Read more about streaming recognition in
55 | `Yandex streaming recognition docs `_
56 | """
57 |
58 | def __init__(
59 | self, session, language_code=None, model=None, profanity_filter=None, partial_results=None,
60 | single_utterance=None, audio_encoding=None, sample_rate_hertz=None, raw_results=None
61 | ):
62 | """
63 | Initialize :py:class:`speechkit.DataStreamingRecognition`
64 |
65 | :param speechkit._auth.Session session: Session instance for auth
66 |
67 | :param string | None language_code: The language to use for recognition. Acceptable values:
68 | `ru-ru` (case-insensitive, used by default): Russian, `en-us` (case-insensitive): English,
69 | `tr-tr` (case-insensitive): Turkish.
70 |
71 | :param string | None model: The language model to be used for recognition. The closer the model is matched,
72 | the better the recognition result. You can only specify one model per request. Default value: `general`.
73 |
74 | :param boolean | None profanity_filter: The profanity filter. Acceptable values:
75 | `true`: Exclude profanity from recognition results,
76 | `false` (default): Do not exclude profanity from recognition results.
77 |
78 | :param boolean | None partial_results: The intermediate results filter. Acceptable values:
79 | `true`: Return intermediate results (part of the recognized utterance).
80 | For intermediate results, final is set to false,
81 | `false` (default): Return only the final results (the entire recognized utterance).
82 |
83 | :param boolean | None single_utterance: Flag that disables recognition after the first utterance.
84 | Acceptable values: `true`: Recognize only the first utterance, stop recognition, and wait for the user
85 | to disconnect, `false` (default): Continue recognition until the end of the session.
86 |
87 | :param string | None audio_encoding: The format of the submitted audio. Acceptable values:
88 | `LINEAR16_PCM`: LPCM with no WAV header, `OGG_OPUS` (default): OggOpus format.
89 |
90 | :param integer | None sample_rate_hertz: (int64) The sampling frequency of the submitted audio.
91 | Required if format is set to LINEAR16_PCM. Acceptable values: `48000` (default): Sampling rate of 48 kHz,
92 | `16000`: Sampling rate of 16 kHz, `8000`: Sampling rate of 8 kHz.
93 |
94 | :param boolean | None raw_results: Flag that indicates how to write numbers. `true`: In words.
95 | `false` (default): In figures.
96 | """
97 | self._headers = session.streaming_recognition_header
98 | self._folder_id = session.folder_id
99 |
100 | specification_options = {k: v for k, v in {
101 | 'language_code': language_code, 'model': model, 'profanity_filter': profanity_filter,
102 | 'partial_results': partial_results, 'single_utterance': single_utterance,
103 | 'audio_encoding': audio_encoding, 'sample_rate_hertz': sample_rate_hertz, 'raw_results': raw_results
104 | }.items() if v is not None}
105 |
106 | config = {'specification': stt_service_pb2.RecognitionSpec(**specification_options)}
107 | if self._folder_id:
108 | config['folder_id'] = self._folder_id
109 |
110 | self._streaming_config = stt_service_pb2.RecognitionConfig(**config)
111 |
112 | def _gen(self, gen_audio_function, *args, **kwargs):
113 | """
114 | Generate audio fragments. Pass args and kwargs to pass it into :py:meth:`gen_audio_function`.
115 |
116 | :param function gen_audio_function: Function generates audio data
117 | :return: Serialized data for sending
118 | """
119 | try:
120 | if not callable(gen_audio_function):
121 | raise RuntimeError("`self._gen_audio_function` must be callable.")
122 |
123 | yield stt_service_pb2.StreamingRecognitionRequest(config=self._streaming_config)
124 |
125 | for data in gen_audio_function(*args, **kwargs):
126 | yield stt_service_pb2.StreamingRecognitionRequest(audio_content=data)
127 |
128 | except Exception as e:
129 | logging.error(e)
130 | raise e
131 |
132 | def recognize_raw(self, gen_audio_function, *args, **kwargs):
133 | """
134 | Recognize streaming data, gen_audio_function must yield audio data with parameters given in init.
135 | Answer type read in `Yandex Docs `_.
136 | Pass args and kwargs to pass it into :py:meth:`gen_audio_function`.
137 |
138 | :param function gen_audio_function: Function generates audio data
139 | :return: Yields recognized data in raw format
140 | :rtype: speechkit._recognition.yandex.cloud.ai.stt.v2.stt_service_pb2.StreamingRecognitionResponse
141 | """
142 | if not callable(gen_audio_function):
143 | raise RuntimeError("`gen_audio_function` must be callable.")
144 |
145 | cred = grpc.ssl_channel_credentials()
146 | channel = grpc.secure_channel('stt.api.cloud.yandex.net:443', cred)
147 | stub = stt_service_pb2_grpc.SttServiceStub(channel)
148 |
149 | it = stub.StreamingRecognize(self._gen(gen_audio_function, *args, **kwargs), metadata=(self._headers,))
150 |
151 | for chunk in it:
152 | yield chunk
153 |
154 | def recognize(self, gen_audio_function, *args, **kwargs):
155 | """
156 | Recognize streaming data, gen_audio_function must yield audio data with parameters given in init.
157 | Pass args and kwargs to pass it into :py:meth:`gen_audio_function`.
158 |
159 | :param function gen_audio_function: Function generates audio data
160 | :return: yields tuple, where first element is list of alternatives text, second final (boolean) flag,
161 | third endOfUtterance (boolean) flag, ex. (['text'], False, False)
162 | :rtype: tuple
163 | """
164 | for item in self.recognize_raw(gen_audio_function, *args, **kwargs):
165 | alternatives = [i.text for i in item.chunks[0].alternatives]
166 | final = item.chunks[0].final
167 | end_of_utterance = item.chunks[0].end_of_utterance
168 | yield alternatives, final, end_of_utterance
169 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/sync_recognition.py:
--------------------------------------------------------------------------------
1 | import io
2 | import sys
3 | import uuid
4 | from pathlib import Path
5 |
6 | import boto3
7 | import requests
8 |
9 | from speechkit.exceptions import RequestError
10 |
11 |
12 | class ShortAudioRecognition:
13 | """
14 | Short audio recognition ensures fast response time and is suitable for single-channel audio of small length.
15 |
16 | Audio requirements:
17 | 1. Maximum file size: 1 MB.
18 | 2. Maximum length: 30 seconds.
19 | 3. Maximum number of audio channels: 1.
20 |
21 | If your file is larger, longer, or has more audio channels, use :py:class:`speechkit.RecognitionLongAudio`.
22 | """
23 |
24 | def __init__(self, session):
25 | """
26 | Initialization :py:class:`speechkit.ShortAudioRecognition`
27 |
28 | :param speechkit.Session session: Session instance for auth
29 | """
30 | self._headers = session.header
31 | self._folder_id = session.folder_id
32 |
33 | def recognize(self, data, **kwargs):
34 | """
35 | Recognize text from BytesIO data given, which is audio
36 |
37 | :type data: io.BytesIO, bytes
38 | :param data: Data with audio samples to recognize
39 |
40 | :type lang: string
41 | :param lang: The language to use for recognition. Acceptable values:
42 |
43 | * `ru-RU` (by default) — Russian.
44 |
45 | * `en-US` — English.
46 |
47 | * `tr-TR` — Turkish.
48 |
49 | :type topic: string
50 | :param topic: The language model to be used for recognition. Default value: `general`.
51 |
52 | :type profanityFilter: boolean
53 | :param profanityFilter: This parameter controls the profanity filter in recognized speech.
54 |
55 | :type format: string
56 | :param format: The format of the submitted audio. Acceptable values:
57 |
58 | * `lpcm` — LPCM with no WAV _header.
59 |
60 | * `oggopus` (default) — OggOpus.
61 |
62 | :param string sampleRateHertz: The sampling frequency of the submitted audio.
63 | Used if format is set to lpcm. Acceptable values:
64 |
65 | * `48000` (default) — Sampling rate of 48 kHz.
66 |
67 | * `16000` — Sampling rate of 16 kHz.
68 |
69 | * `8000` — Sampling rate of 8 kHz.
70 |
71 | :param string folderId: ID of the folder that you have access to. Don't specify this field if
72 | you make a request on behalf of a service account.
73 |
74 | :return: The recognized text
75 | :rtype: string
76 | """
77 | if not isinstance(data, (io.BytesIO, bytes)):
78 | raise ValueError("Data must be bytes io or bytes.")
79 |
80 | if 'lang' in kwargs:
81 | if not type(kwargs['lang']) is str:
82 | raise TypeError("__init__() kwargs['lang']: got {} but expected \
83 | type is str".format(type(kwargs["lang"]).__name__))
84 |
85 | if self._headers is None:
86 | raise RuntimeError("You must call `ShortAudioRecognition.__init__()` first.")
87 |
88 | if sys.getsizeof(data) > 1024 * 1024:
89 | raise ValueError("Maximum file size: 1 MB. Got {} bytes.".format(sys.getsizeof(data)))
90 |
91 | if kwargs.get('format') == 'lpcm':
92 | sample_rate_hertz = int(kwargs.get('sample_rate_hertz', '48000'))
93 | seconds_duration = (sys.getsizeof(data) * 8) / (sample_rate_hertz * 1 * 16)
94 |
95 | if seconds_duration > 30:
96 | raise ValueError(
97 | "Maximum length: 30 seconds. Maximum number of audio channels: 1. Calculated length - {}".format(
98 | seconds_duration))
99 |
100 | params = {'folderId': self._folder_id} if self._folder_id else {}
101 | params.update(kwargs)
102 | url = 'https://stt.api.cloud.yandex.net/speech/v1/stt:recognize'
103 | answer = requests.post(url, params=params, data=data, headers=self._headers)
104 |
105 | if answer.ok:
106 | return answer.json().get('result')
107 | else:
108 | raise RequestError(answer.json())
109 |
110 |
111 | class RecognitionLongAudio:
112 | """
113 | Long audio fragment recognition can be used for multi-channel audio files up to 1 GB.
114 | To recognize long audio fragments, you need to execute 2 requests:
115 |
116 | * Send a file for recognition.
117 |
118 | * Get recognition results.
119 |
120 | :Example:
121 |
122 | >>> recognizeLongAudio = RecognitionLongAudio(session, '')
123 | >>> recognizeLongAudio.send_for_recognition('file/path')
124 | >>> if recognizeLongAudio.get_recognition_results():
125 | ... data = recognizeLongAudio.get_data()
126 | ...
127 | >>> recognizeLongAudio.get_raw_text()
128 | ...'raw recognized text'
129 | """
130 |
131 | def __init__(self, session, service_account_id, aws_bucket_name=None,
132 | aws_credentials_description='Default AWS credentials created by `speechkit` python SDK',
133 | aws_region_name='ru-central1', aws_access_key_id=None, aws_secret=None):
134 | """
135 | Initialize :py:class:`speechkit.RecognitionLongAudio`
136 |
137 | :param speechkit.Session session: Session instance for auth
138 | :param string service_account_id: Yandex Cloud Service account ID
139 | :param string aws_bucket_name: Optional AWS bucket name
140 | :param string aws_credentials_description: AWS credentials description
141 | :param string aws_region_name: AWS region name
142 | :param string aws_access_key_id: Optional AWS access key. Can be got by `.get_aws_credentials`.
143 | If None will be generated automatically
144 | :param string aws_secret: Optional AWS secret. Can be got by `.get_aws_credentials`.
145 | If None will be generated automatically
146 | """
147 | self._id = None
148 | self._answer_data = None
149 | self._aws_file_name = None
150 |
151 | self._headers = session.header
152 | if session.folder_id:
153 | raise ValueError("folder_id specify is not supported, use jwt.")
154 | if session.auth_method == session.API_KEY:
155 | raise ValueError("Only jwt method supported")
156 |
157 | if aws_access_key_id and aws_secret:
158 | self._s3 = self._init_aws(
159 | aws_access_key_id=aws_access_key_id,
160 | aws_secret_access_key=aws_secret,
161 | region_name=aws_region_name,
162 | )
163 | else:
164 | access_key_id, secret = self.get_aws_credentials(session, service_account_id, aws_credentials_description)
165 | self._s3 = self._init_aws(
166 | aws_access_key_id=access_key_id,
167 | aws_secret_access_key=secret,
168 | region_name=aws_region_name,
169 | )
170 |
171 | if aws_bucket_name:
172 | self._aws_bucket_name = aws_bucket_name
173 | else:
174 | self._aws_bucket_name = 'py_speechkit_' + str(uuid.uuid4())
175 | self._s3.create_bucket(Bucket=self._aws_bucket_name)
176 |
177 | @staticmethod
178 | def _init_aws(**kwargs):
179 | """Get s3 session
180 |
181 | :param string aws_access_key_id: The access key to use when creating the client. This is entirely optional,
182 | and if not provided, the credentials configured for the session will automatically be used. You only need to
183 | provide this argument if you want to override the credentials used for this specific client.
184 |
185 | :param string aws_secret_access_key: The secret key to use when creating the client. Same semantics as
186 | aws_access_key_id above.
187 |
188 | :param string region_name: The name of the region associated with the client.
189 | A client is associated with a single region.
190 | """
191 |
192 | session = boto3.session.Session()
193 | return session.client(
194 | service_name='s3',
195 | endpoint_url='https://storage.yandexcloud.net',
196 | **kwargs
197 | )
198 |
199 | @staticmethod
200 | def get_aws_credentials(session, service_account_id,
201 | aws_credentials_description='Default AWS credentials created by `speechkit` python SDK'):
202 | """
203 | Get AWS credentials from yandex cloud
204 |
205 | :type session: speechkit.Session
206 | :param session: Session instance for auth
207 |
208 | :type service_account_id: string
209 | :param service_account_id: Yandex Cloud Service account ID
210 |
211 | :type aws_credentials_description: string
212 | :param aws_credentials_description: AWS credentials description
213 |
214 | :return: tuple with strings (access_key_id, secret)
215 | """
216 |
217 | if len(aws_credentials_description) > 256:
218 | raise ValueError("The maximum `description` string length in characters is 256.")
219 |
220 | url_aws_credentials = 'https://iam.api.cloud.yandex.net/iam/aws-compatibility/v1/accessKeys'
221 | data_aws_credentials = {'description': aws_credentials_description, 'serviceAccountId': service_account_id}
222 | answer = requests.post(url_aws_credentials, headers=session.header, json=data_aws_credentials)
223 |
224 | if not answer.ok:
225 | raise RequestError(answer.json())
226 |
227 | answer = answer.json()
228 | access_key_id = answer.get('accessKey', {}).get('keyId')
229 | secret = answer.get('secret')
230 | return access_key_id, secret
231 |
232 | def _aws_upload_file(self, file_path, baket_name, aws_file_name):
233 | """
234 | Upload a file to object storage
235 |
236 | :type file_path: string
237 | :param file_path: Path to input file
238 |
239 | :type baket_name: string
240 | :param baket_name:
241 |
242 | :type aws_file_name: string
243 | :param aws_file_name: Name of file in object storage
244 | """
245 |
246 | self._s3.upload_file(file_path, baket_name, aws_file_name)
247 |
248 | def _create_presigned_url(self, bucket_name, aws_file_name,
249 | expiration=3600):
250 | """Generate a presigned URL to share an S3 object
251 |
252 | :type bucket_name: string
253 |
254 | :type aws_file_name: string
255 | :param aws_file_name: Name of file in object storage
256 |
257 | :type expiration: integer
258 | :param expiration: Time in seconds for the presigned URL to remain valid
259 |
260 | :return: Resigned URL as string.
261 | :rtype: string
262 | """
263 |
264 | return self._s3.generate_presigned_url(
265 | 'get_object',
266 | Params={'Bucket': bucket_name, 'Key': aws_file_name},
267 | ExpiresIn=expiration
268 | )
269 |
270 | def _delete_object(self, bucket_name, aws_file_name):
271 | """Delete object in bucket
272 |
273 | :param string aws_file_name: Name of file in object storage
274 | :type bucket_name: string
275 | """
276 | return self._s3.delete_objects(
277 | Bucket=bucket_name, Delete={'Objects': [{'Key': aws_file_name}]})
278 |
279 | def send_for_recognition(self, file_path, **kwargs):
280 | """
281 | Send a file for recognition
282 |
283 | :param string file_path: Path to input file
284 |
285 | :param string folder_id: ID of the folder that you have access to. Don't specify this field if
286 | you make a request on behalf of a service account.
287 |
288 | :param string languageCode: The language that recognition will be performed for.
289 | Only Russian is currently supported (`ru-RU`).
290 |
291 | :param string model: The language model to be used for recognition.
292 | Default value: `general`.
293 |
294 | :param boolean profanityFilter: The profanity filters.
295 |
296 | :param string audioEncoding: The format of the submitted audio.
297 | Acceptable values:
298 |
299 | * `LINEAR16_PCM`: LPCM with no WAV _header.
300 |
301 | * `OGG_OPUS` (default): OggOpus format.
302 |
303 | :param integer sampleRateHertz: The sampling frequency of the submitted audio.
304 | Required if format is set to LINEAR16_PCM. Acceptable values:
305 |
306 | * `48000` (default): Sampling rate of 48 kHz.
307 |
308 | * `16000`: Sampling rate of 16 kHz.
309 |
310 | * `8000`: Sampling rate of 8 kHz.
311 |
312 | :param integer audioChannelCount: The number of channels in LPCM files.
313 | By default, `1`. Don't use this field for OggOpus files.
314 |
315 | :param boolean rawResults: Flag that indicates how to write numbers.
316 | `true`: In words. `false` (default): In figures.
317 |
318 | :rtype: None
319 | """
320 | self._aws_file_name = Path(file_path).name + str(uuid.uuid4())
321 | self._aws_upload_file(file_path, self._aws_bucket_name, self._aws_file_name)
322 | aws_presigned_url = self._create_presigned_url(self._aws_bucket_name, self._aws_file_name)
323 |
324 | url = "https://transcribe.api.cloud.yandex.net/" \
325 | "speech/stt/v2/longRunningRecognize"
326 |
327 | data = {
328 |
329 | "config": {
330 | "specification": {
331 | **kwargs
332 | }
333 | },
334 | "audio": {
335 | "uri": aws_presigned_url
336 | }
337 | }
338 | answer = requests.post(url, headers=self._headers, json=data)
339 | if answer.ok:
340 | self._id = answer.json().get('id')
341 | else:
342 | raise RequestError(answer.json())
343 |
344 | def get_recognition_results(self):
345 | """
346 | Monitor the recognition results using the received ID. The number of result monitoring requests is limited,
347 | so consider the recognition speed: it takes about 10 seconds to recognize 1 minute of single-channel audio.
348 |
349 | :return: State of recognition is done or not
350 | :rtype: boolean
351 | """
352 | if self._id is None:
353 | raise RuntimeError("You must send for recognition first.")
354 |
355 | url = "https://operation.api.cloud.yandex.net/operations/{id}".format(id=self._id)
356 | self._answer_data = requests.get(url, headers=self._headers)
357 | if self._answer_data.ok:
358 | self._answer_data = self._answer_data.json()
359 | done = self._answer_data.get('done')
360 | if done:
361 | self._delete_object(self._aws_bucket_name, self._aws_file_name)
362 |
363 | return done
364 | else:
365 | raise RequestError(self._answer_data.json())
366 |
367 | def get_data(self):
368 | """
369 | Get the response.
370 | Use :py:meth:`speechkit.RecognitionLongAudio.get_recognition_results` first to store _answer_data
371 |
372 | Contain a list of recognition results (`chunks[]`).
373 |
374 | :return: `None` if text not found ot Each result in the chunks[] list contains the following fields:
375 |
376 | * `alternatives[]`: List of recognized text alternatives. Each alternative contains the following fields:
377 |
378 | * `words[]`: List of recognized words:
379 |
380 | * `startTime`: Time stamp of the beginning of the word in the recording. An error of 1-2 seconds
381 | is possible.
382 |
383 | * `endTime`: Time stamp of the end of the word. An error of 1-2 seconds is possible.
384 |
385 | * `word`: Recognized word. Recognized numbers are written in words (for example, twelve rather
386 | than 12).
387 |
388 | * `confidence`: This field currently isn't supported. Don't use it.
389 |
390 | * `text`: Full recognized text. By default, numbers are written in figures. To recognition
391 | the entire text in words, specify true in the raw_results field.
392 |
393 | * `confidence`: This field currently isn't supported. Don't use it.
394 |
395 | * `channelTag`: Audio channel that recognition was performed for.
396 | :rtype: list | None
397 | """
398 |
399 | if self._answer_data is None:
400 | raise ValueError("You must call `RecognitionLongAudio.get_recognition_results` first")
401 | return self._answer_data.get('response', {}).get('chunks', [])
402 |
403 | def get_raw_text(self):
404 | """
405 | Get raw text from _answer_data data
406 |
407 | :return: Text
408 | :rtype: string
409 | """
410 | if self._answer_data is None:
411 | raise ValueError("You must call 'get_recognition_results' first")
412 |
413 | text = ''
414 | for chunk in self._answer_data.get('response', {}).get('chunks', []):
415 | if chunk['channelTag'] == '1':
416 | text += f"{chunk['alternatives'][0]['text'].strip()} "
417 | return text
418 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/ai/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/ai/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/ai/stt/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/ai/stt/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/ai/stt/v2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/ai/stt/v2/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/ai/stt/v2/stt_service_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: yandex/cloud/ai/stt/v2/stt_service.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 | from speechkit._recognition.google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
15 | from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
16 | from speechkit._recognition.yandex.cloud.api import operation_pb2 as yandex_dot_cloud_dot_api_dot_operation__pb2
17 | from speechkit._recognition.yandex.cloud.operation import operation_pb2 as yandex_dot_cloud_dot_operation_dot_operation__pb2
18 |
19 |
20 | DESCRIPTOR = _descriptor.FileDescriptor(
21 | name='yandex/cloud/ai/stt/v2/stt_service.proto',
22 | package='yandex.cloud.ai.stt.v2',
23 | syntax='proto3',
24 | serialized_options=b'\n\032yandex.cloud.api.ai.stt.v2Z>github.com/yandex-cloud/go-genproto/yandex/cloud/ai/stt/v2;stt',
25 | create_key=_descriptor._internal_create_key,
26 | serialized_pb=b'\n(yandex/cloud/ai/stt/v2/stt_service.proto\x12\x16yandex.cloud.ai.stt.v2\x1a\x1cgoogle/api/annotations.proto\x1a\x1egoogle/protobuf/duration.proto\x1a yandex/cloud/api/operation.proto\x1a&yandex/cloud/operation/operation.proto\"\x93\x01\n\x1dLongRunningRecognitionRequest\x12\x39\n\x06\x63onfig\x18\x01 \x01(\x0b\x32).yandex.cloud.ai.stt.v2.RecognitionConfig\x12\x37\n\x05\x61udio\x18\x02 \x01(\x0b\x32(.yandex.cloud.ai.stt.v2.RecognitionAudio\"a\n\x1eLongRunningRecognitionResponse\x12?\n\x06\x63hunks\x18\x01 \x03(\x0b\x32/.yandex.cloud.ai.stt.v2.SpeechRecognitionResult\"\x88\x01\n\x1bStreamingRecognitionRequest\x12;\n\x06\x63onfig\x18\x01 \x01(\x0b\x32).yandex.cloud.ai.stt.v2.RecognitionConfigH\x00\x12\x17\n\raudio_content\x18\x02 \x01(\x0cH\x00\x42\x13\n\x11streaming_request\"}\n\x1cStreamingRecognitionResponse\x12>\n\x06\x63hunks\x18\x01 \x03(\x0b\x32..yandex.cloud.ai.stt.v2.SpeechRecognitionChunkJ\x04\x08\x02\x10\x03R\x17\x65nd_of_single_utterance\"D\n\x10RecognitionAudio\x12\x11\n\x07\x63ontent\x18\x01 \x01(\x0cH\x00\x12\r\n\x03uri\x18\x02 \x01(\tH\x00\x42\x0e\n\x0c\x61udio_source\"f\n\x11RecognitionConfig\x12>\n\rspecification\x18\x01 \x01(\x0b\x32\'.yandex.cloud.ai.stt.v2.RecognitionSpec\x12\x11\n\tfolder_id\x18\x02 \x01(\t\"\xf1\x02\n\x0fRecognitionSpec\x12M\n\x0e\x61udio_encoding\x18\x01 \x01(\x0e\x32\x35.yandex.cloud.ai.stt.v2.RecognitionSpec.AudioEncoding\x12\x19\n\x11sample_rate_hertz\x18\x02 \x01(\x03\x12\x15\n\rlanguage_code\x18\x03 \x01(\t\x12\x18\n\x10profanity_filter\x18\x04 \x01(\x08\x12\r\n\x05model\x18\x05 \x01(\t\x12\x17\n\x0fpartial_results\x18\x07 \x01(\x08\x12\x18\n\x10single_utterance\x18\x08 \x01(\x08\x12\x1b\n\x13\x61udio_channel_count\x18\t \x01(\x03\x12\x13\n\x0braw_results\x18\n \x01(\x08\"O\n\rAudioEncoding\x12\x1e\n\x1a\x41UDIO_ENCODING_UNSPECIFIED\x10\x00\x12\x10\n\x0cLINEAR16_PCM\x10\x01\x12\x0c\n\x08OGG_OPUS\x10\x02\"\x8d\x01\n\x16SpeechRecognitionChunk\x12J\n\x0c\x61lternatives\x18\x01 \x03(\x0b\x32\x34.yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative\x12\r\n\x05\x66inal\x18\x02 \x01(\x08\x12\x18\n\x10\x65nd_of_utterance\x18\x03 \x01(\x08\"z\n\x17SpeechRecognitionResult\x12J\n\x0c\x61lternatives\x18\x01 \x03(\x0b\x32\x34.yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative\x12\x13\n\x0b\x63hannel_tag\x18\x02 \x01(\x03\"q\n\x1cSpeechRecognitionAlternative\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x12\n\nconfidence\x18\x02 \x01(\x02\x12/\n\x05words\x18\x03 \x03(\x0b\x32 .yandex.cloud.ai.stt.v2.WordInfo\"\x88\x01\n\x08WordInfo\x12-\n\nstart_time\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12+\n\x08\x65nd_time\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x0c\n\x04word\x18\x03 \x01(\t\x12\x12\n\nconfidence\x18\x04 \x01(\x02\x32\xdb\x02\n\nSttService\x12\xc4\x01\n\x14LongRunningRecognize\x12\x35.yandex.cloud.ai.stt.v2.LongRunningRecognitionRequest\x1a!.yandex.cloud.operation.Operation\"R\x82\xd3\xe4\x93\x02(\"#/speech/stt/v2/longRunningRecognize:\x01*\xb2\xd2* \x12\x1eLongRunningRecognitionResponse\x12\x85\x01\n\x12StreamingRecognize\x12\x33.yandex.cloud.ai.stt.v2.StreamingRecognitionRequest\x1a\x34.yandex.cloud.ai.stt.v2.StreamingRecognitionResponse\"\x00(\x01\x30\x01\x42\\\n\x1ayandex.cloud.api.ai.stt.v2Z>github.com/yandex-cloud/go-genproto/yandex/cloud/ai/stt/v2;sttb\x06proto3'
27 | ,
28 | dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_protobuf_dot_duration__pb2.DESCRIPTOR,yandex_dot_cloud_dot_api_dot_operation__pb2.DESCRIPTOR,yandex_dot_cloud_dot_operation_dot_operation__pb2.DESCRIPTOR,])
29 |
30 |
31 |
32 | _RECOGNITIONSPEC_AUDIOENCODING = _descriptor.EnumDescriptor(
33 | name='AudioEncoding',
34 | full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.AudioEncoding',
35 | filename=None,
36 | file=DESCRIPTOR,
37 | create_key=_descriptor._internal_create_key,
38 | values=[
39 | _descriptor.EnumValueDescriptor(
40 | name='AUDIO_ENCODING_UNSPECIFIED', index=0, number=0,
41 | serialized_options=None,
42 | type=None,
43 | create_key=_descriptor._internal_create_key),
44 | _descriptor.EnumValueDescriptor(
45 | name='LINEAR16_PCM', index=1, number=1,
46 | serialized_options=None,
47 | type=None,
48 | create_key=_descriptor._internal_create_key),
49 | _descriptor.EnumValueDescriptor(
50 | name='OGG_OPUS', index=2, number=2,
51 | serialized_options=None,
52 | type=None,
53 | create_key=_descriptor._internal_create_key),
54 | ],
55 | containing_type=None,
56 | serialized_options=None,
57 | serialized_start=1184,
58 | serialized_end=1263,
59 | )
60 | _sym_db.RegisterEnumDescriptor(_RECOGNITIONSPEC_AUDIOENCODING)
61 |
62 |
63 | _LONGRUNNINGRECOGNITIONREQUEST = _descriptor.Descriptor(
64 | name='LongRunningRecognitionRequest',
65 | full_name='yandex.cloud.ai.stt.v2.LongRunningRecognitionRequest',
66 | filename=None,
67 | file=DESCRIPTOR,
68 | containing_type=None,
69 | create_key=_descriptor._internal_create_key,
70 | fields=[
71 | _descriptor.FieldDescriptor(
72 | name='config', full_name='yandex.cloud.ai.stt.v2.LongRunningRecognitionRequest.config', index=0,
73 | number=1, type=11, cpp_type=10, label=1,
74 | has_default_value=False, default_value=None,
75 | message_type=None, enum_type=None, containing_type=None,
76 | is_extension=False, extension_scope=None,
77 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
78 | _descriptor.FieldDescriptor(
79 | name='audio', full_name='yandex.cloud.ai.stt.v2.LongRunningRecognitionRequest.audio', index=1,
80 | number=2, type=11, cpp_type=10, label=1,
81 | has_default_value=False, default_value=None,
82 | message_type=None, enum_type=None, containing_type=None,
83 | is_extension=False, extension_scope=None,
84 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
85 | ],
86 | extensions=[
87 | ],
88 | nested_types=[],
89 | enum_types=[
90 | ],
91 | serialized_options=None,
92 | is_extendable=False,
93 | syntax='proto3',
94 | extension_ranges=[],
95 | oneofs=[
96 | ],
97 | serialized_start=205,
98 | serialized_end=352,
99 | )
100 |
101 |
102 | _LONGRUNNINGRECOGNITIONRESPONSE = _descriptor.Descriptor(
103 | name='LongRunningRecognitionResponse',
104 | full_name='yandex.cloud.ai.stt.v2.LongRunningRecognitionResponse',
105 | filename=None,
106 | file=DESCRIPTOR,
107 | containing_type=None,
108 | create_key=_descriptor._internal_create_key,
109 | fields=[
110 | _descriptor.FieldDescriptor(
111 | name='chunks', full_name='yandex.cloud.ai.stt.v2.LongRunningRecognitionResponse.chunks', index=0,
112 | number=1, type=11, cpp_type=10, label=3,
113 | has_default_value=False, default_value=[],
114 | message_type=None, enum_type=None, containing_type=None,
115 | is_extension=False, extension_scope=None,
116 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
117 | ],
118 | extensions=[
119 | ],
120 | nested_types=[],
121 | enum_types=[
122 | ],
123 | serialized_options=None,
124 | is_extendable=False,
125 | syntax='proto3',
126 | extension_ranges=[],
127 | oneofs=[
128 | ],
129 | serialized_start=354,
130 | serialized_end=451,
131 | )
132 |
133 |
134 | _STREAMINGRECOGNITIONREQUEST = _descriptor.Descriptor(
135 | name='StreamingRecognitionRequest',
136 | full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionRequest',
137 | filename=None,
138 | file=DESCRIPTOR,
139 | containing_type=None,
140 | create_key=_descriptor._internal_create_key,
141 | fields=[
142 | _descriptor.FieldDescriptor(
143 | name='config', full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionRequest.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 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
149 | _descriptor.FieldDescriptor(
150 | name='audio_content', full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionRequest.audio_content', index=1,
151 | number=2, type=12, cpp_type=9, label=1,
152 | has_default_value=False, default_value=b"",
153 | message_type=None, enum_type=None, containing_type=None,
154 | is_extension=False, extension_scope=None,
155 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
156 | ],
157 | extensions=[
158 | ],
159 | nested_types=[],
160 | enum_types=[
161 | ],
162 | serialized_options=None,
163 | is_extendable=False,
164 | syntax='proto3',
165 | extension_ranges=[],
166 | oneofs=[
167 | _descriptor.OneofDescriptor(
168 | name='streaming_request', full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionRequest.streaming_request',
169 | index=0, containing_type=None,
170 | create_key=_descriptor._internal_create_key,
171 | fields=[]),
172 | ],
173 | serialized_start=454,
174 | serialized_end=590,
175 | )
176 |
177 |
178 | _STREAMINGRECOGNITIONRESPONSE = _descriptor.Descriptor(
179 | name='StreamingRecognitionResponse',
180 | full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionResponse',
181 | filename=None,
182 | file=DESCRIPTOR,
183 | containing_type=None,
184 | create_key=_descriptor._internal_create_key,
185 | fields=[
186 | _descriptor.FieldDescriptor(
187 | name='chunks', full_name='yandex.cloud.ai.stt.v2.StreamingRecognitionResponse.chunks', index=0,
188 | number=1, type=11, cpp_type=10, label=3,
189 | has_default_value=False, default_value=[],
190 | message_type=None, enum_type=None, containing_type=None,
191 | is_extension=False, extension_scope=None,
192 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
193 | ],
194 | extensions=[
195 | ],
196 | nested_types=[],
197 | enum_types=[
198 | ],
199 | serialized_options=None,
200 | is_extendable=False,
201 | syntax='proto3',
202 | extension_ranges=[],
203 | oneofs=[
204 | ],
205 | serialized_start=592,
206 | serialized_end=717,
207 | )
208 |
209 |
210 | _RECOGNITIONAUDIO = _descriptor.Descriptor(
211 | name='RecognitionAudio',
212 | full_name='yandex.cloud.ai.stt.v2.RecognitionAudio',
213 | filename=None,
214 | file=DESCRIPTOR,
215 | containing_type=None,
216 | create_key=_descriptor._internal_create_key,
217 | fields=[
218 | _descriptor.FieldDescriptor(
219 | name='content', full_name='yandex.cloud.ai.stt.v2.RecognitionAudio.content', index=0,
220 | number=1, type=12, cpp_type=9, label=1,
221 | has_default_value=False, default_value=b"",
222 | message_type=None, enum_type=None, containing_type=None,
223 | is_extension=False, extension_scope=None,
224 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
225 | _descriptor.FieldDescriptor(
226 | name='uri', full_name='yandex.cloud.ai.stt.v2.RecognitionAudio.uri', index=1,
227 | number=2, type=9, cpp_type=9, label=1,
228 | has_default_value=False, default_value=b"".decode('utf-8'),
229 | message_type=None, enum_type=None, containing_type=None,
230 | is_extension=False, extension_scope=None,
231 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
232 | ],
233 | extensions=[
234 | ],
235 | nested_types=[],
236 | enum_types=[
237 | ],
238 | serialized_options=None,
239 | is_extendable=False,
240 | syntax='proto3',
241 | extension_ranges=[],
242 | oneofs=[
243 | _descriptor.OneofDescriptor(
244 | name='audio_source', full_name='yandex.cloud.ai.stt.v2.RecognitionAudio.audio_source',
245 | index=0, containing_type=None,
246 | create_key=_descriptor._internal_create_key,
247 | fields=[]),
248 | ],
249 | serialized_start=719,
250 | serialized_end=787,
251 | )
252 |
253 |
254 | _RECOGNITIONCONFIG = _descriptor.Descriptor(
255 | name='RecognitionConfig',
256 | full_name='yandex.cloud.ai.stt.v2.RecognitionConfig',
257 | filename=None,
258 | file=DESCRIPTOR,
259 | containing_type=None,
260 | create_key=_descriptor._internal_create_key,
261 | fields=[
262 | _descriptor.FieldDescriptor(
263 | name='specification', full_name='yandex.cloud.ai.stt.v2.RecognitionConfig.specification', index=0,
264 | number=1, type=11, cpp_type=10, label=1,
265 | has_default_value=False, default_value=None,
266 | message_type=None, enum_type=None, containing_type=None,
267 | is_extension=False, extension_scope=None,
268 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
269 | _descriptor.FieldDescriptor(
270 | name='folder_id', full_name='yandex.cloud.ai.stt.v2.RecognitionConfig.folder_id', index=1,
271 | number=2, type=9, cpp_type=9, label=1,
272 | has_default_value=False, default_value=b"".decode('utf-8'),
273 | message_type=None, enum_type=None, containing_type=None,
274 | is_extension=False, extension_scope=None,
275 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
276 | ],
277 | extensions=[
278 | ],
279 | nested_types=[],
280 | enum_types=[
281 | ],
282 | serialized_options=None,
283 | is_extendable=False,
284 | syntax='proto3',
285 | extension_ranges=[],
286 | oneofs=[
287 | ],
288 | serialized_start=789,
289 | serialized_end=891,
290 | )
291 |
292 |
293 | _RECOGNITIONSPEC = _descriptor.Descriptor(
294 | name='RecognitionSpec',
295 | full_name='yandex.cloud.ai.stt.v2.RecognitionSpec',
296 | filename=None,
297 | file=DESCRIPTOR,
298 | containing_type=None,
299 | create_key=_descriptor._internal_create_key,
300 | fields=[
301 | _descriptor.FieldDescriptor(
302 | name='audio_encoding', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.audio_encoding', index=0,
303 | number=1, type=14, cpp_type=8, label=1,
304 | has_default_value=False, default_value=0,
305 | message_type=None, enum_type=None, containing_type=None,
306 | is_extension=False, extension_scope=None,
307 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
308 | _descriptor.FieldDescriptor(
309 | name='sample_rate_hertz', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.sample_rate_hertz', index=1,
310 | number=2, type=3, cpp_type=2, label=1,
311 | has_default_value=False, default_value=0,
312 | message_type=None, enum_type=None, containing_type=None,
313 | is_extension=False, extension_scope=None,
314 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
315 | _descriptor.FieldDescriptor(
316 | name='language_code', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.language_code', index=2,
317 | number=3, type=9, cpp_type=9, label=1,
318 | has_default_value=False, default_value=b"".decode('utf-8'),
319 | message_type=None, enum_type=None, containing_type=None,
320 | is_extension=False, extension_scope=None,
321 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
322 | _descriptor.FieldDescriptor(
323 | name='profanity_filter', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.profanity_filter', index=3,
324 | number=4, type=8, cpp_type=7, label=1,
325 | has_default_value=False, default_value=False,
326 | message_type=None, enum_type=None, containing_type=None,
327 | is_extension=False, extension_scope=None,
328 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
329 | _descriptor.FieldDescriptor(
330 | name='model', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.model', index=4,
331 | number=5, type=9, cpp_type=9, label=1,
332 | has_default_value=False, default_value=b"".decode('utf-8'),
333 | message_type=None, enum_type=None, containing_type=None,
334 | is_extension=False, extension_scope=None,
335 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
336 | _descriptor.FieldDescriptor(
337 | name='partial_results', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.partial_results', index=5,
338 | number=7, type=8, cpp_type=7, label=1,
339 | has_default_value=False, default_value=False,
340 | message_type=None, enum_type=None, containing_type=None,
341 | is_extension=False, extension_scope=None,
342 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
343 | _descriptor.FieldDescriptor(
344 | name='single_utterance', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.single_utterance', index=6,
345 | number=8, type=8, cpp_type=7, label=1,
346 | has_default_value=False, default_value=False,
347 | message_type=None, enum_type=None, containing_type=None,
348 | is_extension=False, extension_scope=None,
349 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
350 | _descriptor.FieldDescriptor(
351 | name='audio_channel_count', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.audio_channel_count', index=7,
352 | number=9, type=3, cpp_type=2, label=1,
353 | has_default_value=False, default_value=0,
354 | message_type=None, enum_type=None, containing_type=None,
355 | is_extension=False, extension_scope=None,
356 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
357 | _descriptor.FieldDescriptor(
358 | name='raw_results', full_name='yandex.cloud.ai.stt.v2.RecognitionSpec.raw_results', index=8,
359 | number=10, type=8, cpp_type=7, label=1,
360 | has_default_value=False, default_value=False,
361 | message_type=None, enum_type=None, containing_type=None,
362 | is_extension=False, extension_scope=None,
363 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
364 | ],
365 | extensions=[
366 | ],
367 | nested_types=[],
368 | enum_types=[
369 | _RECOGNITIONSPEC_AUDIOENCODING,
370 | ],
371 | serialized_options=None,
372 | is_extendable=False,
373 | syntax='proto3',
374 | extension_ranges=[],
375 | oneofs=[
376 | ],
377 | serialized_start=894,
378 | serialized_end=1263,
379 | )
380 |
381 |
382 | _SPEECHRECOGNITIONCHUNK = _descriptor.Descriptor(
383 | name='SpeechRecognitionChunk',
384 | full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionChunk',
385 | filename=None,
386 | file=DESCRIPTOR,
387 | containing_type=None,
388 | create_key=_descriptor._internal_create_key,
389 | fields=[
390 | _descriptor.FieldDescriptor(
391 | name='alternatives', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionChunk.alternatives', index=0,
392 | number=1, type=11, cpp_type=10, label=3,
393 | has_default_value=False, default_value=[],
394 | message_type=None, enum_type=None, containing_type=None,
395 | is_extension=False, extension_scope=None,
396 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
397 | _descriptor.FieldDescriptor(
398 | name='final', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionChunk.final', index=1,
399 | number=2, type=8, cpp_type=7, label=1,
400 | has_default_value=False, default_value=False,
401 | message_type=None, enum_type=None, containing_type=None,
402 | is_extension=False, extension_scope=None,
403 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
404 | _descriptor.FieldDescriptor(
405 | name='end_of_utterance', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionChunk.end_of_utterance', index=2,
406 | number=3, type=8, cpp_type=7, label=1,
407 | has_default_value=False, default_value=False,
408 | message_type=None, enum_type=None, containing_type=None,
409 | is_extension=False, extension_scope=None,
410 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
411 | ],
412 | extensions=[
413 | ],
414 | nested_types=[],
415 | enum_types=[
416 | ],
417 | serialized_options=None,
418 | is_extendable=False,
419 | syntax='proto3',
420 | extension_ranges=[],
421 | oneofs=[
422 | ],
423 | serialized_start=1266,
424 | serialized_end=1407,
425 | )
426 |
427 |
428 | _SPEECHRECOGNITIONRESULT = _descriptor.Descriptor(
429 | name='SpeechRecognitionResult',
430 | full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionResult',
431 | filename=None,
432 | file=DESCRIPTOR,
433 | containing_type=None,
434 | create_key=_descriptor._internal_create_key,
435 | fields=[
436 | _descriptor.FieldDescriptor(
437 | name='alternatives', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionResult.alternatives', index=0,
438 | number=1, type=11, cpp_type=10, label=3,
439 | has_default_value=False, default_value=[],
440 | message_type=None, enum_type=None, containing_type=None,
441 | is_extension=False, extension_scope=None,
442 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
443 | _descriptor.FieldDescriptor(
444 | name='channel_tag', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionResult.channel_tag', index=1,
445 | number=2, type=3, cpp_type=2, label=1,
446 | has_default_value=False, default_value=0,
447 | message_type=None, enum_type=None, containing_type=None,
448 | is_extension=False, extension_scope=None,
449 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
450 | ],
451 | extensions=[
452 | ],
453 | nested_types=[],
454 | enum_types=[
455 | ],
456 | serialized_options=None,
457 | is_extendable=False,
458 | syntax='proto3',
459 | extension_ranges=[],
460 | oneofs=[
461 | ],
462 | serialized_start=1409,
463 | serialized_end=1531,
464 | )
465 |
466 |
467 | _SPEECHRECOGNITIONALTERNATIVE = _descriptor.Descriptor(
468 | name='SpeechRecognitionAlternative',
469 | full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative',
470 | filename=None,
471 | file=DESCRIPTOR,
472 | containing_type=None,
473 | create_key=_descriptor._internal_create_key,
474 | fields=[
475 | _descriptor.FieldDescriptor(
476 | name='text', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative.text', index=0,
477 | number=1, type=9, cpp_type=9, label=1,
478 | has_default_value=False, default_value=b"".decode('utf-8'),
479 | message_type=None, enum_type=None, containing_type=None,
480 | is_extension=False, extension_scope=None,
481 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
482 | _descriptor.FieldDescriptor(
483 | name='confidence', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative.confidence', index=1,
484 | number=2, type=2, cpp_type=6, label=1,
485 | has_default_value=False, default_value=float(0),
486 | message_type=None, enum_type=None, containing_type=None,
487 | is_extension=False, extension_scope=None,
488 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
489 | _descriptor.FieldDescriptor(
490 | name='words', full_name='yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative.words', index=2,
491 | number=3, type=11, cpp_type=10, label=3,
492 | has_default_value=False, default_value=[],
493 | message_type=None, enum_type=None, containing_type=None,
494 | is_extension=False, extension_scope=None,
495 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
496 | ],
497 | extensions=[
498 | ],
499 | nested_types=[],
500 | enum_types=[
501 | ],
502 | serialized_options=None,
503 | is_extendable=False,
504 | syntax='proto3',
505 | extension_ranges=[],
506 | oneofs=[
507 | ],
508 | serialized_start=1533,
509 | serialized_end=1646,
510 | )
511 |
512 |
513 | _WORDINFO = _descriptor.Descriptor(
514 | name='WordInfo',
515 | full_name='yandex.cloud.ai.stt.v2.WordInfo',
516 | filename=None,
517 | file=DESCRIPTOR,
518 | containing_type=None,
519 | create_key=_descriptor._internal_create_key,
520 | fields=[
521 | _descriptor.FieldDescriptor(
522 | name='start_time', full_name='yandex.cloud.ai.stt.v2.WordInfo.start_time', index=0,
523 | number=1, type=11, cpp_type=10, label=1,
524 | has_default_value=False, default_value=None,
525 | message_type=None, enum_type=None, containing_type=None,
526 | is_extension=False, extension_scope=None,
527 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
528 | _descriptor.FieldDescriptor(
529 | name='end_time', full_name='yandex.cloud.ai.stt.v2.WordInfo.end_time', index=1,
530 | number=2, type=11, cpp_type=10, label=1,
531 | has_default_value=False, default_value=None,
532 | message_type=None, enum_type=None, containing_type=None,
533 | is_extension=False, extension_scope=None,
534 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
535 | _descriptor.FieldDescriptor(
536 | name='word', full_name='yandex.cloud.ai.stt.v2.WordInfo.word', index=2,
537 | number=3, type=9, cpp_type=9, label=1,
538 | has_default_value=False, default_value=b"".decode('utf-8'),
539 | message_type=None, enum_type=None, containing_type=None,
540 | is_extension=False, extension_scope=None,
541 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
542 | _descriptor.FieldDescriptor(
543 | name='confidence', full_name='yandex.cloud.ai.stt.v2.WordInfo.confidence', index=3,
544 | number=4, type=2, cpp_type=6, label=1,
545 | has_default_value=False, default_value=float(0),
546 | message_type=None, enum_type=None, containing_type=None,
547 | is_extension=False, extension_scope=None,
548 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
549 | ],
550 | extensions=[
551 | ],
552 | nested_types=[],
553 | enum_types=[
554 | ],
555 | serialized_options=None,
556 | is_extendable=False,
557 | syntax='proto3',
558 | extension_ranges=[],
559 | oneofs=[
560 | ],
561 | serialized_start=1649,
562 | serialized_end=1785,
563 | )
564 |
565 | _LONGRUNNINGRECOGNITIONREQUEST.fields_by_name['config'].message_type = _RECOGNITIONCONFIG
566 | _LONGRUNNINGRECOGNITIONREQUEST.fields_by_name['audio'].message_type = _RECOGNITIONAUDIO
567 | _LONGRUNNINGRECOGNITIONRESPONSE.fields_by_name['chunks'].message_type = _SPEECHRECOGNITIONRESULT
568 | _STREAMINGRECOGNITIONREQUEST.fields_by_name['config'].message_type = _RECOGNITIONCONFIG
569 | _STREAMINGRECOGNITIONREQUEST.oneofs_by_name['streaming_request'].fields.append(
570 | _STREAMINGRECOGNITIONREQUEST.fields_by_name['config'])
571 | _STREAMINGRECOGNITIONREQUEST.fields_by_name['config'].containing_oneof = _STREAMINGRECOGNITIONREQUEST.oneofs_by_name['streaming_request']
572 | _STREAMINGRECOGNITIONREQUEST.oneofs_by_name['streaming_request'].fields.append(
573 | _STREAMINGRECOGNITIONREQUEST.fields_by_name['audio_content'])
574 | _STREAMINGRECOGNITIONREQUEST.fields_by_name['audio_content'].containing_oneof = _STREAMINGRECOGNITIONREQUEST.oneofs_by_name['streaming_request']
575 | _STREAMINGRECOGNITIONRESPONSE.fields_by_name['chunks'].message_type = _SPEECHRECOGNITIONCHUNK
576 | _RECOGNITIONAUDIO.oneofs_by_name['audio_source'].fields.append(
577 | _RECOGNITIONAUDIO.fields_by_name['content'])
578 | _RECOGNITIONAUDIO.fields_by_name['content'].containing_oneof = _RECOGNITIONAUDIO.oneofs_by_name['audio_source']
579 | _RECOGNITIONAUDIO.oneofs_by_name['audio_source'].fields.append(
580 | _RECOGNITIONAUDIO.fields_by_name['uri'])
581 | _RECOGNITIONAUDIO.fields_by_name['uri'].containing_oneof = _RECOGNITIONAUDIO.oneofs_by_name['audio_source']
582 | _RECOGNITIONCONFIG.fields_by_name['specification'].message_type = _RECOGNITIONSPEC
583 | _RECOGNITIONSPEC.fields_by_name['audio_encoding'].enum_type = _RECOGNITIONSPEC_AUDIOENCODING
584 | _RECOGNITIONSPEC_AUDIOENCODING.containing_type = _RECOGNITIONSPEC
585 | _SPEECHRECOGNITIONCHUNK.fields_by_name['alternatives'].message_type = _SPEECHRECOGNITIONALTERNATIVE
586 | _SPEECHRECOGNITIONRESULT.fields_by_name['alternatives'].message_type = _SPEECHRECOGNITIONALTERNATIVE
587 | _SPEECHRECOGNITIONALTERNATIVE.fields_by_name['words'].message_type = _WORDINFO
588 | _WORDINFO.fields_by_name['start_time'].message_type = google_dot_protobuf_dot_duration__pb2._DURATION
589 | _WORDINFO.fields_by_name['end_time'].message_type = google_dot_protobuf_dot_duration__pb2._DURATION
590 | DESCRIPTOR.message_types_by_name['LongRunningRecognitionRequest'] = _LONGRUNNINGRECOGNITIONREQUEST
591 | DESCRIPTOR.message_types_by_name['LongRunningRecognitionResponse'] = _LONGRUNNINGRECOGNITIONRESPONSE
592 | DESCRIPTOR.message_types_by_name['StreamingRecognitionRequest'] = _STREAMINGRECOGNITIONREQUEST
593 | DESCRIPTOR.message_types_by_name['StreamingRecognitionResponse'] = _STREAMINGRECOGNITIONRESPONSE
594 | DESCRIPTOR.message_types_by_name['RecognitionAudio'] = _RECOGNITIONAUDIO
595 | DESCRIPTOR.message_types_by_name['RecognitionConfig'] = _RECOGNITIONCONFIG
596 | DESCRIPTOR.message_types_by_name['RecognitionSpec'] = _RECOGNITIONSPEC
597 | DESCRIPTOR.message_types_by_name['SpeechRecognitionChunk'] = _SPEECHRECOGNITIONCHUNK
598 | DESCRIPTOR.message_types_by_name['SpeechRecognitionResult'] = _SPEECHRECOGNITIONRESULT
599 | DESCRIPTOR.message_types_by_name['SpeechRecognitionAlternative'] = _SPEECHRECOGNITIONALTERNATIVE
600 | DESCRIPTOR.message_types_by_name['WordInfo'] = _WORDINFO
601 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
602 |
603 | LongRunningRecognitionRequest = _reflection.GeneratedProtocolMessageType('LongRunningRecognitionRequest', (_message.Message,), {
604 | 'DESCRIPTOR' : _LONGRUNNINGRECOGNITIONREQUEST,
605 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
606 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.LongRunningRecognitionRequest)
607 | })
608 | _sym_db.RegisterMessage(LongRunningRecognitionRequest)
609 |
610 | LongRunningRecognitionResponse = _reflection.GeneratedProtocolMessageType('LongRunningRecognitionResponse', (_message.Message,), {
611 | 'DESCRIPTOR' : _LONGRUNNINGRECOGNITIONRESPONSE,
612 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
613 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.LongRunningRecognitionResponse)
614 | })
615 | _sym_db.RegisterMessage(LongRunningRecognitionResponse)
616 |
617 | StreamingRecognitionRequest = _reflection.GeneratedProtocolMessageType('StreamingRecognitionRequest', (_message.Message,), {
618 | 'DESCRIPTOR' : _STREAMINGRECOGNITIONREQUEST,
619 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
620 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.StreamingRecognitionRequest)
621 | })
622 | _sym_db.RegisterMessage(StreamingRecognitionRequest)
623 |
624 | StreamingRecognitionResponse = _reflection.GeneratedProtocolMessageType('StreamingRecognitionResponse', (_message.Message,), {
625 | 'DESCRIPTOR' : _STREAMINGRECOGNITIONRESPONSE,
626 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
627 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.StreamingRecognitionResponse)
628 | })
629 | _sym_db.RegisterMessage(StreamingRecognitionResponse)
630 |
631 | RecognitionAudio = _reflection.GeneratedProtocolMessageType('RecognitionAudio', (_message.Message,), {
632 | 'DESCRIPTOR' : _RECOGNITIONAUDIO,
633 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
634 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.RecognitionAudio)
635 | })
636 | _sym_db.RegisterMessage(RecognitionAudio)
637 |
638 | RecognitionConfig = _reflection.GeneratedProtocolMessageType('RecognitionConfig', (_message.Message,), {
639 | 'DESCRIPTOR' : _RECOGNITIONCONFIG,
640 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
641 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.RecognitionConfig)
642 | })
643 | _sym_db.RegisterMessage(RecognitionConfig)
644 |
645 | RecognitionSpec = _reflection.GeneratedProtocolMessageType('RecognitionSpec', (_message.Message,), {
646 | 'DESCRIPTOR' : _RECOGNITIONSPEC,
647 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
648 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.RecognitionSpec)
649 | })
650 | _sym_db.RegisterMessage(RecognitionSpec)
651 |
652 | SpeechRecognitionChunk = _reflection.GeneratedProtocolMessageType('SpeechRecognitionChunk', (_message.Message,), {
653 | 'DESCRIPTOR' : _SPEECHRECOGNITIONCHUNK,
654 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
655 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.SpeechRecognitionChunk)
656 | })
657 | _sym_db.RegisterMessage(SpeechRecognitionChunk)
658 |
659 | SpeechRecognitionResult = _reflection.GeneratedProtocolMessageType('SpeechRecognitionResult', (_message.Message,), {
660 | 'DESCRIPTOR' : _SPEECHRECOGNITIONRESULT,
661 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
662 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.SpeechRecognitionResult)
663 | })
664 | _sym_db.RegisterMessage(SpeechRecognitionResult)
665 |
666 | SpeechRecognitionAlternative = _reflection.GeneratedProtocolMessageType('SpeechRecognitionAlternative', (_message.Message,), {
667 | 'DESCRIPTOR' : _SPEECHRECOGNITIONALTERNATIVE,
668 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
669 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.SpeechRecognitionAlternative)
670 | })
671 | _sym_db.RegisterMessage(SpeechRecognitionAlternative)
672 |
673 | WordInfo = _reflection.GeneratedProtocolMessageType('WordInfo', (_message.Message,), {
674 | 'DESCRIPTOR' : _WORDINFO,
675 | '__module__' : 'yandex.cloud.ai.stt.v2.stt_service_pb2'
676 | # @@protoc_insertion_point(class_scope:yandex.cloud.ai.stt.v2.WordInfo)
677 | })
678 | _sym_db.RegisterMessage(WordInfo)
679 |
680 |
681 | DESCRIPTOR._options = None
682 |
683 | _STTSERVICE = _descriptor.ServiceDescriptor(
684 | name='SttService',
685 | full_name='yandex.cloud.ai.stt.v2.SttService',
686 | file=DESCRIPTOR,
687 | index=0,
688 | serialized_options=None,
689 | create_key=_descriptor._internal_create_key,
690 | serialized_start=1788,
691 | serialized_end=2135,
692 | methods=[
693 | _descriptor.MethodDescriptor(
694 | name='LongRunningRecognize',
695 | full_name='yandex.cloud.ai.stt.v2.SttService.LongRunningRecognize',
696 | index=0,
697 | containing_service=None,
698 | input_type=_LONGRUNNINGRECOGNITIONREQUEST,
699 | output_type=yandex_dot_cloud_dot_operation_dot_operation__pb2._OPERATION,
700 | serialized_options=b'\202\323\344\223\002(\"#/speech/stt/v2/longRunningRecognize:\001*\262\322* \022\036LongRunningRecognitionResponse',
701 | create_key=_descriptor._internal_create_key,
702 | ),
703 | _descriptor.MethodDescriptor(
704 | name='StreamingRecognize',
705 | full_name='yandex.cloud.ai.stt.v2.SttService.StreamingRecognize',
706 | index=1,
707 | containing_service=None,
708 | input_type=_STREAMINGRECOGNITIONREQUEST,
709 | output_type=_STREAMINGRECOGNITIONRESPONSE,
710 | serialized_options=None,
711 | create_key=_descriptor._internal_create_key,
712 | ),
713 | ])
714 | _sym_db.RegisterServiceDescriptor(_STTSERVICE)
715 |
716 | DESCRIPTOR.services_by_name['SttService'] = _STTSERVICE
717 |
718 | # @@protoc_insertion_point(module_scope)
719 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/ai/stt/v2/stt_service_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 | from speechkit._recognition.yandex.cloud.ai.stt.v2 import stt_service_pb2 as yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2
6 | from speechkit._recognition.yandex.cloud.operation import operation_pb2 as yandex_dot_cloud_dot_operation_dot_operation__pb2
7 |
8 |
9 | class SttServiceStub(object):
10 | """Missing associated documentation comment in .proto file."""
11 |
12 | def __init__(self, channel):
13 | """Constructor.
14 |
15 | Args:
16 | channel: A grpc.Channel.
17 | """
18 | self.LongRunningRecognize = channel.unary_unary(
19 | '/yandex.cloud.ai.stt.v2.SttService/LongRunningRecognize',
20 | request_serializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.LongRunningRecognitionRequest.SerializeToString,
21 | response_deserializer=yandex_dot_cloud_dot_operation_dot_operation__pb2.Operation.FromString,
22 | )
23 | self.StreamingRecognize = channel.stream_stream(
24 | '/yandex.cloud.ai.stt.v2.SttService/StreamingRecognize',
25 | request_serializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionRequest.SerializeToString,
26 | response_deserializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionResponse.FromString,
27 | )
28 |
29 |
30 | class SttServiceServicer(object):
31 | """Missing associated documentation comment in .proto file."""
32 |
33 | def LongRunningRecognize(self, request, context):
34 | """Missing associated documentation comment in .proto file."""
35 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
36 | context.set_details('Method not implemented!')
37 | raise NotImplementedError('Method not implemented!')
38 |
39 | def StreamingRecognize(self, request_iterator, context):
40 | """Missing associated documentation comment in .proto file."""
41 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
42 | context.set_details('Method not implemented!')
43 | raise NotImplementedError('Method not implemented!')
44 |
45 |
46 | def add_SttServiceServicer_to_server(servicer, server):
47 | rpc_method_handlers = {
48 | 'LongRunningRecognize': grpc.unary_unary_rpc_method_handler(
49 | servicer.LongRunningRecognize,
50 | request_deserializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.LongRunningRecognitionRequest.FromString,
51 | response_serializer=yandex_dot_cloud_dot_operation_dot_operation__pb2.Operation.SerializeToString,
52 | ),
53 | 'StreamingRecognize': grpc.stream_stream_rpc_method_handler(
54 | servicer.StreamingRecognize,
55 | request_deserializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionRequest.FromString,
56 | response_serializer=yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionResponse.SerializeToString,
57 | ),
58 | }
59 | generic_handler = grpc.method_handlers_generic_handler(
60 | 'yandex.cloud.ai.stt.v2.SttService', rpc_method_handlers)
61 | server.add_generic_rpc_handlers((generic_handler,))
62 |
63 |
64 | # This class is part of an EXPERIMENTAL API.
65 | class SttService(object):
66 | """Missing associated documentation comment in .proto file."""
67 |
68 | @staticmethod
69 | def LongRunningRecognize(request,
70 | target,
71 | options=(),
72 | channel_credentials=None,
73 | call_credentials=None,
74 | insecure=False,
75 | compression=None,
76 | wait_for_ready=None,
77 | timeout=None,
78 | metadata=None):
79 | return grpc.experimental.unary_unary(request, target, '/yandex.cloud.ai.stt.v2.SttService/LongRunningRecognize',
80 | yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.LongRunningRecognitionRequest.SerializeToString,
81 | yandex_dot_cloud_dot_operation_dot_operation__pb2.Operation.FromString,
82 | options, channel_credentials,
83 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
84 |
85 | @staticmethod
86 | def StreamingRecognize(request_iterator,
87 | target,
88 | options=(),
89 | channel_credentials=None,
90 | call_credentials=None,
91 | insecure=False,
92 | compression=None,
93 | wait_for_ready=None,
94 | timeout=None,
95 | metadata=None):
96 | return grpc.experimental.stream_stream(request_iterator, target, '/yandex.cloud.ai.stt.v2.SttService/StreamingRecognize',
97 | yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionRequest.SerializeToString,
98 | yandex_dot_cloud_dot_ai_dot_stt_dot_v2_dot_stt__service__pb2.StreamingRecognitionResponse.FromString,
99 | options, channel_credentials,
100 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
101 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/api/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/api/operation_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: yandex/cloud/api/operation.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 | from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
15 |
16 |
17 | DESCRIPTOR = _descriptor.FileDescriptor(
18 | name='yandex/cloud/api/operation.proto',
19 | package='yandex.cloud.api',
20 | syntax='proto3',
21 | serialized_options=b'Z8github.com/yandex-cloud/go-genproto/yandex/cloud/api;api',
22 | create_key=_descriptor._internal_create_key,
23 | serialized_pb=b'\n yandex/cloud/api/operation.proto\x12\x10yandex.cloud.api\x1a google/protobuf/descriptor.proto\"/\n\tOperation\x12\x10\n\x08metadata\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t:P\n\toperation\x12\x1e.google.protobuf.MethodOptions\x18\xa6\xaa\x05 \x01(\x0b\x32\x1b.yandex.cloud.api.OperationB:Z8github.com/yandex-cloud/go-genproto/yandex/cloud/api;apib\x06proto3'
24 | ,
25 | dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
26 |
27 |
28 | OPERATION_FIELD_NUMBER = 87334
29 | operation = _descriptor.FieldDescriptor(
30 | name='operation', full_name='yandex.cloud.api.operation', index=0,
31 | number=87334, type=11, cpp_type=10, label=1,
32 | has_default_value=False, default_value=None,
33 | message_type=None, enum_type=None, containing_type=None,
34 | is_extension=True, extension_scope=None,
35 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
36 |
37 |
38 | _OPERATION = _descriptor.Descriptor(
39 | name='Operation',
40 | full_name='yandex.cloud.api.Operation',
41 | filename=None,
42 | file=DESCRIPTOR,
43 | containing_type=None,
44 | create_key=_descriptor._internal_create_key,
45 | fields=[
46 | _descriptor.FieldDescriptor(
47 | name='metadata', full_name='yandex.cloud.api.Operation.metadata', index=0,
48 | number=1, type=9, cpp_type=9, label=1,
49 | has_default_value=False, default_value=b"".decode('utf-8'),
50 | message_type=None, enum_type=None, containing_type=None,
51 | is_extension=False, extension_scope=None,
52 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
53 | _descriptor.FieldDescriptor(
54 | name='response', full_name='yandex.cloud.api.Operation.response', index=1,
55 | number=2, type=9, cpp_type=9, label=1,
56 | has_default_value=False, default_value=b"".decode('utf-8'),
57 | message_type=None, enum_type=None, containing_type=None,
58 | is_extension=False, extension_scope=None,
59 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
60 | ],
61 | extensions=[
62 | ],
63 | nested_types=[],
64 | enum_types=[
65 | ],
66 | serialized_options=None,
67 | is_extendable=False,
68 | syntax='proto3',
69 | extension_ranges=[],
70 | oneofs=[
71 | ],
72 | serialized_start=88,
73 | serialized_end=135,
74 | )
75 |
76 | DESCRIPTOR.message_types_by_name['Operation'] = _OPERATION
77 | DESCRIPTOR.extensions_by_name['operation'] = operation
78 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
79 |
80 | Operation = _reflection.GeneratedProtocolMessageType('Operation', (_message.Message,), {
81 | 'DESCRIPTOR' : _OPERATION,
82 | '__module__' : 'yandex.cloud.api.operation_pb2'
83 | # @@protoc_insertion_point(class_scope:yandex.cloud.api.Operation)
84 | })
85 | _sym_db.RegisterMessage(Operation)
86 |
87 | operation.message_type = _OPERATION
88 | google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(operation)
89 |
90 | DESCRIPTOR._options = None
91 | # @@protoc_insertion_point(module_scope)
92 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/api/operation_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/operation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/speechkit/_recognition/yandex/cloud/operation/__init__.py
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/operation/operation_pb2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by the protocol buffer compiler. DO NOT EDIT!
3 | # source: yandex/cloud/operation/operation.proto
4 | """Generated protocol buffer code."""
5 | from google.protobuf import descriptor as _descriptor
6 | from google.protobuf import message as _message
7 | from google.protobuf import reflection as _reflection
8 | from google.protobuf import symbol_database as _symbol_database
9 | # @@protoc_insertion_point(imports)
10 |
11 | _sym_db = _symbol_database.Default()
12 |
13 |
14 | from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
15 | from speechkit._recognition.google.rpc import status_pb2 as google_dot_rpc_dot_status__pb2
16 | from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
17 |
18 |
19 | DESCRIPTOR = _descriptor.FileDescriptor(
20 | name='yandex/cloud/operation/operation.proto',
21 | package='yandex.cloud.operation',
22 | syntax='proto3',
23 | serialized_options=b'\n\032yandex.cloud.api.operationZDgithub.com/yandex-cloud/go-genproto/yandex/cloud/operation;operation',
24 | create_key=_descriptor._internal_create_key,
25 | serialized_pb=b'\n&yandex/cloud/operation/operation.proto\x12\x16yandex.cloud.operation\x1a\x19google/protobuf/any.proto\x1a\x17google/rpc/status.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb0\x02\n\tOperation\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12.\n\ncreated_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x04 \x01(\t\x12/\n\x0bmodified_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04\x64one\x18\x06 \x01(\x08\x12&\n\x08metadata\x18\x07 \x01(\x0b\x32\x14.google.protobuf.Any\x12#\n\x05\x65rror\x18\x08 \x01(\x0b\x32\x12.google.rpc.StatusH\x00\x12(\n\x08response\x18\t \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x08\n\x06resultBb\n\x1ayandex.cloud.api.operationZDgithub.com/yandex-cloud/go-genproto/yandex/cloud/operation;operationb\x06proto3'
26 | ,
27 | dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_rpc_dot_status__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
28 |
29 |
30 |
31 |
32 | _OPERATION = _descriptor.Descriptor(
33 | name='Operation',
34 | full_name='yandex.cloud.operation.Operation',
35 | filename=None,
36 | file=DESCRIPTOR,
37 | containing_type=None,
38 | create_key=_descriptor._internal_create_key,
39 | fields=[
40 | _descriptor.FieldDescriptor(
41 | name='id', full_name='yandex.cloud.operation.Operation.id', index=0,
42 | number=1, type=9, cpp_type=9, label=1,
43 | has_default_value=False, default_value=b"".decode('utf-8'),
44 | message_type=None, enum_type=None, containing_type=None,
45 | is_extension=False, extension_scope=None,
46 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
47 | _descriptor.FieldDescriptor(
48 | name='description', full_name='yandex.cloud.operation.Operation.description', index=1,
49 | number=2, type=9, cpp_type=9, label=1,
50 | has_default_value=False, default_value=b"".decode('utf-8'),
51 | message_type=None, enum_type=None, containing_type=None,
52 | is_extension=False, extension_scope=None,
53 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
54 | _descriptor.FieldDescriptor(
55 | name='created_at', full_name='yandex.cloud.operation.Operation.created_at', index=2,
56 | number=3, type=11, cpp_type=10, label=1,
57 | has_default_value=False, default_value=None,
58 | message_type=None, enum_type=None, containing_type=None,
59 | is_extension=False, extension_scope=None,
60 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
61 | _descriptor.FieldDescriptor(
62 | name='created_by', full_name='yandex.cloud.operation.Operation.created_by', index=3,
63 | number=4, type=9, cpp_type=9, label=1,
64 | has_default_value=False, default_value=b"".decode('utf-8'),
65 | message_type=None, enum_type=None, containing_type=None,
66 | is_extension=False, extension_scope=None,
67 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
68 | _descriptor.FieldDescriptor(
69 | name='modified_at', full_name='yandex.cloud.operation.Operation.modified_at', index=4,
70 | number=5, type=11, cpp_type=10, label=1,
71 | has_default_value=False, default_value=None,
72 | message_type=None, enum_type=None, containing_type=None,
73 | is_extension=False, extension_scope=None,
74 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
75 | _descriptor.FieldDescriptor(
76 | name='done', full_name='yandex.cloud.operation.Operation.done', index=5,
77 | number=6, type=8, cpp_type=7, label=1,
78 | has_default_value=False, default_value=False,
79 | message_type=None, enum_type=None, containing_type=None,
80 | is_extension=False, extension_scope=None,
81 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
82 | _descriptor.FieldDescriptor(
83 | name='metadata', full_name='yandex.cloud.operation.Operation.metadata', index=6,
84 | number=7, type=11, cpp_type=10, label=1,
85 | has_default_value=False, default_value=None,
86 | message_type=None, enum_type=None, containing_type=None,
87 | is_extension=False, extension_scope=None,
88 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
89 | _descriptor.FieldDescriptor(
90 | name='error', full_name='yandex.cloud.operation.Operation.error', index=7,
91 | number=8, type=11, cpp_type=10, label=1,
92 | has_default_value=False, default_value=None,
93 | message_type=None, enum_type=None, containing_type=None,
94 | is_extension=False, extension_scope=None,
95 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
96 | _descriptor.FieldDescriptor(
97 | name='response', full_name='yandex.cloud.operation.Operation.response', index=8,
98 | number=9, type=11, cpp_type=10, label=1,
99 | has_default_value=False, default_value=None,
100 | message_type=None, enum_type=None, containing_type=None,
101 | is_extension=False, extension_scope=None,
102 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
103 | ],
104 | extensions=[
105 | ],
106 | nested_types=[],
107 | enum_types=[
108 | ],
109 | serialized_options=None,
110 | is_extendable=False,
111 | syntax='proto3',
112 | extension_ranges=[],
113 | oneofs=[
114 | _descriptor.OneofDescriptor(
115 | name='result', full_name='yandex.cloud.operation.Operation.result',
116 | index=0, containing_type=None,
117 | create_key=_descriptor._internal_create_key,
118 | fields=[]),
119 | ],
120 | serialized_start=152,
121 | serialized_end=456,
122 | )
123 |
124 | _OPERATION.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
125 | _OPERATION.fields_by_name['modified_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
126 | _OPERATION.fields_by_name['metadata'].message_type = google_dot_protobuf_dot_any__pb2._ANY
127 | _OPERATION.fields_by_name['error'].message_type = google_dot_rpc_dot_status__pb2._STATUS
128 | _OPERATION.fields_by_name['response'].message_type = google_dot_protobuf_dot_any__pb2._ANY
129 | _OPERATION.oneofs_by_name['result'].fields.append(
130 | _OPERATION.fields_by_name['error'])
131 | _OPERATION.fields_by_name['error'].containing_oneof = _OPERATION.oneofs_by_name['result']
132 | _OPERATION.oneofs_by_name['result'].fields.append(
133 | _OPERATION.fields_by_name['response'])
134 | _OPERATION.fields_by_name['response'].containing_oneof = _OPERATION.oneofs_by_name['result']
135 | DESCRIPTOR.message_types_by_name['Operation'] = _OPERATION
136 | _sym_db.RegisterFileDescriptor(DESCRIPTOR)
137 |
138 | Operation = _reflection.GeneratedProtocolMessageType('Operation', (_message.Message,), {
139 | 'DESCRIPTOR' : _OPERATION,
140 | '__module__' : 'yandex.cloud.operation.operation_pb2'
141 | # @@protoc_insertion_point(class_scope:yandex.cloud.operation.Operation)
142 | })
143 | _sym_db.RegisterMessage(Operation)
144 |
145 |
146 | DESCRIPTOR._options = None
147 | # @@protoc_insertion_point(module_scope)
148 |
--------------------------------------------------------------------------------
/src/speechkit/_recognition/yandex/cloud/operation/operation_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/src/speechkit/_synthesis.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from speechkit.exceptions import RequestError
4 |
5 |
6 | class SpeechSynthesis:
7 | """Generates speech from received text."""
8 |
9 | def __init__(self, session):
10 | """
11 | Initialize :py:class:`speechkit.SpeechSynthesis`
12 |
13 | :param speechkit.Session session: Session instance for auth
14 | """
15 | self._headers = session.header
16 | self._folder_id = session.folder_id
17 |
18 | def _synthesize_stream(self, **kwargs):
19 | """Creates request to generate speech from text"""
20 |
21 | url = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize'
22 | params = {'folderId': self._folder_id} if self._folder_id else {}
23 | params.update(kwargs)
24 | answer = requests.post(url, headers=self._headers, data=params, stream=True)
25 |
26 | if not answer.ok:
27 | raise RequestError(answer.json())
28 |
29 | answer.raw.decode_content = True
30 | return answer.content
31 |
32 | def synthesize(self, file_path, **kwargs):
33 | """
34 | Generates speech from received text and saves it to file
35 |
36 | :type file_path: string
37 | :param file_path: The path to file where store data
38 |
39 | :type text: string
40 | :param text: UTF-8 encoded text to be converted to speech.
41 | You can only use one `text` and `ssml` field.
42 | For homographs, place a `+` before the stressed vowel.
43 | For example, `contr+ol` or `def+ect`.
44 | To indicate a pause between words, use `-`.
45 | Maximum string length: 5000 characters.
46 |
47 | :type ssml: string
48 | :param ssml: Text in SSML format to be converted into speech.
49 | You can only use one text and ssml fields.
50 |
51 | :type lang: string
52 | :param lang: Language.
53 | Acceptable values:
54 |
55 | * `ru-RU` (default) — Russian.
56 |
57 | * `en-US` — English.
58 |
59 | * `tr-TR` — Turkish.
60 |
61 | :type voice: string
62 | :param voice: Preferred speech synthesis voice from the list.
63 | Default value: `oksana`.
64 |
65 | :type speed: string
66 | :param speed: Rate (speed) of synthesized speech.
67 | The rate of speech is set as a decimal number in the range from 0.1 to 3.0. Where:
68 |
69 | * `3.0` — Fastest rate.
70 |
71 | * `1.0` (default) — Average human speech rate.
72 |
73 | * `0.1` — Slowest speech rate.
74 |
75 | :type format: string
76 | :param format: The format of the synthesized audio. Acceptable values:
77 |
78 | * `lpcm` — Audio file is synthesized in LPCM format with no WAV _header. Audio properties:
79 |
80 | * Sampling — 8, 16, or 48 kHz, depending on the value of the `sample_rate_hertz` parameter.
81 |
82 | * Bit depth — 16-bit.
83 |
84 | * Byte order — Reversed (little-endian).
85 |
86 | * Audio data is stored as signed integers.
87 |
88 | * `oggopus` (default) — Data in the audio file is encoded using the OPUS audio codec and compressed using
89 | the OGG container format (OggOpus).
90 |
91 | :type sampleRateHertz: string
92 | :param sample_rate_hertz: The sampling frequency of the synthesized audio. Used
93 | if format is set to lpcm. Acceptable values: * `48000` (default): Sampling rate of 48 kHz. * `16000`:
94 | Sampling rate of 16 kHz. * `8000`: Sampling rate of 8 kHz.
95 |
96 | :type folderId: string
97 | :param folderId: ID of the folder that you have access to.
98 | Required for authorization with a user account (see the UserAccount resource).
99 | Don't specify this field if you make a request on behalf of a service account.
100 | """
101 |
102 | if 'text' in kwargs and len(kwargs.get('text', '')) > 5000:
103 | raise ValueError("Text must be less than 5000 characters")
104 |
105 | with open(file_path, "wb") as f:
106 | audio_data = self._synthesize_stream(**kwargs)
107 | f.write(audio_data)
108 |
109 | def synthesize_stream(self, **kwargs):
110 | """
111 | Generates speech from received text and return :py:meth:`io.BytesIO` object with data.
112 |
113 | :type text: string
114 | :param text: UTF-8 encoded text to be converted to speech.
115 | You can only use one `text` and `ssml` field.
116 | For homographs, place a `+` before the stressed vowel.
117 | For example, `contr+ol` or `def+ect`.
118 | To indicate a pause between words, use `-`.
119 | Maximum string length: 5000 characters.
120 |
121 | :type ssml: string
122 | :param ssml: Text in SSML format to be converted into speech.
123 | You can only use one text and ssml fields.
124 |
125 | :type lang: string
126 | :param lang: Language.
127 | Acceptable values:
128 |
129 | * `ru-RU` (default) — Russian.
130 |
131 | * `en-US` — English.
132 |
133 | * `tr-TR` — Turkish.
134 |
135 | :type voice: string
136 | :param voice: Preferred speech synthesis voice from the list.
137 | Default value: `oksana`.
138 |
139 | :type speed: string
140 | :param speed: Rate (speed) of synthesized speech.
141 | The rate of speech is set as a decimal number in the range from 0.1 to 3.0. Where:
142 |
143 | * `3.0` — Fastest rate.
144 |
145 | * `1.0` (default) — Average human speech rate.
146 |
147 | * `0.1` — Slowest speech rate.
148 |
149 | :type format: string
150 | :param format: The format of the synthesized audio. Acceptable values:
151 |
152 | - `lpcm` — Audio file is synthesized in LPCM format with no WAV _header. Audio properties:
153 |
154 | * Sampling — 8, 16, or 48 kHz, depending on the value of the `sample_rate_hertz` parameter.
155 |
156 | * Bit depth — 16-bit.
157 |
158 | * Byte order — Reversed (little-endian).
159 |
160 | * Audio data is stored as signed integers.
161 |
162 | - `oggopus` (default) — Data in the audio file is encoded using the OPUS audio codec and compressed using
163 | the OGG container format (OggOpus).
164 |
165 | :type sampleRateHertz: string
166 | :param sampleRateHertz: The sampling frequency of the synthesized audio.
167 | Used if format is set to lpcm. Acceptable values:
168 |
169 | * `48000` (default): Sampling rate of 48 kHz.
170 |
171 | * `16000`: Sampling rate of 16 kHz.
172 |
173 | * `8000`: Sampling rate of 8 kHz.
174 |
175 | :type folderId: string
176 | :param folderId: ID of the folder that you have access to.
177 | Required for authorization with a user account (see the UserAccount resource).
178 | Don't specify this field if you make a request on behalf of a service account.
179 | """
180 | if 'text' in kwargs and len(kwargs.get('text', '')) > 5000:
181 | raise ValueError("Text must be less than 5000 characters")
182 |
183 | return self._synthesize_stream(**kwargs)
--------------------------------------------------------------------------------
/src/speechkit/auth.py:
--------------------------------------------------------------------------------
1 | """
2 | Utilities for Yandex Cloud authorisation
3 | `IAM token `_
4 | `Api-Key `_
5 | """
6 |
7 | from speechkit._auth import generate_jwt, get_iam_token, get_api_key
8 |
9 | __all__ = ['generate_jwt', 'get_iam_token', 'get_api_key']
10 |
--------------------------------------------------------------------------------
/src/speechkit/exceptions.py:
--------------------------------------------------------------------------------
1 | """Basic speechkit exceptions."""
2 |
3 |
4 | class RequestError(Exception):
5 | """Exception raised for errors while yandex api request"""
6 |
7 | def __init__(self, answer: dict, *args):
8 | self.error_code = str(answer.get('code', '')) + str(answer.get('error_code', ''))
9 | self.message = str(answer.get('message', '')) + str(answer.get('error_message', ''))
10 | if self.error_code + self.message == '':
11 | self.message = str(answer)
12 |
13 | super().__init__(self.error_code + ' ' + self.message, *args)
14 |
--------------------------------------------------------------------------------
/src/speechkit/utils.py:
--------------------------------------------------------------------------------
1 | """Utilities functions, tht allow to use different api methods."""
2 |
3 | import requests
4 |
5 | from speechkit.exceptions import RequestError
6 |
7 |
8 | def list_of_service_accounts(session, **kwargs):
9 | """
10 | Retrieves the list of ServiceAccount resources in the specified folder.
11 |
12 | :param speechkit._auth.Session session: Session instance for auth
13 | :param dict kwargs: Additional parameters
14 | :return: List of dict with data of services accounts
15 | :rtype: list[dict]
16 | """
17 | if session.auth_method == session.API_KEY:
18 | raise ValueError("Api-Key authorisation method is invalid.")
19 | if session.folder_id is None:
20 | raise ValueError("You must specify folder is in session.")
21 |
22 | headers = session.header
23 | url = 'https://iam.api.cloud.yandex.net/iam/v1/serviceAccounts'
24 | data = {'folderId': session.folder_id, **kwargs}
25 | answer = requests.get(url, headers=headers, json=data)
26 |
27 | if answer.ok:
28 | return answer.json().get('serviceAccounts', [])
29 | else:
30 | raise RequestError(answer.json())
31 |
--------------------------------------------------------------------------------
/src/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikhonp/yandex-speechkit-lib-python/3376c02ed42870c0ad741b52067b5c9941ec84b5/src/tests/__init__.py
--------------------------------------------------------------------------------
/src/tests/test_auth.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 | from unittest import TestCase
4 |
5 | from speechkit.auth import generate_jwt, get_iam_token, get_api_key
6 | from speechkit import Session
7 |
8 |
9 | def get_private_key():
10 | with open('../.YANDEX_PRIVATE_KEY.txt', 'rb') as f:
11 | return f.read()
12 |
13 |
14 | class GenerateJwtTestCase(unittest.TestCase):
15 | def test_generating(self):
16 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
17 | key_id = os.environ.get('YANDEX_KEY_ID')
18 | private_key = get_private_key()
19 | jwt = generate_jwt(service_account_id, key_id, private_key)
20 | self.assertIsInstance(jwt, str)
21 |
22 | def test_assert_incorrect_service_account_id_key_id_private_key(self):
23 | with self.assertRaises(ValueError):
24 | generate_jwt('', 's', b'')
25 |
26 | with self.assertRaises(ValueError):
27 | generate_jwt('s', '', b'')
28 |
29 | with self.assertRaises(ValueError):
30 | generate_jwt('s', '', '')
31 |
32 |
33 | class GetIamTokenTestCase(unittest.TestCase):
34 | def test_assert_empty_data(self):
35 | with self.assertRaises(ValueError):
36 | get_iam_token()
37 |
38 | def test_assert_invalid_yandex_passport_oauth_token(self):
39 | with self.assertRaises(ValueError):
40 | get_iam_token(yandex_passport_oauth_token='', jwt_token='')
41 |
42 | def test_request_yandex_oauth(self):
43 | oauth_token = os.environ.get('YANDEX_OAUTH')
44 |
45 | data = get_iam_token(yandex_passport_oauth_token=oauth_token)
46 | self.assertIsInstance(data, str)
47 |
48 | def test_request_jwt(self):
49 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
50 | key_id = os.environ.get('YANDEX_KEY_ID')
51 | private_key = get_private_key()
52 | jwt = generate_jwt(service_account_id, key_id, private_key)
53 |
54 | data = get_iam_token(jwt_token=jwt)
55 | self.assertIsInstance(data, str)
56 |
57 |
58 | class GetApiKeyTestCase(unittest.TestCase):
59 | def test_request(self):
60 | yandex_passport_oauth_token = os.environ.get('YANDEX_OAUTH')
61 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
62 |
63 | data = get_api_key(yandex_passport_oauth_token, service_account_id)
64 | self.assertIsInstance(data, str)
65 |
66 | def test_invalid_data_empty(self):
67 | with self.assertRaises(ValueError):
68 | get_api_key()
69 |
70 |
71 | class SessionTestCase(TestCase):
72 | def test_from_api_key(self):
73 | api_key = os.environ.get('SERVICE_API_KEY')
74 | folder_id = os.environ.get('CATALOG')
75 |
76 | session = Session.from_api_key(api_key, folder_id)
77 | self.assertIsInstance(session.header, dict)
78 | self.assertEqual(session.folder_id, folder_id)
79 |
80 | def test_from_yandex_passport_oauth_token(self):
81 | oauth_token = os.environ.get('YANDEX_OAUTH')
82 | folder_id = os.environ.get('CATALOG')
83 |
84 | session = Session.from_yandex_passport_oauth_token(oauth_token, folder_id)
85 | self.assertIsInstance(session.header, dict)
86 |
87 | def test_from_jwt(self):
88 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
89 | key_id = os.environ.get('YANDEX_KEY_ID')
90 | private_key = get_private_key()
91 | jwt = generate_jwt(service_account_id, key_id, private_key)
92 |
93 | session = Session.from_jwt(jwt)
94 | self.assertIsInstance(session.header, dict)
95 |
96 | def test_header_api_key(self):
97 | session = Session(Session.API_KEY, 'hello', None)
98 | self.assertEqual(session.header, {'Authorization': 'Api-Key hello'})
99 |
100 | def test_header_iam_token(self):
101 | session = Session(Session.IAM_TOKEN, 'hello', None)
102 | self.assertEqual(session.header, {'Authorization': 'Bearer hello'})
103 |
104 | def test_auth_method(self):
105 | session = Session(Session.API_KEY, 'hello', None)
106 | self.assertEqual(session.auth_method, Session.API_KEY)
107 |
108 | session = Session(Session.IAM_TOKEN, 'hello', None)
109 | self.assertEqual(session.auth_method, Session.IAM_TOKEN)
110 |
111 |
112 | if __name__ == '__main__':
113 | unittest.main()
114 |
--------------------------------------------------------------------------------
/src/tests/test_exceptions.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from speechkit.exceptions import RequestError
4 |
5 |
6 | class RequestErrorTestCase(unittest.TestCase):
7 | def test_raise_data_1(self):
8 | with self.assertRaises(RequestError) as cm:
9 | raise RequestError({'code': 3, 'message': 'message'})
10 |
11 | the_exception = cm.exception
12 | self.assertEqual(the_exception.error_code, '3')
13 | self.assertEqual(the_exception.message, 'message')
14 | self.assertEqual(str(the_exception), '3 message')
15 |
16 | def test_raise_data_2(self):
17 | with self.assertRaises(RequestError) as cm:
18 | raise RequestError({'error_code': 3, 'error_message': 'message'})
19 |
20 | the_exception = cm.exception
21 | self.assertEqual(the_exception.error_code, '3')
22 | self.assertEqual(the_exception.message, 'message')
23 | self.assertEqual(str(the_exception), '3 message')
24 |
--------------------------------------------------------------------------------
/src/tests/test_long_audio_recognition.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | import unittest
4 | import warnings
5 |
6 | from speechkit import RecognitionLongAudio, Session
7 | from speechkit.auth import generate_jwt
8 |
9 | test_data = b'RIFFl@\x08\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00\x80\xbb\x00\x00\x00w\x01\x00\x02\x00\x10\x00LIST@\x00\x00\x00INFOINAM\x1d\x00\x00\x00\xd1\x83\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb0 8 \xd0\x9c\xd0\xb0\xd1\x80\xd1\x82\xd0\xb0, 6 9\x00\x00ISFT\x0e\x00\x00\x00Lavf58.76.100\x00data\x00@\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x01\x00\x00\x00\x00\x00\x01\x00\x02\x00\x02\x00\x03\x00\x02\x00\x02\x00\x01\x00\xff\xff\xff\xff\x00\x00\xff\xff\xfe\xff\xff\xff\x02\x00\x03\x00\x00\x00\xfd\xff\xfe\xff\x02\x00\x03\x00\x01\x00\xfe\xff\x01\x00\x04\x00\x03\x00\xfe\xff\xfb\xff\xfd\xff\x01\x00\x02\x00\x00\x00\xfc\xff\xfb\xff\xfc\xff\xff\xff\x02\x00\xff\xff\xf2\xff\xe0\xff\xd3\xff\xcf\xff\xd0\xff\xcc\xff\xc4\xff\xbd\xff\xb5\xff\xa5\xff\x8d\xfft\xffd\xff\\\xffX\xffV\xffV\xffV\xffN\xff?\xff1\xff/\xff8\xffA\xffG\xffJ\xffN\xffO\xffL\xffF\xffF\xffH\xffG\xff<\xff.\xff(\xff(\xff&\xff\x1e\xff\x16\xff\x18\xff#\xff0\xff8\xff<\xffA\xffF\xffH\xffH\xffL\xffV\xffb\xffm\xffs\xffv\xffy\xff}\xff\x85\xff\x8f\xff\x9a\xff\xa1\xff\xa8\xff\xaf\xff\xb4\xff\xb6\xff\xb7\xff\xbd\xff\xcc\xff\xdd\xff\xec\xff\xf9\xff\x08\x00\x18\x00\'\x003\x00?\x00J\x00Q\x00T\x00T\x00T\x00S\x00S\x00Z\x00n\x00\x87\x00\x99\x00\xa2\x00\xab\x00\xbb\x00\xcb\x00\xd4\x00\xd3\x00\xce\x00\xc9\x00\xc1\x00\xb4\x00\xa6\x00\x99\x00\x8b\x00~\x00w\x00z\x00\x80\x00\x80\x00w\x00n\x00k\x00o\x00q\x00n\x00j\x00k\x00p\x00q\x00h\x00Y\x00K\x00G\x00G\x00I\x00M\x00V\x00`\x00b\x00]\x00Y\x00X\x00T\x00D\x001\x00(\x00\'\x00 \x00\x0f\x00\xff\xff\xff\xff\t\x00\x0e\x00\x08\x00\xff\xff\xff\xff\x03\x00\x07\x00\t\x00\t\x00\x07\x00\x04\x00\x08\x00\x18\x00,\x005\x007\x00>\x00P\x00_\x00`\x00Y\x00Y\x00e\x00s\x00z\x00\x7f\x00\x85\x00\x8c\x00\x8f\x00\x8e\x00\x8d\x00\x8a\x00\x80\x00r\x00h\x00h\x00n\x00r\x00n\x00j\x00l\x00s\x00w\x00u\x00m\x00f\x00_\x00U\x00F\x008\x001\x00/\x00+\x00"\x00\x1a\x00\x16\x00\x0e\x00\xf9\xff\xda\xff\xbd\xff\xa7\xff\x90\xffs\xffX\xffH\xffA\xff6\xff#\xff\x12\xff\x0c\xff\x0b\xff\x05\xff\xf8\xfe\xed\xfe\xec\xfe\xed\xfe\xea\xfe\xe2\xfe\xde\xfe\xe0\xfe\xe4\xfe\xe5\xfe\xe4\xfe\xe3\xfe\xe1\xfe\xde\xfe\xdb\xfe\xdc\xfe\xe1\xfe\xe3\xfe\xe0\xfe\xde\xfe\xe1\xfe\xe7\xfe\xec\xfe\xf0\xfe\xfc\xfe\x10\xff!\xff\'\xff\'\xff-\xff<\xffJ\xffQ\xffV\xff]\xffe\xfff\xffa\xff\\\xff\\\xff`\xffh\xffs\xff\x81\xff\x8d\xff\x9a\xff\xa9\xff\xbc\xff\xcf\xff\xdf\xff\xf1\xff\x06\x00\x18\x00\x1f\x00!\x00,\x00E\x00^\x00m\x00v\x00\x82\x00\x91\x00\x9b\x00\x9f\x00\xa7\x00\xb8\x00\xcb\x00\xd9\x00\xe2\x00\xee\x00\xfb\x00\x04\x01\x05\x01\x02\x01\x01\x01\x01\x01\xff\x00\xfa\x00\xf4\x00\xec\x00\xe5\x00\xe3\x00\xe6\x00\xed\x00\xf5\x00\x01\x01\x0e\x01\x14\x01\x14\x01\x11\x01\x14\x01\x19\x01\x19\x01\x11\x01\x06\x01\xfc\x00\xf4\x00\xee\x00\xeb\x00\xe9\x00\xe5\x00\xde\x00\xd8\x00\xd5\x00\xce\x00\xbe\x00\xae\x00\xa8\x00\xaa\x00\xa3\x00\x91\x00\x83\x00\x86\x00\x91\x00\x90\x00\x82\x00v\x00r\x00l\x00[\x00H\x00A\x00F\x00G\x00=\x000\x00)\x00\'\x00$\x00\x1b\x00\x11\x00\n\x00\x07\x00\x05\x00\x01\x00\xf8\xff\xe9\xff\xd8\xff\xcc\xff\xc3\xff\xb6\xff\xa2\xff\x91\xff\x8a\xff\x90\xff\x9b\xff\xa4\xff\xad\xff\xba\xff\xcb\xff\xda\xff\xe5\xff\xef\xff\xf9\xff\xff\xff\xfe\xff\xfa\xff\xfa\xff\x02\x00\x08\x00\n\x00\x0e\x00\x1e\x004\x00D\x00K\x00U\x00k\x00\x84\x00\x92\x00\x99\x00\xa9\x00\xc3\x00\xd9\x00\xe3\x00\xec\x00\x02\x01\x1c\x01.\x017\x01D\x01X\x01d\x01^\x01T\x01U\x01^\x01^\x01P\x01C\x01C\x01N\x01W\x01\\\x01b\x01l\x01w\x01\x7f\x01\x84\x01\x83\x01|\x01u\x01q\x01o\x01g\x01W\x01F\x01<\x017\x012\x01)\x01"\x01\x1d\x01\x1b\x01\x16\x01\n\x01\xf5\x00\xd7\x00\xb6\x00\x9c\x00\x87\x00o\x00S\x007\x00$\x00\x1c\x00\x14\x00\x07\x00\xf4\xff\xe1\xff\xd0\xff\xc1\xff\xb1\xff\x9f\xff\x8e\xff\x82\xff|\xffz\xfft\xffj\xff`\xffZ\xffT\xffL\xffC\xff:\xff4\xff-\xff%\xff\x1b\xff\x11\xff\x08\xff\xff\xfe\xfa\xfe\xf8\xfe\xf7\xfe\xf3\xfe\xec\xfe\xe4\xfe\xdf\xfe\xe0\xfe\xe5\xfe\xed\xfe\xf4\xfe\xfd\xfe\r\xff\x1f\xff,\xff.\xff,\xff3\xffE\xffY\xfff\xffq\xff\x80\xff\x98\xff\xb8\xff\xd9\xff\xf5\xff\x06\x00\x10\x00\x1d\x00.\x00<\x00<\x005\x004\x00:\x00:\x00&\x00\n\x00\xf8\xff\xf5\xff\xf6\xff\xf2\xff\xef\xff\xf3\xff\xfa\xff\xfc\xff\xf9\xff\xfb\xff\x00\x00\x03\x00\x01\x00\xff\xff\x04\x00\x0c\x00\x10\x00\x0e\x00\n\x00\x0b\x00\r\x00\x0f\x00\x0e\x00\x0c\x00\x0c\x00\x0c\x00\x0e\x00\r\x00\x0b\x00\t\x00\x0c\x00\x10\x00\x0f\x00\t\x00\x02\x00\x02\x00\x07\x00\n\x00\n\x00\t\x00\t\x00\t\x00\x07\x00\x06\x00\x05\x00\x04\x00\x01\x00\x00\x00\x01\x00\x00\x00\xfe\xff\xfb\xff\xfb\xff\xfc\xff\xfb\xff\xf8\xff\xf5\xff\xf7\xff\xf9\xff\xf7\xff\xf2\xff\xf1\xff\xf4\xff\xf7\xff\xf5\xff\xf2\xff\xf1\xff\xf2\xff\xf3\xff\xf3\xff\xf2\xff\xf2\xff\xf2\xff\xf1\xff\xef\xff\xed\xff\xec\xff\xed\xff\xef\xff\xf0\xff\xf1\xff\xf2\xff\xf3\xff\xf4\xff\xf5\xff\xf3\xff\xf0\xff\xee\xff\xed\xff\xee\xff\xed\xff\xeb\xff\xea\xff\xeb\xff\xec\xff\xeb\xff\xe9\xff\xe8\xff\xea\xff\xec\xff\xec\xff\xea\xff\xe9\xff\xea\xff\xeb\xff\xea\xff\xe9\xff\xe8\xff\xe9\xff\xe9\xff\xea\xff\xea\xff\xe8\xff\xe5\xff\xe2\xff\xe2\xff\xe4\xff\xe4\xff\xe2\xff\xdf\xff\xdf\xff\xe0\xff\xe0\xff\xde\xff\xdd\xff\xdc\xff\xda\xff\xd9\xff\xd9\xff\xdb\xff\xdd\xff\xdc\xff\xd9\xff\xd8\xff\xda\xff\xdb\xff\xdb\xff\xdc\xff\xde\xff\xdd\xff\xda\xff\xd7\xff\xd7\xff\xd8\xff\xd8\xff\xd7\xff\xd7\xff\xd9\xff\xda\xff\xd8\xff\xd6\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd6\xff\xda\xff\xdd\xff\xde\xff\xde\xff\xde\xff\xe1\xff\xe2\xff\xe1\xff\xe0\xff\xe1\xff\xe3\xff\xe4\xff\xe2\xff\xe1\xff\xe3\xff\xe4\xff\xe4\xff\xe2\xff\xe2\xff\xe4\xff\xe6\xff\xe8\xff\xe9\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xec\xff\xec\xff\xed\xff\xef\xff\xf0\xff\xef\xff\xed\xff\xed\xff\xee\xff\xef\xff\xee\xff\xec\xff\xeb\xff\xeb\xff\xeb\xff\xea\xff\xea\xff\xe9\xff\xe9\xff\xe8\xff\xe8\xff\xe8\xff\xe7\xff\xe5\xff\xe4\xff\xe4\xff\xe6\xff\xe8\xff\xe8\xff\xe6\xff\xe4\xff\xe4\xff\xe5\xff\xe6\xff\xe6\xff\xe5\xff\xe4\xff\xe3\xff\xe4\xff\xe4\xff\xe3\xff\xe1\xff\xe0\xff\xe0\xff\xe0\xff\xdf\xff\xde\xff\xde\xff\xdd\xff\xdb\xff\xda\xff\xda\xff\xda\xff\xd9\xff\xd8\xff\xd7\xff\xd8\xff\xd8\xff\xd6\xff\xd3\xff\xd2\xff\xd3\xff\xd5\xff\xd7\xff\xda\xff\xdc\xff\xde\xff\xde\xff\xde\xff\xdf\xff\xe0\xff\xe0\xff\xe0\xff\xe1\xff\xe3\xff\xe5\xff\xe4\xff\xe0\xff\xdd\xff\xdd\xff\xe1\xff\xe4\xff\xe4\xff\xe2\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe5\xff\xe5\xff\xe4\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe7\xff\xe6\xff\xe6\xff\xe7\xff\xe7\xff\xe8\xff\xe8\xff\xe8\xff\xe8\xff\xe9\xff\xea\xff\xea\xff\xea\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe8\xff\xe8\xff\xe8\xff\xe8\xff\xe9\xff\xe9\xff\xe8\xff\xe7\xff\xe6\xff\xe7\xff\xe7\xff\xe6\xff\xe5\xff\xe5\xff\xe5\xff\xe6\xff\xe5\xff\xe4\xff\xe4\xff\xe5\xff\xe4\xff\xe4\xff\xe3\xff\xe2\xff\xe2\xff\xe2\xff\xe1\xff\xe0\xff\xe0\xff\xdf\xff\xde\xff\xde\xff\xdd\xff\xdd\xff\xdc\xff\xdc\xff\xdb\xff\xdb\xff\xdb\xff\xda\xff\xda\xff\xda\xff\xda\xff\xd9\xff\xd9\xff\xd9\xff\xd8\xff\xd8\xff\xd9\xff\xd9\xff\xd9\xff\xd9\xff\xd9\xff\xda\xff\xda\xff\xda\xff\xda\xff\xdb\xff\xdb\xff\xdb\xff\xdc\xff\xdc\xff\xdc\xff\xdd\xff\xdd\xff\xde\xff\xde\xff\xdf\xff\xdf\xff\xe0\xff\xe0\xff\xe1\xff\xe1\xff\xe1\xff\xe2\xff\xe2\xff\xe3\xff\xe3\xff\xe3\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe3\xff\xe3\xff\xe3\xff\xe2\xff\xe2\xff\xe2\xff\xe2\xff\xe1\xff\xe1\xff\xe1\xff\xe1\xff'
10 |
11 |
12 | def get_private_key():
13 | with open('../.YANDEX_PRIVATE_KEY.txt', 'rb') as f:
14 | return f.read()
15 |
16 |
17 | class RecognizeLongAudio(unittest.TestCase):
18 | def setUp(self):
19 | warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*")
20 |
21 | def test_init_wrong_description(self):
22 | session = Session(auth_type=Session.IAM_TOKEN, credential='lol', folder_id='ad')
23 |
24 | with self.assertRaises(ValueError):
25 | RecognitionLongAudio(session, 'acid', 'bucket', aws_credentials_description='l' * 257)
26 |
27 | def test_init(self):
28 | bucket_name = os.environ.get('BUCKET_NAME')
29 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
30 | key_id = os.environ.get('YANDEX_KEY_ID')
31 | private_key = get_private_key()
32 | jwt = generate_jwt(service_account_id, key_id, private_key)
33 |
34 | session = Session.from_jwt(jwt)
35 | recognize_long_audio = RecognitionLongAudio(session, service_account_id, bucket_name)
36 | self.assertIsInstance(recognize_long_audio._headers, dict)
37 |
38 | def test_get_aws_credentials(self):
39 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
40 | key_id = os.environ.get('YANDEX_KEY_ID')
41 | private_key = get_private_key()
42 | jwt = generate_jwt(service_account_id, key_id, private_key)
43 |
44 | session = Session.from_jwt(jwt)
45 | access_key_id, secret = RecognitionLongAudio.get_aws_credentials(session, service_account_id)
46 | self.assertIsInstance(access_key_id, str)
47 | self.assertIsInstance(secret, str)
48 |
49 | def test_init_from_aws_credentials(self):
50 | bucket_name = os.environ.get('BUCKET_NAME')
51 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
52 | key_id = os.environ.get('YANDEX_KEY_ID')
53 | private_key = get_private_key()
54 | jwt = generate_jwt(service_account_id, key_id, private_key)
55 |
56 | session = Session.from_jwt(jwt)
57 | access_key_id, secret = RecognitionLongAudio.get_aws_credentials(session, service_account_id)
58 |
59 | recognize_long_audio = RecognitionLongAudio(session, service_account_id, bucket_name,
60 | aws_access_key_id=access_key_id, aws_secret=secret)
61 | self.assertIsInstance(recognize_long_audio._headers, dict)
62 |
63 | def test_recognition(self):
64 | bucket_name = os.environ.get('BUCKET_NAME')
65 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
66 | key_id = os.environ.get('YANDEX_KEY_ID')
67 | private_key = get_private_key()
68 | jwt = generate_jwt(service_account_id, key_id, private_key)
69 |
70 | session = Session.from_jwt(jwt)
71 | recognize_long_audio = RecognitionLongAudio(session, service_account_id, bucket_name)
72 |
73 | self.path = os.path.join(os.path.dirname(__file__), 'test_rec.wav')
74 | with open(self.path, 'wb') as f:
75 | f.write(test_data)
76 |
77 | recognize_long_audio.send_for_recognition(self.path, audioEncoding='LINEAR16_PCM', sampleRateHertz='48000',
78 | audioChannelCount=1, rawResults=False)
79 |
80 | while True:
81 | time.sleep(2)
82 | if recognize_long_audio.get_recognition_results():
83 | break
84 |
85 | data = recognize_long_audio.get_data()
86 | self.assertIsInstance(data, (list, type(None)))
87 |
88 | text = recognize_long_audio.get_raw_text()
89 | self.assertIsInstance(text, str)
90 |
--------------------------------------------------------------------------------
/src/tests/test_short_audio_recognition.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 |
4 | import speechkit
5 | from speechkit import Session, ShortAudioRecognition
6 | from speechkit.auth import generate_jwt
7 |
8 | test_data = b'RIFFl@\x08\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00\x80\xbb\x00\x00\x00w\x01\x00\x02\x00\x10\x00LIST@\x00\x00\x00INFOINAM\x1d\x00\x00\x00\xd1\x83\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb0 8 \xd0\x9c\xd0\xb0\xd1\x80\xd1\x82\xd0\xb0, 6 9\x00\x00ISFT\x0e\x00\x00\x00Lavf58.76.100\x00data\x00@\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x01\x00\x00\x00\x00\x00\x01\x00\x02\x00\x02\x00\x03\x00\x02\x00\x02\x00\x01\x00\xff\xff\xff\xff\x00\x00\xff\xff\xfe\xff\xff\xff\x02\x00\x03\x00\x00\x00\xfd\xff\xfe\xff\x02\x00\x03\x00\x01\x00\xfe\xff\x01\x00\x04\x00\x03\x00\xfe\xff\xfb\xff\xfd\xff\x01\x00\x02\x00\x00\x00\xfc\xff\xfb\xff\xfc\xff\xff\xff\x02\x00\xff\xff\xf2\xff\xe0\xff\xd3\xff\xcf\xff\xd0\xff\xcc\xff\xc4\xff\xbd\xff\xb5\xff\xa5\xff\x8d\xfft\xffd\xff\\\xffX\xffV\xffV\xffV\xffN\xff?\xff1\xff/\xff8\xffA\xffG\xffJ\xffN\xffO\xffL\xffF\xffF\xffH\xffG\xff<\xff.\xff(\xff(\xff&\xff\x1e\xff\x16\xff\x18\xff#\xff0\xff8\xff<\xffA\xffF\xffH\xffH\xffL\xffV\xffb\xffm\xffs\xffv\xffy\xff}\xff\x85\xff\x8f\xff\x9a\xff\xa1\xff\xa8\xff\xaf\xff\xb4\xff\xb6\xff\xb7\xff\xbd\xff\xcc\xff\xdd\xff\xec\xff\xf9\xff\x08\x00\x18\x00\'\x003\x00?\x00J\x00Q\x00T\x00T\x00T\x00S\x00S\x00Z\x00n\x00\x87\x00\x99\x00\xa2\x00\xab\x00\xbb\x00\xcb\x00\xd4\x00\xd3\x00\xce\x00\xc9\x00\xc1\x00\xb4\x00\xa6\x00\x99\x00\x8b\x00~\x00w\x00z\x00\x80\x00\x80\x00w\x00n\x00k\x00o\x00q\x00n\x00j\x00k\x00p\x00q\x00h\x00Y\x00K\x00G\x00G\x00I\x00M\x00V\x00`\x00b\x00]\x00Y\x00X\x00T\x00D\x001\x00(\x00\'\x00 \x00\x0f\x00\xff\xff\xff\xff\t\x00\x0e\x00\x08\x00\xff\xff\xff\xff\x03\x00\x07\x00\t\x00\t\x00\x07\x00\x04\x00\x08\x00\x18\x00,\x005\x007\x00>\x00P\x00_\x00`\x00Y\x00Y\x00e\x00s\x00z\x00\x7f\x00\x85\x00\x8c\x00\x8f\x00\x8e\x00\x8d\x00\x8a\x00\x80\x00r\x00h\x00h\x00n\x00r\x00n\x00j\x00l\x00s\x00w\x00u\x00m\x00f\x00_\x00U\x00F\x008\x001\x00/\x00+\x00"\x00\x1a\x00\x16\x00\x0e\x00\xf9\xff\xda\xff\xbd\xff\xa7\xff\x90\xffs\xffX\xffH\xffA\xff6\xff#\xff\x12\xff\x0c\xff\x0b\xff\x05\xff\xf8\xfe\xed\xfe\xec\xfe\xed\xfe\xea\xfe\xe2\xfe\xde\xfe\xe0\xfe\xe4\xfe\xe5\xfe\xe4\xfe\xe3\xfe\xe1\xfe\xde\xfe\xdb\xfe\xdc\xfe\xe1\xfe\xe3\xfe\xe0\xfe\xde\xfe\xe1\xfe\xe7\xfe\xec\xfe\xf0\xfe\xfc\xfe\x10\xff!\xff\'\xff\'\xff-\xff<\xffJ\xffQ\xffV\xff]\xffe\xfff\xffa\xff\\\xff\\\xff`\xffh\xffs\xff\x81\xff\x8d\xff\x9a\xff\xa9\xff\xbc\xff\xcf\xff\xdf\xff\xf1\xff\x06\x00\x18\x00\x1f\x00!\x00,\x00E\x00^\x00m\x00v\x00\x82\x00\x91\x00\x9b\x00\x9f\x00\xa7\x00\xb8\x00\xcb\x00\xd9\x00\xe2\x00\xee\x00\xfb\x00\x04\x01\x05\x01\x02\x01\x01\x01\x01\x01\xff\x00\xfa\x00\xf4\x00\xec\x00\xe5\x00\xe3\x00\xe6\x00\xed\x00\xf5\x00\x01\x01\x0e\x01\x14\x01\x14\x01\x11\x01\x14\x01\x19\x01\x19\x01\x11\x01\x06\x01\xfc\x00\xf4\x00\xee\x00\xeb\x00\xe9\x00\xe5\x00\xde\x00\xd8\x00\xd5\x00\xce\x00\xbe\x00\xae\x00\xa8\x00\xaa\x00\xa3\x00\x91\x00\x83\x00\x86\x00\x91\x00\x90\x00\x82\x00v\x00r\x00l\x00[\x00H\x00A\x00F\x00G\x00=\x000\x00)\x00\'\x00$\x00\x1b\x00\x11\x00\n\x00\x07\x00\x05\x00\x01\x00\xf8\xff\xe9\xff\xd8\xff\xcc\xff\xc3\xff\xb6\xff\xa2\xff\x91\xff\x8a\xff\x90\xff\x9b\xff\xa4\xff\xad\xff\xba\xff\xcb\xff\xda\xff\xe5\xff\xef\xff\xf9\xff\xff\xff\xfe\xff\xfa\xff\xfa\xff\x02\x00\x08\x00\n\x00\x0e\x00\x1e\x004\x00D\x00K\x00U\x00k\x00\x84\x00\x92\x00\x99\x00\xa9\x00\xc3\x00\xd9\x00\xe3\x00\xec\x00\x02\x01\x1c\x01.\x017\x01D\x01X\x01d\x01^\x01T\x01U\x01^\x01^\x01P\x01C\x01C\x01N\x01W\x01\\\x01b\x01l\x01w\x01\x7f\x01\x84\x01\x83\x01|\x01u\x01q\x01o\x01g\x01W\x01F\x01<\x017\x012\x01)\x01"\x01\x1d\x01\x1b\x01\x16\x01\n\x01\xf5\x00\xd7\x00\xb6\x00\x9c\x00\x87\x00o\x00S\x007\x00$\x00\x1c\x00\x14\x00\x07\x00\xf4\xff\xe1\xff\xd0\xff\xc1\xff\xb1\xff\x9f\xff\x8e\xff\x82\xff|\xffz\xfft\xffj\xff`\xffZ\xffT\xffL\xffC\xff:\xff4\xff-\xff%\xff\x1b\xff\x11\xff\x08\xff\xff\xfe\xfa\xfe\xf8\xfe\xf7\xfe\xf3\xfe\xec\xfe\xe4\xfe\xdf\xfe\xe0\xfe\xe5\xfe\xed\xfe\xf4\xfe\xfd\xfe\r\xff\x1f\xff,\xff.\xff,\xff3\xffE\xffY\xfff\xffq\xff\x80\xff\x98\xff\xb8\xff\xd9\xff\xf5\xff\x06\x00\x10\x00\x1d\x00.\x00<\x00<\x005\x004\x00:\x00:\x00&\x00\n\x00\xf8\xff\xf5\xff\xf6\xff\xf2\xff\xef\xff\xf3\xff\xfa\xff\xfc\xff\xf9\xff\xfb\xff\x00\x00\x03\x00\x01\x00\xff\xff\x04\x00\x0c\x00\x10\x00\x0e\x00\n\x00\x0b\x00\r\x00\x0f\x00\x0e\x00\x0c\x00\x0c\x00\x0c\x00\x0e\x00\r\x00\x0b\x00\t\x00\x0c\x00\x10\x00\x0f\x00\t\x00\x02\x00\x02\x00\x07\x00\n\x00\n\x00\t\x00\t\x00\t\x00\x07\x00\x06\x00\x05\x00\x04\x00\x01\x00\x00\x00\x01\x00\x00\x00\xfe\xff\xfb\xff\xfb\xff\xfc\xff\xfb\xff\xf8\xff\xf5\xff\xf7\xff\xf9\xff\xf7\xff\xf2\xff\xf1\xff\xf4\xff\xf7\xff\xf5\xff\xf2\xff\xf1\xff\xf2\xff\xf3\xff\xf3\xff\xf2\xff\xf2\xff\xf2\xff\xf1\xff\xef\xff\xed\xff\xec\xff\xed\xff\xef\xff\xf0\xff\xf1\xff\xf2\xff\xf3\xff\xf4\xff\xf5\xff\xf3\xff\xf0\xff\xee\xff\xed\xff\xee\xff\xed\xff\xeb\xff\xea\xff\xeb\xff\xec\xff\xeb\xff\xe9\xff\xe8\xff\xea\xff\xec\xff\xec\xff\xea\xff\xe9\xff\xea\xff\xeb\xff\xea\xff\xe9\xff\xe8\xff\xe9\xff\xe9\xff\xea\xff\xea\xff\xe8\xff\xe5\xff\xe2\xff\xe2\xff\xe4\xff\xe4\xff\xe2\xff\xdf\xff\xdf\xff\xe0\xff\xe0\xff\xde\xff\xdd\xff\xdc\xff\xda\xff\xd9\xff\xd9\xff\xdb\xff\xdd\xff\xdc\xff\xd9\xff\xd8\xff\xda\xff\xdb\xff\xdb\xff\xdc\xff\xde\xff\xdd\xff\xda\xff\xd7\xff\xd7\xff\xd8\xff\xd8\xff\xd7\xff\xd7\xff\xd9\xff\xda\xff\xd8\xff\xd6\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd5\xff\xd6\xff\xda\xff\xdd\xff\xde\xff\xde\xff\xde\xff\xe1\xff\xe2\xff\xe1\xff\xe0\xff\xe1\xff\xe3\xff\xe4\xff\xe2\xff\xe1\xff\xe3\xff\xe4\xff\xe4\xff\xe2\xff\xe2\xff\xe4\xff\xe6\xff\xe8\xff\xe9\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xec\xff\xec\xff\xed\xff\xef\xff\xf0\xff\xef\xff\xed\xff\xed\xff\xee\xff\xef\xff\xee\xff\xec\xff\xeb\xff\xeb\xff\xeb\xff\xea\xff\xea\xff\xe9\xff\xe9\xff\xe8\xff\xe8\xff\xe8\xff\xe7\xff\xe5\xff\xe4\xff\xe4\xff\xe6\xff\xe8\xff\xe8\xff\xe6\xff\xe4\xff\xe4\xff\xe5\xff\xe6\xff\xe6\xff\xe5\xff\xe4\xff\xe3\xff\xe4\xff\xe4\xff\xe3\xff\xe1\xff\xe0\xff\xe0\xff\xe0\xff\xdf\xff\xde\xff\xde\xff\xdd\xff\xdb\xff\xda\xff\xda\xff\xda\xff\xd9\xff\xd8\xff\xd7\xff\xd8\xff\xd8\xff\xd6\xff\xd3\xff\xd2\xff\xd3\xff\xd5\xff\xd7\xff\xda\xff\xdc\xff\xde\xff\xde\xff\xde\xff\xdf\xff\xe0\xff\xe0\xff\xe0\xff\xe1\xff\xe3\xff\xe5\xff\xe4\xff\xe0\xff\xdd\xff\xdd\xff\xe1\xff\xe4\xff\xe4\xff\xe2\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe5\xff\xe5\xff\xe4\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe7\xff\xe6\xff\xe6\xff\xe7\xff\xe7\xff\xe8\xff\xe8\xff\xe8\xff\xe8\xff\xe9\xff\xea\xff\xea\xff\xea\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe9\xff\xe8\xff\xe8\xff\xe8\xff\xe8\xff\xe9\xff\xe9\xff\xe8\xff\xe7\xff\xe6\xff\xe7\xff\xe7\xff\xe6\xff\xe5\xff\xe5\xff\xe5\xff\xe6\xff\xe5\xff\xe4\xff\xe4\xff\xe5\xff\xe4\xff\xe4\xff\xe3\xff\xe2\xff\xe2\xff\xe2\xff\xe1\xff\xe0\xff\xe0\xff\xdf\xff\xde\xff\xde\xff\xdd\xff\xdd\xff\xdc\xff\xdc\xff\xdb\xff\xdb\xff\xdb\xff\xda\xff\xda\xff\xda\xff\xda\xff\xd9\xff\xd9\xff\xd9\xff\xd8\xff\xd8\xff\xd9\xff\xd9\xff\xd9\xff\xd9\xff\xd9\xff\xda\xff\xda\xff\xda\xff\xda\xff\xdb\xff\xdb\xff\xdb\xff\xdc\xff\xdc\xff\xdc\xff\xdd\xff\xdd\xff\xde\xff\xde\xff\xdf\xff\xdf\xff\xe0\xff\xe0\xff\xe1\xff\xe1\xff\xe1\xff\xe2\xff\xe2\xff\xe3\xff\xe3\xff\xe3\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe4\xff\xe3\xff\xe3\xff\xe3\xff\xe2\xff\xe2\xff\xe2\xff\xe2\xff\xe1\xff\xe1\xff\xe1\xff\xe1\xff'
9 |
10 |
11 | def get_private_key():
12 | with open('../.YANDEX_PRIVATE_KEY.txt', 'rb') as f:
13 | return f.read()
14 |
15 |
16 | class RecognizeShortAudioTestCaseApiKey(unittest.TestCase):
17 | def setUp(self) -> None:
18 | api_key = os.environ.get('SERVICE_API_KEY')
19 | folder_id = os.environ.get('CATALOG')
20 |
21 | session = Session.from_api_key(api_key, folder_id)
22 | self.recognize_short_audio = ShortAudioRecognition(session)
23 |
24 | def test_init(self):
25 | self.assertIsInstance(self.recognize_short_audio._headers, dict)
26 |
27 | def test_wrong_catalog(self):
28 | with self.assertRaises(speechkit.exceptions.RequestError):
29 | api_key = os.environ.get('SERVICE_API_KEY')
30 |
31 | session = Session.from_api_key(api_key, 'lol')
32 | recognize_short_audio = ShortAudioRecognition(session)
33 |
34 | recognize_short_audio.recognize(bytes())
35 |
36 | def test_recognize(self):
37 | text = self.recognize_short_audio.recognize(
38 | test_data, format='lpcm', sampleRateHertz='48000'
39 | )
40 | self.assertIsInstance(text, str)
41 |
42 |
43 | class RecognizeShortAudioTestCaseJwt(unittest.TestCase):
44 | def setUp(self) -> None:
45 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
46 | key_id = os.environ.get('YANDEX_KEY_ID')
47 | private_key = get_private_key()
48 | jwt = generate_jwt(service_account_id, key_id, private_key)
49 |
50 | session = Session.from_jwt(jwt)
51 |
52 | self.recognize_short_audio = ShortAudioRecognition(session)
53 |
54 | def test_init(self):
55 | self.assertIsInstance(self.recognize_short_audio._headers, dict)
56 |
57 | def test_wrong_catalog(self):
58 | with self.assertRaises(speechkit.exceptions.RequestError):
59 | api_key = os.environ.get('SERVICE_API_KEY')
60 |
61 | session = Session.from_api_key(api_key, 'lol')
62 | recognize_short_audio = ShortAudioRecognition(session)
63 |
64 | recognize_short_audio.recognize(bytes())
65 |
66 | def test_recognize(self):
67 | text = self.recognize_short_audio.recognize(
68 | test_data, format='lpcm', sampleRateHertz='48000'
69 | )
70 | self.assertIsInstance(text, str)
71 |
--------------------------------------------------------------------------------
/src/tests/test_speech_synthesis.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pathlib
3 | import unittest
4 |
5 | from speechkit import SpeechSynthesis, Session
6 |
7 |
8 | class SynthesizeAudio(unittest.TestCase):
9 | def test_init(self):
10 | api_key = os.environ.get('SERVICE_API_KEY')
11 | session = Session.from_api_key(api_key)
12 | synthesize_audio = SpeechSynthesis(session)
13 | self.assertIsInstance(synthesize_audio._headers, dict)
14 |
15 | def test_synthesize(self):
16 | api_key = os.environ.get('SERVICE_API_KEY')
17 | session = Session.from_api_key(api_key)
18 | synthesize_audio = SpeechSynthesis(session)
19 |
20 | self.path = os.path.join(os.path.dirname(__file__), 'test_synth.wav')
21 | synthesize_audio.synthesize(
22 | self.path, text='text',
23 | voice='oksana', format='lpcm', sampleRateHertz='16000'
24 | )
25 | self.assertTrue(pathlib.Path(self.path).resolve().is_file())
26 |
27 | def test_assert_synthesize(self):
28 | api_key = os.environ.get('SERVICE_API_KEY')
29 | session = Session.from_api_key(api_key)
30 | synthesize_audio = SpeechSynthesis(session)
31 |
32 | with self.assertRaises(ValueError):
33 | synthesize_audio.synthesize(
34 | 'ok', text='t' * 5001
35 | )
36 |
37 | def test_synthesize_stream(self):
38 | api_key = os.environ.get('SERVICE_API_KEY')
39 | session = Session.from_api_key(api_key)
40 | synthesize_audio = SpeechSynthesis(session)
41 |
42 | data = synthesize_audio.synthesize_stream(
43 | text='text', voice='oksana', format='lpcm',
44 | sampleRateHertz='16000'
45 | )
46 | self.assertIsInstance(data, bytes)
47 |
--------------------------------------------------------------------------------
/src/tests/test_streaming_recognition.py:
--------------------------------------------------------------------------------
1 | import os
2 | from unittest import TestCase
3 |
4 | from speechkit import Session, DataStreamingRecognition
5 | from speechkit.auth import generate_jwt
6 | import speechkit
7 |
8 |
9 | def get_private_key():
10 | with open('../.YANDEX_PRIVATE_KEY.txt', 'rb') as f:
11 | return f.read()
12 |
13 |
14 | class DataStreamingRecognitionTestCase(TestCase):
15 | def setUp(self) -> None:
16 | service_account_id = os.environ.get('SERVICE_ACCOUNT_ID')
17 | key_id = os.environ.get('YANDEX_KEY_ID')
18 | private_key = get_private_key()
19 |
20 | jwt = generate_jwt(service_account_id, key_id, private_key)
21 | self.session = Session.from_jwt(jwt)
22 |
23 | def test_init(self):
24 | data_streaming_recognition = DataStreamingRecognition(
25 | self.session,
26 | language_code='ru-RU',
27 | audio_encoding='LINEAR16_PCM',
28 | sample_rate_hertz=8000,
29 | partial_results=False,
30 | single_utterance=True,
31 | )
32 | self.assertIsInstance(data_streaming_recognition._headers, tuple)
33 |
34 | def test__gen(self):
35 | def gen_func():
36 | yield bytes()
37 |
38 | data_streaming_recognition = DataStreamingRecognition(
39 | self.session,
40 | language_code='ru-RU',
41 | audio_encoding='LINEAR16_PCM',
42 | sample_rate_hertz=8000,
43 | partial_results=False,
44 | single_utterance=True,
45 | )
46 | next(data_streaming_recognition._gen(gen_func))
47 | self.assertIsInstance(next(data_streaming_recognition._gen(gen_func)),
48 | speechkit._recognition.yandex.cloud.ai.stt.v2.stt_service_pb2.StreamingRecognitionRequest)
49 |
50 | # def test_recognize_raw(self):
51 | # self.fail()
52 | #
53 | # def test_recognize(self):
54 | # self.fail()
55 |
--------------------------------------------------------------------------------
/src/tests/test_utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 |
4 | from speechkit import Session
5 | from speechkit.utils import list_of_service_accounts
6 |
7 |
8 | class ListOfServiceAccountsTestCase(unittest.TestCase):
9 | def test_request(self):
10 | api_key = os.environ.get('YANDEX_OAUTH')
11 | folder_id = os.environ.get('CATALOG')
12 |
13 | session = Session.from_yandex_passport_oauth_token(api_key, folder_id)
14 |
15 | data = list_of_service_accounts(session)
16 | self.assertIsInstance(data, list)
17 |
18 | def invalid_session_from_api_key(self):
19 | session = Session.from_api_key('api_key', 'sdsas')
20 | with self.assertRaises(ValueError):
21 | list_of_service_accounts(session)
22 |
23 | def invalid_session_no_folder_id(self):
24 | api_key = os.environ.get('YANDEX_OAUTH')
25 | session = Session.from_api_key(api_key)
26 | with self.assertRaises(ValueError):
27 | list_of_service_accounts(session)
28 |
--------------------------------------------------------------------------------