Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
27087eb
Merge pull request #225 from Syncano/release-v5.3.0
opalczynski Jul 26, 2016
a03fd8c
Merge pull request #226 from Syncano/master
opalczynski Jul 26, 2016
90c4333
[LIB-821] add retry-after handling;
opalczynski Aug 9, 2016
3801a26
[LIB-821] correct isort issues;
opalczynski Aug 9, 2016
49fa010
Merge pull request #227 from Syncano/LIB-821
opalczynski Aug 9, 2016
12cda74
[LIB-837][WIP] working on custom sockets in LIB
opalczynski Aug 10, 2016
460006f
[LIB-837] Add missing docs about custom_sockets; move utils to anothe…
opalczynski Aug 11, 2016
5eca906
[LIB-837] add missing fields in doc string;
opalczynski Aug 11, 2016
cb5f0ab
[readme_changes] Some readme changes
23doors Aug 12, 2016
9a7c280
Merge pull request #229 from Syncano/readme_changes
23doors Aug 12, 2016
c0f75cb
[LIB-837] correct documentation; add possibility to read all endpoint…
opalczynski Aug 12, 2016
e108b5a
[LIB-837] Correct after tests;
opalczynski Aug 12, 2016
5eab464
[LIB-837] another portion of corrects;
opalczynski Aug 12, 2016
1afcd9f
[LIB-837] correct tests again;
opalczynski Aug 12, 2016
48eb08e
[LIB-837] change tests instead of doing a magic in ModelField;
opalczynski Aug 12, 2016
4e2ee33
Language updates
MariuszWisniewski Aug 12, 2016
fe52e7a
[ci skip] readme
MariuszWisniewski Aug 12, 2016
7bc974a
[ci skip] Endpoints readme update
MariuszWisniewski Aug 15, 2016
bc71ad1
[LIB-837] revert ModelField on script in script endpoint model;
opalczynski Aug 16, 2016
327a3fc
[LIB-837] correct data passing on run methods;
opalczynski Aug 16, 2016
d50344b
[LIB-837] correct custom socket behaviour;
opalczynski Aug 16, 2016
c2ffd3a
Merge branch 'LIB-837' of github.com:Syncano/syncano-python into LIB-837
opalczynski Aug 16, 2016
42e4373
[LIB-837] corrects after qa;
opalczynski Aug 16, 2016
04c5ef6
[LIB-837] corrects after qa;
opalczynski Aug 16, 2016
9f5adba
[LIB-837] correct docs examples, polish the tests;
opalczynski Aug 16, 2016
69f3a11
[LIB-837] remove default custom socket in setupclass;
opalczynski Aug 16, 2016
3d1f4dd
[LIB-837] remove default custom socket in setupclass;
opalczynski Aug 16, 2016
d982fd0
[LIB-837] final test correction;
opalczynski Aug 16, 2016
8662e42
Update language
devintyler Aug 16, 2016
2ff6c68
[LIB-819] - Add support for creating objects through DataEndpoint
ilu2112 Aug 18, 2016
0864163
[LIB-837] add possibility to directly point instance name when gettin…
opalczynski Aug 18, 2016
9246b98
[LIB-837] change interface: publish to install in custom socket context;
opalczynski Aug 19, 2016
31c51b9
Merge branch 'LIB-837' of github.com:Syncano/syncano-python into LIB-837
opalczynski Aug 19, 2016
14f6ff7
[LIB-837] add status badges to README
opalczynski Aug 19, 2016
2372986
[LIB-837] small changes after CORE change;
opalczynski Aug 22, 2016
515e50b
[LIB-837] correct SocketEndpoint behaviour (run mainly);
opalczynski Aug 22, 2016
16795dd
[LIB-837] correct run in CustomSocket;
opalczynski Aug 22, 2016
b8c252f
[LIB-837] add possiblity to install from url;
opalczynski Aug 23, 2016
3cf2465
[LIB-837] update documentation for installing socket from url;
opalczynski Aug 23, 2016
ef39be6
[LIB-837] fixes after qa;
opalczynski Aug 24, 2016
38e94ad
Merge pull request #230 from Syncano/LIB-819
opalczynski Aug 24, 2016
6ab2429
Merge pull request #228 from Syncano/LIB-837
opalczynski Aug 24, 2016
21ddeaf
[RELEASE v5.4] bump the version;
opalczynski Aug 24, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[LIB-837][WIP] working on custom sockets in LIB
  • Loading branch information
opalczynski committed Aug 11, 2016
commit 12cda74d7fe6260e84b87270fcccfe32f3d31b06
3 changes: 2 additions & 1 deletion syncano/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
from .geo import * # NOQA
from .backups import * # NOQA
from .hosting import * # NOQA
from .data_views import DataEndpoint as EndpointData # NOQA
from .data_views import DataEndpoint as EndpointData # NOQA
from .custom_sockets import * # NOQA
220 changes: 220 additions & 0 deletions syncano/models/custom_sockets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
from .base import Instance, Model
from . import fields

from syncano.exceptions import SyncanoValueError


class CallTypeE(object):
SCRIPT = 'script'


class DependencyTypeE(object):
SCRIPT = 'script'


class Call(object):

def __init__(self, name, methods, call_type=None):
call_type = call_type or CallTypeE.SCRIPT
self.type = call_type
self.name = name
self.methods = methods

def to_dict(self):
return {
'type': self.type,
'name': self.name,
'methods': self.methods
}


class Endpoint(object):

def __init__(self, name):
self.name = name
self.calls = []

def add_call(self, call):
self.calls.append(call)

def to_endpoint_data(self):
return {
self.name: {
'calls': [call.to_dict() for call in self.calls]
}
}


class BaseDependency(object):

fields = []
dependency_type = None
field_mapping = {}

def __init__(self, dependency_object):
self.dependency_object = dependency_object

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({field_name: getattr(
self.dependency_object,
self.field_mapping.get(field_name, field_name)
) for field_name in self.fields})
return dependency_data


class ScriptDependency(BaseDependency):
dependency_type = DependencyTypeE.SCRIPT
fields = [
'runtime_name',
'name',
'source'
]

field_mapping = {'name': 'label'}


class EndpointMetadataMixin(object):

def __init__(self, *args, **kwargs):
self._endpoints = []
super(EndpointMetadataMixin, self).__init__(*args, **kwargs)

def add_endpoint(self, endpoint):
self._endpoints.append(endpoint)

@property
def endpoints_data(self):
endpoints = {}
for endpoint in self._endpoints:
endpoints.update(endpoint.to_endpoint_data())
return endpoints


class DependencyMetadataMixin(object):

def __init__(self, *args, **kwargs):
self._dependencies = []
super(DependencyMetadataMixin, self).__init__(*args, **kwargs)

def add_dependency(self, depedency):
self._dependencies.append(depedency)

@property
def dependencies_data(self):
return [dependency.to_dependency_data() for dependency in self._dependencies]


class CustomSocket(EndpointMetadataMixin, DependencyMetadataMixin, Model):
"""
OO wrapper around instance custom sockets.

:ivar name: :class:`~syncano.models.fields.StringField`
:ivar endpoints: :class:`~syncano.models.fields.JSONField`
:ivar dependencies: :class:`~syncano.models.fields.JSONField`
:ivar metadata: :class:`~syncano.models.fields.JSONField`
:ivar links: :class:`~syncano.models.fields.LinksField`
"""

name = fields.StringField(max_length=64)
endpoints = fields.JSONField()
dependencies = fields.JSONField()
metadata = fields.JSONField(read_only=True, required=False)
links = fields.LinksField()

class Meta:
parent = Instance
endpoints = {
'detail': {
'methods': ['get', 'put', 'patch', 'delete'],
'path': '/sockets/{name}/',
},
'list': {
'methods': ['post', 'get'],
'path': '/sockets/',
}
}

def get_endpoints(self):
endpoints_path = self.links.endpoints
connection = self._get_connection()
response = connection.request('GET', endpoints_path)
endpoints = []
for endpoint in response['objects']:
endpoints.append(SocketEndpoint(**endpoint))
return endpoints

def run(self, method, endpoint_name, data={}):
endpoint = self._find_endpoint(endpoint_name)
return endpoint.run(method, data=data)

def _find_endpoint(self, endpoint_name):
endpoints = self.get_endpoints()
for endpoint in endpoints:
print(endpoint.name, endpoint_name)
if endpoint_name == endpoint.name:
return endpoint
raise SyncanoValueError('Endpoint {} not found.'.format(endpoint_name))

def publish(self):
created_socket = self.__class__.please.create(
name=self.name,
endpoints=self.endpoints_data,
dependencies=self.dependencies_data
)
raw_data = created_socket._raw_data
raw_data['links'] = raw_data['links'].links_dict
self.to_python(raw_data)
return self


class SocketEndpoint(Model):
"""
OO wrapper around endpoints defined in CustomSocket instance.

:ivar name: :class:`~syncano.models.fields.StringField`
:ivar calls: :class:`~syncano.models.fields.JSONField`
:ivar links: :class:`~syncano.models.fields.LinksField`
"""
name = fields.StringField(max_length=64, primary_key=True)
calls = fields.JSONField()
links = fields.LinksField()

class Meta:
parent = CustomSocket
endpoints = {
'detail': {
'methods': ['get'],
'path': '/endpoints/{name}/'
},
'list': {
'methods': ['get'],
'path': '/endpoints/'
}
}

def run(self, method='GET', data={}):
endpoint_path = self.links.endpoint
connection = self._get_connection()
if not self._validate_method(method):
raise SyncanoValueError('Method: {} not specified in calls for this custom socket.'.format(method))

if method == ['GET', 'DELETE']:
response = connection.request(method, endpoint_path)
elif method in ['POST', 'PUT', 'PATCH']:
response = connection.request(method, endpoint_path, data=data)
else:
raise SyncanoValueError('Method: {} not supported.'.format(method))
return response

def _validate_method(self, method):

methods = []
for call in self.calls:
methods.extend(call['methods'])
if '*' in methods or method in methods:
return True
return False
2 changes: 1 addition & 1 deletion syncano/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ def to_python(self, value):
return LinksWrapper(value, self.IGNORED_LINKS)

def to_native(self, value):
return value
return value.to_native()


class ModelField(Field):
Expand Down