# Copyright 2026 Alibaba Group Holding Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Extension-related reads from persisted workload metadata (separate from core lifecycle API).""" from __future__ import annotations from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from opensandbox_server.services.sandbox_service import SandboxService class ExtensionService(ABC): """Workload extension metadata reads; kept off ``SandboxService`` lifecycle surface.""" @abstractmethod def get_access_renew_extend_seconds(self, sandbox_id: str) -> Optional[int]: """Seconds from workload metadata for access-driven renew, or None if missing/invalid.""" pass def require_extension_service(sandbox_service: "SandboxService") -> ExtensionService: """Assert the runtime sandbox service also implements ExtensionService (Docker/K8s do).""" if isinstance(sandbox_service, ExtensionService): return sandbox_service raise TypeError( f"{type(sandbox_service).__name__} must implement ExtensionService for renew-intent" )