Add generic URL handler to blueprint importer (#110576)

* Add generic url handler to blueprint importer

* Update tests/components/blueprint/test_importer.py

* Update tests/components/blueprint/test_importer.py

* Update test_importer.py

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Lukas Kolletzki 2024-07-31 08:26:57 +02:00 committed by GitHub
parent 6d8bc84db3
commit 5766ea9541
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 11 deletions

View File

@ -245,14 +245,36 @@ async def fetch_blueprint_from_website_url(
return ImportedBlueprint(suggested_filename, raw_yaml, blueprint)
async def fetch_blueprint_from_generic_url(
hass: HomeAssistant, url: str
) -> ImportedBlueprint:
"""Get a blueprint from a generic website."""
session = aiohttp_client.async_get_clientsession(hass)
resp = await session.get(url, raise_for_status=True)
raw_yaml = await resp.text()
data = yaml.parse_yaml(raw_yaml)
assert isinstance(data, dict)
blueprint = Blueprint(data)
parsed_import_url = yarl.URL(url)
suggested_filename = f"{parsed_import_url.host}/{parsed_import_url.parts[-1][:-5]}"
return ImportedBlueprint(suggested_filename, raw_yaml, blueprint)
FETCH_FUNCTIONS = (
fetch_blueprint_from_community_post,
fetch_blueprint_from_github_url,
fetch_blueprint_from_github_gist_url,
fetch_blueprint_from_website_url,
fetch_blueprint_from_generic_url,
)
async def fetch_blueprint_from_url(hass: HomeAssistant, url: str) -> ImportedBlueprint:
"""Get a blueprint from a url."""
for func in (
fetch_blueprint_from_community_post,
fetch_blueprint_from_github_url,
fetch_blueprint_from_github_gist_url,
fetch_blueprint_from_website_url,
):
for func in FETCH_FUNCTIONS:
with suppress(UnsupportedUrl):
imported_bp = await func(hass, url)
imported_bp.blueprint.update_metadata(source_url=url)

View File

@ -192,9 +192,28 @@ async def test_fetch_blueprint_from_website_url(
assert imported_blueprint.blueprint.metadata["source_url"] == url
async def test_fetch_blueprint_from_unsupported_url(hass: HomeAssistant) -> None:
"""Test fetching blueprint from an unsupported URL."""
url = "https://example.com/unsupported.yaml"
async def test_fetch_blueprint_from_generic_url(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test fetching blueprint from url."""
aioclient_mock.get(
"https://example.org/path/someblueprint.yaml",
text=Path(
hass.config.path("blueprints/automation/test_event_service.yaml")
).read_text(encoding="utf8"),
)
with pytest.raises(HomeAssistantError, match=r"^Unsupported URL$"):
await importer.fetch_blueprint_from_url(hass, url)
url = "https://example.org/path/someblueprint.yaml"
imported_blueprint = await importer.fetch_blueprint_from_url(hass, url)
assert isinstance(imported_blueprint, importer.ImportedBlueprint)
assert imported_blueprint.blueprint.domain == "automation"
assert imported_blueprint.suggested_filename == "example.org/someblueprint"
assert imported_blueprint.blueprint.metadata["source_url"] == url
def test_generic_importer_last() -> None:
"""Test that generic importer is always the last one."""
assert (
importer.FETCH_FUNCTIONS.count(importer.fetch_blueprint_from_generic_url) == 1
)
assert importer.FETCH_FUNCTIONS[-1] == importer.fetch_blueprint_from_generic_url