1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2025-12-20 02:18:59 +00:00

Fix type annotations in API modules (#6389)

* Fix incorrect type annotations in API modules

Correct several type annotation issues found during typeguard testing:

- Fix `options_config` return type from `None` to `dict[str, Any]`
  (method returns validation result dict)
- Fix `uninstall` return type from `Awaitable[None]` to `None` and
  remove unnecessary return statement (async methods already return
  awaitables)
- Fix `stats` return type from `dict[Any, str]` to `dict[str, Any]`
  (type arguments were reversed)
- Fix `stop` return type from `Awaitable[None]` to `None` (async
  method shouldn't declare Awaitable return type)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add missing type annotations to API methods

Add explicit return type annotations and request parameter types to
API endpoint methods that were missing them:

- backups.py: Add types to reload, download, upload methods
- docker.py: Add types to info, create_registry, remove_registry
- host.py: Add types to info, options, reboot, shutdown, reload,
  services, list_boots, list_identifiers, disk_usage; fix overly
  generic dict type
- services.py: Add types to list_services, set_service, get_service,
  del_service; add required imports
- store.py: Add types to add_repository, remove_repository
- supervisor.py: Add type to ping method

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Stefan Agner
2025-12-03 21:52:25 +01:00
committed by GitHub
parent 7895bc9007
commit 3b3db2a9bc
8 changed files with 32 additions and 27 deletions

View File

@@ -390,7 +390,7 @@ class APIAddons(CoreSysAttributes):
return data
@api_process
async def options_config(self, request: web.Request) -> None:
async def options_config(self, request: web.Request) -> dict[str, Any]:
"""Validate user options for add-on."""
slug: str = request.match_info["addon"]
if slug != "self":
@@ -435,11 +435,11 @@ class APIAddons(CoreSysAttributes):
}
@api_process
async def uninstall(self, request: web.Request) -> Awaitable[None]:
async def uninstall(self, request: web.Request) -> None:
"""Uninstall add-on."""
addon = self.get_addon_for_request(request)
body: dict[str, Any] = await api_validate(SCHEMA_UNINSTALL, request)
return await asyncio.shield(
await asyncio.shield(
self.sys_addons.uninstall(
addon.slug, remove_config=body[ATTR_REMOVE_CONFIG]
)

View File

@@ -211,7 +211,7 @@ class APIBackups(CoreSysAttributes):
await self.sys_backups.save_data()
@api_process
async def reload(self, _):
async def reload(self, _: web.Request) -> bool:
"""Reload backup list."""
await asyncio.shield(self.sys_backups.reload())
return True
@@ -421,7 +421,7 @@ class APIBackups(CoreSysAttributes):
await self.sys_backups.remove(backup, locations=locations)
@api_process
async def download(self, request: web.Request):
async def download(self, request: web.Request) -> web.StreamResponse:
"""Download a backup file."""
backup = self._extract_slug(request)
# Query will give us '' for /backups, convert value to None
@@ -451,7 +451,7 @@ class APIBackups(CoreSysAttributes):
return response
@api_process
async def upload(self, request: web.Request):
async def upload(self, request: web.Request) -> dict[str, str] | bool:
"""Upload a backup file."""
location: LOCATION_TYPE = None
locations: list[LOCATION_TYPE] | None = None

View File

@@ -55,7 +55,7 @@ class APIDocker(CoreSysAttributes):
"""Handle RESTful API for Docker configuration."""
@api_process
async def info(self, request: web.Request):
async def info(self, request: web.Request) -> dict[str, Any]:
"""Get docker info."""
data_registries = {}
for hostname, registry in self.sys_docker.config.registries.items():
@@ -113,7 +113,7 @@ class APIDocker(CoreSysAttributes):
return {ATTR_REGISTRIES: data_registries}
@api_process
async def create_registry(self, request: web.Request):
async def create_registry(self, request: web.Request) -> None:
"""Create a new docker registry."""
body = await api_validate(SCHEMA_DOCKER_REGISTRY, request)
@@ -123,7 +123,7 @@ class APIDocker(CoreSysAttributes):
await self.sys_docker.config.save_data()
@api_process
async def remove_registry(self, request: web.Request):
async def remove_registry(self, request: web.Request) -> None:
"""Delete a docker registry."""
hostname = request.match_info.get(ATTR_HOSTNAME)
if hostname not in self.sys_docker.config.registries:

View File

@@ -154,7 +154,7 @@ class APIHomeAssistant(CoreSysAttributes):
await self.sys_homeassistant.save_data()
@api_process
async def stats(self, request: web.Request) -> dict[Any, str]:
async def stats(self, request: web.Request) -> dict[str, Any]:
"""Return resource information."""
stats = await self.sys_homeassistant.core.stats()
if not stats:
@@ -191,7 +191,7 @@ class APIHomeAssistant(CoreSysAttributes):
return await update_task
@api_process
async def stop(self, request: web.Request) -> Awaitable[None]:
async def stop(self, request: web.Request) -> None:
"""Stop Home Assistant."""
body = await api_validate(SCHEMA_STOP, request)
await self._check_offline_migration(force=body[ATTR_FORCE])

View File

@@ -1,6 +1,7 @@
"""Init file for Supervisor host RESTful API."""
import asyncio
from collections.abc import Awaitable
from contextlib import suppress
import json
import logging
@@ -99,7 +100,7 @@ class APIHost(CoreSysAttributes):
)
@api_process
async def info(self, request):
async def info(self, request: web.Request) -> dict[str, Any]:
"""Return host information."""
return {
ATTR_AGENT_VERSION: self.sys_dbus.agent.version,
@@ -128,7 +129,7 @@ class APIHost(CoreSysAttributes):
}
@api_process
async def options(self, request):
async def options(self, request: web.Request) -> None:
"""Edit host settings."""
body = await api_validate(SCHEMA_OPTIONS, request)
@@ -139,7 +140,7 @@ class APIHost(CoreSysAttributes):
)
@api_process
async def reboot(self, request):
async def reboot(self, request: web.Request) -> None:
"""Reboot host."""
body = await api_validate(SCHEMA_SHUTDOWN, request)
await self._check_ha_offline_migration(force=body[ATTR_FORCE])
@@ -147,7 +148,7 @@ class APIHost(CoreSysAttributes):
return await asyncio.shield(self.sys_host.control.reboot())
@api_process
async def shutdown(self, request):
async def shutdown(self, request: web.Request) -> None:
"""Poweroff host."""
body = await api_validate(SCHEMA_SHUTDOWN, request)
await self._check_ha_offline_migration(force=body[ATTR_FORCE])
@@ -155,12 +156,12 @@ class APIHost(CoreSysAttributes):
return await asyncio.shield(self.sys_host.control.shutdown())
@api_process
def reload(self, request):
def reload(self, request: web.Request) -> Awaitable[None]:
"""Reload host data."""
return asyncio.shield(self.sys_host.reload())
@api_process
async def services(self, request):
async def services(self, request: web.Request) -> dict[str, Any]:
"""Return list of available services."""
services = []
for unit in self.sys_host.services:
@@ -175,7 +176,7 @@ class APIHost(CoreSysAttributes):
return {ATTR_SERVICES: services}
@api_process
async def list_boots(self, _: web.Request):
async def list_boots(self, _: web.Request) -> dict[str, Any]:
"""Return a list of boot IDs."""
boot_ids = await self.sys_host.logs.get_boot_ids()
return {
@@ -186,7 +187,7 @@ class APIHost(CoreSysAttributes):
}
@api_process
async def list_identifiers(self, _: web.Request):
async def list_identifiers(self, _: web.Request) -> dict[str, list[str]]:
"""Return a list of syslog identifiers."""
return {ATTR_IDENTIFIERS: await self.sys_host.logs.get_identifiers()}
@@ -332,7 +333,7 @@ class APIHost(CoreSysAttributes):
)
@api_process
async def disk_usage(self, request: web.Request) -> dict:
async def disk_usage(self, request: web.Request) -> dict[str, Any]:
"""Return a breakdown of storage usage for the system."""
max_depth = request.query.get(ATTR_MAX_DEPTH, 1)

View File

@@ -1,5 +1,9 @@
"""Init file for Supervisor network RESTful API."""
from typing import Any
from aiohttp import web
from ..const import (
ATTR_AVAILABLE,
ATTR_PROVIDERS,
@@ -25,7 +29,7 @@ class APIServices(CoreSysAttributes):
return service
@api_process
async def list_services(self, request):
async def list_services(self, request: web.Request) -> dict[str, Any]:
"""Show register services."""
services = []
for service in self.sys_services.list_services:
@@ -40,7 +44,7 @@ class APIServices(CoreSysAttributes):
return {ATTR_SERVICES: services}
@api_process
async def set_service(self, request):
async def set_service(self, request: web.Request) -> None:
"""Write data into a service."""
service = self._extract_service(request)
body = await api_validate(service.schema, request)
@@ -50,7 +54,7 @@ class APIServices(CoreSysAttributes):
await service.set_service_data(addon, body)
@api_process
async def get_service(self, request):
async def get_service(self, request: web.Request) -> dict[str, Any]:
"""Read data into a service."""
service = self._extract_service(request)
@@ -62,7 +66,7 @@ class APIServices(CoreSysAttributes):
return service.get_service_data()
@api_process
async def del_service(self, request):
async def del_service(self, request: web.Request) -> None:
"""Delete data into a service."""
service = self._extract_service(request)
addon = request[REQUEST_FROM]

View File

@@ -349,13 +349,13 @@ class APIStore(CoreSysAttributes):
return self._generate_repository_information(repository)
@api_process
async def add_repository(self, request: web.Request):
async def add_repository(self, request: web.Request) -> None:
"""Add repository to the store."""
body = await api_validate(SCHEMA_ADD_REPOSITORY, request)
await asyncio.shield(self.sys_store.add_repository(body[ATTR_REPOSITORY]))
@api_process
async def remove_repository(self, request: web.Request):
async def remove_repository(self, request: web.Request) -> None:
"""Remove repository from the store."""
repository: Repository = self._extract_repository(request)
await asyncio.shield(self.sys_store.remove_repository(repository))

View File

@@ -80,7 +80,7 @@ class APISupervisor(CoreSysAttributes):
"""Handle RESTful API for Supervisor functions."""
@api_process
async def ping(self, request):
async def ping(self, request: web.Request) -> bool:
"""Return ok for signal that the API is ready."""
return True