Add initial rest query params (#42198)
* add initial rest query params * of course I didn't run black * fix tests * fix tests * add test * reformat * add binary sensor test * fix tests * add one more test and fix switch * should not have touched that * if you don't pay attention once
This commit is contained in:
parent
6a7b71e8fb
commit
434d39a5ea
11 changed files with 106 additions and 6 deletions
|
@ -53,7 +53,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
verify_ssl = DEFAULT_VERIFY_SSL
|
||||
headers = {"X-Pvoutput-Apikey": api_key, "X-Pvoutput-SystemId": system_id}
|
||||
|
||||
rest = RestData(method, _ENDPOINT, auth, headers, payload, verify_ssl)
|
||||
rest = RestData(method, _ENDPOINT, auth, headers, None, payload, verify_ssl)
|
||||
await rest.async_update()
|
||||
|
||||
if rest.data is None:
|
||||
|
|
|
@ -14,6 +14,7 @@ from homeassistant.const import (
|
|||
CONF_HEADERS,
|
||||
CONF_METHOD,
|
||||
CONF_NAME,
|
||||
CONF_PARAMS,
|
||||
CONF_PASSWORD,
|
||||
CONF_PAYLOAD,
|
||||
CONF_RESOURCE,
|
||||
|
@ -45,6 +46,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
[HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]
|
||||
),
|
||||
vol.Optional(CONF_HEADERS): {cv.string: cv.string},
|
||||
vol.Optional(CONF_PARAMS): {cv.string: cv.string},
|
||||
vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(["POST", "GET"]),
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_PASSWORD): cv.string,
|
||||
|
@ -78,6 +80,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
headers = config.get(CONF_HEADERS)
|
||||
params = config.get(CONF_PARAMS)
|
||||
device_class = config.get(CONF_DEVICE_CLASS)
|
||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||
force_update = config.get(CONF_FORCE_UPDATE)
|
||||
|
@ -97,7 +100,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
else:
|
||||
auth = None
|
||||
|
||||
rest = RestData(method, resource, auth, headers, payload, verify_ssl, timeout)
|
||||
rest = RestData(
|
||||
method, resource, auth, headers, params, payload, verify_ssl, timeout
|
||||
)
|
||||
await rest.async_update()
|
||||
if rest.data is None:
|
||||
raise PlatformNotReady
|
||||
|
|
|
@ -17,6 +17,7 @@ class RestData:
|
|||
resource,
|
||||
auth,
|
||||
headers,
|
||||
params,
|
||||
data,
|
||||
verify_ssl,
|
||||
timeout=DEFAULT_TIMEOUT,
|
||||
|
@ -26,6 +27,7 @@ class RestData:
|
|||
self._resource = resource
|
||||
self._auth = auth
|
||||
self._headers = headers
|
||||
self._params = params
|
||||
self._request_data = data
|
||||
self._timeout = timeout
|
||||
self._verify_ssl = verify_ssl
|
||||
|
@ -53,6 +55,7 @@ class RestData:
|
|||
self._method,
|
||||
self._resource,
|
||||
headers=self._headers,
|
||||
params=self._params,
|
||||
auth=self._auth,
|
||||
data=self._request_data,
|
||||
timeout=self._timeout,
|
||||
|
|
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
|||
CONF_HEADERS,
|
||||
CONF_METHOD,
|
||||
CONF_NAME,
|
||||
CONF_PARAMS,
|
||||
CONF_PASSWORD,
|
||||
CONF_RESOURCE,
|
||||
CONF_USERNAME,
|
||||
|
@ -51,6 +52,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
["POST", "GET", "POST_JSON"]
|
||||
),
|
||||
vol.Optional(CONF_HEADERS): vol.Schema({cv.string: cv.string}),
|
||||
vol.Optional(CONF_PARAMS): vol.Schema({cv.string: cv.string}),
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Optional(CONF_TARGET_PARAMETER_NAME): cv.string,
|
||||
vol.Optional(CONF_TITLE_PARAMETER_NAME): cv.string,
|
||||
|
@ -75,6 +77,7 @@ def get_service(hass, config, discovery_info=None):
|
|||
resource = config.get(CONF_RESOURCE)
|
||||
method = config.get(CONF_METHOD)
|
||||
headers = config.get(CONF_HEADERS)
|
||||
params = config.get(CONF_PARAMS)
|
||||
message_param_name = config.get(CONF_MESSAGE_PARAMETER_NAME)
|
||||
title_param_name = config.get(CONF_TITLE_PARAMETER_NAME)
|
||||
target_param_name = config.get(CONF_TARGET_PARAMETER_NAME)
|
||||
|
@ -97,6 +100,7 @@ def get_service(hass, config, discovery_info=None):
|
|||
resource,
|
||||
method,
|
||||
headers,
|
||||
params,
|
||||
message_param_name,
|
||||
title_param_name,
|
||||
target_param_name,
|
||||
|
@ -116,6 +120,7 @@ class RestNotificationService(BaseNotificationService):
|
|||
resource,
|
||||
method,
|
||||
headers,
|
||||
params,
|
||||
message_param_name,
|
||||
title_param_name,
|
||||
target_param_name,
|
||||
|
@ -129,6 +134,7 @@ class RestNotificationService(BaseNotificationService):
|
|||
self._hass = hass
|
||||
self._method = method.upper()
|
||||
self._headers = headers
|
||||
self._params = params
|
||||
self._message_param_name = message_param_name
|
||||
self._title_param_name = title_param_name
|
||||
self._target_param_name = target_param_name
|
||||
|
@ -171,6 +177,7 @@ class RestNotificationService(BaseNotificationService):
|
|||
response = requests.post(
|
||||
self._resource,
|
||||
headers=self._headers,
|
||||
params=self._params,
|
||||
data=data,
|
||||
timeout=10,
|
||||
auth=self._auth,
|
||||
|
@ -180,6 +187,7 @@ class RestNotificationService(BaseNotificationService):
|
|||
response = requests.post(
|
||||
self._resource,
|
||||
headers=self._headers,
|
||||
params=self._params,
|
||||
json=data,
|
||||
timeout=10,
|
||||
auth=self._auth,
|
||||
|
@ -189,7 +197,7 @@ class RestNotificationService(BaseNotificationService):
|
|||
response = requests.get(
|
||||
self._resource,
|
||||
headers=self._headers,
|
||||
params=data,
|
||||
params=self._params.update(data),
|
||||
timeout=10,
|
||||
auth=self._auth,
|
||||
verify=self._verify_ssl,
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.const import (
|
|||
CONF_HEADERS,
|
||||
CONF_METHOD,
|
||||
CONF_NAME,
|
||||
CONF_PARAMS,
|
||||
CONF_PASSWORD,
|
||||
CONF_PAYLOAD,
|
||||
CONF_RESOURCE,
|
||||
|
@ -56,6 +57,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
[HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]
|
||||
),
|
||||
vol.Optional(CONF_HEADERS): vol.Schema({cv.string: cv.string}),
|
||||
vol.Optional(CONF_PARAMS): vol.Schema({cv.string: cv.string}),
|
||||
vol.Optional(CONF_JSON_ATTRS, default=[]): cv.ensure_list_csv,
|
||||
vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(METHODS),
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
|
@ -90,6 +92,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
headers = config.get(CONF_HEADERS)
|
||||
params = config.get(CONF_PARAMS)
|
||||
unit = config.get(CONF_UNIT_OF_MEASUREMENT)
|
||||
device_class = config.get(CONF_DEVICE_CLASS)
|
||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||
|
@ -112,7 +115,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
auth = (username, password)
|
||||
else:
|
||||
auth = None
|
||||
rest = RestData(method, resource, auth, headers, payload, verify_ssl, timeout)
|
||||
rest = RestData(
|
||||
method, resource, auth, headers, params, payload, verify_ssl, timeout
|
||||
)
|
||||
await rest.async_update()
|
||||
|
||||
if rest.data is None:
|
||||
|
|
|
@ -11,6 +11,7 @@ from homeassistant.const import (
|
|||
CONF_HEADERS,
|
||||
CONF_METHOD,
|
||||
CONF_NAME,
|
||||
CONF_PARAMS,
|
||||
CONF_PASSWORD,
|
||||
CONF_RESOURCE,
|
||||
CONF_TIMEOUT,
|
||||
|
@ -46,6 +47,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
vol.Required(CONF_RESOURCE): cv.url,
|
||||
vol.Optional(CONF_STATE_RESOURCE): cv.url,
|
||||
vol.Optional(CONF_HEADERS): {cv.string: cv.string},
|
||||
vol.Optional(CONF_PARAMS): {cv.string: cv.string},
|
||||
vol.Optional(CONF_BODY_OFF, default=DEFAULT_BODY_OFF): cv.template,
|
||||
vol.Optional(CONF_BODY_ON, default=DEFAULT_BODY_ON): cv.template,
|
||||
vol.Optional(CONF_IS_ON_TEMPLATE): cv.template,
|
||||
|
@ -71,6 +73,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
is_on_template = config.get(CONF_IS_ON_TEMPLATE)
|
||||
method = config.get(CONF_METHOD)
|
||||
headers = config.get(CONF_HEADERS)
|
||||
params = config.get(CONF_PARAMS)
|
||||
name = config.get(CONF_NAME)
|
||||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
|
@ -97,6 +100,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
state_resource,
|
||||
method,
|
||||
headers,
|
||||
params,
|
||||
auth,
|
||||
body_on,
|
||||
body_off,
|
||||
|
@ -129,6 +133,7 @@ class RestSwitch(SwitchEntity):
|
|||
state_resource,
|
||||
method,
|
||||
headers,
|
||||
params,
|
||||
auth,
|
||||
body_on,
|
||||
body_off,
|
||||
|
@ -143,6 +148,7 @@ class RestSwitch(SwitchEntity):
|
|||
self._state_resource = state_resource
|
||||
self._method = method
|
||||
self._headers = headers
|
||||
self._params = params
|
||||
self._auth = auth
|
||||
self._body_on = body_on
|
||||
self._body_off = body_off
|
||||
|
@ -201,6 +207,7 @@ class RestSwitch(SwitchEntity):
|
|||
auth=self._auth,
|
||||
data=bytes(body, "utf-8"),
|
||||
headers=self._headers,
|
||||
params=self._params,
|
||||
)
|
||||
return req
|
||||
|
||||
|
@ -219,7 +226,10 @@ class RestSwitch(SwitchEntity):
|
|||
|
||||
with async_timeout.timeout(self._timeout):
|
||||
req = await websession.get(
|
||||
self._state_resource, auth=self._auth, headers=self._headers
|
||||
self._state_resource,
|
||||
auth=self._auth,
|
||||
headers=self._headers,
|
||||
params=self._params,
|
||||
)
|
||||
text = await req.text()
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
auth = HTTPBasicAuth(username, password)
|
||||
else:
|
||||
auth = None
|
||||
rest = RestData(method, resource, auth, headers, payload, verify_ssl)
|
||||
rest = RestData(method, resource, auth, headers, None, payload, verify_ssl)
|
||||
await rest.async_update()
|
||||
|
||||
if rest.data is None:
|
||||
|
|
|
@ -128,6 +128,7 @@ CONF_NAME = "name"
|
|||
CONF_OFFSET = "offset"
|
||||
CONF_OPTIMISTIC = "optimistic"
|
||||
CONF_PACKAGES = "packages"
|
||||
CONF_PARAMS = "params"
|
||||
CONF_PASSWORD = "password"
|
||||
CONF_PATH = "path"
|
||||
CONF_PAYLOAD = "payload"
|
||||
|
|
|
@ -377,5 +377,28 @@ async def test_reload(hass):
|
|||
assert hass.states.get("binary_sensor.rollout")
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_setup_query_params(hass):
|
||||
"""Test setup with query params."""
|
||||
respx.get(
|
||||
"http://localhost?search=something",
|
||||
status_code=200,
|
||||
)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
binary_sensor.DOMAIN,
|
||||
{
|
||||
"binary_sensor": {
|
||||
"platform": "rest",
|
||||
"resource": "http://localhost",
|
||||
"method": "GET",
|
||||
"params": {"search": "something"},
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 1
|
||||
|
||||
|
||||
def _get_fixtures_base_path():
|
||||
return path.dirname(path.dirname(path.dirname(__file__)))
|
||||
|
|
|
@ -249,6 +249,29 @@ async def test_setup_get_xml(hass):
|
|||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == DATA_MEGABYTES
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_setup_query_params(hass):
|
||||
"""Test setup with query params."""
|
||||
respx.get(
|
||||
"http://localhost?search=something",
|
||||
status_code=200,
|
||||
)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
"sensor": {
|
||||
"platform": "rest",
|
||||
"resource": "http://localhost",
|
||||
"method": "GET",
|
||||
"params": {"search": "something"},
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 1
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_update_with_json_attrs(hass):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
|
|
|
@ -8,6 +8,7 @@ from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
|||
from homeassistant.const import (
|
||||
CONF_HEADERS,
|
||||
CONF_NAME,
|
||||
CONF_PARAMS,
|
||||
CONF_PLATFORM,
|
||||
CONF_RESOURCE,
|
||||
CONTENT_TYPE_JSON,
|
||||
|
@ -28,6 +29,7 @@ RESOURCE = "http://localhost/"
|
|||
STATE_RESOURCE = RESOURCE
|
||||
HEADERS = {"Content-type": CONTENT_TYPE_JSON}
|
||||
AUTH = None
|
||||
PARAMS = None
|
||||
|
||||
|
||||
async def test_setup_missing_config(hass):
|
||||
|
@ -81,6 +83,25 @@ async def test_setup_minimum(hass, aioclient_mock):
|
|||
assert aioclient_mock.call_count == 1
|
||||
|
||||
|
||||
async def test_setup_query_params(hass, aioclient_mock):
|
||||
"""Test setup with query params."""
|
||||
aioclient_mock.get("http://localhost/?search=something", status=HTTP_OK)
|
||||
with assert_setup_component(1, SWITCH_DOMAIN):
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
SWITCH_DOMAIN,
|
||||
{
|
||||
SWITCH_DOMAIN: {
|
||||
CONF_PLATFORM: rest.DOMAIN,
|
||||
CONF_RESOURCE: "http://localhost",
|
||||
CONF_PARAMS: {"search": "something"},
|
||||
}
|
||||
},
|
||||
)
|
||||
print(aioclient_mock)
|
||||
assert aioclient_mock.call_count == 1
|
||||
|
||||
|
||||
async def test_setup(hass, aioclient_mock):
|
||||
"""Test setup with valid configuration."""
|
||||
aioclient_mock.get("http://localhost", status=HTTP_OK)
|
||||
|
@ -137,6 +158,7 @@ def _setup_test_switch(hass):
|
|||
STATE_RESOURCE,
|
||||
METHOD,
|
||||
HEADERS,
|
||||
PARAMS,
|
||||
AUTH,
|
||||
body_on,
|
||||
body_off,
|
||||
|
|
Loading…
Add table
Reference in a new issue