Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
billyrrr committed Nov 2, 2020
1 parent 7fc0872 commit 29217c2
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 34 deletions.
31 changes: 21 additions & 10 deletions onto/attrs/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def data_key(self):
else:
return self.name

@property
def is_internal(self):
return not self.import_enabled and not self.export_enabled

def __init__(
self,
*,
Expand Down Expand Up @@ -477,20 +481,27 @@ def _make_field(self) -> fields.Field:
field_cls = fields.Embedded
return field_cls(**self._field_kwargs, attribute=self.name)

def __init__(self, many=_NA, obj_cls=_NA, **kwargs):
def __init__(self, type_cls=_NA, collection=_NA, **kwargs):

# if many == _NA:
# many = False
# self.many = many
# self._field_kwargs["many"] = self.many

if type_cls == _NA:
type_cls = None
# self.type_cls = obj_cls
# self._field_kwargs["obj_type"] = self.dm_cls

if collection == _NA:
collection = None
self.collection = collection

super().__init__(
type_cls = type_cls,
**kwargs
)

if many == _NA:
many = False
self.many = many
self._field_kwargs["many"] = self.many

if obj_cls == _NA:
obj_cls = None
self.dm_cls = obj_cls
self._field_kwargs["obj_type"] = self.dm_cls


class ObjectTypeAttribute(PropertyAttribute):
Expand Down
9 changes: 9 additions & 0 deletions onto/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@ def create_service(cls, svc_config):
celery_app = Celery('tasks',
broker='pyamqp://guest@localhost//')
return celery_app
elif service_type == 'authing':
user_pool_id = svc_config['user_pool_id']
secret = svc_config['secret'] # TODO: isolate side effect of assignment
from authing import Authing
authing = Authing({
"userPoolId": user_pool_id,
"secret": secret,
})
return authing
else:
raise ValueError

Expand Down
27 changes: 21 additions & 6 deletions onto/models/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import lru_cache
from typing import Iterable, Tuple

from onto.attrs import AttributeBase
Expand Down Expand Up @@ -71,26 +72,32 @@ def _graphql_field_from_attr(attr, input=False):
else:
field_base = graphql.GraphQLInputField

if hasattr(attr, 'collection') and attr.collection == list:
f = lambda ot: graphql.GraphQLList(ot)
else:
f = lambda ot: ot

from onto import attrs
if attr.__class__ is attrs.attribute.EmbeddedAttribute:
e_cls = attr.obj_type
e_cls = attr.type_cls
e_graphql = _graphql_object_type_from_attributed_class(e_cls)
field = field_base(
type_=e_graphql,
type_=f(e_graphql),
description=attr.doc
)
return attr.data_key, field
elif isinstance(attr, attrs.attribute.AttributeBase):
import graphql
field = field_base(
type_=_graphql_type_from_py(t=attr.type_cls),
type_=f(_graphql_type_from_py(t=attr.type_cls)),
description=attr.doc
)
return attr.data_key, field
else:
raise NotImplementedError


@lru_cache(maxsize=None) # Cached property
def _graphql_object_type_from_attributed_class(cls, input=False):
""" Make GraphQL schema from a class containing AttributeBase+ objects
Expand All @@ -104,16 +111,22 @@ def _graphql_object_type_from_attributed_class(cls, input=False):

fields = dict(
_graphql_field_from_attr(attr, input=input)
for key, attr in _collect_attrs(cls)
for key, attr in _collect_attrs(cls) if not attr.is_internal
)

if not input:
base = graphql.GraphQLObjectType
else:
base = graphql.GraphQLInputObjectType

type_name = cls.__name__

# TODO: maybe add
# if input:
# type_name += "Input"

graphql_object_type = base(
cls.__name__,
type_name,
fields=fields
)

Expand All @@ -123,10 +136,12 @@ def _graphql_object_type_from_attributed_class(cls, input=False):
def _collect_attrs(cls) -> Iterable[Tuple[str, AttributeBase]]:
"""
Collect all AttributeBase+ objects in the class and its ancestors.
TODO: debug empty iter of length 0
:param cls:
:return:
"""
for key in dir(cls):
if issubclass(getattr(cls, key).__class__, AttributeBase):
yield (key, getattr(cls, key))
attr = getattr(cls, key)
yield (key, attr)
63 changes: 48 additions & 15 deletions onto/sink/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,37 @@ def triggers(self):
def mediator_instance(self):
return self.parent()()

def _invoke_mediator(self, *args, func_name, **kwargs):
def _maybe_deserialize(self, val, annotated_type):
from onto.models.base import BaseRegisteredModel
if issubclass(annotated_type, BaseRegisteredModel):
return annotated_type.from_dict(val)
else:
return val

def _f_of_rule(self, func_name):
fname = self.protocol.fname_of(func_name)
if fname is None:
raise ValueError(
f"fail to locate {func_name}"
f" for {self.mediator_instance.__class__.__name__}"
)
f = getattr(self.mediator_instance, fname)
return f(*args, **kwargs)
return f

def _invoke_mediator(self, *args, func_name, **kwargs):
f = self._f_of_rule(func_name=func_name)

annotation_d = {
k: v
for k, v in self._parameters_for(f)
}

new_kwargs = {
k:self._maybe_deserialize(val=v, annotated_type=annotation_d[k])
for k, v in kwargs.items()
}

return f(*args, **new_kwargs)

def __init__(self, view_model_cls: Type[ViewModel], camelize=True, many=False):
"""
Expand All @@ -77,29 +99,40 @@ def __init__(self, view_model_cls: Type[ViewModel], camelize=True, many=False):
self.many = many
super().__init__()

def _param_to_graphql_arg(self, param: Parameter):
def _param_to_graphql_arg(self, annotated_type):
from onto.models.utils import _graphql_type_from_py
from graphql import GraphQLArgument, GraphQLInputObjectType
annotation = param.annotation
import inspect
if annotation is inspect._empty:
raise ValueError('parameter {param} is not annotated'
'for conversion to graphql argument')
# TODO: add notes about `typing.*` not supported
gql_field_cls = _graphql_type_from_py(annotation, input=True)
gql_field_cls = _graphql_type_from_py(annotated_type, input=True)
arg = GraphQLArgument(gql_field_cls) # TODO: set default_value
return arg

def _args_of(self, rule):
@staticmethod
def _parameters_for(f):

def _annotation_type_of(param):
annotation = param.annotation
import inspect
if annotation is inspect._empty:
raise ValueError(f'parameter {param} is not annotated'
'for conversion to graphql argument')
return annotation

from inspect import signature
fname = self.triggers.fname_of(rule)
f = getattr(self.parent(), fname)
sig = signature(f)
param_d = OrderedDict(sig.parameters.items())
param_d.popitem(last=False) # Pop self argument
# param_d.popitem(last=False) # Pop self argument
# NOTE: param_d.popitem(last=False) may not always pop self argument
for name, param in param_d.items():
yield name, self._param_to_graphql_arg(param)
yield name, _annotation_type_of(param)

def _args_of_f(self, f):
for name, annotated_type in self._parameters_for(f):
yield name, self._param_to_graphql_arg(annotated_type=annotated_type)

def _args_of(self, rule):
f = self._f_of_rule(func_name=rule)
return self._args_of_f(f=f)

op_type = None

Expand Down Expand Up @@ -132,7 +165,7 @@ class GraphQLSubscriptionSink(GraphQLSink):
op_type = 'Subscription'

def _register_op(self):
from gql import query, subscribe
from gql import subscribe
async def f(parent, info, **kwargs):
# Register topic
topic_name = self._invoke_mediator(func_name='add_topic', **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ apache-flink
couchdb

# Optional
couchbase

# couchbase
#
# Optional
leancloud

Expand Down
15 changes: 14 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
setuptools.setup(
name="onto",
# Beta release
version="0.0.1",
version="0.0.2a1",
author="Bill Rao",
author_email="billrao@me.com",
description="Build reactive back end with ease ",
Expand Down Expand Up @@ -55,6 +55,19 @@
"gitpython",
"ProxyTypes"
],
extras_require={
'firestore': [
'google-auth',
'google-api-python-client',
'firebase-admin>=3.0.0'
],
'flink': ['apache-flink'],
'couchdb': ['couchdb'],
'couchbase': ['couchbase'],
'leancloud': ['leancloud'],
'celery': ['celery'],
'jsonrpc': ['jsonrpcclient[requests]', 'Flask-JSONRPC']
}
# entry_points = {
# 'console_scripts': ['`onto`=scripts.deploy:deploy_all'],
# }
Expand Down

0 comments on commit 29217c2

Please sign in to comment.