angru / corm

MIT License
2 stars 0 forks source link

Hooks #4

Open angru opened 4 years ago

angru commented 4 years ago

Something that able to change data during create entity or make dict from entity

import typing as t

class LoadHook:
    """Base load hook"""
    match_entities: t.Sequence[t.Type[Entity]] = [Entity]  # For all entities

    def match(self, data: t.Any, entity_class: t.Type[Entity]  **kwargs) -> t.Any:
        """should make some actions with data and return something or same data"""
        raise NotImplementedError

class DumpHook:
    """Base dump hook"""
    match_entities: t.Sequence[t.Type[Entity]] = [Entity]  # For all entities

    def match(self, data: t.Any, entity: Entity  **kwargs) -> t.Any:
        """should make some actions with data and return something or same data"""
        raise NotImplementedError   

class SomeLoadHook(LoadHook):
    pass

class SomeDumpHook(DumpHook):
    pass

class User(Entity):
    pass

john = User(data={'id': 1}, storage=Storage(), hooks=[SomeLoadHook()])  # each hook applies to data before create any entity if type of entity in match_entities list
data = john.dict(hooks=[SomeDumbHook()])  # each hook applies to data after any entity transformed to dict if type of entity in match_entities list
angru commented 4 years ago

Exclude hook example

import typing as t

from corm import Storage, Entity, Nested, DumpHook

storage = Storage()

class Address(Entity):
    id: int
    street: str
    number: int

class User(Entity):
    id: int
    name: str
    address: Address = Nested(entity_type=Address)

class ExcludeHook(DumpHook):
    match_entities = [User, Address]

    def __init__(self, exclude_fields: t.List[str], match_entities: t.List[t.Type[Entity]]):
        super().__init__(match_entities)

        self.exclude_fields = exclude_fields

    def match(self, data, entity: Entity):
        for field in self.exclude_fields:
            data.pop(field, None)

        return data

john = User({'id': 1, 'name': 'John', 'address': {'id': 2, 'street': 'First', 'number': 1}}, storage)

assert john.dict(hooks=[ExcludeHook(exclude_fields=['id'])]) == {
    'name': 'John', 
    'address': {'street': 'First', 'number': 1},
}