From d9c2ec556d7fd2297aa7c1260a35a5461f28e8e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:00:14 +0000 Subject: [PATCH 1/3] Initial plan From 9a754554b33418a5494201f68a5f81aca57876e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:10:36 +0000 Subject: [PATCH 2/3] Replace cached_property with functools.cached_property Co-authored-by: ogajduse <20440883+ogajduse@users.noreply.github.com> --- pyproject.toml | 1 - wrapanapi/entities/vm.py | 44 ++++++++++++++++++++++++++- wrapanapi/systems/container/podman.py | 2 +- wrapanapi/systems/msazure.py | 2 +- wrapanapi/systems/scvmm.py | 2 +- wrapanapi/systems/virtualcenter.py | 6 ++-- 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e1672527..8dafa799 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ dependencies = [ "boto", "boto3", "botocore", - "cached_property", "dateparser", "fauxfactory", "google-api-python-client", diff --git a/wrapanapi/entities/vm.py b/wrapanapi/entities/vm.py index bc8e15db..e586445f 100644 --- a/wrapanapi/entities/vm.py +++ b/wrapanapi/entities/vm.py @@ -6,10 +6,52 @@ import time from abc import ABCMeta, abstractmethod, abstractproperty +from functools import cached_property -from cached_property import cached_property_with_ttl from wait_for import TimedOutError, wait_for + +class cached_property_with_ttl: + """A property that is cached for a given TTL (time-to-live) in seconds.""" + + def __init__(self, ttl): + self.ttl = ttl + + def __call__(self, func): + self.func = func + self.__doc__ = func.__doc__ + self.__name__ = func.__name__ + return self + + def __get__(self, obj, objtype=None): + if obj is None: + return self + + attr_name = f'_{self.__name__}_cached' + time_attr_name = f'_{self.__name__}_cached_time' + + current_time = time.time() + + if (hasattr(obj, attr_name) and hasattr(obj, time_attr_name) and + current_time - getattr(obj, time_attr_name) < self.ttl): + return getattr(obj, attr_name) + + value = self.func(obj) + setattr(obj, attr_name, value) + setattr(obj, time_attr_name, current_time) + return value + + def __set__(self, obj, value): + raise AttributeError("can't set attribute") + + def __delete__(self, obj): + attr_name = f'_{self.__name__}_cached' + time_attr_name = f'_{self.__name__}_cached_time' + if hasattr(obj, attr_name): + delattr(obj, attr_name) + if hasattr(obj, time_attr_name): + delattr(obj, time_attr_name) + from wrapanapi.const import CACHED_PROPERTY_TTL from wrapanapi.entities.base import Entity, EntityMixin from wrapanapi.exceptions import MultipleItemsError, NotFoundError diff --git a/wrapanapi/systems/container/podman.py b/wrapanapi/systems/container/podman.py index bd14048e..a64cdbd7 100644 --- a/wrapanapi/systems/container/podman.py +++ b/wrapanapi/systems/container/podman.py @@ -2,7 +2,7 @@ from datetime import datetime from podman import PodmanClient -from proto.utils import cached_property +from functools import cached_property from wrapanapi.entities.base import Entity from wrapanapi.systems.base import System diff --git a/wrapanapi/systems/msazure.py b/wrapanapi/systems/msazure.py index 9d4dd9de..798d02d2 100644 --- a/wrapanapi/systems/msazure.py +++ b/wrapanapi/systems/msazure.py @@ -18,7 +18,7 @@ from azure.mgmt.resource.subscriptions.models import SubscriptionState from azure.mgmt.storage import StorageManagementClient from azure.storage.blob import BlobServiceClient -from cached_property import cached_property +from functools import cached_property from dateutil import parser from msrestazure.azure_exceptions import CloudError from wait_for import wait_for diff --git a/wrapanapi/systems/scvmm.py b/wrapanapi/systems/scvmm.py index 3e288411..a9013df5 100644 --- a/wrapanapi/systems/scvmm.py +++ b/wrapanapi/systems/scvmm.py @@ -12,7 +12,7 @@ import pytz import tzlocal import winrm -from cached_property import cached_property +from functools import cached_property from wait_for import wait_for from wrapanapi.entities import Template, TemplateMixin, Vm, VmMixin, VmState diff --git a/wrapanapi/systems/virtualcenter.py b/wrapanapi/systems/virtualcenter.py index 27c915b3..051a6c5d 100644 --- a/wrapanapi/systems/virtualcenter.py +++ b/wrapanapi/systems/virtualcenter.py @@ -14,7 +14,7 @@ from functools import partial import pytz -from cached_property import threaded_cached_property +from functools import cached_property from pyVim.connect import Disconnect, SmartConnect from pyVmomi import vim, vmodl from wait_for import TimedOutError, wait_for @@ -995,13 +995,13 @@ def _create_service_instance(self): self._start_keepalive() return si - @threaded_cached_property + @cached_property def service_instance(self): """An instance of the service""" self.logger.debug("Attempting to initiate vCenter service instance") return self._create_service_instance() - @threaded_cached_property + @cached_property def content(self): self.logger.debug("calling RetrieveContent()... this might take awhile") return self.service_instance.RetrieveContent() From 4ea1c523a3bdc25b73677eb4351a7063b6ed9183 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:28:49 +0000 Subject: [PATCH 3/3] Revert to using cached_property library for cached_property_with_ttl Co-authored-by: ogajduse <20440883+ogajduse@users.noreply.github.com> --- pyproject.toml | 1 + wrapanapi/entities/vm.py | 44 +-------------------------- wrapanapi/systems/container/podman.py | 2 +- wrapanapi/systems/msazure.py | 2 +- wrapanapi/systems/scvmm.py | 2 +- wrapanapi/systems/virtualcenter.py | 3 +- 6 files changed, 6 insertions(+), 48 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8dafa799..e1672527 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ dependencies = [ "boto", "boto3", "botocore", + "cached_property", "dateparser", "fauxfactory", "google-api-python-client", diff --git a/wrapanapi/entities/vm.py b/wrapanapi/entities/vm.py index e586445f..bc8e15db 100644 --- a/wrapanapi/entities/vm.py +++ b/wrapanapi/entities/vm.py @@ -6,52 +6,10 @@ import time from abc import ABCMeta, abstractmethod, abstractproperty -from functools import cached_property +from cached_property import cached_property_with_ttl from wait_for import TimedOutError, wait_for - -class cached_property_with_ttl: - """A property that is cached for a given TTL (time-to-live) in seconds.""" - - def __init__(self, ttl): - self.ttl = ttl - - def __call__(self, func): - self.func = func - self.__doc__ = func.__doc__ - self.__name__ = func.__name__ - return self - - def __get__(self, obj, objtype=None): - if obj is None: - return self - - attr_name = f'_{self.__name__}_cached' - time_attr_name = f'_{self.__name__}_cached_time' - - current_time = time.time() - - if (hasattr(obj, attr_name) and hasattr(obj, time_attr_name) and - current_time - getattr(obj, time_attr_name) < self.ttl): - return getattr(obj, attr_name) - - value = self.func(obj) - setattr(obj, attr_name, value) - setattr(obj, time_attr_name, current_time) - return value - - def __set__(self, obj, value): - raise AttributeError("can't set attribute") - - def __delete__(self, obj): - attr_name = f'_{self.__name__}_cached' - time_attr_name = f'_{self.__name__}_cached_time' - if hasattr(obj, attr_name): - delattr(obj, attr_name) - if hasattr(obj, time_attr_name): - delattr(obj, time_attr_name) - from wrapanapi.const import CACHED_PROPERTY_TTL from wrapanapi.entities.base import Entity, EntityMixin from wrapanapi.exceptions import MultipleItemsError, NotFoundError diff --git a/wrapanapi/systems/container/podman.py b/wrapanapi/systems/container/podman.py index a64cdbd7..f3800c95 100644 --- a/wrapanapi/systems/container/podman.py +++ b/wrapanapi/systems/container/podman.py @@ -1,8 +1,8 @@ from abc import ABCMeta from datetime import datetime +from functools import cached_property from podman import PodmanClient -from functools import cached_property from wrapanapi.entities.base import Entity from wrapanapi.systems.base import System diff --git a/wrapanapi/systems/msazure.py b/wrapanapi/systems/msazure.py index 798d02d2..50a5ab0c 100644 --- a/wrapanapi/systems/msazure.py +++ b/wrapanapi/systems/msazure.py @@ -5,6 +5,7 @@ import os from datetime import datetime, timedelta +from functools import cached_property import pytz from azure.core.exceptions import HttpResponseError @@ -18,7 +19,6 @@ from azure.mgmt.resource.subscriptions.models import SubscriptionState from azure.mgmt.storage import StorageManagementClient from azure.storage.blob import BlobServiceClient -from functools import cached_property from dateutil import parser from msrestazure.azure_exceptions import CloudError from wait_for import wait_for diff --git a/wrapanapi/systems/scvmm.py b/wrapanapi/systems/scvmm.py index a9013df5..ec9cfc7b 100644 --- a/wrapanapi/systems/scvmm.py +++ b/wrapanapi/systems/scvmm.py @@ -7,12 +7,12 @@ import re import time from datetime import datetime +from functools import cached_property from textwrap import dedent import pytz import tzlocal import winrm -from functools import cached_property from wait_for import wait_for from wrapanapi.entities import Template, TemplateMixin, Vm, VmMixin, VmState diff --git a/wrapanapi/systems/virtualcenter.py b/wrapanapi/systems/virtualcenter.py index 051a6c5d..0b122a56 100644 --- a/wrapanapi/systems/virtualcenter.py +++ b/wrapanapi/systems/virtualcenter.py @@ -11,10 +11,9 @@ import time from datetime import datetime from distutils.version import LooseVersion -from functools import partial +from functools import cached_property, partial import pytz -from functools import cached_property from pyVim.connect import Disconnect, SmartConnect from pyVmomi import vim, vmodl from wait_for import TimedOutError, wait_for