Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #42 from richtier/set-host
Browse files Browse the repository at this point in the history
Allow setting base_url when instantiating the client
  • Loading branch information
Richard Tier authored Nov 26, 2019
2 parents 39f6b9e + 8a9688f commit 2e441af
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 13 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.5.0
[Full Changelog](https://github.com/richtier/alexa-voice-service-client/pull/35)
### Implemented enhancements
- Allow setting base_url when instantiating the client

## 1.4.1
[Full Changelog](https://github.com/richtier/alexa-voice-service-client/pull/34)
### Implemented enhancements
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Run the streaming microphone audio demo to use this feature:
pip install alexa_client[demo]
python -m alexa_client.demo.streaming_microphone \
--client-id="{enter-client-id-here}" \
--client-secret="{enter-client-secret-here"} \
--client-secret="{enter-client-secret-here}" \
--refresh-token="{enter-refresh-token-here}"
```

Expand Down Expand Up @@ -145,6 +145,25 @@ When PCM format is specified the audio should be 16bit Linear PCM (LPCM16), 16kH

When OPUS forat is specified the audio should be 16bit Opus, 16kHz sample rate, 32k bit rate, and little endian.

### Base URL

`base_url` can be set to improve latency. Choose a region closest to your location.

```
from alexa_client.alexa_client import constants
client = AlexaClient(
client_id='my-client-id',
secret='my-secret',
refresh_token='my-refresh-token',
base_url=constants.BASE_URL_ASIA
)
```

The 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.

[Read more](https://developer.amazon.com/docs/alexa-voice-service/api-overview.html#endpoints)

## Authentication

To 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"?
Expand Down
6 changes: 4 additions & 2 deletions alexa_client/alexa_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ class AlexaClient:
authentication_manager = None
connection_manager = None
device_manager = None
base_url = None

def __init__(self, client_id, secret, refresh_token):
def __init__(self, client_id, secret, refresh_token, base_url=None):
self.authentication_manager = self.authentication_manager_class(
client_id=client_id, secret=secret, refresh_token=refresh_token,
)
self.device_manager = self.device_manager_class()
self.connection_manager = self.connection_manager_class()
self.ping_manager = self.ping_manager_class(60*4, self.ping)
self.base_url = base_url

def connect(self):
self.authentication_manager.prefetch_api_token()
self.connection_manager.create_connection()
self.connection_manager.create_connection(base_url=self.base_url)
self.establish_downchannel_stream()
self.synchronise_device_state()
self.ping_manager.start()
Expand Down
10 changes: 6 additions & 4 deletions alexa_client/alexa_client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
from requests.exceptions import HTTPError
from hyper import HTTP20Connection

from alexa_client.alexa_client import helpers
from alexa_client.alexa_client import constants, helpers


class ConnectionManager:
host = 'avs-alexa-eu.amazon.com'
connection = None
# TODO: in next breaking change release rename to `base_url` and move to
# client.connect default kwargs
host = constants.BASE_URL_EUROPE

def create_connection(self):
def create_connection(self, base_url=None):
self.connection = HTTP20Connection(
host=self.host, secure=True, force_proto='h2',
host=base_url or self.host, secure=True, force_proto='h2'
)

def establish_downchannel_stream(self, authentication_headers):
Expand Down
4 changes: 4 additions & 0 deletions alexa_client/alexa_client/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@
# format of captured audio
PCM = 'AUDIO_L16_RATE_16000_CHANNELS_1'
OPUS = 'OPUS'

BASE_URL_ASIA = 'alexa.fe.gateway.devices.a2z.com'
BASE_URL_EUROPE = 'alexa.eu.gateway.devices.a2z.com'
BASE_URL_NORTH_AMERICA = 'alexa.na.gateway.devices.a2z.com'
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

setup(
name='alexa_client',
version='1.4.1',
version='1.5.0',
packages=find_packages(exclude=["tests.*", "tests"]),
url='https://github.com/richtier/alexa-voice-service-client',
license='MIT',
Expand Down
27 changes: 27 additions & 0 deletions tests/alexa_client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,40 @@ def test_client_authentication_manager(client):
)


def test_base_url(client):

class TestAlexaClient(AlexaClient):
authentication_manager_class = mock.Mock()
device_manager_class = mock.Mock()
connection_manager_class = mock.Mock()
ping_manager_class = mock.Mock()

client = TestAlexaClient(
client_id='test_client_id',
secret='test_secret',
refresh_token='test_refresh_token',
base_url=constants.BASE_URL_NORTH_AMERICA
)
client.ping_manager.update_ping_deadline = mock.MagicMock()

client.connect()

assert client.connection_manager.create_connection.call_count == 1
assert client.connection_manager.create_connection.call_args == mock.call(
base_url=constants.BASE_URL_NORTH_AMERICA
)


def test_client_connect(client):
client.connect()

assert client.authentication_manager.prefetch_api_token.call_count == 1
assert (
client.connection_manager.establish_downchannel_stream.call_count == 1
)
assert client.connection_manager.create_connection.call_args == mock.call(
base_url=None
)
assert client.connection_manager.synchronise_device_state.call_count == 1


Expand Down
16 changes: 11 additions & 5 deletions tests/alexa_client/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,16 @@ def audio_file():
def test_create_connection(manager):
manager.create_connection()

assert manager.connection.host == 'avs-alexa-eu.amazon.com'
assert manager.connection.host == constants.BASE_URL_EUROPE
assert manager.connection.secure is True


def test_create_connection_explicit_base_url(manager):
manager.create_connection(base_url=constants.BASE_URL_NORTH_AMERICA)

assert manager.connection.host == constants.BASE_URL_NORTH_AMERICA


def test_establish_downstream_conncetion(manager, authentication_headers):
manager.create_connection()

Expand All @@ -76,7 +82,7 @@ def test_establish_downstream_conncetion(manager, authentication_headers):
b':scheme': b'https',
b':method': b'GET',
b':path': b'/v20160207/directives',
b':authority': b'avs-alexa-eu.amazon.com',
b':authority': b'alexa.eu.gateway.devices.a2z.com',
b'auth': b'value',
}

Expand All @@ -97,7 +103,7 @@ def test_synchronise_device_state(
assert headers == {
b':method': b'POST',
b':scheme': b'https',
b':authority': b'avs-alexa-eu.amazon.com',
b':authority': b'alexa.eu.gateway.devices.a2z.com',
b':path': b'/v20160207/events',
b'content-type': b'multipart/form-data; boundary=boundary',
b'auth': b'value',
Expand Down Expand Up @@ -148,7 +154,7 @@ def test_send_audio_file(
assert headers == {
b':method': b'POST',
b':scheme': b'https',
b':authority': b'avs-alexa-eu.amazon.com',
b':authority': b'alexa.eu.gateway.devices.a2z.com',
b':path': b'/v20160207/events',
b'content-type': b'multipart/form-data; boundary=boundary',
b'auth': b'value',
Expand Down Expand Up @@ -319,6 +325,6 @@ def test_ping(manager, authentication_headers):
b':scheme': b'https',
b':method': b'GET',
b':path': b'/ping',
b':authority': b'avs-alexa-eu.amazon.com',
b':authority': b'alexa.eu.gateway.devices.a2z.com',
b'auth': b'value',
}

0 comments on commit 2e441af

Please sign in to comment.