예제 #1
0
class CanFilterAndExclude(Method):
    filter_validator: Callable = Options(default=DenyAll)
    exclude_validator: Callable = Options(default=DenyAll)

    def set_default_success_code(self, context: Context):
        raise NotImplementedError()

    def query_db(self, context: Context):
        raise NotImplementedError()

    def schema(self):
        _schema = super().schema()
        _schema["filter_schema"] = repr(self.filter_validator)
        _schema["exclude_schema"] = repr(self.exclude_validator)
        return _schema
예제 #2
0
class Example:
    a = 0
    b: int = 0
    c: int
    d: Optional[List]
    e: Optional[int] = 1
    f: int = Options(rename="g")
예제 #3
0
class Get(NoBodyNoObjectsNoInput):
    count_total: bool = Options(default=False)

    def query_db(self, context: Context):
        self.db_layer.get(context, self)

    def set_default_success_code(self, context: Context):
        context.status_code = 200
예제 #4
0
class RequiredDefaultCallable:
    _int: int = Options(default=lambda: 1)
    _float: float = Options(default=lambda: 1.0)
    _bool: bool = Options(default=lambda: True)
    _str: str = Options(default=lambda: "x")
    _dict: dict = Options(default=lambda: {"x": 1})
    _list: list = Options(default=lambda: [1, 2])
예제 #5
0
class RequiredDefault:
    _int: int = Options(default=1)
    _float: float = Options(default=1.0)
    _bool: bool = Options(default=True)
    _str: str = Options(default="x")
    _dict: dict = Options(default={"x": 1})
    _list: List[int] = Options(default=[1, 2])
예제 #6
0
class Put(CanFilterAndExclude):
    def query_db(self, context: Context):
        self.db_layer.put(context, self)
        context.items = []

    input_validator: Callable = Options(default=DenyAll)

    def set_default_success_code(self, context: Context):
        context.status_code = 200

    def schema(self):
        _schema = super().schema()
        _schema["input_schema"] = repr(self.input_validator)
        return _schema
예제 #7
0
class Post(Method):
    input_validator: Callable = Options(default=DenyAll)

    def query_db(self, context: Context):
        self.db_layer.post(context, self)
        context.items = []

    def schema(self):
        _schema = super().schema()
        _schema["input_schema"] = repr(self.input_validator)
        return _schema

    def set_default_success_code(self, context: Context):
        context.status_code = 201
예제 #8
0
class Allowed:
    a: int = Options(allowed=[1, 2])
예제 #9
0
class Method:
    mode: str = 'django'

    query: Any = None
    queryset: Any = None
    db_layer: Optional[DbLayer] = None

    serializer: Optional[Serializer] = None
    deserializer: Optional[Deserializer] = None

    skip_query_db: bool = Options(default=False)

    input_validator: Callable = Options(default=DenyAll)
    output_validator: Callable = Options(default=DenyAll)

    pre_query_hooks: List[Callable] = Options(default=list)
    post_query_hooks: List[Callable] = Options(default=list)

    request_hooks: List[Callable] = Options(default=list)
    response_hooks: List[Callable] = Options(default=list)

    def __validate_it__post_init__(self):
        need_fields = []

        if self.mode == 'django':
            need_fields = ['queryset']

            if not self.db_layer:
                self.db_layer = DjangoDbLayer()

            if not self.serializer:
                self.serializer = DjangoSerializer()

            if not self.deserializer:
                self.deserializer = DjangoDeserializer()

        for field in need_fields:
            if getattr(self, field) is None and not self.skip_query_db:
                raise ValueError(
                    f"Empty `{field}` is allowed only for resources with `skip_query_db` == True"
                )

    def __set_name__(self, owner, name):
        if not hasattr(owner, 'methods') or not owner.methods:
            setattr(owner, 'methods', {})

        owner.methods[self.__class__.__name__.lower()] = self

    def schema(self):
        return {"output_schema": repr(self.output_validator)}

    def query_db(self, context: Context):
        raise NotImplementedError()

    @staticmethod
    def validate(validator, context: Context):
        context.items = [validator(item) for item in context.items]

    def validate_input(self, context: Context):
        self.validate(self.input_validator, context)

    def validate_output(self, context: Context):
        self.validate(self.output_validator, context)

    @staticmethod
    def apply_hooks(hooks, context: Context):
        for hook in hooks:
            hook(context)

    def apply_pre_query_hooks(self, context: Context):
        self.apply_hooks(self.pre_query_hooks, context)

    def apply_post_query_hooks(self, context: Context):
        self.apply_hooks(self.post_query_hooks, context)

    def set_default_success_code(self, context: Context):
        raise NotImplementedError()

    def apply_request_hooks(self, context: Context):
        self.apply_hooks(self.request_hooks, context)

    def apply_response_hooks(self, context: Context):
        self.apply_hooks(self.response_hooks, context)

    def handle(self, request, **kwargs):
        context = self.deserializer.deserialize(request, self, **kwargs)

        self.set_default_success_code(context)
        self.apply_request_hooks(context)
        self.validate_input(context)
        self.apply_pre_query_hooks(context)

        if not self.skip_query_db:
            self.query_db(context)

        self.apply_post_query_hooks(context)
        self.validate_output(context)
        self.apply_response_hooks(context)

        return self.serializer.serialize(context)
예제 #10
0
class Context:
    request: Any
    queryset: Any

    order: dict = Options(default=dict)

    user_filter: dict = Options(default=dict)
    user_exclude: dict = Options(default=dict)

    system_filter: Union[dict, Q, None] = Options(default=None)
    system_exclude: Union[dict, Q, None] = Options(default=None)

    merged_filter: Union[dict, Q, None] = Options(default=None)
    merged_exclude: Union[dict, Q, None] = Options(default=None)

    project: List[str] = Options(default=list)
    items: Union[List[dict], QuerySet] = Options(default=list)
    meta: dict = Options(default=dict)
    status_code: int = Options(default=0)

    limit: int = Options(default=0)
    skip: int = Options(default=0)

    total: int = Options(default=0)
    created: int = Options(default=0)
    updated: int = Options(default=0)
    deleted: int = Options(default=0)
예제 #11
0
class Convert:
    a: str = Options(parser=str)
예제 #12
0
class J:
    c: Union[H, I] = Options(auto_pack=True, packer=pack_value)
예제 #13
0
 class A:
     a: str = Options(default="a")
     b: str = Options(default="b")
예제 #14
0
class SerializerType:
    a: float = Options(parser=float, serializer=int)
예제 #15
0
 class C:
     c: Union[A, B] = Options(auto_pack=True, packer=pack_value)
예제 #16
0
class TypeWithValidator:
    email: str = Options(validators=[is_email])
예제 #17
0
class NotRequiredDefaultCallable:
    _optional: Optional[int] = lambda: 0
    _optional_with_options: Optional[int] = Options(default=lambda: 0)
    _required: int = lambda: 0
예제 #18
0
class NotRequiredDefault:
    _optional: Optional[int] = 0
    _optional_with_options: Optional[int] = Options(default=1)
    _required: int = 0
예제 #19
0
class UnexpectedNotStrip:
    a: float = Options(parser=float, serializer=int)
예제 #20
0
class OptionalDictWithDefaultC:
    s: str
    nested_with_elements: Optional[Dict[int,
                                        OptionalDictWithDefaultB]] = Options()
    nested_empty: Optional[Dict[int, OptionalDictWithDefaultB]] = Options()
예제 #21
0
 class R:
     a: int = 0
     b: str = Options(min_length=3, max_length=10)
예제 #22
0
class AllowedCallable:
    a: int = Options(allowed=lambda: [1, 2])
예제 #23
0
 class B:
     b: int = Options(default=1)
예제 #24
0
class Amount:
    a: int = Options(min_value=10)
    b: int = Options(max_value=20)
예제 #25
0
 class G:
     c: Union[E, F] = Options(auto_pack=True, packer=pack_value)
예제 #26
0
class Length:
    a: str = Options(min_length=2)
    b: str = Options(max_length=5)
예제 #27
0
    class PlayerB:
        name: str = Options(default="")

        items: List[ItemB] = Options(default=list)

        skills: Dict[str, SkillB] = Options(default=dict)
예제 #28
0
class OptionalAutoPackEnabled:
    a: Optional[A] = Options(auto_pack=True, packer=pack_value)
예제 #29
0
 class B:
     a: int = Options(alias="_a")
     b: int = Options(alias="_b")
예제 #30
0

@schema(strip_unknown=True)
class First:
    a: int = 0
    b: int = 0


Second = clone(First, strip_unknown=True, include=["a"])

Third = clone(First, strip_unknown=True, exclude=["a"])

# try replace
Fourth = clone(First,
               strip_unknown=True,
               add=[("a", str, Options(parser=str))])

# add
Fifth = clone(First,
              strip_unknown=True,
              add=[("_id", int, Options(default=1))])


class CloneTestCase(TestCase):
    def test_clone(self):
        data = {"a": 1, "b": 2}

        first = First(**data)
        self.assertEquals(data, to_dict(first))

        second = Second(**data)