Actions are like small programs that can be executed against your Slingshot database. (If you're familiar with other database systems, you can think of actions like stored procedures.)

Actions can be written in either Python 2.7 or a specially-built language called Bairdi. It is recommended to write Actions using Python if you are familiar with how to write programs or scripts and Bairdi if you prefer a more command-oriented experience.

Python Actions

Python actions function exactly like any other Python execution environment and run programs using the IronPython execution environment.

Before your action runs, the execution environment creates two variables for you. slingshot is an object that provides access to several Slinghot-specific methods; these roughly correspond to the commands provided by the Bairdi environment. When an action is executed from a POST request, body is initialized to the POST body.

When the action is finished, the "output" of the action is considered to be the value of the result variable, if it exists, or anything written to standard output otherwise. Note that if you set result to an "empty" value like "", this is still treated as the result of the action.

Currently, standard error is ignored.

Do not try to use standard input, as the standard input stream is closed before running your action.

Bairdi Actions

Bairdi Actions consist of a series of commands. When the action is executed, each command is executed on the currently-available context in order. Typically this context is a document from the Slingshot database, but can also be something explicitly placed into context (via a use command) or downloaded from the web (via e.g. a wget command).

While each command in an action takes the current context as input and replaces the value in context on successful execution, intermediate values can also be saved to explicit names ("variables") to be retrieved later.

Some commands also can take one or more "arguments", which specifiy additional information necessary to complete the specific command's purpose. For instance, the use command requires a value to place into the context, so it would be used as follows:

use "Hello, world!"

This would place the value "Hello, world" into context for the next command to operate on.

Commands

% or addheader

Python Example:

slingshot.AddHeader("api.myservice.com", "Authorization: bearer yourtokenhere")

Bairdi Example:

% api.myservice.com "Authorization: bearer yourtokenhere"

This command sets a header to be used for all web requests to the specified domain. These headers are used with the wget, wpost, etc. family of commands. The most common usage is to set the authentication token for API requests.

This command does not affect the current value in context.

NOTE: It is not recommended to use this command to access the Slingshot REST API.

atob64

Python Example:

output = slingshot.Atob64('Text to encode')

Bairdi Example:

use 'Text to encode'
atob64

This command base-64 encodes the value in the context, converting it to text if necessary, and stores the result in context.

basename

Python Example:

basename = slingshot.Basename('path/to/file/ext')

Bairdi Example:

use 'path/to/file.ext'
basename

This command extracts the file name (including any extension) from the current value in context (which is assumed to be a path) and stores the result in context. The value in context at the end of the example is "file.ext".

count

Python Example:

numItems = slingshot.Count(someList)

Bairdi Example:

// Assume the current value in context is a list
count

This command counts the number of items in the current value in context if it is a list and stores this number in context. If the current value in context is not countable, the command will fail.

get, list, post, put, patch, delete

These commands interact with Slingshot collections and documents

Python Examples:

docs = slingshot.List("posts", "$.public == true")
doc = slingshot.Get("posts", "00000000-0000-0000-0000-000000000000")
slingshot.Post("posts", doc)
slingshot.Put("posts", "00000000-0000-0000-0000-000000000000", doc)
slingshot.Patch("posts", "00000000-0000-0000-0000-000000000000", doc)
slingshot.Delete("posts", "00000000-0000-0000-0000-000000000000")
slingshot.Delete("posts", doc)
doc = slingshot.New()

Bairdi Examples:

// The following commands do not use the context, but do put their results into it
list posts "$.public == true"
get posts "00000000-0000-0000-0000-000000000000"
delete posts "00000000-0000-0000-0000-000000000000"

// The following commands do use the context as the request body, and also put their
.. results into it
post posts
put posts "00000000-0000-0000-0000-000000000000"
patch posts "00000000-0000-0000-0000-000000000000"
delete posts
new

These commands are all run as the same user that is running the Action, which means that authorization is verified for each collection/entity.

jsonpath

Python Examples:

value = slingshot.JsonPath(object, "Values[0].Name")
slingshot.JsonPath(object, "Values[0].Name", "New Name")

Bairdi Examples:

jsonpath Values[0].Name
jsonpath Values[0].Name "new name"

This command traverses the current value in context, assuming it to be a JSON data structure. In the first form, it extracts the value or values at the path provided and stores them in context. In the second form, it sets the provided value at the specified path, adding it to the object if necessary, and stores the complete original object back to context with the specified changes.

For instance, if the following object were in context prior to executing each of the above examples:

{
    "Values": [
        {
            "Name": "old name"
        }
    ]
}

The context after executing only the first example would look like

old name

The context after executing only the second example would look like

{
    "Values": [
        {
            "Name": "new name"
        }
    ]
}

sedt

Python Examples:

sanitized = slingshot.Sedt(original, '#', ' ')
sanitized = slingshot.Sedt(original, ' ')

Bairdi Examples:

use 'This#has#weird#characters'
sedt # ' '

use 'This has    too many spaces'
sedt ' '

This command is essentially a find-and-replace. The first example will replace each occurrence of "#" with a space and store the result back in context. The second example will remove all spaces from the value in context.

sendmail and mail

Note: The two names are equivalent in Bairdi, but only Sendmail exists in Python.

Python Example:

slingshot.Sendmail(message,
    "to", "bob@example.com",
    "cc", "alice@example.com",
    "bcc", "george@example.com",
    "from", "cecil@example.com",
    "subject", "Testing the mail system")

Bairdi Example:

mail to bob@example.com cc alice@example.com bcc george@example.com from cecil@example.com subject "Testing the mail system"

This command sends the current value in context as the body of an email message with the specified TO, CC, BCC, and From addresses and the specified Subject. All information is optional, except the from address must either be specified in the command or via the default in System Settings.

Multiple To, CC, and BCC addresses can be specified by separating them with spaces. For example:

mail to bob@example.com larry@nowhere.edu cc larry@stooges.com moe@stooges.com curly@stooges.com subject "Hello!"

There is currently no way to specify a content-type for the message; instead it is autodetected (usually as plain text).

wget, wpost, wput, wpatch, and wdelete

Python Examples:

response = slingshot.Wget("http://mydomain.com/api/values")
response = slingshot.Wpost(postUrl, postBody)

Bairdi Example:

wget http://mydomain.com/api/values

This family of commands sends web (HTTP) requests. Each name corresponds to one of the common HTTP "verbs": GET, POST, PUT, PATCH, and DELETE.

wpost, wput, and wpatch send the current value in context as the body of the request (for Python Actions, this value is specified explicitly as the second argument to the call).

In Bairdi Actions, all forms store the response body in context afterward; this does mean that typically after executing a wdelete the context will be empty or null.

These commands all use any headers that have been specified using % or addheader for the domain in the specified URL.

xpath

Python Example:

value = slingshot.Xpath(xmlString, "//element/@id")

Bairdi Example:

xpath //element/@id

Extracts the value at the provided XPATH and (for Bairdi) saves it in the context or (for Python) returns it to be saved in the specified variable.