Support adding different server locations for Microsoft face component (#7532)
* Support adding different server locations * Rename variables and move CONF_ const into component as requested in review * Fix unittests * Forgot to add tests for microsoft_face_identifypull/7455/merge
parent
8da10f670b
commit
452c3a1b25
|
@ -28,10 +28,12 @@ _LOGGER = logging.getLogger(__name__)
|
|||
DOMAIN = 'microsoft_face'
|
||||
DEPENDENCIES = ['camera']
|
||||
|
||||
FACE_API_URL = "https://westus.api.cognitive.microsoft.com/face/v1.0/{0}"
|
||||
FACE_API_URL = "api.cognitive.microsoft.com/face/v1.0/{0}"
|
||||
|
||||
DATA_MICROSOFT_FACE = 'microsoft_face'
|
||||
|
||||
CONF_AZURE_REGION = 'azure_region'
|
||||
|
||||
SERVICE_CREATE_GROUP = 'create_group'
|
||||
SERVICE_DELETE_GROUP = 'delete_group'
|
||||
SERVICE_TRAIN_GROUP = 'train_group'
|
||||
|
@ -49,6 +51,7 @@ DEFAULT_TIMEOUT = 10
|
|||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Required(CONF_API_KEY): cv.string,
|
||||
vol.Optional(CONF_AZURE_REGION, default="westus"): cv.string,
|
||||
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
@ -115,6 +118,7 @@ def async_setup(hass, config):
|
|||
entities = {}
|
||||
face = MicrosoftFace(
|
||||
hass,
|
||||
config[DOMAIN].get(CONF_AZURE_REGION),
|
||||
config[DOMAIN].get(CONF_API_KEY),
|
||||
config[DOMAIN].get(CONF_TIMEOUT),
|
||||
entities
|
||||
|
@ -304,12 +308,13 @@ class MicrosoftFaceGroupEntity(Entity):
|
|||
class MicrosoftFace(object):
|
||||
"""Microsoft Face api for HomeAssistant."""
|
||||
|
||||
def __init__(self, hass, api_key, timeout, entities):
|
||||
def __init__(self, hass, server_loc, api_key, timeout, entities):
|
||||
"""Initialize Microsoft Face api."""
|
||||
self.hass = hass
|
||||
self.websession = async_get_clientsession(hass)
|
||||
self.timeout = timeout
|
||||
self._api_key = api_key
|
||||
self._server_url = "https://{0}.{1}".format(server_loc, FACE_API_URL)
|
||||
self._store = {}
|
||||
self._entities = entities
|
||||
|
||||
|
@ -346,7 +351,7 @@ class MicrosoftFace(object):
|
|||
params=None):
|
||||
"""Make a api call."""
|
||||
headers = {"Ocp-Apim-Subscription-Key": self._api_key}
|
||||
url = FACE_API_URL.format(function)
|
||||
url = self._server_url.format(function)
|
||||
|
||||
payload = None
|
||||
if binary:
|
||||
|
|
|
@ -98,6 +98,8 @@ class TestMicrosoftFaceDetect(object):
|
|||
}
|
||||
}
|
||||
|
||||
self.endpoint_url = "https://westus.{0}".format(mf.FACE_API_URL)
|
||||
|
||||
def teardown_method(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
@ -108,15 +110,15 @@ class TestMicrosoftFaceDetect(object):
|
|||
def test_ms_detect_process_image(self, poll_mock, aioclient_mock):
|
||||
"""Setup and scan a picture and test plates from event."""
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups"),
|
||||
self.endpoint_url.format("persongroups"),
|
||||
text=load_fixture('microsoft_face_persongroups.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group2/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
|
||||
|
@ -139,7 +141,7 @@ class TestMicrosoftFaceDetect(object):
|
|||
aioclient_mock.get(url, content=b'image')
|
||||
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format("detect"),
|
||||
self.endpoint_url.format("detect"),
|
||||
text=load_fixture('microsoft_face_detect.json'),
|
||||
params={'returnFaceAttributes': "age,gender"}
|
||||
)
|
||||
|
|
|
@ -99,6 +99,8 @@ class TestMicrosoftFaceIdentify(object):
|
|||
}
|
||||
}
|
||||
|
||||
self.endpoint_url = "https://westus.{0}".format(mf.FACE_API_URL)
|
||||
|
||||
def teardown_method(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
@ -109,15 +111,15 @@ class TestMicrosoftFaceIdentify(object):
|
|||
def test_ms_identify_process_image(self, poll_mock, aioclient_mock):
|
||||
"""Setup and scan a picture and test plates from event."""
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups"),
|
||||
self.endpoint_url.format("persongroups"),
|
||||
text=load_fixture('microsoft_face_persongroups.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group2/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
|
||||
|
@ -140,11 +142,11 @@ class TestMicrosoftFaceIdentify(object):
|
|||
aioclient_mock.get(url, content=b'image')
|
||||
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format("detect"),
|
||||
self.endpoint_url.format("detect"),
|
||||
text=load_fixture('microsoft_face_detect.json')
|
||||
)
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format("identify"),
|
||||
self.endpoint_url.format("identify"),
|
||||
text=load_fixture('microsoft_face_identify.json')
|
||||
)
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ class TestMicrosoftFaceSetup(object):
|
|||
}
|
||||
}
|
||||
|
||||
self.endpoint_url = "https://westus.{0}".format(mf.FACE_API_URL)
|
||||
|
||||
def teardown_method(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
@ -30,7 +32,7 @@ class TestMicrosoftFaceSetup(object):
|
|||
'MicrosoftFace.update_store', return_value=mock_coro())
|
||||
def test_setup_component(self, mock_update):
|
||||
"""Setup component."""
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
@patch('homeassistant.components.microsoft_face.'
|
||||
|
@ -44,7 +46,7 @@ class TestMicrosoftFaceSetup(object):
|
|||
'MicrosoftFace.update_store', return_value=mock_coro())
|
||||
def test_setup_component_test_service(self, mock_update):
|
||||
"""Setup component."""
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
assert self.hass.services.has_service(mf.DOMAIN, 'create_group')
|
||||
|
@ -57,19 +59,19 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_setup_component_test_entities(self, aioclient_mock):
|
||||
"""Setup component."""
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups"),
|
||||
self.endpoint_url.format("persongroups"),
|
||||
text=load_fixture('microsoft_face_persongroups.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group2/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
assert len(aioclient_mock.mock_calls) == 3
|
||||
|
@ -95,15 +97,15 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_service_groups(self, mock_update, aioclient_mock):
|
||||
"""Setup component, test groups services."""
|
||||
aioclient_mock.put(
|
||||
mf.FACE_API_URL.format("persongroups/service_group"),
|
||||
self.endpoint_url.format("persongroups/service_group"),
|
||||
status=200, text="{}"
|
||||
)
|
||||
aioclient_mock.delete(
|
||||
mf.FACE_API_URL.format("persongroups/service_group"),
|
||||
self.endpoint_url.format("persongroups/service_group"),
|
||||
status=200, text="{}"
|
||||
)
|
||||
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
mf.create_group(self.hass, 'Service Group')
|
||||
|
@ -123,29 +125,29 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_service_person(self, aioclient_mock):
|
||||
"""Setup component, test person services."""
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups"),
|
||||
self.endpoint_url.format("persongroups"),
|
||||
text=load_fixture('microsoft_face_persongroups.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group2/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
assert len(aioclient_mock.mock_calls) == 3
|
||||
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_create_person.json')
|
||||
)
|
||||
aioclient_mock.delete(
|
||||
mf.FACE_API_URL.format(
|
||||
self.endpoint_url.format(
|
||||
"persongroups/test_group1/persons/"
|
||||
"25985303-c537-4467-b41d-bdb45cd95ca1"),
|
||||
status=200, text="{}"
|
||||
|
@ -174,11 +176,11 @@ class TestMicrosoftFaceSetup(object):
|
|||
'MicrosoftFace.update_store', return_value=mock_coro())
|
||||
def test_service_train(self, mock_update, aioclient_mock):
|
||||
"""Setup component, test train groups services."""
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format("persongroups/service_group/train"),
|
||||
self.endpoint_url.format("persongroups/service_group/train"),
|
||||
status=200, text="{}"
|
||||
)
|
||||
|
||||
|
@ -192,26 +194,26 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_service_face(self, camera_mock, aioclient_mock):
|
||||
"""Setup component, test person face services."""
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups"),
|
||||
self.endpoint_url.format("persongroups"),
|
||||
text=load_fixture('microsoft_face_persongroups.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group1/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
aioclient_mock.get(
|
||||
mf.FACE_API_URL.format("persongroups/test_group2/persons"),
|
||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
||||
text=load_fixture('microsoft_face_persons.json')
|
||||
)
|
||||
|
||||
self.config['camera'] = {'platform': 'demo'}
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
assert len(aioclient_mock.mock_calls) == 3
|
||||
|
||||
aioclient_mock.post(
|
||||
mf.FACE_API_URL.format(
|
||||
self.endpoint_url.format(
|
||||
"persongroups/test_group2/persons/"
|
||||
"2ae4935b-9659-44c3-977f-61fac20d0538/persistedFaces"),
|
||||
status=200, text="{}"
|
||||
|
@ -229,11 +231,11 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_service_status_400(self, mock_update, aioclient_mock):
|
||||
"""Setup component, test groups services with error."""
|
||||
aioclient_mock.put(
|
||||
mf.FACE_API_URL.format("persongroups/service_group"),
|
||||
self.endpoint_url.format("persongroups/service_group"),
|
||||
status=400, text="{'error': {'message': 'Error'}}"
|
||||
)
|
||||
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
mf.create_group(self.hass, 'Service Group')
|
||||
|
@ -248,11 +250,11 @@ class TestMicrosoftFaceSetup(object):
|
|||
def test_service_status_timeout(self, mock_update, aioclient_mock):
|
||||
"""Setup component, test groups services with timeout."""
|
||||
aioclient_mock.put(
|
||||
mf.FACE_API_URL.format("persongroups/service_group"),
|
||||
self.endpoint_url.format("persongroups/service_group"),
|
||||
status=400, exc=asyncio.TimeoutError()
|
||||
)
|
||||
|
||||
with assert_setup_component(2, mf.DOMAIN):
|
||||
with assert_setup_component(3, mf.DOMAIN):
|
||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
||||
|
||||
mf.create_group(self.hass, 'Service Group')
|
||||
|
|
Loading…
Reference in New Issue