From 1def71713b5b8c67f13952d57ee902f9a226bf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Thu, 25 Aug 2016 14:32:05 +0200 Subject: [PATCH 01/28] [CORE-1639] rework documentation structure; --- README.rst | 9 ++ docs/README.md | 125 +--------------------------- docs/custom_sockets/docs.md | 0 docs/custom_sockets/images/git.keep | 0 docs/migrations/docs.md | 123 +++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 121 deletions(-) create mode 100644 docs/custom_sockets/docs.md create mode 100644 docs/custom_sockets/images/git.keep create mode 100644 docs/migrations/docs.md diff --git a/README.rst b/README.rst index 9e5e9d4..f7b38d3 100644 --- a/README.rst +++ b/README.rst @@ -40,6 +40,11 @@ After when you want to override this setting use --instance-name in particular c syncano sync pull --instance-name new-instance-1234 +Documentation +------------- + +You can read detailed documentation `here `_. + Pulling your instance classes and scripts ----------------------------------------- @@ -164,6 +169,10 @@ This command will publish all files inside and will publish it to the The whole directory structure - will be mapped in Syncano Hosting. +Custom Sockets +-------------- + + Tips & Troubleshooting ---------------------- diff --git a/docs/README.md b/docs/README.md index 17a8002..25918c0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,123 +1,6 @@ -# How does the data transfer from Parse to Syncano work? +# Syncano CLI documentation -## Overview +Please click link below. -The provided tool uses both Syncano and Parse API. How does it work? - -1. Parse schemas are fetched and transferred to Syncano as classes. All field types are supported. -2. Data is transferred for each schema/class. This can be divided into following steps: - - 1. The call to the Parse API is made - to obtain 1000 objects of particular class; - 2. The conversion is made - the Object from Parse is transformed to the Syncano Data Object; - 3. The batch API call is made to the Syncano API - with 50 elements (API limitations); - 4. All the object relations are restored. - -Ad iv) This is the most challenging task. During the first and second step, all the information about relations are saved. The map of references are built -- which binds Parse objects with Syncano Data Objects -- and based on that the relations are restored. It's a time consuming process due to Parse API limitations and Syncano throttling functionality. More information on that can be found in the [data transfer](#data-transfer) section below. - -### Schemas to classes transfer - -**Name normalization** - -For each Parse schema, the Syncano Class schema is created. The class name and name of all fields are normalized. -The normalization process usually just makes a lowercase name. So when you transfer schema from Parse, where class name name is `SomeOutstandingClass`, in Syncano it will be called: `someoutstandingclass`. -The same applies to the fields. - -There are some exceptions. If Parse schema name starts from an underscore: `_`, the name will be changed to `internal_`. That's because Syncano does not support names which start with an underscore. - -**Created at and updated at** - -Syncano classes have two special fields `created_at` and `updated_at`, which store the dates indicating when object was created and last updated. The Parse has fields `createdAt` and `updatedAt` - which are used for the same purpose. - -Syncano `created_at` and `updated_at` fields are read-only, so it's impossible to transfer there values from Parse. -To resolve this, two additional fields are created on Syncano class: `original_createdat` and `original_updatedat` - -which have filter and order index added to them and can be used to find and sort data easily. -These fields store the original creation and update date from Parse (but update date will **NOT** be updated automatically next time). - -**objectId field** - -Syncano and Parse use different methods of object identification. Syncano uses integer ID field, Parse uses string ID field. -That means that simple one-to-one conversion isn't possible. When creating the Syncano schema, additional 'objectid' field is made, which stores the Parse string ID. This field has a filter index added to it, so can be used for filtering data in the Syncano class. - -**ACL** - -The ACL system in both Parse and Syncano is widely different - transferring ACL is **NOT** supported yet. -Currently we also are not able to provide any deadline when support for it will be added. - -**Field mapping** - -For the field types, the following map is used - the key is the Parse field type, the value is the Syncano field type: - -```python -class ClassProcessor(object): - map = { - 'Number': 'integer', - 'Date': 'datetime', - 'Boolean': 'boolean', - 'String': 'string', - 'Array': 'array', - 'Object': 'object', - 'Pointer': 'reference', - 'File': 'file', - 'GeoPoint': 'geopoint', - 'Relation': 'relation', - } -``` - -### Data transfer - -When Parse schemas are transferred as Syncano classes - the data migration process start. - -Class by class is processed: -* get the 1000 objects from Parse (max value of `limit` parameter) -* translate Parse objects to Syncano objects (and make a batch call with 10 Syncano Data Object, to avoid throttling); - -During this process for each class the reference map is made. This reference map stores the class name and connects Parse Object ID with Syncano Object ID. - -It is possible that this structure will use a lot of your local machine memory. - -Last step of data transfer is transferring the files. In previous steps we use batch calls when translating Parse objects into Syncano objects. Unfortunately it's not possible to send files using batch calls in Syncano, so during initial transfer files are not being moved. -What we do here, is we download those files localy to your machine and then we attach them to the right Syncano objects. As a result - all your Parse objects with files end up being Syncano objects with files with a bonus of files are now being stored on Syncano servers. - -### Relations rebuild - -For each Parse object that has a relation field a query is made -- to obtain the related objects. -Then those related objects are added to the Syncano Data Object. Relations are transformed as a whole. In Syncano, relation fields store IDs of the related objects like this: - -```json -books=[1, 2, 3] -``` - -which means that related books are those with ids: 1, 2 and 3. This is why the relations rebuilding process is the last one in the queue. - -Information about Syncano IDs must be known beforehand - we can't make a relation knowing only Parse IDs. - -Whole process can be very time consuming. First, because there's a need to query each parse object with relations about their related objects and second, because the Syncano free Builder account will throttles all requests when 15 request per second limit is reached. - -## Limitations - -The main limitations are: - -1. Syncano free Builder account throttling: 15 requests per second. -2. Parse `limit` parameter max value equal to 1000. -3. Parse API calls for obtaining the related objects - can not be obtained as a large set - only one by one. - -## Things you should know - -### Parse - -The only operations that are made to Parse API are **GET** calls. Your Parse Application is not affected after or -during the process of the data transfer. - -**Master Key** - -Your Parse Master Key - which is required by this tool - is stored locally on your machine, under the home directory in -`.syncano` file. It is used **ONLY** for communication with Parse. - -### Syncano - -Each time the transfer is run - data will be duplicated. It's because Syncano does not support the unique constraint - and -thus it's impossible to check if object with particular Parse ID is already present in the Syncano Data Objects. Before -re-running the data import process, it's a good idea to remove your instance or already trasferred classes, or use a new one in our tool configuration. - -Syncano credentials are stored in `.syncano` file under your home directory, and are used **ONLY** for communication -with Syncano services. +* [Migrations](migrations/docs.md) +* [Custom Sockets](custom_sockets/docs.md) \ No newline at end of file diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/custom_sockets/images/git.keep b/docs/custom_sockets/images/git.keep new file mode 100644 index 0000000..e69de29 diff --git a/docs/migrations/docs.md b/docs/migrations/docs.md new file mode 100644 index 0000000..17a8002 --- /dev/null +++ b/docs/migrations/docs.md @@ -0,0 +1,123 @@ +# How does the data transfer from Parse to Syncano work? + +## Overview + +The provided tool uses both Syncano and Parse API. How does it work? + +1. Parse schemas are fetched and transferred to Syncano as classes. All field types are supported. +2. Data is transferred for each schema/class. This can be divided into following steps: + + 1. The call to the Parse API is made - to obtain 1000 objects of particular class; + 2. The conversion is made - the Object from Parse is transformed to the Syncano Data Object; + 3. The batch API call is made to the Syncano API - with 50 elements (API limitations); + 4. All the object relations are restored. + +Ad iv) This is the most challenging task. During the first and second step, all the information about relations are saved. The map of references are built -- which binds Parse objects with Syncano Data Objects -- and based on that the relations are restored. It's a time consuming process due to Parse API limitations and Syncano throttling functionality. More information on that can be found in the [data transfer](#data-transfer) section below. + +### Schemas to classes transfer + +**Name normalization** + +For each Parse schema, the Syncano Class schema is created. The class name and name of all fields are normalized. +The normalization process usually just makes a lowercase name. So when you transfer schema from Parse, where class name name is `SomeOutstandingClass`, in Syncano it will be called: `someoutstandingclass`. +The same applies to the fields. + +There are some exceptions. If Parse schema name starts from an underscore: `_`, the name will be changed to `internal_`. That's because Syncano does not support names which start with an underscore. + +**Created at and updated at** + +Syncano classes have two special fields `created_at` and `updated_at`, which store the dates indicating when object was created and last updated. The Parse has fields `createdAt` and `updatedAt` - which are used for the same purpose. + +Syncano `created_at` and `updated_at` fields are read-only, so it's impossible to transfer there values from Parse. +To resolve this, two additional fields are created on Syncano class: `original_createdat` and `original_updatedat` - +which have filter and order index added to them and can be used to find and sort data easily. +These fields store the original creation and update date from Parse (but update date will **NOT** be updated automatically next time). + +**objectId field** + +Syncano and Parse use different methods of object identification. Syncano uses integer ID field, Parse uses string ID field. +That means that simple one-to-one conversion isn't possible. When creating the Syncano schema, additional 'objectid' field is made, which stores the Parse string ID. This field has a filter index added to it, so can be used for filtering data in the Syncano class. + +**ACL** + +The ACL system in both Parse and Syncano is widely different - transferring ACL is **NOT** supported yet. +Currently we also are not able to provide any deadline when support for it will be added. + +**Field mapping** + +For the field types, the following map is used - the key is the Parse field type, the value is the Syncano field type: + +```python +class ClassProcessor(object): + map = { + 'Number': 'integer', + 'Date': 'datetime', + 'Boolean': 'boolean', + 'String': 'string', + 'Array': 'array', + 'Object': 'object', + 'Pointer': 'reference', + 'File': 'file', + 'GeoPoint': 'geopoint', + 'Relation': 'relation', + } +``` + +### Data transfer + +When Parse schemas are transferred as Syncano classes - the data migration process start. + +Class by class is processed: +* get the 1000 objects from Parse (max value of `limit` parameter) +* translate Parse objects to Syncano objects (and make a batch call with 10 Syncano Data Object, to avoid throttling); + +During this process for each class the reference map is made. This reference map stores the class name and connects Parse Object ID with Syncano Object ID. + +It is possible that this structure will use a lot of your local machine memory. + +Last step of data transfer is transferring the files. In previous steps we use batch calls when translating Parse objects into Syncano objects. Unfortunately it's not possible to send files using batch calls in Syncano, so during initial transfer files are not being moved. +What we do here, is we download those files localy to your machine and then we attach them to the right Syncano objects. As a result - all your Parse objects with files end up being Syncano objects with files with a bonus of files are now being stored on Syncano servers. + +### Relations rebuild + +For each Parse object that has a relation field a query is made -- to obtain the related objects. +Then those related objects are added to the Syncano Data Object. Relations are transformed as a whole. In Syncano, relation fields store IDs of the related objects like this: + +```json +books=[1, 2, 3] +``` + +which means that related books are those with ids: 1, 2 and 3. This is why the relations rebuilding process is the last one in the queue. + +Information about Syncano IDs must be known beforehand - we can't make a relation knowing only Parse IDs. + +Whole process can be very time consuming. First, because there's a need to query each parse object with relations about their related objects and second, because the Syncano free Builder account will throttles all requests when 15 request per second limit is reached. + +## Limitations + +The main limitations are: + +1. Syncano free Builder account throttling: 15 requests per second. +2. Parse `limit` parameter max value equal to 1000. +3. Parse API calls for obtaining the related objects - can not be obtained as a large set - only one by one. + +## Things you should know + +### Parse + +The only operations that are made to Parse API are **GET** calls. Your Parse Application is not affected after or +during the process of the data transfer. + +**Master Key** + +Your Parse Master Key - which is required by this tool - is stored locally on your machine, under the home directory in +`.syncano` file. It is used **ONLY** for communication with Parse. + +### Syncano + +Each time the transfer is run - data will be duplicated. It's because Syncano does not support the unique constraint - and +thus it's impossible to check if object with particular Parse ID is already present in the Syncano Data Objects. Before +re-running the data import process, it's a good idea to remove your instance or already trasferred classes, or use a new one in our tool configuration. + +Syncano credentials are stored in `.syncano` file under your home directory, and are used **ONLY** for communication +with Syncano services. From 3fa7f56c00594cc245b115097bbfd26b934dc11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Thu, 25 Aug 2016 14:35:39 +0200 Subject: [PATCH 02/28] [CORE-1639] rework documentation structure; --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f7b38d3..441828d 100644 --- a/README.rst +++ b/README.rst @@ -43,7 +43,7 @@ After when you want to override this setting use --instance-name in particular c Documentation ------------- -You can read detailed documentation `here `_. +You can read detailed documentation `here `_. Pulling your instance classes and scripts ----------------------------------------- From be959b3da06e5004a678797a7f143e87c7d76575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Thu, 25 Aug 2016 14:42:13 +0200 Subject: [PATCH 03/28] [CORE-1639] custom socket documentation work on; --- docs/custom_sockets/docs.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md index e69de29..3689ffd 100644 --- a/docs/custom_sockets/docs.md +++ b/docs/custom_sockets/docs.md @@ -0,0 +1,37 @@ +# Syncano Custom Sockets + +## YML file structure + + name: my_tweet + description: Twitter integration + author: + name: Maciek + email: maciek@synano.com + icon: + name: icon_name + color: red + endpoints: + my_endpoint_1: + script: script_endpoint_1 + + my_endpoint_2: + template: template_name + cache: cache_key + POST: + script: script_endpoint_2 + GET: + script: script_endpoint_3 + + dependencies: + scripts: + script_endpoint_1: + runtime_name: python_library_v5.0 + file: scripts/script1.py + + script_endpoint_2: + runtime_name: python_library_v5.0 + file: scripts/script2.py + + script_endpoint_3: + runtime_name: python_library_v5.0 + file: scripts/script3.py From d33767410365557772d78be1a333b8f4a23b6662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Thu, 25 Aug 2016 14:46:07 +0200 Subject: [PATCH 04/28] [CORE-1639] custom socket documentation work on; --- docs/custom_sockets/docs.md | 6 ++++++ docs/custom_sockets/examples/advanced.md | 13 +++++++++++++ docs/custom_sockets/examples/hello_world.md | 13 +++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 docs/custom_sockets/examples/advanced.md create mode 100644 docs/custom_sockets/examples/hello_world.md diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md index 3689ffd..ea79054 100644 --- a/docs/custom_sockets/docs.md +++ b/docs/custom_sockets/docs.md @@ -35,3 +35,9 @@ script_endpoint_3: runtime_name: python_library_v5.0 file: scripts/script3.py + + +## Custom Socket examples + +* ['HelloWorld' example](examples/hello_world.md) +* [Advanced example: ](examples/advanced.md) \ No newline at end of file diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md new file mode 100644 index 0000000..e8cf184 --- /dev/null +++ b/docs/custom_sockets/examples/advanced.md @@ -0,0 +1,13 @@ +# Adanced Custom Socket example + +## Abstract + +## YML definition + +## Scripts definition + +## Custom Socket directory structure + +## Pulling everything together + +## Summary diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md new file mode 100644 index 0000000..4bde254 --- /dev/null +++ b/docs/custom_sockets/examples/hello_world.md @@ -0,0 +1,13 @@ +# HelloWorld example + +## Abstract + +## YML definition + +## Scripts definition + +## Custom Socket directory structure + +## Pulling everything together + +## Summary \ No newline at end of file From 54de00e703adacc2eac1c801fff06314bc849602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Thu, 25 Aug 2016 15:42:08 +0200 Subject: [PATCH 05/28] [CORE-1639] custom socket documentation work on; --- docs/README.md | 17 ++++- docs/custom_sockets/docs.md | 76 +++++++++++++++++--- docs/custom_sockets/examples/advanced.md | 5 ++ docs/custom_sockets/examples/hello_world.md | 5 ++ docs/custom_sockets/images/tree_socket.png | Bin 0 -> 3275 bytes 5 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 docs/custom_sockets/images/tree_socket.png diff --git a/docs/README.md b/docs/README.md index 25918c0..5ed773c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,17 @@ # Syncano CLI documentation -Please click link below. +## Migrations + +Migration allow to transfer data from Parse to Syncano. Read the following carefully to understand possibilities and +limitations. + +[Migrations](migrations/docs.md) + +## Custom Sockets + +Custom Sockets are powerful Syncano solution which allows to customize endpoints behaviour. Custom Sockets can be used +to provide integration with other applications or to define some custom endpoints for eg.: password reset. Custom +Sockets are build on the top of the others Syncano solution - like Script Endpoints. + +[Custom Sockets](custom_sockets/docs.md) -* [Migrations](migrations/docs.md) -* [Custom Sockets](custom_sockets/docs.md) \ No newline at end of file diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md index ea79054..11d8061 100644 --- a/docs/custom_sockets/docs.md +++ b/docs/custom_sockets/docs.md @@ -1,12 +1,12 @@ # Syncano Custom Sockets -## YML file structure +## YAML file structure (socket.yml) - name: my_tweet - description: Twitter integration + name: my_integration + description: Example integration author: - name: Maciek - email: maciek@synano.com + name: Sebastian + email: sebastian@syncano.com icon: name: icon_name color: red @@ -15,8 +15,6 @@ script: script_endpoint_1 my_endpoint_2: - template: template_name - cache: cache_key POST: script: script_endpoint_2 GET: @@ -36,8 +34,70 @@ runtime_name: python_library_v5.0 file: scripts/script3.py +### YAML file structure explanation + +* `name` is the name of the new Custom Socket - this should be unique; +* `description` is the description of the Custom Socket - allows to easily tell what custom socket do; +* `author` is a metadata information about Custom Socket author; Under the hood: all fields that are not in list: +`name`, `description`, `endpoints`, `dependencies` can be found in `metadata` field on Custom Socket in Syncano Dasboard. +* `icon` is a metadata information about Custom Socket - just stores the used icon name and its color - for display in +Syncano Dasboard. +* `endpoints` - definition of the endpoints in Custom Socket; Currently supported endpoints can be of type `script`. + + Consider the example: + + my_endpoint_1: + script: script_endpoint_1 + + In above YAML snippet - the `my_endpoint_1` is an endpoint name - this will be used in url path; the `script` is + a type of the endpoint; and `script_endpoint_1` is a dependency name which will be called when endpoint + `my_endpoint_1` will be requested; In above example the http methods use wildcard - so no matter what http method + will be used - the script endpoints `script_endpoint_1` will be called; + + Consider yet another example: + + my_endpoint_2: + POST: + script: script_endpoint_2 + GET: + script: script_endpoint_3 + + In above YAML snippet - the `my_endpoint_2` is an endpoint name. The difference is that - when GET http method will + be used the script endpoint `script_endpoint_3` will be ran. When POST http method will be used - the script + endpoint `script_endpoint_2` will be ran. + + Currently supported type of endpoint are only `script` - which run script endpoints under the hood, + but we are working to add more integrations. + +* `dependencies` - definition of the dependencies for the Custom Socket. Dependencies define the dependency object +which will be called when endpoint will be requested. + + Consider the example: + + scripts: + script_endpoint_1: + runtime_name: python_library_v5.0 + file: scripts/script1.py + + The above YML snippet defines one dependency of type script (under the `scripts` special word). The name of the + dependency is `script_endpoint_1` - and this is important, because it is a connecting point with an endpoint. + the `runtime_name` is a runtime used in a script, and the `file` stores the source code that will be executed. + It should be `noted` that when defining Custom Script some basic directory structure should be fulfilled - for + better work organization. It's desired to store scripts under the scripts directory - this is why filename + is a relative path: `scripts/script1.py`. Of course this can be omitted - and flat structure can be used. + + +## Custom Socket directory structure + +Below is a sample Custom Socket structure for the above YAML definition: + +![](images/tree_socket.png) + +The `socket.yml` file stores the YAML definition mentioned above; The `scripts` directory stores all scripts source +code used in `script` dependency type. + ## Custom Socket examples * ['HelloWorld' example](examples/hello_world.md) -* [Advanced example: ](examples/advanced.md) \ No newline at end of file +* [Advanced example: provide title here](examples/advanced.md) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index e8cf184..727fbce 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -2,6 +2,11 @@ ## Abstract +## Repository link + +The whole example can be found under: [Syncano/custom-socket-advanced](https://example.com) +This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here + ## YML definition ## Scripts definition diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index 4bde254..4ef93be 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -2,6 +2,11 @@ ## Abstract +## Repository link + +The whole example can be found under: [Syncano/custom-socket-hello-world](https://example.com) +This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here + ## YML definition ## Scripts definition diff --git a/docs/custom_sockets/images/tree_socket.png b/docs/custom_sockets/images/tree_socket.png new file mode 100644 index 0000000000000000000000000000000000000000..bf566daa362fe36789d6dba82e93c804d81f50c1 GIT binary patch literal 3275 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 Awg3PC literal 0 HcmV?d00001 From d376a9cce4d88631bd8ea9385afc701e5a878d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Fri, 26 Aug 2016 13:13:22 +0200 Subject: [PATCH 06/28] [CORE-1639] working on CLI Custom Socket documentation; --- docs/custom_sockets/examples/advanced.md | 4 +- docs/custom_sockets/examples/hello_world.md | 165 +++++++++++++++++- docs/custom_sockets/images/hello_world.png | Bin 0 -> 10473 bytes docs/custom_sockets/images/project_struct.png | Bin 0 -> 9187 bytes syncano_cli/custom_sockets/command.py | 2 +- 5 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 docs/custom_sockets/images/hello_world.png create mode 100644 docs/custom_sockets/images/project_struct.png diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index 727fbce..b2a7cf8 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -4,9 +4,11 @@ ## Repository link -The whole example can be found under: [Syncano/custom-socket-advanced](https://example.com) +The whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example) This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here +## Prerequisites + ## YML definition ## Scripts definition diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index 4ef93be..a244d89 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -2,17 +2,178 @@ ## Abstract +In this example the simple Custom Socket will be created. The idea is to create an endpoint which will return +a `Hello world` message. + ## Repository link -The whole example can be found under: [Syncano/custom-socket-hello-world](https://example.com) +The whole example can be found under: [Syncano/custom-socket-hello-world](https://github.com/Syncano/custom-socket-hello-world) This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here +## Prerequisites + +1. Syncano Account - Create one [here](https://www.syncano.io/). +2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. +3. Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. + + > Note: + > It is nice to use virtualenv to separate your tools: `sudo pip install virtualenv` + > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` + > Install Syncano CLI: `pip install syncano_cli>=0.5` + +4. Your favourite editor. + ## YML definition + name: hello_world + author: + name: Info + email: info@synano.com + description: Hello World example + endpoints: + hello_endpoint: + script: hello_world + + dependencies: + scripts: + hello_world: + runtime_name: python_library_v5.0 + file: scripts/hello_world.py + +The above YAML definition will store definition of the new Custom Socket with name `hello_world`. It defines one endpoint: +`hello_endpoint` with one dependency: `hello_world` script. In my favourite editor the project look as follows: + +![](../images/project_struct.png) + ## Scripts definition +The script (`scripts/hello_world.py`) consist of a few lines: + + content = """ + + + + Hello world! + + + + Hello World! + + + + """ + + set_response(HttpResponse(status_code=200, content=content, content_type='text/html')) + +The above code executed in Syncano will return a valid html response with `Hellow World!` message inside. +The `set_response` is a function which allow to return custom response from the script. + ## Custom Socket directory structure +As can be seen in the example above the basic structure of Custom Socket is: + + . + ├── scripts + │   └── hello_world.py + └── socket.yml + +The `socket.yml` file stores YAML definition of the Custom Socket, and under `scripts` directory there a definition +of Custom Socket dependencies (currently of type `script`). + ## Pulling everything together -## Summary \ No newline at end of file +### Steps: + +1. Assuming that you have Syncano CLI installed, do a login: `syncano login --instance-name your-instance-name` + In my case it is: + + syncano login --instance-name patient-resonance-4283 + + Next you will see the prompt for `username` and `password`; Fill it. + +2. There are two ways of installing Custom Socket - one is using your local files and the second is to use a url. + + To install Custom Socket from url do: + + syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-hello-world/master/socket.yml --name hello_world + + In such scenario - you do not need even clone the repository to your local machine. The name here is neede - because + under the hood empty Custom Socket is created - and code fetch from repository is done asynchronously in second + step. + + To install Custom Socket from local files do: + + syncano sockets install + + In my case it is: + + syncano sockets install ../syncano_scripts/repos/custom-socket-hello-world/ + + So you need to point to the parent directory of your `socket.yml` definition. + +3. Try a newly created Custom Socket: + + To list a Custom Sockets, do: + + syncano sockets list + + In the output you should find: + + - socket: + info: '' + name: hello_world + status: ok + + This mean that Custom Socket hello_world was created successfuly - the status is `ok`. In any other case you will see + here and `error` and detailed information in `info` - what was wrong. + + Now list the defined endpoints: + + syncano sockets list endpoints + + In the output you should find: + + - endpoint: + methods: + - POST + - PUT + - PATCH + - GET + - DELETE + name: hello_world/hello_endpoint + path: /v1.1/instances/your-instance-name/endpoints/sockets/hello_world/hello_endpoint/ + +4. Run the endpoint defined in Custom Socket: + + syncano sockets run hello_world/hello_endpoint + + You should see in the output raw html file: + + + + + Hello world! + + + + Hello World! + + + + + Lets see if output can be seen in the browser: + Go to: `https://api.syncano.io/v1.1/instances/your-instance-name/endpoints/sockets/hello_world/hello_endpoint/?api_key=your_api_key` + We defined the endpoint to handle GET http method. + + In my case: + + ![](../images/hello_world.png) + +5. To delete Custom Socket do: + + syncano sockets delete hello_world + +## Summary + +Hope this will help. If you have any question or problems do no hesitate to contact me: sebastian.opalczynski@syncano.com +Also I am available on the Syncano slack community: http://syncano-community.github.io/slack-invite/ diff --git a/docs/custom_sockets/images/hello_world.png b/docs/custom_sockets/images/hello_world.png new file mode 100644 index 0000000000000000000000000000000000000000..54ceea3010b91defc58883753d8323815ce289e2 GIT binary patch literal 10473 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 +A5Gqt@?3@l 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 Date: Fri, 26 Aug 2016 13:21:13 +0200 Subject: [PATCH 07/28] [CORE-1639] correct main README --- README.rst | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/README.rst b/README.rst index 441828d..e1431ea 100644 --- a/README.rst +++ b/README.rst @@ -172,6 +172,55 @@ The whole directory structure - will be mapped in Syncano Hosting. Custom Sockets -------------- +The commands available for Custom Sockets are (read the detailed docs about Custom Sockets if you want to know +`more `_): + +To install Custom Socket from local files:: + + syncano sockets install /path/to/dir + +To install Custom Socket from ulr:: + + syncano sockets install https://... + +List all Custom Sockets:: + + syncano sockets list + +List all defined endpoints (for all Custom Sockets):: + + syncano sockets list endpoints + +Display the Custom Socket details:: + + syncano sockets details socket_name + +Deletes the Custom Socket:: + + syncano sockets delete socket_name + +Create a template from template stored in Syncano CLI:: + + syncano sockets template /path/to/output_dir + +Create a template from a existing Custom Socket:: + + syncano sockets template /path/to/out --socket socket_name + +Run endpoint defined in Custom Socket:: + + syncano sockets run socket_name/endpoint_name + +Run endpoint providing the POST data:: + + syncano sockets run socket_name/my_endpoint_12 POST --data '{"raz": 1}' + +In all of the above cases you can defined an option:: + + --instance-name my_instance_name + +Which override the default used instance (in syncano login --instance-name my_other_instance) + Tips & Troubleshooting ---------------------- From dc90f8f99b3f943241e9363012b6dc257d22ec13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Fri, 26 Aug 2016 13:23:56 +0200 Subject: [PATCH 08/28] [CORE-1639] correct html template formatting; --- docs/custom_sockets/examples/hello_world.md | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index a244d89..fa6e226 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -52,14 +52,13 @@ The script (`scripts/hello_world.py`) consist of a few lines: content = """ - - Hello world! - - - - Hello World! - + + Hello world! + + + Hello World! + """ @@ -151,14 +150,13 @@ of Custom Socket dependencies (currently of type `script`). - - Hello world! - - - - Hello World! - + + Hello world! + + + Hello World! + Lets see if output can be seen in the browser: From fe6851abc2252d2d1b689a124566c2b21c9b702e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Fri, 26 Aug 2016 15:09:51 +0200 Subject: [PATCH 09/28] [CORE-1639] add advanced socket example; --- docs/custom_sockets/examples/advanced.md | 256 ++++++++++++++++++ docs/custom_sockets/examples/hello_world.md | 9 +- docs/custom_sockets/images/git.keep | 0 .../images/project_struct_adv.png | Bin 0 -> 10340 bytes 4 files changed, 261 insertions(+), 4 deletions(-) delete mode 100644 docs/custom_sockets/images/git.keep create mode 100644 docs/custom_sockets/images/project_struct_adv.png diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index b2a7cf8..9a8aa24 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -2,6 +2,10 @@ ## Abstract +In this advanced example the integration with Mailgun will be made (https://mailgun.com/). The mailgun sandbox environment +will be used. It allows to send 300 mails per day - so it should be enough. In this example two endpoints in Custom Socket +will be implemented - one for sending emails, and second - to obtain some basic statistics. + ## Repository link The whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example) @@ -9,12 +13,264 @@ This can be installed in Syncano instance using the install from url functionali ## Prerequisites +1. Syncano Account - Create one [here](https://www.syncano.io/). +2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. If you want to edit + files locally. +3. Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. + + > Note: + > It is nice to use virtualenv to separate your tools: `sudo pip install virtualenv` + > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` + > Install Syncano CLI: `pip install syncano_cli>=0.5` + +4. Your favourite text editor. + ## YML definition + name: mailgun_integration + description: An advanced example of Custom Socket - mailgun integration. + author: + name: Info at Syncano + email: info@syncano.com + endpoints: + send_mail: + POST: + script: send_mail + + get_stats: + GET: + script: get_stats + + dependencies: + scripts: + send_mail: + runtime_name: python_library_v5.0 + file: scripts/send_mail.py + + get_stats: + runtime_name: python_library_v5.0 + file: scripts/get_stats.py + +The above YAML definition defines a one Custom Socket with two endpoints: one for send email: `send_mail` with POST +http method (we want to pass here some basic information about email: to who it should be send, what subject should be used +and what text should be in the email itself). The second endpoint is for obtaining basic stats from Mailgun service. + +There're also two `script` dependencies defined. + ## Scripts definition +### scripts/send_mail.py + + import requests + import json + + api_key = CONFIG.get('mailgun_api_key') + + to_email = ARGS.get('to_email') + subject = ARGS.get('subject') + email_body = ARGS.get('email_body') + + response = requests.post( + "https://api.mailgun.net/v3/sandboxa8ccfb01296d4b19bace47fb8102d130.mailgun.org/messages", + auth=("api", api_key), + data={ + "from": "Mailgun Sandbox ", + "to": to_email, + "subject": subject, + "text": email_body + } + ) + + if response.status_code == 200: + success_content = json.dumps( + { + 'status_code': 200, + 'info': u'Mail successfully send to {}'.format(to_email) + } + ) + set_response(HttpResponse(status_code=200, content=success_content, content_type='application/json')) + else: + fail_content = json.dumps( + { + 'status_code': response.status_code, + 'info': response.text + } + ) + set_response(HttpResponse(status_code=400, content=fail_content, content_type='application/json')) + +The above script will send a request to the Mailgun service - and this service will send an email to user. +It's worth to note the `CONFIG` variable - it's a Instance global config map - you can define its content in the +Syncano Dasboard under the `Global Config` menu or using Syncano Libraries - more can be found at +[docs.](http://docs.syncano.io/docs/snippets-scripts#section-global-config-dictionary) + +### scripts/get_stats.py + + import requests + + api_key = CONFIG.get('mailgun_api_key') + + response = requests.get( + "https://api.mailgun.net/v3/sandboxa8ccfb01296d4b19bace47fb8102d130.mailgun.org/stats/total", + auth=("api", api_key), + params={ + "event": ["accepted", "delivered", "failed"], + "duration": "1m"} + ) + + if response.status_code == 200: + set_response(HttpResponse(status_code=200, content=response.text, content_type='application/json')) + else: + set_response(HttpResponse(status_code=400, content=response.text, content_type='application/json')) + +Above script will work as a proxy to the Mailgun service - will send a request about stats and passes the results as +a response. + + ## Custom Socket directory structure +The directory structure in my favourite editors looks like this: + +![](../images/project_struct_adv.png) + +or in tree format: + + . + ├── scripts + │   ├── get_stats.py + │   └── send_mail.py + └── socket.yml + + ## Pulling everything together +### Steps: + +1. Assuming that you have Syncano CLI installed, do a login: `syncano login --instance-name your-instance-name` + In my case it is: + + syncano login --instance-name patient-resonance-4283 + + Next you will see the prompt for `username` and `password`; Provide it. + +2. There are two ways of installing Custom Socket - one is using your local files and the second is to use a url. + + To install Custom Socket from url do: + + syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-advanced-example/master/socket.yml --name mailgun_integration + + In such scenario - you do not need even clone the repository to your local machine. The name here is needed - because + under the hood empty Custom Socket is created - and code fetch from repository is done asynchronously in second + step. + + To install Custom Socket from local files do: + + syncano sockets install + + In my case it is: + + syncano sockets install ../syncano_scripts/repos/custom-socket-advanced-example/ + +3. Try a newly created Custom Socket: + + To list a Custom Sockets, do: + + syncano sockets list + + In the output you should find: + + - socket: + info: '' + name: mailgun_integration + status: ok + + This mean that Custom Socket hello_world was created successfuly - the status is `ok`. In any other case you will see + here and `error` and detailed information in `info` - what was wrong. + + Now list the defined endpoints: + + syncano sockets list endpoints + + In the output you should find: + + - endpoint: + methods: + - GET + name: mailgun_integration/get_stats + path: /v1.1/instances/patient-resonance-4283/endpoints/sockets/mailgun_integration/get_stats/ + - endpoint: + methods: + - POST + name: mailgun_integration/send_mail + path: /v1.1/instances/patient-resonance-4283/endpoints/sockets/mailgun_integration/send_mail/ + +4. Before you run an endpoints - be sure that you have a Mailgun `api_key` in your instance Global Config. See the +`send_mail.py` description for more details. + +5. Run the endpoint defined in Custom Socket: + + First run the stats endpoint - as it is easier, because it is simple GET and no arguments are required. + + syncano sockets run mailgun_integration/get_stats + + In the output you should see something like this (probably not formatted): + + { + "stats": [ + { + "delivered": { + "smtp": 5, + "total": 5, + "http": 0 + }, + "accepted": { + "outgoing": 5, + "total": 5, + "incoming": 0 + }, + "time": "Mon, 01 Aug 2016 00:00:00 UTC", + "failed": { + "permanent": { + "suppress-complaint": 0, + "suppress-bounce": 0, + "total": 0, + "bounce": 0, + "suppress-unsubscribe": 0 + }, + "temporary": { + "espblock": 0 + } + } + } + ], + "end": "Mon, 01 Aug 2016 00:00:00 UTC", + "resolution": "month", + "start": "Mon, 01 Aug 2016 00:00:00 UTC" + } + + The above response is one-to-one to the response provided by Mailgun. + + **Let send a mail now** + + Run: + + syncano sockets run mailgun_integration/send_mail POST --data '{"subject": "CustomSocket MailGun test", "to_email": "FirstName LastName ", "email_body": "It is nice to create Custom Sockets!"}' + + Do not forget to change email in JSON data. + + This should return: + + { + u'info': u'Mail successfully send to {to_email_value}', + u'status_code': 200 + } + + You can now call stats again and see if any changes appeared. + +6. To delete Custom Socket do: + + syncano sockets delete mailgun_integration + ## Summary + +Hope this will help. If you have any question or problems do no hesitate to contact me: sebastian.opalczynski@syncano.com +Also I am available on the Syncano slack community: http://syncano-community.github.io/slack-invite/ diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index fa6e226..394eaa0 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -13,7 +13,8 @@ This can be installed in Syncano instance using the install from url functionali ## Prerequisites 1. Syncano Account - Create one [here](https://www.syncano.io/). -2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. +2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. If you want to edit + files locally. 3. Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. > Note: @@ -21,7 +22,7 @@ This can be installed in Syncano instance using the install from url functionali > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` > Install Syncano CLI: `pip install syncano_cli>=0.5` -4. Your favourite editor. +4. Your favourite text editor. ## YML definition @@ -88,7 +89,7 @@ of Custom Socket dependencies (currently of type `script`). syncano login --instance-name patient-resonance-4283 - Next you will see the prompt for `username` and `password`; Fill it. + Next you will see the prompt for `username` and `password`; Provide it. 2. There are two ways of installing Custom Socket - one is using your local files and the second is to use a url. @@ -96,7 +97,7 @@ of Custom Socket dependencies (currently of type `script`). syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-hello-world/master/socket.yml --name hello_world - In such scenario - you do not need even clone the repository to your local machine. The name here is neede - because + In such scenario - you do not need even clone the repository to your local machine. The name here is needed - because under the hood empty Custom Socket is created - and code fetch from repository is done asynchronously in second step. diff --git a/docs/custom_sockets/images/git.keep b/docs/custom_sockets/images/git.keep deleted file mode 100644 index e69de29..0000000 diff --git a/docs/custom_sockets/images/project_struct_adv.png b/docs/custom_sockets/images/project_struct_adv.png new file mode 100644 index 0000000000000000000000000000000000000000..2866f532b7bf7d6e095f62936d7c2328e9faf08a GIT binary patch literal 10340 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 Date: Fri, 26 Aug 2016 15:28:12 +0200 Subject: [PATCH 10/28] [CORE-1639] add config example --- docs/custom_sockets/examples/advanced.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index 9a8aa24..df0d8f9 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -204,8 +204,11 @@ or in tree format: path: /v1.1/instances/patient-resonance-4283/endpoints/sockets/mailgun_integration/send_mail/ 4. Before you run an endpoints - be sure that you have a Mailgun `api_key` in your instance Global Config. See the -`send_mail.py` description for more details. - +`send_mail.py` description for more details. My config looks like this: + + {"mailgun_api_key": "key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} + + 5. Run the endpoint defined in Custom Socket: First run the stats endpoint - as it is easier, because it is simple GET and no arguments are required. From 84e6f1e493caa0756283cac6188e8409ad2ea5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Mon, 29 Aug 2016 16:24:13 +0200 Subject: [PATCH 11/28] [CORE-1640] re-work hosting interface; --- README.rst | 26 +++-- syncano_cli/base/connection.py | 8 +- syncano_cli/commands.py | 1 + syncano_cli/custom_sockets/commands.py | 2 +- syncano_cli/hosting/{utils.py => command.py} | 64 +++++++++-- syncano_cli/hosting/commands.py | 108 ++++++++++++++----- syncano_cli/hosting/validators.py | 16 +++ syncano_cli/main.py | 4 + 8 files changed, 184 insertions(+), 45 deletions(-) rename syncano_cli/hosting/{utils.py => command.py} (55%) create mode 100644 syncano_cli/hosting/validators.py diff --git a/README.rst b/README.rst index 9e5e9d4..d9ca2e7 100644 --- a/README.rst +++ b/README.rst @@ -150,19 +150,31 @@ Syncano Hosting Syncano Hosting is a simple way to host the static files. CLI supports it in the following way: -:: +This command will list files in hosting which match the default hosting:: - syncano hosting --list-files + syncano hosting list -This command will list files in hosting which match the default hosting. +This command will publish all files inside and will publish it to the Syncano Hosting (default one). +The whole directory structure - will be mapped in Syncano Hosting:: -:: + syncano hosting publish - syncano hosting --publish +This command will unpublish currently published hosting:: -This command will publish all files inside and will publish it to the Syncano Hosting (default one). -The whole directory structure - will be mapped in Syncano Hosting. + syncano hosting unpublish + + +This command will permamently delete the hosting:: + + syncano hosting delete + +This command will delete the specified file:: + + syncano hosting delete hosting/file/path + +This command will update single file:: + syncano hosting update hosting/file/path local/file/path Tips & Troubleshooting ---------------------- diff --git a/syncano_cli/base/connection.py b/syncano_cli/base/connection.py index 3ad403a..45bc94c 100644 --- a/syncano_cli/base/connection.py +++ b/syncano_cli/base/connection.py @@ -11,7 +11,13 @@ def create_connection(config): config = config or ACCOUNT_CONFIG_PATH ACCOUNT_CONFIG.read(config) api_key = ACCOUNT_CONFIG.get('DEFAULT', 'key') - return syncano.connect(api_key=api_key) + connection_dict = { + 'api_key': api_key + } + instance_name = ACCOUNT_CONFIG.get('DEFAULT', 'instance_name', None) + if instance_name: + connection_dict['instance_name'] = instance_name + return syncano.connect(**connection_dict) def get_instance_name(config, instance_name): diff --git a/syncano_cli/commands.py b/syncano_cli/commands.py index b612677..2dfa4ab 100644 --- a/syncano_cli/commands.py +++ b/syncano_cli/commands.py @@ -39,5 +39,6 @@ def login(context, config, instance_name): ACCOUNT_CONFIG.set('DEFAULT', 'instance_name', instance_name) with open(context.obj['config'], 'wb') as fp: ACCOUNT_CONFIG.write(fp) + click.echo("INFO: Login successful.") except SyncanoException as error: print(error) diff --git a/syncano_cli/custom_sockets/commands.py b/syncano_cli/custom_sockets/commands.py index 42037f9..9bfc8a1 100644 --- a/syncano_cli/custom_sockets/commands.py +++ b/syncano_cli/custom_sockets/commands.py @@ -17,7 +17,7 @@ def top_sockets(): @click.pass_context @click.option('--config', help=u'Account configuration file.') @click.option('--instance-name', help=u'Instance name.') -def sockets(ctx, config, instance_name, **kwargs): +def sockets(ctx, config, instance_name): """ Allow to create a custom socket. """ diff --git a/syncano_cli/hosting/utils.py b/syncano_cli/hosting/command.py similarity index 55% rename from syncano_cli/hosting/utils.py rename to syncano_cli/hosting/command.py index 8ba38e7..acde3e7 100644 --- a/syncano_cli/hosting/utils.py +++ b/syncano_cli/hosting/command.py @@ -17,22 +17,24 @@ def list_hosting(self): def list_hosting_files(self, domain): hosting = self._get_hosting(domain=domain) - if not hosting: - click.echo(u'WARN: No default hosting found. Exit.') - sys.exit(1) - files_list = hosting.list_files() return files_list def publish(self, domain, base_dir): uploaded_files = [] - hosting = self._get_hosting(domain=domain) + hosting = self._get_hosting(domain=domain, is_new=True) + upload_method_name = 'update_file' if not hosting: # create a new hosting if no default is present; hosting = self.create_hosting(label='Default hosting', domain=domain) + upload_method_name = 'upload_file' for folder, subs, files in os.walk(base_dir): - path = folder.split(base_dir)[1][1:] # skip the / + path = folder.split(base_dir)[1] + + if path.startswith('/'): # skip the / + path = path[1:] + for single_file in files: if path: file_path = '{}/{}'.format(path, single_file) @@ -44,11 +46,42 @@ def publish(self, domain, base_dir): sys_path = os.path.join(folder, single_file) with open(sys_path, 'rb') as upload_file: click.echo(u'INFO: Uploading file: {}'.format(file_path)) - hosting.upload_file(path=file_path, file=upload_file) + getattr(hosting, upload_method_name)(path=file_path, file=upload_file) uploaded_files.append(file_path) return uploaded_files + def unpublish(self, domain): + hosting = self._get_hosting(domain=domain) + hosting.domains = ['unpublished'] + hosting.save() + + def delete_hosting(self, domain, path=None): + hosting = self._get_hosting(domain=domain) + deleted_label = hosting.label + hosting.delete() + click.echo('INFO: Hosting `{}` deleted.'.format(deleted_label)) + + def delete_path(self, domain, path=None): + hosting = self._get_hosting(domain=domain) + hosting_files = hosting.list_files() + is_deleted = False + for hosting_file in hosting_files: + if hosting_file.path == path: + is_deleted = True + hosting_file.delete() + break + + if is_deleted: + click.echo('INFO: File `{}` deleted.'.format(path)) + sys.exit(1) + click.echo('INFO: File `{}` not found.'.format(path)) + + def update_single_file(self, domain, path, file): + hosting = self._get_hosting(domain=domain) + hosting.update_file(path, file) + click.echo('INFO: File `{}` updated.'.format(path)) + def create_hosting(self, label, domain): hosting = self.instance.hostings.create( label=label, @@ -56,11 +89,20 @@ def create_hosting(self, label, domain): ) return hosting - def _get_hosting(self, domain): + def _get_hosting(self, domain, is_new=False): hostings = self.instance.hostings.all() + to_return = None + for hosting in hostings: if domain in hosting.domains: - return hosting + to_return = hosting + break + + if not to_return and not is_new: + click.echo(u'WARN: No default hosting found. Exit.') + sys.exit(1) + + return to_return def _validate_path(self, file_path): try: @@ -72,8 +114,8 @@ def _validate_path(self, file_path): def print_hosting_files(self, hosting_files): print('Hosting files:') self._print_separator() - for file_path in hosting_files: - print(file_path) + for hosting_file in hosting_files: + print(hosting_file.path) @staticmethod def _print_separator(): diff --git a/syncano_cli/hosting/commands.py b/syncano_cli/hosting/commands.py index 8b0a2a7..95ce604 100644 --- a/syncano_cli/hosting/commands.py +++ b/syncano_cli/hosting/commands.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -import os import sys import click from syncano_cli.base.connection import create_connection, get_instance_name from syncano_cli.config import ACCOUNT_CONFIG_PATH -from syncano_cli.hosting.utils import HostingCommands +from syncano_cli.hosting.command import HostingCommands +from syncano_cli.hosting.validators import validate_domain, validate_publish @click.group() @@ -13,24 +13,15 @@ def top_hosting(): pass -@top_hosting.command() +@top_hosting.group() +@click.pass_context @click.option('--config', help=u'Account configuration file.') @click.option('--instance-name', help=u'Instance name.') -@click.option('--list-files', is_flag=True, help='List files within the hosting.') -@click.option('--publish', type=str, help='Publish files from the local directory to the Syncano Hosting.') -def hosting(config, instance_name, list_files, publish): +def hosting(ctx, config, instance_name): """ Handle hosting and hosting files. Allow to publish static pages to the Syncano Hosting. """ - def validate_domain(provided_domain=None): - return 'default' if not provided_domain else provided_domain - - def validate_publish(base_dir): - if not os.path.isdir(base_dir): - click.echo(u'ERROR: You should provide a project root directory here.') - sys.exit(1) - config = config or ACCOUNT_CONFIG_PATH instance_name = get_instance_name(config, instance_name) @@ -39,20 +30,87 @@ def validate_publish(base_dir): instance = connection.Instance.please.get(name=instance_name) hosting_commands = HostingCommands(instance) + ctx.obj['hosting_commands'] = hosting_commands + + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) + + +@hosting.command() +@click.pass_context +@click.argument('directory') +def publish(ctx, directory): + + validate_publish(directory) + domain = validate_domain() # prepared for user defined domains; + + hosting_commands = ctx.obj['hosting_commands'] + try: + hosting_commands.publish(domain=domain, base_dir=directory) + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) - if list_files: - domain = validate_domain() - click.echo(u'INFO: List the hosting files: {} in instance: {}'.format(domain, instance_name)) - hosting_files = hosting_commands.list_hosting_files(domain=domain) - hosting_commands.print_hosting_files(hosting_files) - if publish: - domain = validate_domain() - click.echo(u'INFO: Publish the hosting files: {} in instance: {}'.format(domain, instance_name)) - validate_publish(base_dir=publish) - uploaded_files = hosting_commands.publish(domain=domain, base_dir=publish) - hosting_commands.print_hosting_files(uploaded_files) +@hosting.command() +@click.pass_context +def unpublish(ctx): + domain = validate_domain() + hosting_commands = ctx.obj['hosting_commands'] + try: + hosting_commands.unpublish(domain=domain) + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) + +@hosting.command() +@click.pass_context +def list(ctx): + hosting_commands = ctx.obj['hosting_commands'] + domain = validate_domain() + try: + hosting_commands.print_hosting_files( + hosting_files=hosting_commands.list_hosting_files(domain) + ) + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) + + +@hosting.command() +@click.pass_context +@click.argument('path', required=False) +def delete(ctx, path): + domain = validate_domain() + hosting_commands = ctx.obj['hosting_commands'] + if not path: + if click.confirm('Do you want to remove whole hosting?'): + try: + hosting_commands.delete_hosting(domain=domain, path=path) + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) + else: + click.echo("INFO: Deleting aborted.") + else: + try: + hosting_commands.delete_path(domain=domain, path=path) + except Exception as e: + click.echo(u'ERROR: {}'.format(e)) + sys.exit(1) + + +@hosting.command() +@click.pass_context +@click.argument('path') +@click.argument('file') +def update(ctx, path, file): + domain = validate_domain() + hosting_commands = ctx.obj['hosting_commands'] + try: + hosting_commands.update_single_file(domain=domain, path=path, file=file) except Exception as e: click.echo(u'ERROR: {}'.format(e)) sys.exit(1) diff --git a/syncano_cli/hosting/validators.py b/syncano_cli/hosting/validators.py new file mode 100644 index 0000000..70ff800 --- /dev/null +++ b/syncano_cli/hosting/validators.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +import os +import sys + +import click + + +def validate_publish(directory): + if not os.path.isdir(directory): + click.echo(u'ERROR: You should provide a project root directory here.') + sys.exit(1) + + +def validate_domain(provided_domain=None): + return 'default' if not provided_domain else provided_domain diff --git a/syncano_cli/main.py b/syncano_cli/main.py index b3fef11..c0f480b 100644 --- a/syncano_cli/main.py +++ b/syncano_cli/main.py @@ -12,6 +12,10 @@ from syncano_cli.parse_to_syncano.commands import top_migrate from syncano_cli.sync.commands import top_sync +sys.path.append('/home/sopalczy/projects/syncano/syncano-cli') +sys.path.append('/home/sopalczy/projects/syncano/syncano-python') + + ACCOUNT_KEY = '' cli = click.CommandCollection( From 505932b0450d869f7d26d9fcf908af398c00aaa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Mon, 29 Aug 2016 16:41:48 +0200 Subject: [PATCH 12/28] [CORE-1640] add test for hosting commands; --- syncano_cli/hosting/command.py | 1 + tests/test_hosting_commands.py | 57 ++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/syncano_cli/hosting/command.py b/syncano_cli/hosting/command.py index acde3e7..0653f1c 100644 --- a/syncano_cli/hosting/command.py +++ b/syncano_cli/hosting/command.py @@ -55,6 +55,7 @@ def unpublish(self, domain): hosting = self._get_hosting(domain=domain) hosting.domains = ['unpublished'] hosting.save() + click.echo('INFO: Hosting `{}` unpublished.'.format(hosting.label)) def delete_hosting(self, domain, path=None): hosting = self._get_hosting(domain=domain) diff --git a/tests/test_hosting_commands.py b/tests/test_hosting_commands.py index 716c780..a3c21d5 100644 --- a/tests/test_hosting_commands.py +++ b/tests/test_hosting_commands.py @@ -5,20 +5,65 @@ class HostingCommandsTest(BaseCLITest): - def test_file_list(self): + def test_hosting_commands(self): + # test publishing; self._publish_files() + result = self._get_list_output() + self.assertIn('index.html', result.output) + self.assertIn('css/page.css', result.output) - result = self.runner.invoke(cli, args=[ - 'hosting', '--list-files' - ]) + # test single file deletion; + self._delete_single_file('css/page.css') + result = self._get_list_output() + self.assertNotIn('css/page.css', result.output) - self.assertIn('index.html', result.output) + # test update file which do not exist; + result = self.runner.invoke(cli, args=[ + 'hosting', 'update', 'css/page.css', 'tests/hosting_files_examples/css/page.css' + ], obj={}) self.assertIn('css/page.css', result.output) + # test hosting delete; + self._delete_hosting() + result = self._get_list_output() + self.assertIn('No default hosting found. Exit.', result.output) + + # recreate hosting; + self._publish_files() + + # test unpublish; + result = self.runner.invoke(cli, args=[ + 'hosting', 'unpublish' + ], obj={}) + self.assertIn('unpublished', result.output) + result = self._get_list_output() + self.assertIn('No default hosting found. Exit.', result.output) + + def _get_list_output(self): + result = self.runner.invoke(cli, args=[ + 'hosting', 'list' + ]) + return result + def _publish_files(self): result = self.runner.invoke(cli, args=[ - 'hosting', '--publish', 'tests/hosting_files_examples' + 'hosting', 'publish', 'tests/hosting_files_examples' ], obj={}) self.assertIn('index.html', result.output) self.assertIn('css/page.css', result.output) + + def _delete_single_file(self, path): + result = self.runner.invoke(cli, args=[ + 'hosting', 'delete', path + ], obj={}) + + self.assertIn('deleted.', result.output) + + def _delete_hosting(self): + result = self.runner.invoke(cli, args=[ + 'hosting', 'delete' + ], input='y', obj={}) + + self.assertIn('Hosting', result.output) + self.assertIn('deleted.', result.output) From 86794ead576d97f1bbfa66e748e71e33ddf7e35f Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 13:31:11 -0400 Subject: [PATCH 13/28] Reade edits --- README.rst | 145 +++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/README.rst b/README.rst index e1431ea..3ae324f 100644 --- a/README.rst +++ b/README.rst @@ -23,20 +23,20 @@ Installation **Usage:** -First you need to login into your account +First you need to login into your Syncano account :: syncano login -It will ask you for your email and password and store account key in -${HOME}/.syncano file. You can also override account key with --key option. +It will ask you for your email and password. After successful login your Account Key (admin key) +will be stored in *${HOME}/.syncano* file. You can also override an Account Key later with *--key* option. -You can specify the default instance name - that would be used in all CLI calls:: +You can specify the default instance name that will be used in all consecutive CLI calls:: syncano login --instance-name patient-resonance-4283 -After when you want to override this setting use --instance-name in particular command, eg:: +If you want to override this setting for a specific command, use --instance-name eg:: syncano sync pull --instance-name new-instance-1234 @@ -48,62 +48,61 @@ You can read detailed documentation `here `_. Pulling your instance classes and scripts ----------------------------------------- -In order to pull your instance configuration you can execute +In order to pull your instance configuration, execute :: syncano sync pull This will fetch all Classes and Scripts into current working directory, and -store configuration in syncano.yml file. If you want to pull only selected -classes/scripts you can add -c/--class or -s/--script option eg. +store configuration in *syncano.yml* file. If you want to pull only selected +classes/scripts you can add *-c/--class* or *-s/--script* option e.g. :: syncano sync pull -c Class1 -c Class2 -s script_label_1 -s "script label 2" -Scripts source code is stored in scripts subdirectory, and names are based on -script labels. Keep in mind that script labels in syncano are not unique, and -this tools can't handle this kind of situation. +Scripts' source code is stored in scripts subdirectory. Their names are based on +script labels. Keep in mind that script labels in Syncano are not unique, and +this tools cannot yet handle this kind of situation when pulling Script from Syncano. -Classes and Scripts configuration is stored in syncano.yml file. If file -syncano.yml already exists only classes and scripts stored in this file, will -be pulled and updated. If you want to pull whole instance you can use -a/--all -flag. +Classes and Scripts configuration is stored in *syncano.yml* file. If this file already +exists, only classes and scripts stored in this file will be pulled and updated. +If you want to pull whole instance you can use *-a/--all* switch flag. Pushing your changes -------------------- -When you have made some changes to syncano.yml or some script source code you -can push the changes to syncano using +After you have made changes to *syncano.yml* or any of the script's source code, +you can push the changes to Syncano using :: syncano sync push -It will push only changes newer then last synchronization time. This time is -recorded using .sync file last modification time. If syncano.yml has changed -it will try to push all data to syncano. Otherwise it will just push changed -source code files for scripts. If you want to force push all changes you can -use -a/--all option. +It will push only changes newer than the last synchronization time. +As last synchronization time we use *.sync* file last modification time. +If *syncano.yml* has changed, it will try to push all data to Syncano. Otherwise, +it will just push the source code files for scripts that were changed. +If you want to force push all changes you can use *-a/--all* option. If you want to just push selected classes/scripts changes you can provide them -with -c/--class or -s/--script options like in the pull example above. +with *-c/--class* or *-s/--script* options like in the pull example above. -Synchronization of changes in realtime +Synchronize changes in real-time -------------------------------------- -There is also an option to synchronize your project live. When you change -syncano.yml or some script source code pointed to by syncano.yml your changes -will be automatically pushed to syncano. +There is an option to synchronize your project in real-time. When you change +syncano.yml or a source code of script described in *syncano.yml*, your changes +will be automatically pushed to Syncano. :: syncano sync watch -This command will push all your project configuration to syncano and will -wait for changes made to project files. When it detects file modification -it will push those changes to syncano. +This command will push all your project configuration to Syncano and will +wait for changes made to project files. When it detects that any file was modified, +it will push those changes to Syncano. Syncano Parse migration tool @@ -150,38 +149,48 @@ Run migration This command will run the synchronization process between Parse and Syncano. Sit comfortably in your chair and read the output. +Tips & Troubleshooting +---------------------- + +1. This tool currently does not support checking if some object is already present in the Syncano instance. + If sync is run twice, the end results is that data will duplicated. To avoid such cases, + simply remove your instance using Syncano dashboard; + +2. The whole process can be quite slow - it's because of the throttling on both sides: Parse and Syncano on free trial accounts (which is the bottom boundary for scripts); + Syncano Hosting =============== -Syncano Hosting is a simple way to host the static files. CLI supports it in the following way: +Syncano Hosting is a simple way to host the static files on Syncano servers. +CLI supports it in the following way: :: syncano hosting --list-files -This command will list files in hosting which match the default hosting. +This command will list files for currently hosted website: :: syncano hosting --publish -This command will publish all files inside and will publish it to the Syncano Hosting (default one). -The whole directory structure - will be mapped in Syncano Hosting. +This command will publish all files inside ** in the default Syncano Hosting instance. +When publishing whole directory structure will be mapped on Syncano. Custom Sockets -------------- -The commands available for Custom Sockets are (read the detailed docs about Custom Sockets if you want to know -`more `_): +You can find here list of commands available for Custom Sockets. +If you want to know more about Custom Sockets, `read the detailed docs here `_. -To install Custom Socket from local files:: +To install a Custom Socket from a local file:: syncano sockets install /path/to/dir -To install Custom Socket from ulr:: +To install a Custom Socket from a URL:: - syncano sockets install https://... + syncano sockets install https://web.path.to/your.file List all Custom Sockets:: @@ -191,11 +200,11 @@ List all defined endpoints (for all Custom Sockets):: syncano sockets list endpoints -Display the Custom Socket details:: +Display chosen Custom Socket details:: syncano sockets details socket_name -Deletes the Custom Socket:: +Deletes a Custom Socket:: syncano sockets delete socket_name @@ -203,7 +212,7 @@ Create a template from template stored in Syncano CLI:: syncano sockets template /path/to/output_dir -Create a template from a existing Custom Socket:: +Create a template from an existing Custom Socket:: syncano sockets template /path/to/out --socket socket_name @@ -211,39 +220,16 @@ Run endpoint defined in Custom Socket:: syncano sockets run socket_name/endpoint_name -Run endpoint providing the POST data:: +Run endpoint providing POST data:: - syncano sockets run socket_name/my_endpoint_12 POST --data '{"raz": 1}' + syncano sockets run socket_name/my_endpoint_12 POST --data '{"one": 1}' -In all of the above cases you can defined an option:: +In all of the above cases you can override Syncano instance being used:: --instance-name my_instance_name -Which override the default used instance (in syncano login --instance-name my_other_instance) - - -Tips & Troubleshooting ----------------------- - -1. This tool currently does not support checking if some object is already present in the Syncano instance, - so if sync is run twice the end results is that data is duplicated. To avoid such cases, - simply remove your instance in using Syncano dashboard; - -2. The process can be quite slow - it's because of the throttling on both sides: Parse and Syncano on free accounts - (which is the bottom boundary for scripts); - -3. If you encounter any problems, have some improvements proposal or just wanna talk, - please write me: sebastian.opalczynski@syncano.com; - -4. The Syncano can be found on - please do not hesitate to ask for help or share your thoughts; - -* Github: - * https://github.com/Syncano/ -* Gitter: - * https://gitter.im/Syncano/community - * https://gitter.im/Syncano/community-pl -* Slack: - * http://syncano-community.github.io/slack-invite/ +Instance name provided this way will override the default instance name +defined during initial setup (*syncano login --instance-name my_instance*) Running scripts @@ -256,3 +242,22 @@ This command will allow you to execute any script (Script Endpoint) with optiona :: syncano execute --payload="" + + +Issues +======== + +1. If you encounter any problems, have some improvement ideas or just wanna talk, + please write to me directly: sebastian.opalczynski@syncano.com; + +2. Syncano team can be reached in multiple ways. Please do not hesitate to ask for help or share your thoughts. You can find us on: + +* Github: + * https://github.com/Syncano/ +* Slack: + * http://syncano-community.github.io/slack-invite/ +* Gitter: + * https://gitter.im/Syncano/community + * https://gitter.im/Syncano/community-pl +* Support e-mail: + * `support@syncano.io `_ From ff437789f7e63015f472d8e3354e9800460c72b8 Mon Sep 17 00:00:00 2001 From: Todd Date: Mon, 29 Aug 2016 12:56:21 -0500 Subject: [PATCH 14/28] Update README.rst --- README.rst | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 3ae324f..40f971d 100644 --- a/README.rst +++ b/README.rst @@ -29,7 +29,7 @@ First you need to login into your Syncano account syncano login -It will ask you for your email and password. After successful login your Account Key (admin key) +It will ask you for your email and password. After successfully logging in your Account Key (admin key) will be stored in *${HOME}/.syncano* file. You can also override an Account Key later with *--key* option. You can specify the default instance name that will be used in all consecutive CLI calls:: @@ -54,7 +54,7 @@ In order to pull your instance configuration, execute syncano sync pull -This will fetch all Classes and Scripts into current working directory, and +This will fetch all Classes and Scripts into the current working directory, and store configuration in *syncano.yml* file. If you want to pull only selected classes/scripts you can add *-c/--class* or *-s/--script* option e.g. @@ -62,13 +62,13 @@ classes/scripts you can add *-c/--class* or *-s/--script* option e.g. syncano sync pull -c Class1 -c Class2 -s script_label_1 -s "script label 2" -Scripts' source code is stored in scripts subdirectory. Their names are based on +The Scripts' source code is stored in the scripts subdirectory. Their names are based on script labels. Keep in mind that script labels in Syncano are not unique, and -this tools cannot yet handle this kind of situation when pulling Script from Syncano. +this tool cannot yet handle this kind of situation when pulling a Script from Syncano. Classes and Scripts configuration is stored in *syncano.yml* file. If this file already exists, only classes and scripts stored in this file will be pulled and updated. -If you want to pull whole instance you can use *-a/--all* switch flag. +If you want to pull the whole instance you can use *-a/--all* switch flag. Pushing your changes -------------------- @@ -86,21 +86,21 @@ If *syncano.yml* has changed, it will try to push all data to Syncano. Otherwise it will just push the source code files for scripts that were changed. If you want to force push all changes you can use *-a/--all* option. -If you want to just push selected classes/scripts changes you can provide them +If you only want to push changes from selected classes/scripts you can provide them with *-c/--class* or *-s/--script* options like in the pull example above. Synchronize changes in real-time -------------------------------------- There is an option to synchronize your project in real-time. When you change -syncano.yml or a source code of script described in *syncano.yml*, your changes +syncano.yml or the source code of a script described in *syncano.yml*, your changes will be automatically pushed to Syncano. :: syncano sync watch -This command will push all your project configuration to Syncano and will +This command will push all of your project's configuration to Syncano and will wait for changes made to project files. When it detects that any file was modified, it will push those changes to Syncano. @@ -112,8 +112,8 @@ This tool will help you to move your data from Parse to Syncano. **Usage:** -Currently supports only transferring data. This tool takes the Parse schemas and transform them to Syncano classes. -Next step is to move all of the data between Parse and Syncano. The last step is rebuilding the relations between +Currently supports only transferring data. This tool takes the Parse schemas and transforms them to Syncano classes. +The next step is to move all of the data between Parse and Syncano. The last step is rebuilding the relations between objects. @@ -136,7 +136,7 @@ Will run the configuration that will ask you for the following variables: * -c (--current) which will display the current configuration; * -f (--force) which allow to override the previously set configuration; -The configuration will be stored in your home directory in .syncano file under the P2S section. +The configuration will be stored in your home directory in the .syncano file under the P2S section. It's used to call the Parse API and Syncano API as well. Run migration @@ -146,23 +146,23 @@ Run migration syncano migrate parse -This command will run the synchronization process between Parse and Syncano. Sit comfortably in your chair and read +This command will run the synchronization process between Parse and Syncano. Sit back, relax, and read the output. Tips & Troubleshooting ---------------------- -1. This tool currently does not support checking if some object is already present in the Syncano instance. - If sync is run twice, the end results is that data will duplicated. To avoid such cases, +1. This tool currently does not support checking if an object is already present in the Syncano instance. + If the sync is run twice, the data will be duplicated. To avoid this, simply remove your instance using Syncano dashboard; -2. The whole process can be quite slow - it's because of the throttling on both sides: Parse and Syncano on free trial accounts (which is the bottom boundary for scripts); +2. The whole process can be quite slow because of the throttling on both sides: Parse and Syncano on free trial accounts (which is the bottom boundary for scripts); Syncano Hosting =============== -Syncano Hosting is a simple way to host the static files on Syncano servers. -CLI supports it in the following way: +Syncano Hosting is a simple way to host your static files on Syncano servers. +The CLI supports it in the following way: :: @@ -174,14 +174,14 @@ This command will list files for currently hosted website: syncano hosting --publish -This command will publish all files inside ** in the default Syncano Hosting instance. -When publishing whole directory structure will be mapped on Syncano. +This command will publish all files inside ** to the default Syncano Hosting instance. +When publishing the whole directory, the structure will be mapped on Syncano. Custom Sockets -------------- -You can find here list of commands available for Custom Sockets. +This is a list of commands available for Custom Sockets. If you want to know more about Custom Sockets, `read the detailed docs here `_. To install a Custom Socket from a local file:: @@ -204,11 +204,11 @@ Display chosen Custom Socket details:: syncano sockets details socket_name -Deletes a Custom Socket:: +Delete a Custom Socket:: syncano sockets delete socket_name -Create a template from template stored in Syncano CLI:: +Create a template from a template stored in Syncano CLI:: syncano sockets template /path/to/output_dir @@ -224,12 +224,12 @@ Run endpoint providing POST data:: syncano sockets run socket_name/my_endpoint_12 POST --data '{"one": 1}' -In all of the above cases you can override Syncano instance being used:: +In all of the above cases you can override the Syncano instance being used:: --instance-name my_instance_name -Instance name provided this way will override the default instance name -defined during initial setup (*syncano login --instance-name my_instance*) +Providing the instance name this way will override the default instance name +defined during initial setup (*syncano login --instance-name my_instance*) Running scripts From e44438ce86e047df3b3ccde327eb9de1020e9da2 Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 14:37:07 -0400 Subject: [PATCH 15/28] Readme edits --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5ed773c..0ffaeee 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,16 +2,16 @@ ## Migrations -Migration allow to transfer data from Parse to Syncano. Read the following carefully to understand possibilities and -limitations. +Migration allows to transfer data from Parse to Syncano. Read the following guide carefully, to understand +what can transferred from Parse to Syncano, and what are the limitations of the process. [Migrations](migrations/docs.md) ## Custom Sockets -Custom Sockets are powerful Syncano solution which allows to customize endpoints behaviour. Custom Sockets can be used -to provide integration with other applications or to define some custom endpoints for eg.: password reset. Custom -Sockets are build on the top of the others Syncano solution - like Script Endpoints. +Custom Sockets are a powerful Syncano feature, which allows you to create your own API. +They can be used to provide an integration with other applications (e.g. sending emails with SendGrid) or to define custom behaviour for your endpoints e.g. for password reset. +Sockets are build on the top of other Syncano solution - like Script Endpoints. [Custom Sockets](custom_sockets/docs.md) From 98094ef421ef90f73d0f41201de73ba8a845ea34 Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 15:14:37 -0400 Subject: [PATCH 16/28] Readme edits --- docs/custom_sockets/docs.md | 76 ++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md index 11d8061..72eb9fa 100644 --- a/docs/custom_sockets/docs.md +++ b/docs/custom_sockets/docs.md @@ -36,23 +36,30 @@ ### YAML file structure explanation -* `name` is the name of the new Custom Socket - this should be unique; -* `description` is the description of the Custom Socket - allows to easily tell what custom socket do; -* `author` is a metadata information about Custom Socket author; Under the hood: all fields that are not in list: -`name`, `description`, `endpoints`, `dependencies` can be found in `metadata` field on Custom Socket in Syncano Dasboard. -* `icon` is a metadata information about Custom Socket - just stores the used icon name and its color - for display in -Syncano Dasboard. -* `endpoints` - definition of the endpoints in Custom Socket; Currently supported endpoints can be of type `script`. - - Consider the example: +* `name` is the name of your new Custom Socket - this should be unique; +* `description` is a description of your Custom Socket - it allows to easily identify what your custom socket does; +* `author` is a metadata information about Custom Socket author; Under the hood: all fields that are not + * `name`, + * `description`, + * `endpoints`, + * `dependencies` + * can be found in `metadata` field on Custom Socket in Syncano Dasboard. +* `icon` is a metadata information about your Custom Socket - it stores the icon name used and its color for (used in Syncano Dashboard) +* `endpoints` - definition of the endpoints in Custom Socket; Currently supported endpoints can be only of `script` type. + + Consider this example: my_endpoint_1: script: script_endpoint_1 - In above YAML snippet - the `my_endpoint_1` is an endpoint name - this will be used in url path; the `script` is - a type of the endpoint; and `script_endpoint_1` is a dependency name which will be called when endpoint - `my_endpoint_1` will be requested; In above example the http methods use wildcard - so no matter what http method - will be used - the script endpoints `script_endpoint_1` will be called; + In the YAML snippet: + * `my_endpoint_1` is an endpoint name - it will be used in the url path; + * `script` is a type of the endpoint; + * `script_endpoint_1` is the dependency name which will be called when endpoint + `my_endpoint_1` will be requested; + + In example above we didn't specify HTTP method - so no matter what HTTP method + will be used to call `my_endpoint_1` (can be PATCH, POST, GET, etc.), script endpoint `script_endpoint_1` will be called; Consider yet another example: @@ -62,29 +69,36 @@ Syncano Dasboard. GET: script: script_endpoint_3 - In above YAML snippet - the `my_endpoint_2` is an endpoint name. The difference is that - when GET http method will - be used the script endpoint `script_endpoint_3` will be ran. When POST http method will be used - the script - endpoint `script_endpoint_2` will be ran. + In the above YAML snippet: + * `my_endpoint_2` is an endpoint name. + * GET, POST - define HTTP method type used to call our endpoint - Currently supported type of endpoint are only `script` - which run script endpoints under the hood, - but we are working to add more integrations. + The difference is that we now define what happens for different HTTP methods. When GET HTTP method will be used, + `script_endpoint_3` script endpoint will be ran. When POST HTTP method will be used - `script_endpoint_2` endpoint will be executed. + + Currently only supported endpoint types are Script Endpoints, which run scripts under the hood. But don't worry, + we are working on adding more options! -* `dependencies` - definition of the dependencies for the Custom Socket. Dependencies define the dependency object -which will be called when endpoint will be requested. +* `dependencies` - it's the definition of your Custom Socket dependencies. They define all dependency objects +which will be called when endpoint is requested. Consider the example: - scripts: + dependencies: + scripts: script_endpoint_1: - runtime_name: python_library_v5.0 - file: scripts/script1.py - - The above YML snippet defines one dependency of type script (under the `scripts` special word). The name of the - dependency is `script_endpoint_1` - and this is important, because it is a connecting point with an endpoint. - the `runtime_name` is a runtime used in a script, and the `file` stores the source code that will be executed. - It should be `noted` that when defining Custom Script some basic directory structure should be fulfilled - for - better work organization. It's desired to store scripts under the scripts directory - this is why filename - is a relative path: `scripts/script1.py`. Of course this can be omitted - and flat structure can be used. + runtime_name: python_library_v5.0 + file: scripts/script1.py + + Above YAML snippet defines one dependency: + * `script` - type of the dependency (defined using `scripts` keyword). + * `script_endpoint_1` - name of the dependency is; it's an important element, because that's the place where you connect a dependency to an endpoint. + * `runtime_name` is name of the runtime used in a script; + * `file` stores the source code that will be executed. + + It should be noted that when defining Custom Scripts, we suggest following some basic directory structure- for + better work organization. We recommend storing scripts under `scripts` directory - this is why filename + is a relative path: `scripts/script1.py`. Of course your can also follow your own rules, e.g. by using a flat file structure. ## Custom Socket directory structure @@ -93,7 +107,7 @@ Below is a sample Custom Socket structure for the above YAML definition: ![](images/tree_socket.png) -The `socket.yml` file stores the YAML definition mentioned above; The `scripts` directory stores all scripts source +`socket.yml` file stores the YAML definition mentioned above; `scripts` directory stores all scripts source code used in `script` dependency type. From f550eff35733ec75e799b6631b310ee232d8fcce Mon Sep 17 00:00:00 2001 From: Todd Date: Mon, 29 Aug 2016 14:24:41 -0500 Subject: [PATCH 17/28] Update README.md --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 0ffaeee..5a41959 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,16 +2,16 @@ ## Migrations -Migration allows to transfer data from Parse to Syncano. Read the following guide carefully, to understand -what can transferred from Parse to Syncano, and what are the limitations of the process. +Migration allows you to transfer data from Parse to Syncano. Read the following guide carefully, to understand +what can be transferred from Parse to Syncano, and what the limitations are. [Migrations](migrations/docs.md) ## Custom Sockets Custom Sockets are a powerful Syncano feature, which allows you to create your own API. -They can be used to provide an integration with other applications (e.g. sending emails with SendGrid) or to define custom behaviour for your endpoints e.g. for password reset. -Sockets are build on the top of other Syncano solution - like Script Endpoints. +They can be used to provide an integration with other applications (e.g. sending emails with SendGrid) or to define custom behavior for your endpoints e.g. for password reset. +Sockets are built on the top of other Syncano solutions - like Script Endpoints. [Custom Sockets](custom_sockets/docs.md) From 94c131108fdc3e87fddd33472ea6a3c2dc964fe7 Mon Sep 17 00:00:00 2001 From: Todd Date: Mon, 29 Aug 2016 14:32:47 -0500 Subject: [PATCH 18/28] Update docs.md --- docs/custom_sockets/docs.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/custom_sockets/docs.md b/docs/custom_sockets/docs.md index 72eb9fa..f0996fc 100644 --- a/docs/custom_sockets/docs.md +++ b/docs/custom_sockets/docs.md @@ -37,15 +37,15 @@ ### YAML file structure explanation * `name` is the name of your new Custom Socket - this should be unique; -* `description` is a description of your Custom Socket - it allows to easily identify what your custom socket does; -* `author` is a metadata information about Custom Socket author; Under the hood: all fields that are not +* `description` is a description of your Custom Socket - it allows you to easily identify what your custom socket does; +* `author` is metadata information about the Custom Socket author; Under the hood: all fields that are not * `name`, * `description`, * `endpoints`, * `dependencies` * can be found in `metadata` field on Custom Socket in Syncano Dasboard. -* `icon` is a metadata information about your Custom Socket - it stores the icon name used and its color for (used in Syncano Dashboard) -* `endpoints` - definition of the endpoints in Custom Socket; Currently supported endpoints can be only of `script` type. +* `icon` is metadata information about your Custom Socket - it stores the icon name used and its color (used in Syncano Dashboard) +* `endpoints` - definition of the endpoints in a Custom Socket; Currently supported endpoints can be only of `script` type. Consider this example: @@ -58,8 +58,8 @@ * `script_endpoint_1` is the dependency name which will be called when endpoint `my_endpoint_1` will be requested; - In example above we didn't specify HTTP method - so no matter what HTTP method - will be used to call `my_endpoint_1` (can be PATCH, POST, GET, etc.), script endpoint `script_endpoint_1` will be called; + In the example above we didn't specify HTTP method - so no matter what HTTP method + is used to call `my_endpoint_1` (can be PATCH, POST, GET, etc.), script endpoint `script_endpoint_1` will be called; Consider yet another example: @@ -73,14 +73,14 @@ * `my_endpoint_2` is an endpoint name. * GET, POST - define HTTP method type used to call our endpoint - The difference is that we now define what happens for different HTTP methods. When GET HTTP method will be used, - `script_endpoint_3` script endpoint will be ran. When POST HTTP method will be used - `script_endpoint_2` endpoint will be executed. + The difference is that we now define what happens for the different HTTP methods. When the GET HTTP method is used, + `script_endpoint_3` script endpoint will be run. When the POST HTTP method is used - `script_endpoint_2` endpoint will be executed. - Currently only supported endpoint types are Script Endpoints, which run scripts under the hood. But don't worry, + Currently only Script Endpoints are supported, which run scripts under the hood. But don't worry, we are working on adding more options! -* `dependencies` - it's the definition of your Custom Socket dependencies. They define all dependency objects -which will be called when endpoint is requested. +* `dependencies` - the definition of your Custom Socket dependencies. They define all dependency objects +which will be called when the endpoint is requested. Consider the example: @@ -92,12 +92,12 @@ which will be called when endpoint is requested. Above YAML snippet defines one dependency: * `script` - type of the dependency (defined using `scripts` keyword). - * `script_endpoint_1` - name of the dependency is; it's an important element, because that's the place where you connect a dependency to an endpoint. + * `script_endpoint_1` - name of the dependency; it's an important element, because that's the place where you connect a dependency to an endpoint. * `runtime_name` is name of the runtime used in a script; * `file` stores the source code that will be executed. It should be noted that when defining Custom Scripts, we suggest following some basic directory structure- for - better work organization. We recommend storing scripts under `scripts` directory - this is why filename + better work organization. We recommend storing scripts under the `scripts` directory - this is why the filename is a relative path: `scripts/script1.py`. Of course your can also follow your own rules, e.g. by using a flat file structure. From 24c9820a3f6181153fac2576c76b5cc127f48111 Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 16:01:27 -0400 Subject: [PATCH 19/28] Readme edits --- docs/custom_sockets/examples/advanced.md | 99 +++++++++++++----------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index df0d8f9..146bb05 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -2,28 +2,36 @@ ## Abstract -In this advanced example the integration with Mailgun will be made (https://mailgun.com/). The mailgun sandbox environment -will be used. It allows to send 300 mails per day - so it should be enough. In this example two endpoints in Custom Socket -will be implemented - one for sending emails, and second - to obtain some basic statistics. +This in an advanced example of Syncano Custom Sockets, showing an integration with Mailgun (https://mailgun.com/). + +We will use Mailgun sandbox environment, that allows sending up to 300 mails per day - it should be more than enough for testing. + +We will implement two endpoint inside Custom Socket - one for sending emails, and second one to obtain some basic statistics. ## Repository link -The whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example) -This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here +Whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example). +It can be installed to your Syncano instance using the `install from url` functionality in CLI. The url is: + +https://github.com/Syncano/custom-socket-advanced-example/blob/master/socket.yml ## Prerequisites -1. Syncano Account - Create one [here](https://www.syncano.io/). -2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. If you want to edit - files locally. -3. Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. +* Syncano Account - [Create one here](https://www.syncano.io/). +* GIT - If you want to edit files locally, clone our repository using: + +```bash +git clone git@github.com:Syncano/custom-socket-hello-world.git` +``` + +* Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. > Note: > It is nice to use virtualenv to separate your tools: `sudo pip install virtualenv` > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` > Install Syncano CLI: `pip install syncano_cli>=0.5` -4. Your favourite text editor. +* Your favourite text editor. ## YML definition @@ -51,11 +59,11 @@ This can be installed in Syncano instance using the install from url functionali runtime_name: python_library_v5.0 file: scripts/get_stats.py -The above YAML definition defines a one Custom Socket with two endpoints: one for send email: `send_mail` with POST -http method (we want to pass here some basic information about email: to who it should be send, what subject should be used -and what text should be in the email itself). The second endpoint is for obtaining basic stats from Mailgun service. +Above YAML file defines one Custom Socket with two endpoints: +* `send_mail` for sending emails, it's run on POST HTTP method call; we want to pass here some basic information about who it should be sent to, what subject should be used and what text should be in the email itself; +* `get_stats` - second endpoint is for obtaining basic stats from Mailgun service. -There're also two `script` dependencies defined. +There are also two `script` dependencies defined. ## Scripts definition @@ -85,7 +93,7 @@ There're also two `script` dependencies defined. success_content = json.dumps( { 'status_code': 200, - 'info': u'Mail successfully send to {}'.format(to_email) + 'info': u'Mail successfully sent to {}'.format(to_email) } ) set_response(HttpResponse(status_code=200, content=success_content, content_type='application/json')) @@ -98,10 +106,10 @@ There're also two `script` dependencies defined. ) set_response(HttpResponse(status_code=400, content=fail_content, content_type='application/json')) -The above script will send a request to the Mailgun service - and this service will send an email to user. -It's worth to note the `CONFIG` variable - it's a Instance global config map - you can define its content in the -Syncano Dasboard under the `Global Config` menu or using Syncano Libraries - more can be found at -[docs.](http://docs.syncano.io/docs/snippets-scripts#section-global-config-dictionary) +Script above will send a request to Mailgun service - and this service will send an email to a user. +It's worth to note the `CONFIG` variable - it's an Instance global config dictionary/map - you can define its content inside +Syncano Dasboard under `Global Config` menu on the left, or using Syncano Libraries - more about it can be found +[in our docs](http://docs.syncano.io/docs/snippets-scripts#section-global-config-dictionary). ### scripts/get_stats.py @@ -122,13 +130,13 @@ Syncano Dasboard under the `Global Config` menu or using Syncano Libraries - mor else: set_response(HttpResponse(status_code=400, content=response.text, content_type='application/json')) -Above script will work as a proxy to the Mailgun service - will send a request about stats and passes the results as +Above script will work as a proxy to the Mailgun service - will send a request about stats and pass the result as a response. ## Custom Socket directory structure -The directory structure in my favourite editors looks like this: +The directory structure in my favourite editor looks like this: ![](../images/project_struct_adv.png) @@ -141,26 +149,24 @@ or in tree format: └── socket.yml -## Pulling everything together +## Putting everything together ### Steps: -1. Assuming that you have Syncano CLI installed, do a login: `syncano login --instance-name your-instance-name` +1. Assuming that you have Syncano CLI installed, log in using: `syncano login --instance-name your-instance-name` In my case it is: syncano login --instance-name patient-resonance-4283 - Next you will see the prompt for `username` and `password`; Provide it. + Next you will see a prompt for `username` and `password`; provide both and confirm with `enter`. -2. There are two ways of installing Custom Socket - one is using your local files and the second is to use a url. +2. There are two ways of installing a Custom Socket - one is using your local files and the second one is by using a URL. - To install Custom Socket from url do: + To install Custom Socket from a URL do: syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-advanced-example/master/socket.yml --name mailgun_integration - In such scenario - you do not need even clone the repository to your local machine. The name here is needed - because - under the hood empty Custom Socket is created - and code fetch from repository is done asynchronously in second - step. + In such scenario - you do not even need to clone the repository to your local machine. The `--name` parameter and name here are needed - because under the hood, empty Custom Socket is created - and code fetching from repository is done asynchronously in the second step. To install Custom Socket from local files do: @@ -172,7 +178,7 @@ or in tree format: 3. Try a newly created Custom Socket: - To list a Custom Sockets, do: + To list Custom Sockets, do: syncano sockets list @@ -183,10 +189,9 @@ or in tree format: name: mailgun_integration status: ok - This mean that Custom Socket hello_world was created successfuly - the status is `ok`. In any other case you will see - here and `error` and detailed information in `info` - what was wrong. + This means that Custom Socket `mailgun_integration` was created successfuly - the status is `ok`. In any other case you will see here an `error` and detailed information in `info` about what went wrong. - Now list the defined endpoints: + Now, list all defined endpoints: syncano sockets list endpoints @@ -203,15 +208,17 @@ or in tree format: name: mailgun_integration/send_mail path: /v1.1/instances/patient-resonance-4283/endpoints/sockets/mailgun_integration/send_mail/ -4. Before you run an endpoints - be sure that you have a Mailgun `api_key` in your instance Global Config. See the +4. Before you run an endpoint - be sure that you have Mailgun `api_key` inside your Instance Global Config. See the `send_mail.py` description for more details. My config looks like this: {"mailgun_api_key": "key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} + + Of course you need to replace `key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` with your Mailgun API Key. -5. Run the endpoint defined in Custom Socket: +5. Run the endpoint defined in your Custom Socket: - First run the stats endpoint - as it is easier, because it is simple GET and no arguments are required. + First, run the stats endpoint - it's easier, as it is a simple GET request without any arguments required. syncano sockets run mailgun_integration/get_stats @@ -250,30 +257,30 @@ or in tree format: "start": "Mon, 01 Aug 2016 00:00:00 UTC" } - The above response is one-to-one to the response provided by Mailgun. + Above response is one-to-one to the response provided by Mailgun. - **Let send a mail now** + Now lets send an e-mail! Run: - syncano sockets run mailgun_integration/send_mail POST --data '{"subject": "CustomSocket MailGun test", "to_email": "FirstName LastName ", "email_body": "It is nice to create Custom Sockets!"}' + syncano sockets run mailgun_integration/send_mail POST --data '{"subject": "CustomSocket MailGun test", "to_email": "FirstName LastName ", "email_body": "So nice to create Custom Sockets!"}' - Do not forget to change email in JSON data. + Do not forget to change e-mail address in JSON data. - This should return: + It should return: { - u'info': u'Mail successfully send to {to_email_value}', + u'info': u'Mail successfully sent to {to_email_value}', u'status_code': 200 } - You can now call stats again and see if any changes appeared. + You can now call stats again and see if anything changed. -6. To delete Custom Socket do: +6. To delete mailgun Custom Socket do: syncano sockets delete mailgun_integration ## Summary -Hope this will help. If you have any question or problems do no hesitate to contact me: sebastian.opalczynski@syncano.com -Also I am available on the Syncano slack community: http://syncano-community.github.io/slack-invite/ +Hope this was helpful! If you have any question or issues, do no hesitate to contact me directly: sebastian.opalczynski@syncano.com +I am also available on the [Syncano Slack community](http://syncano-community.github.io/slack-invite/). See you there! From 0dc8703b535e68c26aa02943df18b514354a8dd8 Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 16:01:59 -0400 Subject: [PATCH 20/28] [ci skip] Typo fix --- docs/custom_sockets/examples/advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index 146bb05..a9b456b 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -1,4 +1,4 @@ -# Adanced Custom Socket example +# Advanced Custom Socket example ## Abstract From f7ba3da2ddafc7043b650a7a9fc308194314f8cb Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 16:08:10 -0400 Subject: [PATCH 21/28] [ci skip] proper git clone path --- docs/custom_sockets/examples/advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index a9b456b..8b0a2e1 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -21,7 +21,7 @@ https://github.com/Syncano/custom-socket-advanced-example/blob/master/socket.yml * GIT - If you want to edit files locally, clone our repository using: ```bash -git clone git@github.com:Syncano/custom-socket-hello-world.git` +git clone git@github.com:Syncano/custom-socket-advanced-example.git` ``` * Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. From c6af657c27374551c41d42a1c4a9062969f17ed6 Mon Sep 17 00:00:00 2001 From: Mariusz Wisniewski Date: Mon, 29 Aug 2016 16:13:55 -0400 Subject: [PATCH 22/28] Readme edits --- docs/custom_sockets/examples/hello_world.md | 59 +++++++++++---------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index 394eaa0..7419ae1 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -2,20 +2,24 @@ ## Abstract -In this example the simple Custom Socket will be created. The idea is to create an endpoint which will return +In this example we will create a simple Custom Socket. Idea here is to create an endpoint which will return a `Hello world` message. ## Repository link -The whole example can be found under: [Syncano/custom-socket-hello-world](https://github.com/Syncano/custom-socket-hello-world) -This can be installed in Syncano instance using the install from url functionality in CLI. The url is: url here +Whole example can be found under: [Syncano/custom-socket-hello-world](https://github.com/Syncano/custom-socket-hello-world) +It's possible to install it to Syncano Instance using `install from url` functionality in CLI. The URL is: + +`https://github.com/Syncano/custom-socket-hello-world/blob/master/socket.yml` ## Prerequisites -1. Syncano Account - Create one [here](https://www.syncano.io/). -2. GIT - for repository clone: `git clone git@github.com:Syncano/custom-socket-hello-world.git`. If you want to edit - files locally. -3. Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. +* Syncano Account - [Create one here](https://www.syncano.io/). +* GIT - If you want to edit files locally, clone our repository using: +```bash +git clone git@github.com:Syncano/custom-socket-hello-world.git +```` +* Syncano [CLI tool](https://pypi.python.org/pypi/syncano-cli/0.5) in version 0.5 or higher. > Note: > It is nice to use virtualenv to separate your tools: `sudo pip install virtualenv` @@ -40,9 +44,13 @@ This can be installed in Syncano instance using the install from url functionali hello_world: runtime_name: python_library_v5.0 file: scripts/hello_world.py + +Above YAML file defines one Custom Socket with one endpoint: +* `hello_endpoint` for printing hello world on every HTTP method call. + +There is also one `script` dependency defined, to `hello_world` script. -The above YAML definition will store definition of the new Custom Socket with name `hello_world`. It defines one endpoint: -`hello_endpoint` with one dependency: `hello_world` script. In my favourite editor the project look as follows: +In my favourite editor the project look as follows: ![](../images/project_struct.png) @@ -65,41 +73,39 @@ The script (`scripts/hello_world.py`) consist of a few lines: set_response(HttpResponse(status_code=200, content=content, content_type='text/html')) -The above code executed in Syncano will return a valid html response with `Hellow World!` message inside. -The `set_response` is a function which allow to return custom response from the script. +The above code executed in Syncano will return a valid HTML response with `Hello World!` message inside. +The `set_response` is a function which allows returning custom response (e.g. in JSON, CSV or HTML format) from the script. ## Custom Socket directory structure -As can be seen in the example above the basic structure of Custom Socket is: +As can be seen in the example above, the basic structure of this Custom Socket is: . ├── scripts │   └── hello_world.py └── socket.yml -The `socket.yml` file stores YAML definition of the Custom Socket, and under `scripts` directory there a definition +`socket.yml` file stores YAML definition of the Custom Socket, and under `scripts` directory there is a definition of Custom Socket dependencies (currently of type `script`). -## Pulling everything together +## Putting everything together ### Steps: -1. Assuming that you have Syncano CLI installed, do a login: `syncano login --instance-name your-instance-name` +1. Assuming that you have Syncano CLI installed, log in using: `syncano login --instance-name your-instance-name` In my case it is: syncano login --instance-name patient-resonance-4283 - Next you will see the prompt for `username` and `password`; Provide it. + Next you will see a prompt for `username` and `password`; provide both and confirm with `enter`. -2. There are two ways of installing Custom Socket - one is using your local files and the second is to use a url. +2. There are two ways of installing a Custom Socket - one is using your local files and the second one is by using a URL. To install Custom Socket from url do: syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-hello-world/master/socket.yml --name hello_world - In such scenario - you do not need even clone the repository to your local machine. The name here is needed - because - under the hood empty Custom Socket is created - and code fetch from repository is done asynchronously in second - step. + In such scenario - you do not even need to clone the repository to your local machine. The `--name` parameter and name here are needed - because under the hood, empty Custom Socket is created - and code fetching from repository is done asynchronously in the second step. To install Custom Socket from local files do: @@ -113,7 +119,7 @@ of Custom Socket dependencies (currently of type `script`). 3. Try a newly created Custom Socket: - To list a Custom Sockets, do: + To list Custom Sockets, do: syncano sockets list @@ -124,10 +130,9 @@ of Custom Socket dependencies (currently of type `script`). name: hello_world status: ok - This mean that Custom Socket hello_world was created successfuly - the status is `ok`. In any other case you will see - here and `error` and detailed information in `info` - what was wrong. + This means that Custom Socket `hello_world` was created successfuly - the status is `ok`. In any other case you will see here an `error` and detailed information in `info` about what went wrong. - Now list the defined endpoints: + Now, list all defined endpoints: syncano sockets list endpoints @@ -162,7 +167,7 @@ of Custom Socket dependencies (currently of type `script`). Lets see if output can be seen in the browser: Go to: `https://api.syncano.io/v1.1/instances/your-instance-name/endpoints/sockets/hello_world/hello_endpoint/?api_key=your_api_key` - We defined the endpoint to handle GET http method. + We defined the endpoint to handle GET HTTP method. In my case: @@ -174,5 +179,5 @@ of Custom Socket dependencies (currently of type `script`). ## Summary -Hope this will help. If you have any question or problems do no hesitate to contact me: sebastian.opalczynski@syncano.com -Also I am available on the Syncano slack community: http://syncano-community.github.io/slack-invite/ +Hope this was helpful! If you have any question or issues, do no hesitate to contact me directly: sebastian.opalczynski@syncano.com +I am also available on the [Syncano Slack community](http://syncano-community.github.io/slack-invite/). See you there! From d27bad8b18a017b533f198d69be241644a037101 Mon Sep 17 00:00:00 2001 From: Todd Date: Mon, 29 Aug 2016 15:15:29 -0500 Subject: [PATCH 23/28] Update advanced.md --- docs/custom_sockets/examples/advanced.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/custom_sockets/examples/advanced.md b/docs/custom_sockets/examples/advanced.md index 8b0a2e1..2eba3eb 100644 --- a/docs/custom_sockets/examples/advanced.md +++ b/docs/custom_sockets/examples/advanced.md @@ -4,14 +4,14 @@ This in an advanced example of Syncano Custom Sockets, showing an integration with Mailgun (https://mailgun.com/). -We will use Mailgun sandbox environment, that allows sending up to 300 mails per day - it should be more than enough for testing. +We will use Mailgun's sandbox environment, which allows sending up to 300 emails per day - it should be more than enough for testing. -We will implement two endpoint inside Custom Socket - one for sending emails, and second one to obtain some basic statistics. +We will implement two endpoints inside the Custom Socket - one for sending emails, and a second one to obtain some basic statistics. ## Repository link -Whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example). -It can be installed to your Syncano instance using the `install from url` functionality in CLI. The url is: +The whole example can be found under: [Syncano/custom-socket-advanced-example](https://github.com/Syncano/custom-socket-advanced-example). +It can be installed to your Syncano instance using the `install from url` functionality in the CLI. The url is: https://github.com/Syncano/custom-socket-advanced-example/blob/master/socket.yml @@ -31,7 +31,7 @@ git clone git@github.com:Syncano/custom-socket-advanced-example.git` > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` > Install Syncano CLI: `pip install syncano_cli>=0.5` -* Your favourite text editor. +* Your favorite text editor. ## YML definition @@ -60,7 +60,7 @@ git clone git@github.com:Syncano/custom-socket-advanced-example.git` file: scripts/get_stats.py Above YAML file defines one Custom Socket with two endpoints: -* `send_mail` for sending emails, it's run on POST HTTP method call; we want to pass here some basic information about who it should be sent to, what subject should be used and what text should be in the email itself; +* `send_mail` for sending emails, it's run on POST HTTP method call; we want to pass some basic information about who it should be sent to, what subject should be used and what text should be in the email itself; * `get_stats` - second endpoint is for obtaining basic stats from Mailgun service. There are also two `script` dependencies defined. @@ -107,7 +107,7 @@ There are also two `script` dependencies defined. set_response(HttpResponse(status_code=400, content=fail_content, content_type='application/json')) Script above will send a request to Mailgun service - and this service will send an email to a user. -It's worth to note the `CONFIG` variable - it's an Instance global config dictionary/map - you can define its content inside +It's worth noting the `CONFIG` variable - it's an Instance global config dictionary/map - you can define its content inside Syncano Dasboard under `Global Config` menu on the left, or using Syncano Libraries - more about it can be found [in our docs](http://docs.syncano.io/docs/snippets-scripts#section-global-config-dictionary). @@ -162,7 +162,7 @@ or in tree format: 2. There are two ways of installing a Custom Socket - one is using your local files and the second one is by using a URL. - To install Custom Socket from a URL do: + To install the Custom Socket from a URL do: syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-advanced-example/master/socket.yml --name mailgun_integration @@ -189,7 +189,7 @@ or in tree format: name: mailgun_integration status: ok - This means that Custom Socket `mailgun_integration` was created successfuly - the status is `ok`. In any other case you will see here an `error` and detailed information in `info` about what went wrong. + This means that Custom Socket `mailgun_integration` was created successfuly - the status is `ok`. In any other case you will see an `error` and detailed information in `info` about what went wrong. Now, list all defined endpoints: @@ -259,7 +259,7 @@ or in tree format: Above response is one-to-one to the response provided by Mailgun. - Now lets send an e-mail! + Now let's send an e-mail! Run: From c567ed0782c210a712f21ea269c1de4660b753d8 Mon Sep 17 00:00:00 2001 From: Todd Date: Mon, 29 Aug 2016 15:19:18 -0500 Subject: [PATCH 24/28] Update hello_world.md --- docs/custom_sockets/examples/hello_world.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/custom_sockets/examples/hello_world.md b/docs/custom_sockets/examples/hello_world.md index 7419ae1..d806c3a 100644 --- a/docs/custom_sockets/examples/hello_world.md +++ b/docs/custom_sockets/examples/hello_world.md @@ -2,12 +2,12 @@ ## Abstract -In this example we will create a simple Custom Socket. Idea here is to create an endpoint which will return +In this example we will create a simple Custom Socket. The idea here is to create an endpoint which will return a `Hello world` message. ## Repository link -Whole example can be found under: [Syncano/custom-socket-hello-world](https://github.com/Syncano/custom-socket-hello-world) +The whole example can be found under: [Syncano/custom-socket-hello-world](https://github.com/Syncano/custom-socket-hello-world) It's possible to install it to Syncano Instance using `install from url` functionality in CLI. The URL is: `https://github.com/Syncano/custom-socket-hello-world/blob/master/socket.yml` @@ -26,7 +26,7 @@ git clone git@github.com:Syncano/custom-socket-hello-world.git > Then create virtual env: `virtualenv cli` and active it: `source cli/bin/activate` > Install Syncano CLI: `pip install syncano_cli>=0.5` -4. Your favourite text editor. +4. Your favorite text editor. ## YML definition @@ -50,13 +50,13 @@ Above YAML file defines one Custom Socket with one endpoint: There is also one `script` dependency defined, to `hello_world` script. -In my favourite editor the project look as follows: +In my favorite editor the project look as follows: ![](../images/project_struct.png) ## Scripts definition -The script (`scripts/hello_world.py`) consist of a few lines: +The script (`scripts/hello_world.py`) consists of a few lines: content = """ @@ -73,8 +73,8 @@ The script (`scripts/hello_world.py`) consist of a few lines: set_response(HttpResponse(status_code=200, content=content, content_type='text/html')) -The above code executed in Syncano will return a valid HTML response with `Hello World!` message inside. -The `set_response` is a function which allows returning custom response (e.g. in JSON, CSV or HTML format) from the script. +The above code executed in Syncano will return a valid HTML response with the `Hello World!` message inside. +The `set_response` is a function which returns a custom response (e.g. in JSON, CSV or HTML format) from the script. ## Custom Socket directory structure @@ -101,11 +101,11 @@ of Custom Socket dependencies (currently of type `script`). 2. There are two ways of installing a Custom Socket - one is using your local files and the second one is by using a URL. - To install Custom Socket from url do: + To install the Custom Socket from url do: syncano sockets install https://raw.githubusercontent.com/Syncano/custom-socket-hello-world/master/socket.yml --name hello_world - In such scenario - you do not even need to clone the repository to your local machine. The `--name` parameter and name here are needed - because under the hood, empty Custom Socket is created - and code fetching from repository is done asynchronously in the second step. + In this scenario - you do not even need to clone the repository to your local machine. The `--name` parameter and name here are needed - because under the hood, an empty Custom Socket is created - and fetching code from the repository is done asynchronously in the second step. To install Custom Socket from local files do: From 68e9f622c2e6546eea7037fc943b21c2666b0a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Tue, 30 Aug 2016 14:29:22 +0200 Subject: [PATCH 25/28] [CORE-1640] remove local paths; --- syncano_cli/base/connection.py | 2 +- syncano_cli/main.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/syncano_cli/base/connection.py b/syncano_cli/base/connection.py index 45bc94c..d27ab5a 100644 --- a/syncano_cli/base/connection.py +++ b/syncano_cli/base/connection.py @@ -12,7 +12,7 @@ def create_connection(config): ACCOUNT_CONFIG.read(config) api_key = ACCOUNT_CONFIG.get('DEFAULT', 'key') connection_dict = { - 'api_key': api_key + 'api_key': api_key, } instance_name = ACCOUNT_CONFIG.get('DEFAULT', 'instance_name', None) if instance_name: diff --git a/syncano_cli/main.py b/syncano_cli/main.py index c0f480b..7268340 100644 --- a/syncano_cli/main.py +++ b/syncano_cli/main.py @@ -12,9 +12,6 @@ from syncano_cli.parse_to_syncano.commands import top_migrate from syncano_cli.sync.commands import top_sync -sys.path.append('/home/sopalczy/projects/syncano/syncano-cli') -sys.path.append('/home/sopalczy/projects/syncano/syncano-python') - ACCOUNT_KEY = '' From b292ec9416a441ab11030ad6e6c433f7ff3f08fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Tue, 30 Aug 2016 16:10:43 +0200 Subject: [PATCH 26/28] [CORE-1640] update required LIB version; --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c8dfaad..f7b16ce 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ url='https://github.com/Syncano/syncano-cli', packages=find_packages(), license='MIT', - install_requires=['syncano>=5.4.0', 'PyYaml>=3.11', 'watchdog>=0.8.3', 'click>=6.6'], + install_requires=['syncano>=5.4.1', 'PyYaml>=3.11', 'watchdog>=0.8.3', 'click>=6.6'], test_suite='tests', entry_points=""" [console_scripts] From a9643edfa8d0280eb77c035b792c1a607bbdbd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Tue, 30 Aug 2016 16:53:32 +0200 Subject: [PATCH 27/28] [CORE-1640] correct isort and tests; --- syncano_cli/main.py | 1 - tests/test_hosting_commands.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/syncano_cli/main.py b/syncano_cli/main.py index 7268340..b3fef11 100644 --- a/syncano_cli/main.py +++ b/syncano_cli/main.py @@ -12,7 +12,6 @@ from syncano_cli.parse_to_syncano.commands import top_migrate from syncano_cli.sync.commands import top_sync - ACCOUNT_KEY = '' cli = click.CommandCollection( diff --git a/tests/test_hosting_commands.py b/tests/test_hosting_commands.py index a3c21d5..4ec2a53 100644 --- a/tests/test_hosting_commands.py +++ b/tests/test_hosting_commands.py @@ -42,7 +42,7 @@ def test_hosting_commands(self): def _get_list_output(self): result = self.runner.invoke(cli, args=[ 'hosting', 'list' - ]) + ], obj={}) return result def _publish_files(self): From df8d4abdaebcea20abf5ddd5c8a1c8bff13ab323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Opa=C5=82czy=C5=84ski?= Date: Wed, 31 Aug 2016 12:08:04 +0200 Subject: [PATCH 28/28] [RELEASE v0.6] bump the version; --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f7b16ce..7e31d14 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='syncano-cli', - version='0.5', + version='0.6', description='Syncano command line utilities', long_description=README, author='Marcin Swiderski, Sebastian Opalczynski',