Alohomora-team / AlohomoraAPI

Um sistema de autenticação biométrica por voz utilizando mfcc e fastDTW.
MIT License
3 stars 0 forks source link

Arrumar duplicações no código #24

Closed Bumbleblo closed 5 years ago

Bumbleblo commented 5 years ago

Descrição da funcionalidade

Arrumar duplicações na API apontados pelo code climate.

Tarefas necessárias

Contexto Adicional

Duplicações

Bumbleblo commented 5 years ago

Exemplo de como refatorar o ActivedUSer

from abc import abstractmethod, ABC

class ManagerUser(graphene.Mutation):
    """Mutation from graphene for activating user"""

    user = graphene.Field(UserType)

    @abstractmethod
    def state(self):
        pass

    class Arguments:
        """Mutation arguments for activate a user"""
        user_email = graphene.String()

    def mutate(self, info, user_email):
        """Method to execute the mutation"""
        user = get_user_model().objects.get(email=user_email)
        user.is_active = self.state()
        user.save()
        return ActivateUser(user=user)

class ActivateUser(ManagerUser):

    def state(self):
        return True

class DesactivateUser(ManagerUser):

    def state(self)
        return False
higton commented 5 years ago

Tem algumas duplicações que vão ser resolvidas quando eu for alterar os updates na issue #32

higton commented 5 years ago

Resolvi algumas duplicações na issue #32, mas depois que o código entrou na devel perecebi que as alterações que eu fiz acabou gerando outras duplicações :) Seria bom se algum EPS @mateusnr @Bumbleblo @BordaLorde disponibilizasse uma forma de ver o code climate por branches ou por PR

VictorJorgeFGA commented 5 years ago

Estarei resolvendo o resto das duplicações hoje.

VictorJorgeFGA commented 5 years ago

Exemplo de como refatorar o ActivedUSer

from abc import abstractmethod, ABC

class ManagerUser(graphene.Mutation):
    """Mutation from graphene for activating user"""

    user = graphene.Field(UserType)

    @abstractmethod
    def state(self):
        pass

    class Arguments:
        """Mutation arguments for activate a user"""
        user_email = graphene.String()

    def mutate(self, info, user_email):
        """Method to execute the mutation"""
        user = get_user_model().objects.get(email=user_email)
        user.is_active = self.state()
        user.save()
        return ActivateUser(user=user)

class ActivateUser(ManagerUser):

    def state(self):
        return True

class DesactivateUser(ManagerUser):

    def state(self)
        return False

Essa forma de resolver o problema não está funcionando, pois para usar o decorator abstractmethod, a classe deve herdar de ABC, o que está causando conflitos de metaclass


Código

class ManagerUser(ABC, graphene.Mutation):
    """Base mutation class to activate/deactivate user"""
    user = graphene.Field(UserType)

    @abstractmethod
    def activity_state(self):
        pass

    class Arguments:
        """Mutation arguments for activate a user"""
        user_email = graphene.String()

    def mutate(self, info, user_email):
        """Method to execute the mutation"""
        user = get_user_model().objects.get(email=user_email)
        user.is_active = self.activity_state()
        user.save()
        return user

class ActivateUser(ManagerUser):
    """Mutation from graphene for activating user"""
    def activity_state(self):
        return True

class DeactivateUser(ManagerUser):
    """Mutation from graphene for deactivating user"""
    def activity_state(self):
        return False
class ManagerUser(ABC, graphene.Mutation):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
VictorJorgeFGA commented 5 years ago

Dei uma vasculhada nas documentações do Graphene em busca de algo que permita um comportamento polimórfico. Depois de um tempo razoável pesquisando eu não achei nada explícito e simples que resolva o problema.

Porém, depois de entrar no código fonte do graphql-python encontrei uma maneira de simular o comportamento polimórfico e vencer a duplicação de código através de um atributo disponível na variável info presente nas mutations. Entretanto, haverá um acoplamento que pode vir a se tornar um peso pra futuras modificações.

Exemplo

import graphene
import json

class AbstractMutation(graphene.Mutation):
    class Arguments:
        pass

    test_return = graphene.String()

    def mutate(self, info, **kwargs):
        if info.field_name == 'foo':
            return_value = "YOU CALLED FOO"
        elif info.field_name == 'bar':
            return_value = "YOU CALLED BAR"

        return AbstractMutation(test_return=return_value)

class Foo(AbstractMutation):
    pass

class Bar(AbstractMutation):
    pass

class Mutation(graphene.ObjectType):
    foo = Foo.Field()
    bar = Bar.Field()

schema = graphene.Schema(query=Mutation)
result = schema.execute('''
{
    foo{
        testReturn
    }
}
'''
)

print(json.dumps(result.data))

result = schema.execute('''
{
    bar{
        testReturn
    }
}
'''
)

print(json.dumps(result.data))

Esse código produzirá um comportamento polimórfico baseado no nome da mutation.

Output

{"foo": {"testReturn": "YOU CALLED FOO"}}
{"bar": {"testReturn": "YOU CALLED BAR"}}