{ "info": { "author": "Richard Tier", "author_email": "rikatee@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# Alexa Voice Service Client\n\n[![code-climate-image]][code-climate]\n[![circle-ci-image]][circle-ci]\n[![codecov-image]][codecov]\n\n**Python Client for Alexa Voice Service (AVS)**\n\n---\n\n## Installation\n```sh\npip install alexa_client\n```\n\nor if you want to run the demos:\n\n```sh\npip install alexa_client[demo]\n```\n\n## Usage\n\n### File audio ###\n```py\nfrom alexa_client import AlexaClient\n\nclient = AlexaClient(\n client_id='my-client-id',\n secret='my-secret',\n refresh_token='my-refresh-token',\n)\nclient.connect() # authenticate and other handshaking steps\nwith open('./tests/resources/alexa_what_time_is_it.wav', 'rb') as f:\n for i, directive in enumerate(client.send_audio_file(f)):\n if directive.name in ['Speak', 'Play']:\n with open(f'./output_{i}.mp3', 'wb') as f:\n f.write(directive.audio_attachment)\n```\n\nNow listen to `output_0.wav` and Alexa should tell you the time.\n\n### Microphone audio\n\n```py\nimport io\n\nfrom alexa_client import AlexaClient\nimport pyaudio\n\n\ndef callback(in_data, frame_count, time_info, status):\n buffer.write(in_data)\n return (in_data, pyaudio.paContinue)\n\np = pyaudio.PyAudio()\nstream = p.open(\n format=pyaudio.paInt16,\n channels=1,\n rate=16000,\n input=True,\n stream_callback=callback,\n)\n\nclient = AlexaClient(\n client_id='my-client-id',\n secret='my-secret',\n refresh_token='my-refresh-token',\n)\n\nbuffer = io.BytesIO()\ntry:\n stream.start_stream()\n print('listening. Press CTRL + C to exit.')\n client.connect()\n for i, directive in enumerate(client.send_audio_file(buffer)):\n if directive.name in ['Speak', 'Play']:\n with open(f'./output_{i}.mp3', 'wb') as f:\n f.write(directive.audio_attachment)\nfinally:\n stream.stop_stream()\n stream.close()\n p.terminate()\n```\n\n### Multi-step requests\n\nAn Alexa command may relate to a previous command e.g,\n\n[you] \"Alexa, play twenty questions\"\n[Alexa] \"Is it a animal, mineral, or vegetable?\"\n[you] \"Mineral\"\n[Alexa] \"Is it valuable\"\n[you] \"No\"\n[Alexa] \"is it...\"\n\nThis can be achieved by passing the same dialog request ID to multiple `send_audio_file` calls:\n\n```py\nfrom alexa_client.alexa_client import helpers\n\ndialog_request_id = helpers.generate_unique_id()\ndirectives_one = client.send_audio_file(audio_one, dialog_request_id=dialog_request_id)\ndirectives_two = client.send_audio_file(audio_two, dialog_request_id=dialog_request_id)\ndirectives_three = client.send_audio_file(audio_three, dialog_request_id=dialog_request_id)\n\n```\n\nRun the streaming microphone audio demo to use this feature:\n\n```sh\npip install alexa_client[demo]\npython -m alexa_client.demo.streaming_microphone \\\n --client-id=\"{enter-client-id-here}\" \\\n --client-secret=\"{enter-client-secret-here}\" \\\n --refresh-token=\"{enter-refresh-token-here}\"\n```\n\n### ASR Profiles\nAutomatic Speech Recognition (ASR) profiles optimized for user speech from varying distances. By default CLOSE_TALK is used but this can be specified:\n\n```\nfrom alexa_client import constants\n\nclient.send_audio_file(\n audio_file=audio_file,\n distance_profile=constants.NEAR_FIELD, # or constants.FAR_FIELD\n)\n```\n\n### Audio format\n\nBy default PCM audio format is assumed, but OPUS can be specified:\n\n```\nfrom alexa_client import constants\n\nclient.send_audio_file(\n audio_file=audio_file,\n audio_format=constants.OPUS,\n)\n```\n\nWhen PCM format is specified the audio should be 16bit Linear PCM (LPCM16), 16kHz sample rate, single-channel, and little endian.\n\nWhen OPUS forat is specified the audio should be 16bit Opus, 16kHz sample rate, 32k bit rate, and little endian.\n\n### Base URL\n\n`base_url` can be set to improve latency. Choose a region closest to your location.\n\n```\nfrom alexa_client.alexa_client import constants\n\nclient = AlexaClient(\n client_id='my-client-id',\n secret='my-secret',\n refresh_token='my-refresh-token',\n base_url=constants.BASE_URL_ASIA\n)\n```\n\nThe default base URL is Europe. The available constants are BASE_URL_EUROPE, BASE_URL_ASIA and BASE_URL_NORTH_AMERICA but you can pass any string if required.\n\n[Read more](https://developer.amazon.com/docs/alexa-voice-service/api-overview.html#endpoints)\n\n## Authentication\n\nTo use AVS you must first have a [developer account](http://developer.amazon.com). Then register your product [here](https://developer.amazon.com/avs/home.html#/avs/products/new). Choose \"Application\" under \"Is your product an app or a device\"?\n\nThe client requires your `client_id`, `secret` and `refresh_token`:\n\n| client kwarg | Notes |\n| --------------- | ------------------------------------- |\n| `client_id` | Retrieve by clicking on the your product listed [here](https://developer.amazon.com/avs/home.html#/avs/home) |\n| `secret` | Retrieve by clicking on the your product listed [here](https://developer.amazon.com/avs/home.html#/avs/home) |\n| `refresh_token` | You must generate this. [See below](#refresh-token) |\n\n### Refresh token ###\n\nYou will need to login to Amazon via a web browser to get your refresh token.\n\nTo enable this first go [here](https://developer.amazon.com/avs/home.html#/avs/home) and click on your product to set some security settings under `Security Profile`:\n\n| setting | value |\n| ------------------- | --------------------------------|\n| Allowed Origins | http://localhost:9000 |\n| Allowed Return URLs | http://localhost:9000/callback/ |\n\nNote what you entered for Product ID under Product Information, as this will be used as the device-type-id (case sensitive!)\n\nThen run:\n\n```sh\npython -m alexa_client.refreshtoken.serve \\\n --device-type-id=\"{enter-device-type-id-here}\" \\\n --client-id=\"{enter-client-id-here}\" \\\n --client-secret=\"{enter-client-secret-here}\"\n```\n\nFollow the on-screen instructions shown at `http://localhost:9000` in your web browser. \nOn completion Amazon will return your `refresh_token` - which you will require to [send audio](#file-audio) or [recorded voice](#microphone-audio).\n\n## Steaming audio to AVS\n`AlexaClient.send_audio_file` streaming uploads a file-like object to AVS for great latency. The file-like object can be an actual file on your filesystem, an in-memory BytesIo buffer containing audio from your microphone, or even audio streaming from [your browser over a websocket in real-time](https://github.com/richtier/alexa-browser-client).\n\n## Persistent AVS connection\n\nCalling `AlexaClient.connect` creates a persistent connection to AVS. A thread runs that pings AVS after 4 minutes of no request being made to AVS. This prevents the connection getting forcefully closed due to inactivity.\n\n## Unit test ##\n\nTo run the unit tests, call the following commands:\n\n```sh\ngit clone git@github.com:richtier/alexa-voice-service-client.git\nmake test_requirements\npytest\n```\n\n## Other projects ##\n\nThis library is used by [alexa-browser-client](https://github.com/richtier/alexa-browser-client), which allows you to talk to Alexa from your browser.\n\n[code-climate-image]: https://codeclimate.com/github/richtier/alexa-voice-service-client/badges/gpa.svg\n[code-climate]: https://codeclimate.com/github/richtier/alexa-voice-service-client\n\n[circle-ci-image]: https://circleci.com/gh/richtier/alexa-voice-service-client/tree/master.svg?style=svg\n[circle-ci]: https://circleci.com/gh/richtier/alexa-voice-service-client/tree/master\n\n[codecov-image]: https://codecov.io/gh/richtier/alexa-voice-service-client/branch/master/graph/badge.svg\n[codecov]: https://codecov.io/gh/richtier/alexa-voice-service-client\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/richtier/alexa-voice-service-client", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "alexa-client", "package_url": "https://pypi.org/project/alexa-client/", "platform": "", "project_url": "https://pypi.org/project/alexa-client/", "project_urls": { "Homepage": "https://github.com/richtier/alexa-voice-service-client" }, "release_url": "https://pypi.org/project/alexa-client/1.5.1/", "requires_dist": [ "hyper (>=0.7.0<1.0.0)", "requests-toolbelt (>=0.8.0<1.0.0)", "requests (>=2.19.1<3.0.0)", "resettabletimer (<1.0.0,>=0.6.3)", "pydub (<1.0.0,>=0.23.0) ; extra == 'demo'", "pyaudio (<1.0.0,>=0.2.11) ; extra == 'demo'", "flake8 (==3.4.0) ; extra == 'test'", "freezegun (==0.3.9) ; extra == 'test'", "pytest-cov (==2.5.1) ; extra == 'test'", "pytest-sugar (==0.9.0) ; extra == 'test'", "pytest (==3.2.0) ; extra == 'test'", "requests-mock (==1.3.0) ; extra == 'test'", "codecov (==2.0.9) ; extra == 'test'", "twine (<2.0.0,>=1.11.0) ; extra == 'test'", "wheel (<1.0.0,>=0.31.0) ; extra == 'test'", "setuptools (<39.0.0,>=38.6.0) ; extra == 'test'" ], "requires_python": "", "summary": "Python Client for Alexa Voice Service (AVS)", "version": "1.5.1", "yanked": false, "yanked_reason": null }, "last_serial": 6443013, "releases": { "1.3.0": [ { "comment_text": "", "digests": { "md5": "6745dc52fd20e16fbf43fdebddfec62c", "sha256": "45928863a013f0d6265caa7c8d24d14b1a7a9a0771636ee9e689ca03f471bbfd" }, "downloads": -1, "filename": "alexa_client-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "6745dc52fd20e16fbf43fdebddfec62c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14922, "upload_time": "2019-01-17T19:42:56", "upload_time_iso_8601": "2019-01-17T19:42:56.638923Z", "url": "https://files.pythonhosted.org/packages/87/21/e02ac0b7a01adaf3371c742976411de59650fb848aa7c90a1fc95a855083/alexa_client-1.3.0-py3-none-any.whl", "yanked": false, "yanked_reason": null } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "daead45a11637360207a8a228763bbcf", "sha256": "b286b91361dcaa61589686f60c22971a216a0d49588ca6afda452d4302a39a72" }, "downloads": -1, "filename": "alexa_client-1.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "daead45a11637360207a8a228763bbcf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15597, "upload_time": "2019-02-03T21:23:15", "upload_time_iso_8601": "2019-02-03T21:23:15.850440Z", "url": "https://files.pythonhosted.org/packages/21/f8/ddd0f6e02fd88e69bdd55745fc55c56f72622b9497a115fc9efab69a5f4e/alexa_client-1.4.0-py3-none-any.whl", "yanked": false, "yanked_reason": null } ], "1.4.1": [ { "comment_text": "", "digests": { "md5": "6bda4e864ec5f584e44adf7e4241ce68", "sha256": "da74f5f353d208f92735e508d5fe648b0db885f5ad986eab8e4c6c2dcba4f0fe" }, "downloads": -1, "filename": "alexa_client-1.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "6bda4e864ec5f584e44adf7e4241ce68", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15590, "upload_time": "2019-10-28T07:03:11", "upload_time_iso_8601": "2019-10-28T07:03:11.146226Z", "url": "https://files.pythonhosted.org/packages/53/98/472bcf900b9098cf5b7ec350ea6d6db67fbdb08524fcd964229341f5c94b/alexa_client-1.4.1-py3-none-any.whl", "yanked": false, "yanked_reason": null } ], "1.5.0": [ { "comment_text": "", "digests": { "md5": "a79c02a910f0f54033ee463a3f8c8767", "sha256": "4e6c0db0639fe7539f45ea5e0d80c3c90edb55c4fef668f0a07844052591b438" }, "downloads": -1, "filename": "alexa_client-1.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "a79c02a910f0f54033ee463a3f8c8767", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15946, "upload_time": "2019-11-26T08:41:05", "upload_time_iso_8601": "2019-11-26T08:41:05.384179Z", "url": "https://files.pythonhosted.org/packages/a4/d8/2f31aec299a10b0a443ddd1e7904693ddc5388b2b4b9d5ddbefdadda78f1/alexa_client-1.5.0-py3-none-any.whl", "yanked": false, "yanked_reason": null } ], "1.5.1": [ { "comment_text": "", "digests": { "md5": "e6d3c5a25874e71c3c1b55aeacbc7def", "sha256": "3923647b71f85edc981b21289aa4f7438d2d368b113172946a3db0bd898287e6" }, "downloads": -1, "filename": "alexa_client-1.5.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e6d3c5a25874e71c3c1b55aeacbc7def", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15957, "upload_time": "2020-01-13T08:09:04", "upload_time_iso_8601": "2020-01-13T08:09:04.038303Z", "url": "https://files.pythonhosted.org/packages/08/e4/3b135b457e278fc34d9c35e208b0d961cf5d416727305905e5f4ee1e9fa1/alexa_client-1.5.1-py3-none-any.whl", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e6d3c5a25874e71c3c1b55aeacbc7def", "sha256": "3923647b71f85edc981b21289aa4f7438d2d368b113172946a3db0bd898287e6" }, "downloads": -1, "filename": "alexa_client-1.5.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e6d3c5a25874e71c3c1b55aeacbc7def", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15957, "upload_time": "2020-01-13T08:09:04", "upload_time_iso_8601": "2020-01-13T08:09:04.038303Z", "url": "https://files.pythonhosted.org/packages/08/e4/3b135b457e278fc34d9c35e208b0d961cf5d416727305905e5f4ee1e9fa1/alexa_client-1.5.1-py3-none-any.whl", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }