Add websocket type hints in config (#80532)

pull/80596/head
epenet 2022-10-19 04:15:55 +02:00 committed by GitHub
parent 60640b4436
commit 971ac015e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 28 deletions

View File

@ -1,7 +1,10 @@
"""Offer API to configure Home Assistant auth.""" """Offer API to configure Home Assistant auth."""
from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant
WS_TYPE_LIST = "config/auth/list" WS_TYPE_LIST = "config/auth/list"
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend( SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
@ -29,7 +32,11 @@ async def async_setup(hass):
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.async_response @websocket_api.async_response
async def websocket_list(hass, connection, msg): async def websocket_list(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Return a list of users.""" """Return a list of users."""
result = [_user_info(u) for u in await hass.auth.async_get_users()] result = [_user_info(u) for u in await hass.auth.async_get_users()]
@ -38,7 +45,11 @@ async def websocket_list(hass, connection, msg):
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.async_response @websocket_api.async_response
async def websocket_delete(hass, connection, msg): async def websocket_delete(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Delete a user.""" """Delete a user."""
if msg["user_id"] == connection.user.id: if msg["user_id"] == connection.user.id:
connection.send_message( connection.send_message(
@ -69,7 +80,11 @@ async def websocket_delete(hass, connection, msg):
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def websocket_create(hass, connection, msg): async def websocket_create(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Create a user.""" """Create a user."""
user = await hass.auth.async_create_user( user = await hass.auth.async_create_user(
msg["name"], group_ids=msg.get("group_ids"), local_only=msg.get("local_only") msg["name"], group_ids=msg.get("group_ids"), local_only=msg.get("local_only")
@ -92,7 +107,11 @@ async def websocket_create(hass, connection, msg):
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def websocket_update(hass, connection, msg): async def websocket_update(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Update a user.""" """Update a user."""
if not (user := await hass.auth.async_get_user(msg.pop("user_id"))): if not (user := await hass.auth.async_get_user(msg.pop("user_id"))):
connection.send_message( connection.send_message(

View File

@ -1,9 +1,11 @@
"""Offer API to configure the Home Assistant auth provider.""" """Offer API to configure the Home Assistant auth provider."""
from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.auth.providers import homeassistant as auth_ha from homeassistant.auth.providers import homeassistant as auth_ha
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.websocket_api import decorators from homeassistant.core import HomeAssistant
from homeassistant.exceptions import Unauthorized from homeassistant.exceptions import Unauthorized
@ -16,7 +18,7 @@ async def async_setup(hass):
return True return True
@decorators.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required("type"): "config/auth_provider/homeassistant/create", vol.Required("type"): "config/auth_provider/homeassistant/create",
vol.Required("user_id"): str, vol.Required("user_id"): str,
@ -26,7 +28,11 @@ async def async_setup(hass):
) )
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.async_response @websocket_api.async_response
async def websocket_create(hass, connection, msg): async def websocket_create(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Create credentials and attach to a user.""" """Create credentials and attach to a user."""
provider = auth_ha.async_get_provider(hass) provider = auth_ha.async_get_provider(hass)
@ -56,7 +62,7 @@ async def websocket_create(hass, connection, msg):
connection.send_result(msg["id"]) connection.send_result(msg["id"])
@decorators.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required("type"): "config/auth_provider/homeassistant/delete", vol.Required("type"): "config/auth_provider/homeassistant/delete",
vol.Required("username"): str, vol.Required("username"): str,
@ -64,7 +70,11 @@ async def websocket_create(hass, connection, msg):
) )
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.async_response @websocket_api.async_response
async def websocket_delete(hass, connection, msg): async def websocket_delete(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Delete username and related credential.""" """Delete username and related credential."""
provider = auth_ha.async_get_provider(hass) provider = auth_ha.async_get_provider(hass)
credentials = await provider.async_get_or_create_credentials( credentials = await provider.async_get_or_create_credentials(
@ -90,7 +100,7 @@ async def websocket_delete(hass, connection, msg):
connection.send_result(msg["id"]) connection.send_result(msg["id"])
@decorators.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required("type"): "config/auth_provider/homeassistant/change_password", vol.Required("type"): "config/auth_provider/homeassistant/change_password",
vol.Required("current_password"): str, vol.Required("current_password"): str,
@ -98,7 +108,11 @@ async def websocket_delete(hass, connection, msg):
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def websocket_change_password(hass, connection, msg): async def websocket_change_password(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Change current user password.""" """Change current user password."""
if (user := connection.user) is None: if (user := connection.user) is None:
connection.send_error(msg["id"], "user_not_found", "User not found") connection.send_error(msg["id"], "user_not_found", "User not found")
@ -130,7 +144,7 @@ async def websocket_change_password(hass, connection, msg):
connection.send_result(msg["id"]) connection.send_result(msg["id"])
@decorators.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required( vol.Required(
"type" "type"
@ -139,9 +153,13 @@ async def websocket_change_password(hass, connection, msg):
vol.Required("password"): str, vol.Required("password"): str,
} }
) )
@decorators.require_admin @websocket_api.require_admin
@decorators.async_response @websocket_api.async_response
async def websocket_admin_change_password(hass, connection, msg): async def websocket_admin_change_password(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Change password of any user.""" """Change password of any user."""
if not connection.user.is_owner: if not connection.user.is_owner:
raise Unauthorized(context=connection.context(msg)) raise Unauthorized(context=connection.context(msg))

View File

@ -13,7 +13,6 @@ from homeassistant import config_entries, data_entry_flow
from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.websocket_api.connection import ActiveConnection
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import DependencyError, Unauthorized from homeassistant.exceptions import DependencyError, Unauthorized
from homeassistant.helpers.data_entry_flow import ( from homeassistant.helpers.data_entry_flow import (
@ -291,7 +290,11 @@ def get_entry(
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def config_entry_update(hass, connection, msg): async def config_entry_update(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Update config entry.""" """Update config entry."""
changes = dict(msg) changes = dict(msg)
changes.pop("id") changes.pop("id")
@ -311,9 +314,10 @@ async def config_entry_update(hass, connection, msg):
"require_restart": False, "require_restart": False,
} }
initial_state = entry.state
if ( if (
old_disable_polling != entry.pref_disable_polling old_disable_polling != entry.pref_disable_polling
and entry.state is config_entries.ConfigEntryState.LOADED and initial_state is config_entries.ConfigEntryState.LOADED
): ):
if not await hass.config_entries.async_reload(entry.entry_id): if not await hass.config_entries.async_reload(entry.entry_id):
result["require_restart"] = ( result["require_restart"] = (
@ -334,14 +338,18 @@ async def config_entry_update(hass, connection, msg):
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def config_entry_disable(hass, connection, msg): async def config_entry_disable(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Disable config entry.""" """Disable config entry."""
if (disabled_by := msg["disabled_by"]) is not None: if (disabled_by := msg["disabled_by"]) is not None:
disabled_by = config_entries.ConfigEntryDisabler(disabled_by) disabled_by = config_entries.ConfigEntryDisabler(disabled_by)
result = False success = False
try: try:
result = await hass.config_entries.async_set_disabled_by( success = await hass.config_entries.async_set_disabled_by(
msg["entry_id"], disabled_by msg["entry_id"], disabled_by
) )
except config_entries.OperationNotAllowed: except config_entries.OperationNotAllowed:
@ -351,7 +359,7 @@ async def config_entry_disable(hass, connection, msg):
send_entry_not_found(connection, msg["id"]) send_entry_not_found(connection, msg["id"])
return return
result = {"require_restart": not result} result = {"require_restart": not success}
connection.send_result(msg["id"], result) connection.send_result(msg["id"], result)
@ -361,7 +369,11 @@ async def config_entry_disable(hass, connection, msg):
{"type": "config_entries/ignore_flow", "flow_id": str, "title": str} {"type": "config_entries/ignore_flow", "flow_id": str, "title": str}
) )
@websocket_api.async_response @websocket_api.async_response
async def ignore_config_flow(hass, connection, msg): async def ignore_config_flow(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Ignore a config flow.""" """Ignore a config flow."""
flow = next( flow = next(
( (
@ -399,7 +411,9 @@ async def ignore_config_flow(hass, connection, msg):
) )
@websocket_api.async_response @websocket_api.async_response
async def config_entries_get( async def config_entries_get(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any] hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None: ) -> None:
"""Return matching config entries by type and/or domain.""" """Return matching config entries by type and/or domain."""
connection.send_result( connection.send_result(
@ -418,7 +432,9 @@ async def config_entries_get(
) )
@websocket_api.async_response @websocket_api.async_response
async def config_entries_subscribe( async def config_entries_subscribe(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any] hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None: ) -> None:
"""Subscribe to config entry updates.""" """Subscribe to config entry updates."""
type_filter = msg.get("type_filter") type_filter = msg.get("type_filter")

View File

@ -1,10 +1,13 @@
"""Component to interact with Hassbian tools.""" """Component to interact with Hassbian tools."""
from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.config import async_check_ha_config_file from homeassistant.config import async_check_ha_config_file
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import location, unit_system from homeassistant.util import location, unit_system
@ -49,7 +52,11 @@ class CheckConfigView(HomeAssistantView):
} }
) )
@websocket_api.async_response @websocket_api.async_response
async def websocket_update_config(hass, connection, msg): async def websocket_update_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Handle update core config command.""" """Handle update core config command."""
data = dict(msg) data = dict(msg)
data.pop("id") data.pop("id")
@ -65,12 +72,16 @@ async def websocket_update_config(hass, connection, msg):
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.websocket_command({"type": "config/core/detect"}) @websocket_api.websocket_command({"type": "config/core/detect"})
@websocket_api.async_response @websocket_api.async_response
async def websocket_detect_config(hass, connection, msg): async def websocket_detect_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Detect core config.""" """Detect core config."""
session = async_get_clientsession(hass) session = async_get_clientsession(hass)
location_info = await location.async_detect_location_info(session) location_info = await location.async_detect_location_info(session)
info = {} info: dict[str, Any] = {}
if location_info is None: if location_info is None:
connection.send_result(msg["id"], info) connection.send_result(msg["id"], info)