diff --git a/core/api/utils/polymorphism.py b/core/api/utils/polymorphism.py index da0aa2db..9d03129b 100644 --- a/core/api/utils/polymorphism.py +++ b/core/api/utils/polymorphism.py @@ -12,7 +12,7 @@ from core.api.v3.objects import * from core.api.v3.objects.base import BaseProvider -from core.utils.types import APIObjOperations, APISerializerOperations, ProviderDetails +from core.utils.types import APIObjOperations type IgnoredKey = str | Iterable[str] type SerializerItems = Dict[str, BaseSerializer] @@ -117,23 +117,6 @@ def get_providers_by_operation( ] -def get_operations_by_provider(provider: BaseProvider) -> ProviderDetails: - """ - Returns a list of operations supported by the given provider. - """ - options = set() - for operation in provider.supported_operations(): - data = APISerializerOperations( - operation=operation, - serializer=provider.raw_serializers.get( - operation, provider.raw_serializers.get("_") - ), - ) - options.add(data) - - return options - - class ObjectAPIView(generics.GenericAPIView): def initial(self, *args, **kwargs): super().initial(*args, **kwargs) diff --git a/core/api/v3/objects/base.py b/core/api/v3/objects/base.py index 2bae1ffa..490e334b 100644 --- a/core/api/v3/objects/base.py +++ b/core/api/v3/objects/base.py @@ -9,7 +9,7 @@ type SerializerItems = Dict[str, BaseSerializer] -class BaseProvider(ABC): +class BaseProvider(ABC, object): allow_list: bool = ( True # Is the view able to list the model's objects. (e.g. /user would list all users ) diff --git a/core/api/v3/objects/main.py b/core/api/v3/objects/main.py index 767f8c6d..795a3caf 100644 --- a/core/api/v3/objects/main.py +++ b/core/api/v3/objects/main.py @@ -270,7 +270,7 @@ class ObjectSingle( detail = None kind = "single" - def check_allow_single(self): + def check_allow_single(self) -> JsonResponse | None: allow_single = getattr(self.provider, "allow_single", True) if not allow_single: return JsonResponse({"detail": "editing/deletion not allowed"}, status=422) diff --git a/core/schema.py b/core/schema.py index 40ff1b1d..c5376a7d 100644 --- a/core/schema.py +++ b/core/schema.py @@ -1,6 +1,6 @@ import dataclasses from functools import wraps -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type +from typing import Any, Callable, Dict, Final, List, Optional, Sequence, Tuple, Type from drf_spectacular.drainage import set_override from drf_spectacular.generators import SchemaGenerator @@ -9,7 +9,6 @@ from rest_framework.serializers import Serializer from core.api.utils.polymorphism import ( - get_operations_by_provider, get_path_by_provider, get_provider, get_providers_by_operation, @@ -164,8 +163,7 @@ def _generate_data(self): for provider_name, provider_obj in providers.items(): self._provider_details[provider_name] = ProviderDetails( provider=provider_obj, - operations_supported=[], - data=dict(), + operations_supported=dict(), ) @staticmethod @@ -225,8 +223,7 @@ def _get_paths_and_endpoints(self): obj3.add( ProviderDetails( provider=provider, - operations_supported=get_operations_by_provider(provider), - data=data, + operations_supported=data, url=path.replace( "{type}", get_path_by_provider(provider), @@ -234,10 +231,37 @@ def _get_paths_and_endpoints(self): ) ) - print(f"obj3: {obj3}") - formatted_obj3 = list() - for provider in obj3: - ... + # print(f"obj3: {obj3}") + formatted_obj3 = self._generate_endpoints(obj3) view_endpoints.extend(formatted_obj3) + print(f"View Endpoints: {formatted_obj3}") return view_endpoints + + def _generate_endpoints( + self, obj_data: List[ProviderDetails] + ) -> List[Tuple[str, str, str, Any]]: + """ + Generate the endpoints for the API3 objects + Takes in a list of ProviderDetails and returns a list of tuples in the fmt of (path, path_regex, method, view) + """ + CONVERTER: Final = { + "list": ["GET"], + "new": ["POST"], + "retrieve": ["GET"], + "single": ["PUT", "PATCH", "DELETE"], + } + endpoints = [] + for obj in obj_data: + for operation, serializer in obj.operations_supported: + for method in CONVERTER[operation]: + endpoints.append( + ( + obj.url, + obj.url, + method, + obj.provider, + ) + ) + + return endpoints diff --git a/core/utils/types.py b/core/utils/types.py index 96768241..be3ea3f0 100644 --- a/core/utils/types.py +++ b/core/utils/types.py @@ -11,17 +11,6 @@ type PathData = NamedTuple[str, "BaseProvider", dict] -@dataclass -class APISerializerOperations: - operation: APIObjOperations - serializer: BaseSerializer - - def __hash__(self): - return hash(self.operation.__class__.__name__) - - # tags? - - @dataclass class SingleOperationData: providers: List["BaseProvider"] @@ -32,9 +21,8 @@ class SingleOperationData: @dataclass class ProviderDetails: provider: "BaseProvider" - operations_supported: List[APISerializerOperations] + operations_supported: Dict[APIObjOperations, BaseSerializer] url: Optional[str] = None - data: Optional[Dict] = None def __hash__(self): return hash(self.provider.__class__.__name__)