Skip to content

Commit c0f75cb

Browse files
committed
[LIB-837] correct documentation; add possibility to read all endpoints; correct ScriptDependency to handle ScriptEndpoint; make Script a model field in ScriptEndpoint; overall fixes;
1 parent 5eca906 commit c0f75cb

File tree

8 files changed

+310
-81
lines changed

8 files changed

+310
-81
lines changed

docs/source/custom_sockets.rst

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,80 @@
44
Custom Sockets in Syncano
55
=========================
66

7-
``Syncano`` provides possibility of creating the custom sockets. It means that there's a possibility
8-
to define a very specific endpoints in syncano application and use them as normal api calls.
7+
``Syncano`` provides possibility of creating custom sockets. It means that there's a possibility
8+
to define a very specific endpoints in syncano application and use them as normal API calls.
99
Currently custom sockets allow only one dependency - script. This mean that on the backend side
10-
each time the api is called - the script is executed and result from this script is returned as a result of the
11-
api call.
10+
each time the API is called - the script is executed and result from this script is returned as a result of the
11+
API call.
1212

1313
Creating a custom socket
1414
------------------------
1515

16-
There are two methods of creating the custom socket. First: use the helpers objects defined in Python Libray.
17-
Second: use the raw format - this is described below.
18-
19-
To create a custom socket follow the steps::
16+
To create a custom socket follow these steps::
2017

2118
import syncano
2219
from syncano.models import CustomSocket, Endpoint, ScriptCall, ScriptDependency, RuntimeChoices
2320
from syncano.connection import Connection
2421

25-
custom_socket = CustomSocket(name='my_custom_socket') # this will create an object in place (do api call)
22+
# 1. Initialize the custom socket.
23+
custom_socket = CustomSocket(name='my_custom_socket') # this will create an object in place (do API call)
2624

27-
# define endpoints
28-
my_endpoint = Endpoint(name='my_endpoint') # again - no api call here
25+
# 2. Define endpoints.
26+
my_endpoint = Endpoint(name='my_endpoint') # again - no API call here
2927
my_endpoint.add_call(ScriptCall(name='custom_script'), methods=['GET'])
3028
my_endpoint.add_call(ScriptCall(name='another_custom_script'), methods=['POST'])
3129

3230
# explanation for the above lines:
3331
# The endpoint will be seen under `my_endpoint` name:
34-
# On this syncano api endpoint the above endpoint will be called (after custom socket creation)
32+
# On this syncano API endpoint the above endpoint will be called (after custom socket creation)
3533
# <host>://<api_version>/instances/<instance_name>/endpoints/sockets/my_endpoint/
36-
# On this syncano api endpoint the details of the defined endpoint will be returned
34+
# On this syncano API endpoint the details of the defined endpoint will be returned
3735
# <host>://<api_version>/instances/<instance_name>/sockets/my_custom_socket/endpoints/my_endpoint/
3836
# For the above endpoint - the two calls are defined, one uses GET method - the custom_script will be executed
3937
# there, second uses the POST method and then the another_custom_script will be called;
4038
# Currently only script are available for calls;
4139

42-
# After the creation of the endpoint, add them to custom_socket:
40+
# 3. After the creation of the endpoint, add them to custom_socket.
4341
custom_socket.add_endpoint(my_endpoint)
4442

45-
# define dependency now;
46-
# using a new script - defining new source code;
43+
# 4. Define dependency now.
44+
# 4.1 using a new script - defining new source code.
4745
custom_socket.add_dependency(
4846
ScriptDependency(
49-
Script(
50-
label='custom_script',
47+
name='custom_script'
48+
script=Script(
5149
runtime_name=RuntimeChoices.PYTHON_V5_0,
5250
source='print("custom_script")'
5351
)
5452
)
5553
)
56-
# using a existing script:
54+
# 4.2 using an existing script.
5755
another_custom_script = Script.please.get(id=2)
5856
custom_socket.add_dependency(
5957
ScriptDependency(
60-
another_custom_script
58+
name='another_custom_script',
59+
script=another_custom_script
6160
)
6261
)
6362

64-
# now it is time to publish custom_socket;
65-
custom_socket.publish() # this will do an api call and will create script;
63+
# 4.3 using an existing ScriptEndpoint.
64+
script_endpoint = ScriptEndpoint.please.get(name='script_endpoint_name')
65+
custom_socket.add_dependency(
66+
script_endpoint=script_endpoint
67+
)
68+
69+
# 5. Publish custom_socket.
70+
custom_socket.publish() # this will do an API call and will create script;
6671

6772
Some time is needed to setup the environment for this custom socket.
6873
There is possibility to check the custom socket status::
6974

75+
# Reload will refresh object using syncano API.
76+
custom_socket.reload()
7077
print(custom_socket.status)
7178
# and
7279
print(custom_socket.status_info)
7380

74-
# to reload object (read it again from syncano api) use:
75-
custom_socket.reload()
76-
77-
78-
7981
Updating the custom socket
8082
--------------------------
8183

@@ -103,8 +105,8 @@ To run custom socket use::
103105
result = custom_socket.run(method='GET', endpoint_name='my_endpoint')
104106

105107

106-
Read all endpoints
107-
------------------
108+
Read all endpoints in custom socket
109+
-----------------------------------
108110

109111
To get the all defined endpoints in custom socket run::
110112

@@ -114,27 +116,40 @@ To get the all defined endpoints in custom socket run::
114116
print(endpoint.name)
115117
print(endpoint.calls)
116118

117-
To run particular endpoint::
119+
To run a particular endpoint::
118120

119121
endpoint.run(method='GET')
120122
# or:
121123
endpoint.run(method='POST', data={'name': 'test_name'})
122124

123-
The data will be passed to the api call in the request body.
125+
The data will be passed to the API call in the request body.
126+
127+
Read all endpoints
128+
------------------
129+
130+
To get all endpoints that are defined in all custom sockets::
131+
132+
socket_endpoint_list = SocketEndpoint.get_all_endpoints()
133+
134+
Above code will return a list with SocketEndpoint objects. To run such endpoint, use::
135+
136+
socket_endpoint_list.run(method='GET')
137+
# or:
138+
socket_endpoint_list.run(method='POST', data={'custom_data': 1})
124139

125140
Custom sockets endpoints
126141
------------------------
127142

128-
Each custom socket is created from at least one endpoint. The endpoint is characterized by name and
129-
defined calls. Calls is characterized by name and methods. The name is a identification for dependency, eg.
130-
if it's equal to 'my_script' - the Script with label 'my_script' will be used (if exist and the source match),
131-
or new one will be created.
143+
Each custom socket requires to define at least one endpoint. The endpoint is defined by name and
144+
a list of calls. Each call is defined by a name and a list of methods. The name is a identification for dependency, eg.
145+
if it's equal to 'my_script' - the ScriptEndpoint with name 'my_script' will be used
146+
(if it exists and Script source and runtime matches) or a new one will be created.
132147
There's a special wildcard method: `methods=['*']` - this mean that any request with
133148
any method will be executed in this endpoint.
134149

135-
To add endpoint to the custom_socket use::
150+
To add an endpoint to the custom_socket use::
136151

137-
my_endpoint = Endpoint(name='my_endpoint') # again - no api call here
152+
my_endpoint = Endpoint(name='my_endpoint') # again - no API call here
138153
my_endpoint.add_call(ScriptCall(name='custom_script'), methods=['GET'])
139154
my_endpoint.add_call(ScriptCall(name='another_custom_script'), methods=['POST'])
140155

@@ -144,17 +159,17 @@ Custom socket dependency
144159
------------------------
145160

146161
Each custom socket has dependency - this is a meta information for endpoint: which resource
147-
should be used to return the api call results. The dependencies are bind to the endpoints call objects.
148-
Currently supported dependency in only script.
162+
should be used to return the API call results. The dependencies are bind to the endpoints call objects.
163+
Currently the only supported dependency is script.
149164

150165
**Using new script**
151166

152167
::
153168

154169
custom_socket.add_dependency(
155170
ScriptDependency(
156-
Script(
157-
label='custom_script',
171+
name='custom_script'
172+
script=Script(
158173
runtime_name=RuntimeChoices.PYTHON_V5_0,
159174
source='print("custom_script")'
160175
)
@@ -169,10 +184,19 @@ Currently supported dependency in only script.
169184
another_custom_script = Script.please.get(id=2)
170185
custom_socket.add_dependency(
171186
ScriptDependency(
172-
another_custom_script
187+
name='another_custom_script',
188+
script=another_custom_script
173189
)
174190
)
175191

192+
**Using defined script endpoint**
193+
194+
::
195+
196+
script_endpoint = ScriptEndpoint.please.get(name='script_endpoint_name')
197+
custom_socket.add_dependency(
198+
script_endpoint=script_endpoint
199+
)
176200

177201
Custom socket recheck
178202
---------------------
@@ -183,13 +207,14 @@ custom socket. To check the statuses use::
183207
print(custom_socket.status)
184208
print(custom_socket.status_info)
185209

186-
There is a possibility to re-check socket - this mean that if conditions are met - the socket will be
187-
`created` again and available to use - if not the error will be returned in status field.
210+
There is a possibility to re-check socket - this mean that if conditions are met - the socket endpoints and dependencies
211+
will be checked - and if some of them are missing (eg. mistake deletion), they will be created again.
212+
If the endpoints and dependencies do not met the criteria - the error will be returned in the status field.
188213

189214
Custom socket - raw format
190215
--------------------------
191216

192-
There is a possibility to create a custom socket from the raw JSON format::
217+
If you prefer raw JSON format for creating sockets, you can resort to use it in python library as well::::
193218

194219
CustomSocket.please.create(
195220
name='my_custom_socket_3',

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ def readme():
1111
version=__version__,
1212
description='Python Library for syncano.com api',
1313
long_description=readme(),
14-
author='Daniel Kopka',
15-
author_email='daniel.kopka@syncano.com',
14+
author='Syncano',
15+
author_email='support@syncano.io',
1616
url='http://syncano.com',
1717
packages=find_packages(exclude=['tests']),
1818
zip_safe=False,

syncano/models/custom_sockets.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,23 @@ def run(self, method='GET', data={}):
128128
connection = self._get_connection()
129129
if not self._validate_method(method):
130130
raise SyncanoValueError('Method: {} not specified in calls for this custom socket.'.format(method))
131-
132-
if method in ['GET', 'DELETE']:
131+
method = method.lower()
132+
if method in ['get', 'delete']:
133133
response = connection.request(method, endpoint_path)
134-
elif method in ['POST', 'PUT', 'PATCH']:
134+
elif method in ['post', 'put', 'patch']:
135135
response = connection.request(method, endpoint_path, data=data)
136136
else:
137137
raise SyncanoValueError('Method: {} not supported.'.format(method))
138138
return response
139139

140+
@classmethod
141+
def get_all_endpoints(cls):
142+
connection = cls._meta.connection
143+
all_endpoints_path = Instance._meta.resolve_endpoint('endpoints',
144+
{'name': cls.please.properties.get('instance_name')})
145+
response = connection.request('GET', all_endpoints_path)
146+
return [cls(**endpoint) for endpoint in response['objects']]
147+
140148
def _validate_method(self, method):
141149

142150
methods = []

0 commit comments

Comments
 (0)