Skip to main content
The homeassistant.loader module provides the integration loading system that discovers, validates, and loads integrations.

Integration Class

The Integration class represents a loaded integration and provides access to its components and metadata.

Attributes

domain
str
Domain name of the integration
name
str
Human-readable name from the manifest
pkg_path
str
Python package path (e.g., “homeassistant.components.light”)
file_path
pathlib.Path
Filesystem path to the integration
manifest
Manifest
The integration’s manifest.json contents
dependencies
list[str]
List of domains this integration depends on
requirements
list[str]
List of Python package requirements
version
AwesomeVersion | None
Version of the integration (for custom integrations)
is_built_in
bool
Whether this is a built-in integration
config_flow
bool
Whether the integration has a config flow
documentation
str | None
URL to the integration’s documentation
integration_type
str
Type of integration (entity, device, hub, service, helper, system, virtual)
iot_class
str | None
IoT class of the integration (cloud_polling, cloud_push, local_polling, local_push, etc.)
quality_scale
str | None
Quality scale rating (internal, silver, gold, platinum)

Methods

async_get_component()

Load and return the integration’s main component.
return
ComponentProtocol
The loaded component module
integration = await async_get_integration(hass, "light")
component = await integration.async_get_component()

# Now you can call component methods
if hasattr(component, "async_setup_entry"):
    await component.async_setup_entry(hass, entry)

async_get_platform(platform_name)

Load and return a specific platform.
platform_name
str
required
Name of the platform to load
return
ModuleType
The loaded platform module
# Load the MQTT platform for the light integration
integration = await async_get_integration(hass, "light")
mqtt_platform = await integration.async_get_platform("mqtt")

async_get_platforms(platform_names)

Load multiple platforms at once.
platform_names
Iterable[str]
required
Names of platforms to load
return
dict[str, ModuleType]
Dictionary mapping platform names to loaded modules
integration = await async_get_integration(hass, "my_integration")
platforms = await integration.async_get_platforms(["sensor", "switch"])

sensor_platform = platforms["sensor"]
switch_platform = platforms["switch"]

get_component()

Synchronously get the component (thread-safe).
This method is thread-safe but should generally be avoided in favor of async_get_component() in async code.
component = integration.get_component()

get_platform(platform_name)

Synchronously get a platform (thread-safe).
platform = integration.get_platform("mqtt")

Loading Functions

async_get_integration(hass, domain)

Get an integration by domain.
hass
HomeAssistant
required
Home Assistant instance
domain
str
required
Domain of the integration to load
return
Integration
The loaded integration
from homeassistant.loader import async_get_integration

integration = await async_get_integration(hass, "light")
print(f"Loaded {integration.name}")
Raises IntegrationNotFound if the integration doesn’t exist.

async_get_integrations(hass, domains)

Get multiple integrations at once.
hass
HomeAssistant
required
Home Assistant instance
domains
Iterable[str]
required
List of domains to load
return
dict[str, Integration | Exception]
Dictionary mapping domains to Integration objects or exceptions
results = await async_get_integrations(hass, ["light", "switch", "sensor"])

for domain, result in results.items():
    if isinstance(result, Integration):
        print(f"Loaded {domain}")
    else:
        print(f"Failed to load {domain}: {result}")

async_get_custom_components(hass)

Get all custom integrations.
return
dict[str, Integration]
Dictionary of custom integrations by domain
custom = await async_get_custom_components(hass)
for domain, integration in custom.items():
    print(f"Custom: {domain} - {integration.name}")

async_get_config_flows(hass, type_filter=None)

Get all integrations that support config flows.
hass
HomeAssistant
required
Home Assistant instance
type_filter
str
Filter by integration type (device, helper, hub, service)
return
set[str]
Set of domain names that support config flows
# Get all integrations with config flows
all_flows = await async_get_config_flows(hass)

# Get only device integrations with config flows
device_flows = await async_get_config_flows(hass, "device")

Manifest Structure

The manifest.json file defines integration metadata:
{
  "domain": "my_integration",
  "name": "My Integration",
  "codeowners": ["@username"],
  "config_flow": true,
  "dependencies": ["http"],
  "documentation": "https://www.home-assistant.io/integrations/my_integration",
  "iot_class": "cloud_polling",
  "requirements": ["my-library==1.0.0"],
  "version": "1.0.0",
  "integration_type": "hub"
}

Manifest Fields

domain
str
required
Unique domain identifier (must match directory name)
name
str
required
Human-readable name
codeowners
list[str]
GitHub usernames of code owners
config_flow
bool
default:"false"
Whether the integration supports config flows
dependencies
list[str]
List of integration domains this depends on
after_dependencies
list[str]
Integrations to load before this one (soft dependencies)
requirements
list[str]
Python package requirements (with versions)
documentation
str
URL to documentation
integration_type
str
One of: entity, device, hardware, helper, hub, service, system, virtual
iot_class
str
IoT class: cloud_polling, cloud_push, local_polling, local_push, assumed, calculated
quality_scale
str
Quality scale: internal, silver, gold, platinum
version
str
Version string (required for custom integrations)
single_config_entry
bool
default:"false"
Whether only one config entry is allowed
import_executor
bool
default:"true"
Whether to import the integration in the executor

Component Protocol

Integrations can implement these methods to support various features:

async_setup(hass, config)

Set up the integration from YAML configuration.
hass
HomeAssistant
required
Home Assistant instance
config
ConfigType
required
Configuration dictionary
return
bool
True if setup succeeded
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the integration."""
    # Setup code here
    return True

async_setup_entry(hass, entry)

Set up from a config entry.
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Set up from a config entry."""
    # Setup code here
    return True

async_unload_entry(hass, entry)

Unload a config entry.
async def async_unload_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Unload a config entry."""
    # Cleanup code here
    return True

async_remove_entry(hass, entry)

Called when a config entry is removed.
async def async_remove_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> None:
    """Handle removal of an entry."""
    # Cleanup code here
    pass

async_migrate_entry(hass, entry)

Migrate a config entry to a new version.
async def async_migrate_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Migrate old entry."""
    # Migration code here
    return True

Discovery Integration Types

Bluetooth

Integrations can be discovered via Bluetooth:
{
  "bluetooth": [
    {
      "local_name": "My Device*",
      "service_uuid": "0000180f-0000-1000-8000-00805f9b34fb"
    }
  ]
}

Zeroconf

Discovery via Zeroconf/mDNS:
{
  "zeroconf": [
    "_my-service._tcp.local.",
    {
      "type": "_another-service._tcp.local.",
      "name": "mydevice*"
    }
  ]
}

SSDP

Discovery via SSDP:
{
  "ssdp": [
    {
      "manufacturer": "My Manufacturer",
      "modelName": "My Model"
    }
  ]
}

USB

Discovery via USB:
{
  "usb": [
    {
      "vid": "10C4",
      "pid": "EA60"
    }
  ]
}

Error Handling

IntegrationNotFound

Raised when an integration cannot be found:
from homeassistant.loader import IntegrationNotFound

try:
    integration = await async_get_integration(hass, "nonexistent")
except IntegrationNotFound:
    _LOGGER.error("Integration not found")

Best Practices

Cache Integration References

Cache integration references to avoid repeated lookups:
class MyCoordinator:
    def __init__(self, hass, entry):
        self._integration = None
    
    async def _get_integration(self):
        if self._integration is None:
            self._integration = await async_get_integration(
                self.hass, "my_integration"
            )
        return self._integration

Use Executor for Blocking Code

Set import_executor: true in manifest for integrations with blocking imports:
{
  "domain": "my_integration",
  "import_executor": true
}

Specify Dependencies

Always declare integration dependencies:
{
  "dependencies": ["http", "mqtt"],
  "after_dependencies": ["recorder"]
}

Build docs developers (and LLMs) love