Project

General

Profile

Actions

Task #7596

closed

uncloud-api refactoring & make schemas less horrible

Added by Ahmed Bilal almost 5 years ago. Updated almost 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
-
Start date:
01/09/2020
Due date:
% Done:

0%

Estimated time:
PM Check date:
Actions #1

Updated by Ahmed Bilal almost 5 years ago

  • Done `uncloud api` refactoring which was due for a long time and is the last refactoring beside https://redmine.ungleich.ch/issues/7590.
  • Schemas has been greatly simplified (now approaching to beautiful code :) and are now pleasant to work with.

A sample comparison

Before

class BaseSchema:
    def __init__(self, data, fields=None):
        _ = data  # suppress linter warning
        self.__errors = []
        if fields is None:
            self.fields = []
        else:
            self.fields = fields

    def validation(self):
        pass

    def is_valid(self):
        for field in self.fields:
            field.is_valid()
            self.add_field_errors(field)

        for parent in self.__class__.__bases__:
            try:
                parent.validation(self)
            except AttributeError:
                pass
        if not self.__errors:
            self.validation()

        if self.__errors:
            return False
        return True

    def get_errors(self):
        return {"message": self.__errors}

    def add_field_errors(self, field: Field):
        self.__errors += field.get_errors()

    def add_error(self, error):
        self.__errors.append(error)

class OTPSchema(BaseSchema):
    def __init__(self, data: dict, fields=None):
        self.name = Field("name", str, data.get("name", KeyError))
        self.realm = Field("realm", str, data.get("realm", KeyError))
        self.token = Field("token", str, data.get("token", KeyError))

        _fields = [self.name, self.realm, self.token]
        if fields:
            _fields += fields
        super().__init__(data=data, fields=_fields)

    def validation(self):
        if (check_otp(self.name.value, self.realm.value, self.token.value) != 200):
            self.add_error("Wrong Credentials")

After

class BaseSchema:
    def __init__(self):
        self.fields = [getattr(self, field) for field in dir(self) if isinstance(getattr(self, field), Field)]

    def validation(self):
        # custom validation is optional
        return True

    def is_valid(self):
        for field in self.fields:
            field.is_valid()

        for parent in self.__class__.__bases__:
            parent.validation(self)

        self.validation()

        for field in self.fields:
            setattr(self, field.name, field.value)

class OTPSchema(BaseSchema):
    def __init__(self, data: dict):
        self.name = Field('name', str, get(data, 'name'))
        self.realm = Field('realm', str, get(data, 'realm'))
        self.token = Field('token', str, get(data, 'token'))
        super().__init__()

    def validation(self):
        if check_otp(self.name.value, self.realm.value, self.token.value) != 200:
            raise ValidationException('Wrong Credentials')
Actions #3

Updated by Ahmed Bilal almost 5 years ago

  • Status changed from New to Closed
Actions

Also available in: Atom PDF