# -*- coding: utf-8 -*-
import six
from syncano.exceptions import SyncanoValueError
from .classes import Class
from .incentives import Script, ScriptEndpoint
[docs]class CallType(object):
"""
The type of the call object used in the custom socket;
"""
SCRIPT = 'script'
[docs]class DependencyType(object):
"""
The type of the dependency object used in the custom socket;
"""
SCRIPT = 'script'
CLASS = 'class'
[docs]class BaseCall(object):
"""
Base class for call object.
"""
call_type = None
def __init__(self, name, methods):
self.name = name
self.methods = methods
[docs] def to_dict(self):
if self.call_type is None:
raise SyncanoValueError('call_type not set.')
return {
'type': self.call_type,
'name': self.name,
'methods': self.methods
}
[docs]class ScriptCall(BaseCall):
"""
Script call object.
The JSON format is as follows (to_dict in the base class)::
{
'type': 'script',
'name': '<script_label>,
'methods': [<method_list>],
}
methods can be as follows:
* ['GET']
* ['*'] - which will do a call on every request method;
"""
call_type = CallType.SCRIPT
[docs]class Endpoint(object):
"""
The object which stores metadata about endpoints in custom socket;
The JSON format is as follows::
{
'<endpoint_name>': {
'calls': [
<list of JSON format of Calls objects>
]
}
}
"""
def __init__(self, name):
self.name = name
self.calls = []
[docs] def add_call(self, call):
self.calls.append(call)
[docs] def to_endpoint_data(self):
return {
self.name: {
'calls': [call.to_dict() for call in self.calls]
}
}
[docs]class BaseDependency(object):
"""
Base dependency object;
On the base of the fields attribute - the JSON format of the dependency is returned.
The fields are taken from the dependency object - which can be Script (supported now).
"""
fields = []
dependency_type = None
name = None
[docs] def to_dependency_data(self):
if self.dependency_type is None:
raise SyncanoValueError('dependency_type not set.')
dependency_data = {'type': self.dependency_type}
dependency_data.update(self.get_dependency_data())
return dependency_data
[docs] def get_name(self):
if self.name is not None:
return {'name': self.name}
return {'name': self.dependency_object.name}
[docs] def get_dependency_data(self):
raise NotImplementedError()
[docs] def create_from_raw_data(self, raw_data):
raise NotImplementedError()
def _build_dict(self, instance):
return {field_name: getattr(instance, field_name) for field_name in self.fields}
[docs]class ScriptDependency(BaseDependency):
"""
Script dependency object;
The JSON format is as follows::
{
'type': 'script',
'runtime_name': '<runtime name defined in RuntimeChoices>',
'source': '<source>',
'name': '<name>'
}
"""
dependency_type = DependencyType.SCRIPT
fields = [
'runtime_name',
'source'
]
def __init__(self, script_or_script_endpoint, name=None):
if not isinstance(script_or_script_endpoint, (Script, ScriptEndpoint)):
raise SyncanoValueError('Script or ScriptEndpoint expected.')
if isinstance(script_or_script_endpoint, Script) and not name:
raise SyncanoValueError('Name should be provided.')
self.dependency_object = script_or_script_endpoint
self.name = name
[docs] def get_dependency_data(self):
if isinstance(self.dependency_object, ScriptEndpoint):
script = Script.please.get(id=self.dependency_object.script,
instance_name=self.dependency_object.instance_name)
else:
script = self.dependency_object
dependency_data = self.get_name()
dependency_data.update(self._build_dict(script))
return dependency_data
@classmethod
[docs] def create_from_raw_data(cls, raw_data):
return cls(**{
'script_or_script_endpoint': Script(source=raw_data['source'], runtime_name=raw_data['runtime_name']),
'name': raw_data['name'],
})
[docs]class ClassDependency(BaseDependency):
"""
Class dependency object;
The JSON format is as follows::
{
'type': 'class',
'name': '<class_name>',
'schema': [
{"name": "f1", "type": "string"},
{"name": "f2", "type": "string"},
{"name": "f3", "type": "integer"}
],
}
"""
dependency_type = DependencyType.CLASS
fields = [
'name',
'schema'
]
def __init__(self, class_instance):
self.dependency_object = class_instance
self.name = class_instance.name
[docs] def get_dependency_data(self):
data_dict = self._build_dict(self.dependency_object)
data_dict['schema'] = data_dict['schema'].schema
return data_dict
@classmethod
[docs] def create_from_raw_data(cls, raw_data):
return cls(**{'class_instance': Class(**raw_data)})