Skip to content

Add Scaleway Object Storage backup integration#166868

Draft
BjoernPetersen wants to merge 1 commit intohome-assistant:devfrom
BjoernPetersen:scaleway-object-storage
Draft

Add Scaleway Object Storage backup integration#166868
BjoernPetersen wants to merge 1 commit intohome-assistant:devfrom
BjoernPetersen:scaleway-object-storage

Conversation

@BjoernPetersen
Copy link
Copy Markdown

@BjoernPetersen BjoernPetersen commented Mar 30, 2026

Proposed change

This PR adds a new Scaleway Object Storage integration that allows users to store Home Assistant backups in Scaleway Object Storage.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

No AI tools were used to create this PR (except for the Copilot PR review over here).

I choose the aiohttp-s3-client package as a dependency because - other than aiobotocore - it's a fully async dependendency and offers type hints without a separate stub package.

I plan to add further improvements and achieve a higher ranking on the quality scale in the future. This PR just adds what I consider a "basic" feature set.

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • (not applicable) For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

Copilot AI review requested due to automatic review settings March 30, 2026 12:06
Copy link
Copy Markdown

@home-assistant home-assistant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @BjoernPetersen

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Home Assistant integration to store backups in Scaleway Object Storage, including config flow support and initial test coverage.

Changes:

  • Introduces scaleway_object_storage integration (config flow, backup agent, exceptions, translations, quality scale metadata).
  • Adds config flow tests (user / reauth / reconfigure) and shared fixtures.
  • Registers dependency (aiohttp-s3-client), code ownership, strict typing, and generated registry updates.

Reviewed changes

Copilot reviewed 19 out of 21 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
tests/components/scaleway_object_storage/test_config_flow_step_user.py Adds user-step config flow tests.
tests/components/scaleway_object_storage/test_config_flow_step_reconfigure.py Adds reconfigure-step config flow tests.
tests/components/scaleway_object_storage/test_config_flow_step_reauth.py Adds reauth-step config flow tests.
tests/components/scaleway_object_storage/conftest.py Adds shared fixtures for Scaleway Object Storage tests.
tests/components/scaleway_object_storage/init.py Initializes the test package.
requirements_test_all.txt Adds aiohttp-s3-client to test requirements.
requirements_all.txt Adds aiohttp-s3-client to runtime requirements.
mypy.ini Enables strict mypy settings for the new integration package.
homeassistant/generated/integrations.json Registers the new integration in generated metadata.
homeassistant/generated/config_flows.py Adds the integration domain to generated config flow registry.
homeassistant/components/scaleway_object_storage/strings.json Adds config flow text, selector options, and exception translations.
homeassistant/components/scaleway_object_storage/quality_scale.yaml Declares quality scale compliance status for the integration.
homeassistant/components/scaleway_object_storage/manifest.json Defines integration metadata and dependency requirements.
homeassistant/components/scaleway_object_storage/helpers.py Adds S3 client creation, connection check, and metadata read helpers.
homeassistant/components/scaleway_object_storage/exceptions.py Adds translated, typed exception hierarchy for config/runtime errors.
homeassistant/components/scaleway_object_storage/const.py Adds integration constants (config keys, limits, headers).
homeassistant/components/scaleway_object_storage/config_flow.py Implements user / reauth / reconfigure config flow steps.
homeassistant/components/scaleway_object_storage/backup.py Implements BackupAgent against Scaleway S3-compatible object storage.
homeassistant/components/scaleway_object_storage/init.py Sets up the config entry and wires runtime client creation.
CODEOWNERS Assigns ownership for the new integration and its tests.
.strict-typing Marks the new integration for strict typing enforcement.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch 2 times, most recently from 24c5809 to 0cd40e8 Compare March 30, 2026 12:25
Copilot AI review requested due to automatic review settings March 30, 2026 12:25
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch 2 times, most recently from cffb3f4 to f30177a Compare March 30, 2026 12:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 9 comments.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from f30177a to c3bf285 Compare March 30, 2026 12:36
Copilot AI review requested due to automatic review settings March 30, 2026 12:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 4 comments.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 3b5b5e8 to d6972ae Compare March 30, 2026 13:19
Copilot AI review requested due to automatic review settings March 30, 2026 14:01
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from d6972ae to b3830b6 Compare March 30, 2026 14:01
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from b3830b6 to 9e2d0b5 Compare March 30, 2026 14:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 6 comments.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 9e2d0b5 to aa362de Compare March 30, 2026 14:27
Copilot AI review requested due to automatic review settings March 30, 2026 14:38
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from aa362de to 3e55dcb Compare March 30, 2026 14:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 9 comments.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 3e55dcb to 93ead40 Compare March 30, 2026 15:08
Copilot AI review requested due to automatic review settings March 30, 2026 15:39
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 93ead40 to bb1dc56 Compare March 30, 2026 15:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 2 comments.

@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from bb1dc56 to 30ee6c2 Compare March 30, 2026 16:42
Copilot AI review requested due to automatic review settings March 30, 2026 17:18
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 30ee6c2 to 02045f0 Compare March 30, 2026 17:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 21 comments.

@@ -0,0 +1,165 @@
"""Integration-internal helper functions that bundle common interactions with the underlying aiohttp_s3_client."""

Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module uses Mapping, AsyncGenerator, and Generator in runtime type annotations, but they are only imported under TYPE_CHECKING. Without from __future__ import annotations, this can raise NameError at import time. Fix by adding from __future__ import annotations at the top, or by importing these types unconditionally (outside TYPE_CHECKING).

Suggested change
from __future__ import annotations

Copilot uses AI. Check for mistakes.
from http import HTTPStatus
import json
import logging
from typing import TYPE_CHECKING, Any
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module uses Mapping, AsyncGenerator, and Generator in runtime type annotations, but they are only imported under TYPE_CHECKING. Without from __future__ import annotations, this can raise NameError at import time. Fix by adding from __future__ import annotations at the top, or by importing these types unconditionally (outside TYPE_CHECKING).

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +18
if TYPE_CHECKING:
from collections.abc import AsyncGenerator, Generator, Mapping
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module uses Mapping, AsyncGenerator, and Generator in runtime type annotations, but they are only imported under TYPE_CHECKING. Without from __future__ import annotations, this can raise NameError at import time. Fix by adding from __future__ import annotations at the top, or by importing these types unconditionally (outside TYPE_CHECKING).

Suggested change
if TYPE_CHECKING:
from collections.abc import AsyncGenerator, Generator, Mapping
from collections.abc import AsyncGenerator, Generator, Mapping

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,204 @@
"""Config flow for the Scaleway Object Storage integration."""
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigFlowResult is referenced in return annotations but only imported under TYPE_CHECKING. Without postponed annotation evaluation, this can raise NameError at import time. Add from __future__ import annotations or import ConfigFlowResult at runtime.

Suggested change
"""Config flow for the Scaleway Object Storage integration."""
"""Config flow for the Scaleway Object Storage integration."""
from __future__ import annotations

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +33
if TYPE_CHECKING:
from homeassistant.config_entries import ConfigFlowResult
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigFlowResult is referenced in return annotations but only imported under TYPE_CHECKING. Without postponed annotation evaluation, this can raise NameError at import time. Add from __future__ import annotations or import ConfigFlowResult at runtime.

Copilot uses AI. Check for mistakes.

# Notify backup listeners
def notify_backup_listeners() -> None:
for listener in hass.data.get(DATA_BACKUP_AGENT_LISTENERS, []):
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterating over the listeners list directly can break if a listener unregisters itself (or another listener) during callback execution, mutating the list while iterating. Iterate over a shallow copy (e.g., for listener in list(...):) to make this robust.

Suggested change
for listener in hass.data.get(DATA_BACKUP_AGENT_LISTENERS, []):
for listener in list(hass.data.get(DATA_BACKUP_AGENT_LISTENERS, [])):

Copilot uses AI. Check for mistakes.

return self._yield_chunks(response)

async def async_upload_backup(
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds substantial new BackupAgent behavior (download/upload/list/get/delete, multipart uploads, error handling, and reauth triggering) but the added tests cover only config flows. Add tests for the backup agent methods (at least: async_list_backups success + ignored-object behavior, async_download_backup response cleanup on errors, and upload paths single vs multipart) to prevent regressions.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,424 @@
"""BackupAgent implementation based on Scaleway Object Storage."""

Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds substantial new BackupAgent behavior (download/upload/list/get/delete, multipart uploads, error handling, and reauth triggering) but the added tests cover only config flows. Add tests for the backup agent methods (at least: async_list_backups success + ignored-object behavior, async_download_backup response cleanup on errors, and upload paths single vs multipart) to prevent regressions.

Copilot uses AI. Check for mistakes.
# Get task results and filter out None values
return list(filter(None, (task.result() for task in backups)))

async def async_get_backup(self, backup_id: str, **kwargs: Any) -> AgentBackup:
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds substantial new BackupAgent behavior (download/upload/list/get/delete, multipart uploads, error handling, and reauth triggering) but the added tests cover only config flows. Add tests for the backup agent methods (at least: async_list_backups success + ignored-object behavior, async_download_backup response cleanup on errors, and upload paths single vs multipart) to prevent regressions.

Copilot uses AI. Check for mistakes.
@BjoernPetersen BjoernPetersen force-pushed the scaleway-object-storage branch from 02045f0 to ebd4df2 Compare March 30, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants