Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aaxelb committed Feb 22, 2024
1 parent 46cfb62 commit cc0e075
Show file tree
Hide file tree
Showing 26 changed files with 288 additions and 134 deletions.
3 changes: 3 additions & 0 deletions addon_imps/storage/my_blarg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@


class MyBlargStorage(StorageInterface):
"""blarg?"""

def item_download_url(self, item_id):
"""blarg blarg blarg"""
return f"http://blarg.example/{item_id}"
10 changes: 6 additions & 4 deletions addon_service/authorized_storage_account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from addon_service.capability.enums import IntStorageCapability
from addon_service.common.base_model import AddonsServiceBaseModel
from addon_service.storage_operation.models import StorageOperationModel
from addon_toolkit import get_operation_implementations


Expand Down Expand Up @@ -46,10 +47,11 @@ def authorized_capabilities_enum(self) -> list[enum.Enum]:
]

@property
def authorized_operations(self):
return list(
get_operation_implementations(
def authorized_operations(self) -> list[StorageOperationModel]:
return [
StorageOperationModel(_imp)
for _imp in get_operation_implementations(
self.external_storage_service.storage_implementation_cls,
capabilities=self.authorized_capabilities_enum,
)
)
]
10 changes: 5 additions & 5 deletions addon_service/authorized_storage_account/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
)
from rest_framework_json_api.utils import get_resource_type_from_model

from addon_service.capability.serializers import StorageCapabilityMultipleChoiceField
from addon_service.capability.serializers import IntStorageCapabilityMultipleChoiceField
from addon_service.models import (
AuthorizedStorageAccount,
ConfiguredStorageAddon,
Expand All @@ -14,6 +14,7 @@
ExternalStorageService,
UserReference,
)
from addon_service.storage_operation.serializers import StorageOperationRelationField


RESOURCE_TYPE = get_resource_type_from_model(AuthorizedStorageAccount)
Expand Down Expand Up @@ -46,7 +47,7 @@ def __init__(self, *args, **kwargs):
url = serializers.HyperlinkedIdentityField(
view_name=SELF_LINK_VIEW_NAME, required=False
)
authorized_capabilities = StorageCapabilityMultipleChoiceField()
authorized_capabilities = IntStorageCapabilityMultipleChoiceField()
account_owner = AccountOwnerField(
many=False,
queryset=UserReference.objects.all(),
Expand All @@ -63,8 +64,7 @@ def __init__(self, *args, **kwargs):
related_link_view_name=RELATED_LINK_VIEW_NAME,
required=False,
)
authorized_operations = HyperlinkedRelatedField(
many=True,
authorized_operations = StorageOperationRelationField(
related_link_view_name=RELATED_LINK_VIEW_NAME,
)
username = serializers.CharField(
Expand All @@ -78,7 +78,7 @@ def __init__(self, *args, **kwargs):
"account_owner": "addon_service.serializers.UserReferenceSerializer",
"external_storage_service": "addon_service.serializers.ExternalStorageServiceSerializer",
"configured_storage_addons": "addon_service.serializers.ConfiguredStorageAddonSerializer",
"supported_operations": "addon_service.serializers.StorageOperationSerializer",
"authorized_operations": "addon_service.serializers.StorageOperationSerializer",
}

def create(self, validate_data):
Expand Down
4 changes: 2 additions & 2 deletions addon_service/capability/enums.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from addon_service.common.enums import IntEnumForEnum
from addon_service.common.enums import IntEnumMirror
from addon_toolkit.storage import StorageCapability


__all__ = ("IntStorageCapability",)


class IntStorageCapability(IntEnumForEnum, original_enum=StorageCapability):
class IntStorageCapability(IntEnumMirror, original_enum=StorageCapability):
ACCESS = 1
UPDATE = 2
4 changes: 2 additions & 2 deletions addon_service/capability/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

class StorageCapabilityChoiceField(DualEnumsChoiceField):
external_enum = StorageCapability
internal_enum = IntStorageCapability
internal_enum = StorageCapability


class StorageCapabilityMultipleChoiceField(DualEnumsMultipleChoiceField):
class IntStorageCapabilityMultipleChoiceField(DualEnumsMultipleChoiceField):
external_enum = StorageCapability
internal_enum = IntStorageCapability
26 changes: 17 additions & 9 deletions addon_service/common/enums/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,29 @@ def same_enum_names(enum_a: type[enum.Enum], enum_b: type[enum.Enum]) -> bool:
return _names_a == _names_b


class IntEnumForEnum(enum.IntEnum):
class EnumMirror(enum.Enum):
__original_enum: ClassVar[type[enum.Enum]]

def __init_subclass__(cls, /, original_enum: type[enum.Enum], **kwargs):
def __init_subclass__(
cls, /, original_enum: type[enum.Enum] | None = None, **kwargs
):
super().__init_subclass__(**kwargs)
assert same_enum_names(original_enum, cls)
cls.__original_enum = original_enum
if original_enum is not None:
assert same_enum_names(original_enum, cls)
cls.__original_enum = original_enum

def to_original_enum(self) -> enum.Enum:
return self.__original_enum[self.name]

@classmethod
def to_int(cls, original_enum_member):
return cls[original_enum_member.name]
def from_original_enum_value(cls, original_enum_value):
_name = cls.__original_enum(original_enum_value).name
return cls[_name]


class IntEnumMirror(EnumMirror, enum.IntEnum):
"""map an enum to integers for database use"""

@classmethod
def as_django_choices(cls):
return [(int(_item), _item.name) for _item in cls]

def to_original_enum(self) -> enum.Enum:
return self.__original_enum[self.name]
42 changes: 34 additions & 8 deletions addon_service/common/enums/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@
from addon_service.common.enums import same_enum_names


class EnumChoiceField(serializers.ChoiceField):
__enum_cls: type[enum.Enum]

def __init__(self, enum_cls: type[enum.Enum], **kwargs):
self.__enum_cls = enum_cls
super().__init__(
**kwargs,
choices=_values(enum_cls),
)

def to_internal_value(self, data) -> enum.Enum:
_name = super().to_internal_value(data)
return self.__enum_cls[_name]

def to_representation(self, value: enum.Enum):
return super().to_representation(value).value


class DualEnums:
internal_enum: ClassVar[type[enum.Enum]] # expected on subclasses
external_enum: ClassVar[type[enum.Enum]] # expected on subclasses
Expand All @@ -19,7 +37,7 @@ def get_internal_enum_member(self, external_value) -> enum.Enum:
_external_member = self.external_enum(external_value)
return self.internal_enum[_external_member.name]

def get_external_enum_value(self, internal_value: enum.Enum):
def get_external_enum_value(self, internal_value):
_internal_member = self.internal_enum(internal_value)
_external_member = self.external_enum[_internal_member.name]
return _external_member.value
Expand All @@ -29,13 +47,13 @@ class DualEnumsChoiceField(DualEnums, serializers.ChoiceField):
def __init__(self, **kwargs):
super().__init__(
**kwargs,
choices={ # valid serialized values come from the external enum
_external_member.value for _external_member in self.external_enum
},
choices=_values(
self.external_enum
), # valid serialized values come from the external enum
)

def to_internal_value(self, data) -> enum.Enum:
_name: set = super().to_internal_value(data)
_name = super().to_internal_value(data)
return self.get_internal_enum_member(_name)

def to_representation(self, value):
Expand All @@ -47,9 +65,9 @@ class DualEnumsMultipleChoiceField(DualEnums, serializers.MultipleChoiceField):
def __init__(self, **kwargs):
super().__init__(
**kwargs,
choices={ # valid serialized values come from the external enum
_external_member.value for _external_member in self.external_enum
},
choices=_values(
self.external_enum
), # valid serialized values come from the external enum
)

def to_internal_value(self, data) -> list[enum.Enum]:
Expand All @@ -59,3 +77,11 @@ def to_internal_value(self, data) -> list[enum.Enum]:
def to_representation(self, value):
_member_list = super().to_representation(value)
return {self.get_external_enum_value(_member) for _member in _member_list}


###
# module-local helpers


def _values(enum_cls: type[enum.Enum]) -> set:
return {_member.value for _member in enum_cls}
4 changes: 2 additions & 2 deletions addon_service/common/invocation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enum

from addon_service.common.enums import IntEnumForEnum
from addon_service.common.enums import IntEnumMirror


class InvocationStatus(enum.Enum):
Expand All @@ -10,7 +10,7 @@ class InvocationStatus(enum.Enum):
ERROR = "error"


class IntInvocationStatus(IntEnumForEnum, original_enum=InvocationStatus):
class IntInvocationStatus(IntEnumMirror, original_enum=InvocationStatus):
STARTING = 1
WAITING = 2
DONE = 3
Expand Down
10 changes: 6 additions & 4 deletions addon_service/configured_storage_addon/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from addon_service.capability.enums import IntStorageCapability
from addon_service.common.base_model import AddonsServiceBaseModel
from addon_service.storage_operation.models import StorageOperationModel
from addon_toolkit import get_operation_implementations


Expand Down Expand Up @@ -47,13 +48,14 @@ def connected_capabilities_enum(self) -> list[enum.Enum]:
]

@property
def connected_operations(self):
return list(
get_operation_implementations(
def connected_operations(self) -> list[StorageOperationModel]:
return [
StorageOperationModel(_imp)
for _imp in get_operation_implementations(
self.external_storage_service.storage_implementation_cls,
capabilities=self.connected_capabilities_enum,
)
)
]

def clean(self):
_connected_caps = set(self.connected_capabilities)
Expand Down
13 changes: 5 additions & 8 deletions addon_service/configured_storage_addon/serializers.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from rest_framework_json_api import serializers
from rest_framework_json_api.relations import (
HyperlinkedRelatedField,
ResourceRelatedField,
)
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.utils import get_resource_type_from_model

from addon_service.capability.serializers import StorageCapabilityMultipleChoiceField
from addon_service.capability.serializers import IntStorageCapabilityMultipleChoiceField
from addon_service.models import (
AuthorizedStorageAccount,
ConfiguredStorageAddon,
ResourceReference,
)
from addon_service.storage_operation.serializers import StorageOperationRelationField


RESOURCE_TYPE = get_resource_type_from_model(ConfiguredStorageAddon)
Expand All @@ -29,9 +27,8 @@ def to_internal_value(self, data):
class ConfiguredStorageAddonSerializer(serializers.HyperlinkedModelSerializer):
root_folder = serializers.CharField(required=False)
url = serializers.HyperlinkedIdentityField(view_name=SELF_LINK_VIEW_NAME)
connected_capabilities = StorageCapabilityMultipleChoiceField()
connected_operations = HyperlinkedRelatedField(
many=True,
connected_capabilities = IntStorageCapabilityMultipleChoiceField()
connected_operations = StorageOperationRelationField(
related_link_view_name=RELATED_LINK_VIEW_NAME,
)
base_account = ResourceRelatedField(
Expand Down
14 changes: 9 additions & 5 deletions addon_service/external_storage_service/models.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from django.db import models

from addon_service.common.base_model import AddonsServiceBaseModel
from addon_service.common.imp import IntStorageImps
from addon_service.storage_imp.known import IntStorageImp
from addon_service.storage_operation.models import StorageOperationModel
from addon_toolkit import get_operation_implementations


class ExternalStorageService(AddonsServiceBaseModel):
storage_implementation = models.IntegerField(
null=False,
choices=IntStorageImps.as_django_choices(),
choices=IntStorageImp.as_django_choices(),
)
max_concurrent_downloads = models.IntegerField(null=False)
max_upload_mb = models.IntegerField(null=False)
Expand All @@ -30,8 +31,11 @@ class JSONAPIMeta:

@property
def storage_implementation_cls(self):
return IntStorageImps(self.storage_implementation).to_original_enum()
return IntStorageImp(self.storage_implementation).to_original_enum().value

@property
def supported_operations(self):
return list(get_operation_implementations(self.storage_implementation_cls))
def supported_operations(self) -> list[StorageOperationModel]:
return [
StorageOperationModel(_imp)
for _imp in get_operation_implementations(self.storage_implementation_cls)
]
10 changes: 5 additions & 5 deletions addon_service/external_storage_service/serializers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from rest_framework_json_api import serializers
from rest_framework_json_api.relations import HyperlinkedRelatedField
from rest_framework_json_api.utils import get_resource_type_from_model

from addon_service.imp.serializers import StorageImpsChoiceField
from addon_service.models import ExternalStorageService
from addon_service.storage_imp.serializers import StorageImpChoiceField
from addon_service.storage_operation.serializers import StorageOperationRelationField


RESOURCE_TYPE = get_resource_type_from_model(ExternalStorageService)
Expand All @@ -13,9 +13,8 @@

class ExternalStorageServiceSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name=SELF_LINK_VIEW_NAME)
storage_implementation = StorageImpsChoiceField()
supported_operations = HyperlinkedRelatedField(
many=True,
storage_implementation = StorageImpChoiceField()
supported_operations = StorageOperationRelationField(
related_link_view_name=RELATED_LINK_VIEW_NAME,
)

Expand All @@ -31,4 +30,5 @@ class Meta:
"max_upload_mb",
"auth_uri",
"supported_operations",
"storage_implementation",
]
20 changes: 0 additions & 20 deletions addon_service/imp/known.py

This file was deleted.

18 changes: 0 additions & 18 deletions addon_service/imp/serializers.py

This file was deleted.

Loading

0 comments on commit cc0e075

Please sign in to comment.