Node.js SDK
Note: This page explains using The Ops Platform SDK in Node.js. The SDK can also be used in other programming languages such as Python, Golang, or Bash.
The Node.js support in The Ops Platform SDK allows you to write Ops in either JavaScript or Typescript. When you run ops init
from the command-line, a JavaScript project will be created for you. To switch to TypeScript, you can copy the default ops.yml and Dockerfile from the JavaScript project and add them to your TypeScript project.
Node SDK Installation
You can install and use the SDK in a Node.js project like this:
$ npm install @cto.ai/sdk
Usage:
const { sdk, ux } from '@cto.ai/sdk';
sdk.exec
sdk.exec(command: string): Promise<{ stdout: string, stderr: string }>
Runs a shell command inside the container asynchronously. Returns the stdout
and stderr
output of the process.
Example:
Executing the following code in the command template:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
await sdk.exec('mkdir test-directory')
const { stdout, stderr } = await sdk.exec('ls')
sdk.log('stdout is:\n', stdout)
sdk.log('stderr is:\n', stderr)
}
main()
will create a folder named test-directory
in the container, and logs the following text.
stdout is:
demo.js
index.js
node_modules
package-lock.json
package.json
test-directory
stderr is:
sdk.getHostOS
sdk.getHostOS(): string
Returns the Operating System the host is running on. For remote ops, will return "unknown"
as no host is accessible in the remote environment.
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const hostOs = sdk.getHostOS()
sdk.log("Host's os is:", hostOs)
}
Output:
Host's os is: darwin
sdk.homeDir
sdk.homeDir(): string
Returns the home directory of the host machine.
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const homeDir = sdk.homeDir()
console.log("Host's home directory is:", homeDir)
}
Output:
Host's home directory is: /root
sdk.log
sdk.log(...args: any[]): void
Logs to the console in in a standardized way. Will not be relayed to
the user in a remote environment (use ux.print
for that).
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
sdk.log('I am a log!', '\nI am too!')
}
Output:
I am a log!
I am too!
sdk.getStatePath
sdk.getStatePath(): string
Returns the path of the state directory. The contents of this directory are persistent through a workflow, including on remote.
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const statePath = sdk.getStatePath()
sdk.log('The state path is:', statePath)
}
Output:
The state path is: /root/.config/@cto.ai/ops/superman/test-op/00000000-1111-2222-3333-444444444444
sdk.getConfigPath
sdk.getConfigPath(): string
Returns the path of the config directory. This directory is persistent across multiple runs of the op if the mountHome
option in ops.yml
is set to true.
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const configPath = sdk.getConfigPath()
sdk.log('The config path is:', configPath)
}
Output:
The config path is: /root/.config/@cto.ai/ops/superman/test-op
sdk.setState
sdk.setState(key: string, value: any): Promise<void>
Stores a key-value pair in the workflow-local state. If the key is already present, the value will be replaced with the one provided.
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const key = 'test-key'
// state = {}
const initialState = await sdk.getState(key)
sdk.log('Initial state', initialState)
// state = { test-key: 'Value one' }
await sdk.setState(key, 'Value one')
const insertedState = await sdk.getState(key)
sdk.log('Inserted state', insertedState)
// state = { test-key: 'Value two' }
await sdk.setState(key, 'Value two')
const updatedState = await sdk.getState(key)
sdk.log('Updated state', updatedState)
}
Output:
Initial state undefined
Inserted state Value one
Updated state Value two
sdk.getState
sdk.getState(key: string): Promise<any>
Gets the value that is saved under the given key in the workflow-local state, or undefined
if the key is not set.
Example:
See sdk.setState
above
sdk.setConfig
sdk.setConfig(key: string, value: any): Promise<void>
Stores a key-value pair in the persistent configuration. If the key is already present, the value will be replaced with the one provided. This function requires mountHome: true
in the ops.yml
Example:
import { sdk } from '@cto.ai/sdk'
const main = async () => {
const key = 'test-key'
// config = {}
const initialConfig = await sdk.getConfig(key)
sdk.log('Initial config', initialConfig)
// config = { test-key: 'Value one' }
await sdk.setConfig(key, 'Value one')
const insertedConfig = await sdk.getConfig(key)
sdk.log('Inserted config', insertedConfig)
// config = { test-key: 'Value two' }
await sdk.setConfig(key, 'Value two')
const updatedConfig = await sdk.getConfig(key)
sdk.log('Updated config', updatedConfig)
}
Output:
Initial config undefined
Inserted config Value one
Updated config Value two
sdk.getConfig
sdk.getConfig(key: string): Promise<any>
Gets the value that is saved under the given key in the persistent configuration, or undefined
if the key is not set.
Example
See sdk.setConfig
above
sdk.track
sdk.track(tags, metadata): Promise<any>
Send an analytics tracking event to the Ops Platform.
- tags: (String || String[]) Tags for the event you want to track
- metaData: (Object) Data you want to be tracked
Terminology
Config
The SDK provides persistent config so that your op can store data on the host between executions. This can be accessed with the sdk.setState
and sdk.getState
functions.
- The config is stored in a JSON file at the host path
~/.config/@cto.ai/ops/${username}/${opName}/config.json
- Configs are persisted if the code is executed multiple times
- Each op has its own config, and cannot affect any other op's config
State
The SDK provides a mechanism for maintaining state through the different steps of a workflow. Anything stored in the state directory (found with sdk.getStatePath
) will be available in later steps. Additionally, the SDK provides key/value storage in the state similar to the config.
- Locally, the state is stored in the following directory:
~/.config/@cto.ai/ops/${username}/${opName}/${runId}
, with the key/value store saved in `state.json therein. - Each execution of a workflow is a different run and will have a different state, which will initially be blank.