perf(api): share cached provider-type choices across filters and serializer

- Move get_provider_type_choices into a leaf module so the provider
  serializer field reuses the filters' cached list instead of recomputing
  SDK provider discovery on every request
This commit is contained in:
StylusFrost
2026-06-01 21:18:39 +02:00
parent 28433362c5
commit c94456c131
3 changed files with 20 additions and 20 deletions
+1 -13
View File
@@ -1,5 +1,4 @@
from datetime import date, datetime, timedelta, timezone
from functools import lru_cache
from dateutil.parser import parse
from django.conf import settings
@@ -67,19 +66,8 @@ from api.uuid_utils import (
uuid7_range,
uuid7_start,
)
from api.provider_types import get_provider_type_choices
from api.v1.serializers import TaskBase
from prowler.providers.common.provider import Provider as SDKProvider
@lru_cache(maxsize=1)
def get_provider_type_choices():
"""Provider-type filter choices driven by the SDK's available providers
instead of a static enum, so filtering covers external providers too.
Cached because the installed providers are fixed for the process lifetime
and provider-type filters live on hot list endpoints.
"""
return [(name, name) for name in SDKProvider.get_available_providers()]
class CustomDjangoFilterBackend(DjangoFilterBackend):
+15
View File
@@ -0,0 +1,15 @@
from functools import lru_cache
from prowler.providers.common.provider import Provider as SDKProvider
@lru_cache(maxsize=1)
def get_provider_type_choices():
"""Provider-type choices from the SDK's available providers, so they cover
external providers and not just a static enum.
Cached for the process lifetime; hot-installing a provider needs
coordinated cache invalidation (tracked separately) to show up here without
a restart. Shared by the filters and the provider serializer.
"""
return [(name, name) for name in SDKProvider.get_available_providers()]
+4 -7
View File
@@ -71,9 +71,9 @@ from api.v1.serializer_utils.lighthouse import (
OpenAICredentialsSerializer,
)
from api.v1.serializer_utils.processors import ProcessorConfigField
from api.provider_types import get_provider_type_choices
from api.v1.serializer_utils.providers import ProviderSecretField
from prowler.lib.mutelist.mutelist import Mutelist
from prowler.providers.common.provider import Provider as SDKProvider
# Base
@@ -855,12 +855,9 @@ class ProviderGroupMembershipSerializer(RLSSerializer, BaseWriteSerializer):
# Providers
class ProviderEnumSerializerField(serializers.ChoiceField):
def __init__(self, **kwargs):
# The SDK is the source of truth for which providers exist, so the
# accepted values track the installed providers (built-in or external)
# instead of a static enum.
kwargs["choices"] = [
(name, name) for name in SDKProvider.get_available_providers()
]
# Accepted values track the SDK's installed providers (built-in or
# external), shared with the filters via one cached source.
kwargs["choices"] = get_provider_type_choices()
super().__init__(**kwargs)