@platforma-sdk/workflow-tengo 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  declare type TemplateFromFile = { readonly type: "from-file"; readonly path: string; };
2
- declare type TplName = "pframes.aggregate" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.map-pframe" | "workdir.save" | "workflow.build-ctx" | "exec.python.install-deps" | "pframes.export-multiple-pcolumns" | "pframes.export-pframe" | "exec.python.create-venv" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-map";
2
+ declare type TplName = "pframes.aggregate" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.map-pframe" | "workdir.save" | "workflow.build-ctx" | "exec.R.create-renv" | "exec.python.install-deps" | "pframes.export-multiple-pcolumns" | "pframes.export-pframe" | "exec.python.create-venv" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-map";
3
3
  declare const Templates: Record<TplName, TemplateFromFile>;
4
4
  export { Templates };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ module.exports = { Templates: {
5
5
  'pframes.map-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.map-pframe.plj.gz') },
6
6
  'workdir.save': { type: 'from-file', path: require.resolve('./tengo/tpl/workdir.save.plj.gz') },
7
7
  'workflow.build-ctx': { type: 'from-file', path: require.resolve('./tengo/tpl/workflow.build-ctx.plj.gz') },
8
+ 'exec.R.create-renv': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.R.create-renv.plj.gz') },
8
9
  'exec.python.install-deps': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.install-deps.plj.gz') },
9
10
  'pframes.export-multiple-pcolumns': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-multiple-pcolumns.plj.gz') },
10
11
  'pframes.export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe.plj.gz') },
package/dist/index.mjs CHANGED
@@ -6,6 +6,7 @@ export const Templates = {
6
6
  'pframes.map-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.map-pframe.plj.gz') },
7
7
  'workdir.save': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/workdir.save.plj.gz') },
8
8
  'workflow.build-ctx': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/workflow.build-ctx.plj.gz') },
9
+ 'exec.R.create-renv': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.R.create-renv.plj.gz') },
9
10
  'exec.python.install-deps': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.install-deps.plj.gz') },
10
11
  'pframes.export-multiple-pcolumns': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-multiple-pcolumns.plj.gz') },
11
12
  'pframes.export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe.plj.gz') },
@@ -0,0 +1,29 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+ validation := import("@platforma-sdk/workflow-tengo:validation")
3
+ runcmd := import("@platforma-sdk/workflow-tengo:exec.runcmd")
4
+ pkg := import("@platforma-sdk/workflow-tengo:exec.package")
5
+ path := import("@platforma-sdk/workflow-tengo:path")
6
+
7
+ rVenvInputSchema := {
8
+ operationMode: "string",
9
+ toolset: "string",
10
+ dependencies: {"any": "string"},
11
+ software: validation.reference,
12
+
13
+ rDescriptor: pkg.runEnvDescriptorScheme,
14
+ R: validation.reference
15
+ }
16
+
17
+ runRBuilder := func(wd, rPackage, rDescriptor) {
18
+ return runcmd.builder(wd).
19
+ ref("r-run-environment", rPackage).
20
+ substitutionRule("{R}", "r-run-environment").
21
+ addToPath(path.join("{R}", rDescriptor.binDir), true).
22
+ envVar("R_HOME_DIR", "{R}").
23
+ envVar("RENV_PATHS_ROOT", path.join("{R}", "renv-root"))
24
+ }
25
+
26
+ export ll.toStrict({
27
+ rVenvInputSchema : rVenvInputSchema,
28
+ runRBuilder : runRBuilder
29
+ })
@@ -0,0 +1,186 @@
1
+ times := import("times")
2
+
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
4
+ oop := import("@platforma-sdk/workflow-tengo:oop")
5
+ validation := import("@platforma-sdk/workflow-tengo:validation")
6
+ assets := import("@platforma-sdk/workflow-tengo:assets")
7
+ smart := import("@platforma-sdk/workflow-tengo:smart")
8
+ render := import("@platforma-sdk/workflow-tengo:render")
9
+ pkg := import("@platforma-sdk/workflow-tengo:exec.package")
10
+ internal := import("@platforma-sdk/workflow-tengo:exec.R.internal")
11
+ runenv := import("@platforma-sdk/workflow-tengo:exec.runenv")
12
+
13
+ _OUTPUT_RUN_ENV := "runEnv"
14
+
15
+ rVenvBuilder := func() {
16
+ self := undefined
17
+
18
+ opMode := "remote"
19
+ toolset := "renv"
20
+ rDescriptor := undefined
21
+ softwareRef := undefined
22
+ dependencies := undefined
23
+ cache := 0
24
+
25
+ self = {
26
+ operationMode: func(mode) {
27
+ validation.assertJsonSchema(mode, "string",
28
+ "exec.R.operationMode: <mode> must be string")
29
+
30
+ ll.assert(mode == "remote" || mode == "dev-local",
31
+ "exec.R.operationMode: unsupported operation mode: 'remote', 'dev-local' are valid in this version of workflow-tengo SDK")
32
+
33
+ opMode = mode
34
+ return self
35
+ },
36
+
37
+ useToolset: func(name) {
38
+ validation.assertJsonSchema(name, "string",
39
+ "exec.R.useToolset: <name> must be valid name of R packaging toolset (i.e. 'renv')")
40
+ ll.assert(name != "", "exec.R.useToolset: toolset name must not be empty")
41
+
42
+ toolset = name
43
+ return self
44
+ },
45
+
46
+ runEnvDescriptor: func(descriptor) {
47
+ validation.assertJsonSchema(descriptor, pkg.runEnvDescriptorScheme, "exec.R.runEnvDescriptor: <descriptor> must be run environment specification")
48
+ ll.assert(descriptor.type == "R", "exec.R.runEnvDescriptor: not a 'R' run environment: %q", descriptor.type)
49
+
50
+ rDescriptor = ll.fromStrict(descriptor)
51
+ return self
52
+ },
53
+
54
+ software: func(pkgRef) {
55
+ validation.assertJsonSchema(pkgRef, validation.reference, "exec.R.software: <pkgRef> must be a reference to software package")
56
+
57
+ softwareRef = pkgRef
58
+ return self
59
+ },
60
+
61
+ dependencies: func(deps) {
62
+ validation.assertJsonSchema(deps, { "any": "string" }, "exec.R.dependencies: <deps> must be map of reference file paths")
63
+
64
+ dependencies = deps
65
+ return self
66
+ },
67
+
68
+ /**
69
+ * Sets the cache time in milliseconds.
70
+ *
71
+ * @param millis: number
72
+ */
73
+ cacheMillis: func(millis) {
74
+ ll.assert(is_int(millis) && millis > 0, "exec.R.cacheMillis: cache time must be a number of milliseconds")
75
+ cache = millis * times.millisecond
76
+ return self
77
+ },
78
+
79
+ /**
80
+ * Sets the cache time in seconds.
81
+ *
82
+ * @param seconds: number
83
+ */
84
+ cacheSeconds: func(seconds) {
85
+ ll.assert(is_int(seconds) && seconds > 0, "exec.R.cacheSeconds: cache time must be a number of seconds")
86
+ cache = seconds * times.second
87
+ return self
88
+ },
89
+
90
+ /**
91
+ * Sets the cache time in minutes.
92
+ *
93
+ * @param minutes: number
94
+ */
95
+ cacheMinutes: func(minutes) {
96
+ ll.assert(is_int(minutes) && minutes > 0, "exec.R.cacheMinutes: cache time must be a number of minutes")
97
+ cache = minutes * times.minute
98
+ return self
99
+ },
100
+
101
+ /**
102
+ * Sets the cache time in hours.
103
+ *
104
+ * @param hours: number
105
+ */
106
+ cacheHours: func(hours) {
107
+ ll.assert(is_int(hours) && hours > 0, "exec.R.cacheHours: cache time must be a number of hours")
108
+ cache = hours * times.hour
109
+ return self
110
+ },
111
+
112
+ /**
113
+ * Sets the cache time in days
114
+ *
115
+ * @param days: number
116
+ */
117
+ cacheDays: func(days) {
118
+ ll.assert(is_int(days) && days > 0, "exec.R.cacheDays: cache time must be a number of days")
119
+ cache = days * times.hour * 24
120
+ return self
121
+ },
122
+
123
+ /**
124
+ * @deprecated, use cacheMillis, cacheSeconds, cacheMinutes, cacheHours and cacheDays instead.
125
+ * Sets the cache time.
126
+ *
127
+ * @param time: duration - the cache time from 'times' library.
128
+ */
129
+ cache: func(time) {
130
+ ll.assert(
131
+ is_int(time) && time > times.millisecond,
132
+ "exec.R.cache: cache time must be an integer. " +
133
+ "Did you forget to import a standard tengo library 'times'?")
134
+ cache = time
135
+ return self
136
+ },
137
+
138
+ build: func() {
139
+ archive := pkg.get(rDescriptor.registry, rDescriptor.package).archive()
140
+ rPkg := pkg.install(archive).package()
141
+
142
+ rVenvInputs := {
143
+ operationMode: opMode,
144
+ toolset: toolset,
145
+ dependencies: dependencies,
146
+ software: softwareRef,
147
+ rDescriptor: rDescriptor,
148
+ R: rPkg
149
+ }
150
+
151
+ validation.assertJsonSchema(rVenvInputs, internal.rVenvInputSchema, "incomplete R runenv configuration")
152
+
153
+ tpl := render.create(assets.importTemplate("@platforma-sdk/workflow-tengo:exec.R.create-renv"), rVenvInputs)
154
+
155
+ self := undefined
156
+ self = ll.toStrict(oop.inherit(tpl, {
157
+ /**
158
+ * R virtual environment with all dependencies installed.
159
+ *
160
+ * @return renv: smart.field - a reference to the R portable run environment.
161
+ */
162
+ venv: func() {
163
+ return tpl.output(_OUTPUT_RUN_ENV, cache)
164
+ },
165
+
166
+ /**
167
+ * R runtime used for R virtual environment creation.
168
+ *
169
+ * @return R: smart.Field - a reference to the R runtime.
170
+ */
171
+ R: func() {
172
+ return rPkg
173
+ }
174
+ }))
175
+
176
+ return self
177
+ }
178
+ }
179
+
180
+ return self
181
+ }
182
+
183
+
184
+ export ll.toStrict({
185
+ rVenvBuilder : rVenvBuilder
186
+ })
@@ -13,12 +13,16 @@ oop := import("@platforma-sdk/workflow-tengo:oop")
13
13
  maps := import("@platforma-sdk/workflow-tengo:maps")
14
14
  path := import("@platforma-sdk/workflow-tengo:path")
15
15
  pkg := import("@platforma-sdk/workflow-tengo:exec.package")
16
- runenv := import("@platforma-sdk/workflow-tengo:exec.runenv")
16
+ runcmd := import("@platforma-sdk/workflow-tengo:exec.runcmd")
17
+ python := import("@platforma-sdk/workflow-tengo:exec.python")
18
+ R := import("@platforma-sdk/workflow-tengo:exec.R")
17
19
 
18
20
  // Variables, substituted in command arguments and environment variable values
19
21
  _ARG_VAR_PKG := "{pkg}" // abs path to software package
20
22
  _ARG_VAR_JAVA := "{java}" // abs path to 'java' run environment
21
23
  _ARG_VAR_PYTHON := "{python}" // abs path to 'python' run environment
24
+ _ARG_VAR_R := "{R}" // abs path to 'R' run environment runtime
25
+ _ARG_VAR_R_VENV := "{rVenv}" // abs path to 'R' portable virtual environment
22
26
 
23
27
  /**
24
28
  * Create new argument marking it as 'with' or 'without' variables inside.
@@ -67,19 +71,21 @@ _directCallOptions := func(runOptions) {
67
71
  })
68
72
  }
69
73
 
70
- _loadJavaRunEnvironment := func(descriptor) {
74
+ _loadJavaRunEnvironment := func(operationMode, descriptor) {
71
75
  javaPkg := _installSoftware(descriptor.runEnv.registry, descriptor.runEnv.package)
72
76
  javaRefVar := _newRefVar(_ARG_VAR_JAVA, descriptor.runEnv.name, javaPkg)
73
77
 
74
78
  return ll.toStrict({
79
+ runEnvType: "java",
80
+
75
81
  variables: [ javaRefVar ],
76
82
  customPaths: [ _newArg(true, path.join(_ARG_VAR_JAVA, descriptor.runEnv.binDir)) ],
77
83
  envs: {}
78
84
  })
79
85
  }
80
86
 
81
- _loadPythonRunEnvironment := func(descriptor, softName, softPkg) {
82
- venvBuilder := runenv.pythonVenv().
87
+ _loadPythonRunEnvironment := func(operationMode, descriptor, softName, softPkg) {
88
+ venvBuilder := python.venvBuilder().
83
89
  software(softPkg).
84
90
  runEnvDescriptor(descriptor.runEnv).
85
91
  dependencies(descriptor.dependencies)
@@ -99,6 +105,8 @@ _loadPythonRunEnvironment := func(descriptor, softName, softPkg) {
99
105
  pythonRefVar := _newRefVar(_ARG_VAR_PYTHON, venvRefKey, venv)
100
106
 
101
107
  return ll.toStrict({
108
+ runEnvType: "python",
109
+
102
110
  variables: [ pythonRefVar ],
103
111
  customPaths: [ _newArg(true, path.join(venvRoot, "bin")) ],
104
112
  envs: {
@@ -107,27 +115,78 @@ _loadPythonRunEnvironment := func(descriptor, softName, softPkg) {
107
115
  })
108
116
  }
109
117
 
110
- _loadRunEnvironment := func(descriptor, softName, softPackage) {
118
+ _loadRRunEnvironment := func(operationMode, descriptor, softName, softPkg) {
119
+ renvBuilder := R.rVenvBuilder().
120
+ operationMode(operationMode).
121
+ software(softPkg).
122
+ runEnvDescriptor(descriptor.runEnv).
123
+ dependencies(descriptor.dependencies)
124
+
125
+ if !is_undefined(descriptor.toolset) && descriptor.toolset != "" {
126
+ renvBuilder.useToolset(descriptor.toolset)
127
+ }
128
+
129
+ rRuntime := renvBuilder.
130
+ cacheDays(7).
131
+ build()
132
+
133
+ rEnv := rRuntime.venv()
134
+ rPackage := rRuntime.R()
135
+
136
+ rBinDir := path.join(_ARG_VAR_R, descriptor.runEnv.binDir)
137
+
138
+ rRefKey := softName + "/R-runtime"
139
+ rRefVar := _newRefVar(_ARG_VAR_R, rRefKey, rPackage)
140
+
141
+ rEnvRefKey := softName + "/R-virtual-env"
142
+ rEnvRefVar := _newRefVar(_ARG_VAR_R_VENV, rEnvRefKey, rEnv)
143
+
144
+ return ll.toStrict({
145
+ runEnvType: "R",
146
+
147
+ variables: [ rRefVar, rEnvRefVar ],
148
+ customPaths: [ _newArg(true, rBinDir) ],
149
+ envs: {
150
+ "R_HOME_DIR": _newArg(true, _ARG_VAR_R),
151
+ "RENV_PATHS_ROOT": _newArg(true, path.join(_ARG_VAR_R, "renv-root")),
152
+ "RENV_PATHS_RENV": _newArg(true, path.join(_ARG_VAR_R_VENV, "renv")),
153
+ "RENV_PATHS_LOCKFILE": _newArg(true, path.join(_ARG_VAR_PKG, descriptor.dependencies.lockFile)),
154
+ "RENV_CONFIG_AUTO_SNAPSHOT": _newArg(false, "FALSE"),
155
+ "RENV_CONFIG_SYNCHRONIZED_CHECK": _newArg(false, "FALSE")
156
+ }
157
+ })
158
+ }
159
+
160
+
161
+ _loadRunEnvironment := func(operationMode, descriptor, softName, softPackage) {
111
162
  if descriptor.runEnv.type == "java" {
112
- return _loadJavaRunEnvironment(descriptor)
163
+ return _loadJavaRunEnvironment(operationMode, descriptor)
113
164
  }
114
165
  if descriptor.runEnv.type == "python" {
115
- return _loadPythonRunEnvironment(descriptor, softName, softPackage)
166
+ return _loadPythonRunEnvironment(operationMode, descriptor, softName, softPackage)
167
+ }
168
+ if descriptor.runEnv.type == "R" {
169
+ return _loadRRunEnvironment(operationMode, descriptor, softName, softPackage)
116
170
  }
117
171
 
118
172
  ll.panic("run environment type %q is not currently supported by workflow-sdk", descriptor.runEnv.type)
119
173
  }
120
174
 
121
- _binPackageCallOptions := func(runOptions, variables, descriptor, softPackage) {
175
+ /**
176
+ * @param operationMode: 'remote' | 'dev-local'
177
+ */
178
+ _binPackageCallOptions := func(operationMode, runOptions, variables, descriptor, softPackage) {
122
179
  customPaths := []
123
180
  envs := ll.toStrict({})
124
181
  args := []
182
+ runEnvType := "binary"
125
183
 
126
184
  // Real command should be:
127
185
  // [<runEnv bin>] [<runEnv options>] [<entrypoint bin>] [<entrypoint options>] <cmd> <args>
128
186
  if (maps.containsKey(descriptor, "runEnv")) {
129
- runEnvInfo := _loadRunEnvironment(descriptor, runOptions.software.name, softPackage)
187
+ runEnvInfo := _loadRunEnvironment(operationMode, descriptor, runOptions.software.name, softPackage)
130
188
 
189
+ runEnvType = runEnvInfo.runEnvType
131
190
  if len(runEnvInfo.variables) > 0 {
132
191
  variables = append(variables, runEnvInfo.variables...)
133
192
  }
@@ -157,6 +216,7 @@ _binPackageCallOptions := func(runOptions, variables, descriptor, softPackage) {
157
216
  }
158
217
 
159
218
  return oop.inherit(runOptions, {
219
+ runEnvType: runEnvType,
160
220
  variables: variables,
161
221
  customPaths: customPaths,
162
222
  cmd: cmd,
@@ -182,7 +242,7 @@ _devLocalPackageCallOptions := func(runOptions) {
182
242
 
183
243
  variables := [ _newRefVar(_ARG_VAR_PKG, software.name, softPackage) ]
184
244
 
185
- return _binPackageCallOptions(runOptions, variables, localDescriptor, softPackage)
245
+ return _binPackageCallOptions("dev-local", runOptions, variables, localDescriptor, softPackage)
186
246
  }
187
247
 
188
248
  _remotePackageCallOptions := func(runOptions) {
@@ -192,7 +252,7 @@ _remotePackageCallOptions := func(runOptions) {
192
252
 
193
253
  variables := [ _newRefVar(_ARG_VAR_PKG, software.name, softPackage) ]
194
254
 
195
- return _binPackageCallOptions(runOptions, variables, binaryDescriptor, softPackage)
255
+ return _binPackageCallOptions("remote", runOptions, variables, binaryDescriptor, softPackage)
196
256
  }
197
257
 
198
258
  binaryRunOptions := func(runOptions) {
@@ -217,6 +277,58 @@ binaryRunOptions := func(runOptions) {
217
277
  ll.panic("Unable to run software %s v%s: 'binary' execution mode is not enabled in software descriptor", software.name, software.version)
218
278
  }
219
279
 
280
+ prepareCommandRun := func(wd, opts) {
281
+ runBuilder := runcmd.builder(wd)
282
+
283
+ // Make installed packages to be available for the command run
284
+ for varInfo in opts.variables {
285
+ runBuilder.ref(varInfo.refName, varInfo.reference)
286
+ runBuilder.substitutionRule(varInfo.varName, varInfo.refName)
287
+ }
288
+
289
+ // Patch command's PATH env variable
290
+ for p in opts.customPaths {
291
+ runBuilder.addToPath(p.value, p.hasVars)
292
+ }
293
+
294
+ // Configure environment variables required for correct command run environment setup
295
+ for name, value in opts.envs {
296
+ if value.hasVars {
297
+ runBuilder.envVar(name, value.value)
298
+ } else {
299
+ runBuilder.env(name, value.value)
300
+ }
301
+ }
302
+
303
+ return runBuilder
304
+ }
305
+
306
+ _activateRenv := func(wd, opts) {
307
+ activateRenv := prepareCommandRun(wd, opts)
308
+ activateRenv.
309
+ cmd("R").
310
+ arg("-e").arg("renv::activate()")
311
+
312
+ activateRenvRun := activateRenv.build()
313
+
314
+ return activateRenvRun
315
+ }
316
+
317
+ prepareWDForRunEnvironment := func(wd, opts) {
318
+ if (!maps.containsKey(opts, "runEnvType")) {
319
+ return wd
320
+ }
321
+
322
+ if (opts.runEnvType == "R") {
323
+ return _activateRenv(wd, opts).workdir
324
+ }
325
+
326
+ return wd
327
+ }
328
+
220
329
  export {
221
- binaryRunOptions : binaryRunOptions
330
+ binaryRunOptions : binaryRunOptions,
331
+
332
+ prepareWDForRunEnvironment : prepareWDForRunEnvironment,
333
+ prepareCommandRun : prepareCommandRun
222
334
  }
@@ -0,0 +1,16 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+ validation := import("@platforma-sdk/workflow-tengo:validation")
3
+ pkg := import("@platforma-sdk/workflow-tengo:exec.package")
4
+
5
+ pythonVenvInputSchema := {
6
+ toolset: "string",
7
+ dependencies: {"any": validation.reference},
8
+ // software: validation.reference,
9
+
10
+ pythonDescriptor: pkg.runEnvDescriptorScheme,
11
+ python: validation.reference
12
+ }
13
+
14
+ export ll.toStrict({
15
+ pythonVenvInputSchema : pythonVenvInputSchema
16
+ })
@@ -0,0 +1,165 @@
1
+ times := import("times")
2
+
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
4
+ oop := import("@platforma-sdk/workflow-tengo:oop")
5
+ validation := import("@platforma-sdk/workflow-tengo:validation")
6
+ assets := import("@platforma-sdk/workflow-tengo:assets")
7
+ smart := import("@platforma-sdk/workflow-tengo:smart")
8
+ render := import("@platforma-sdk/workflow-tengo:render")
9
+ pkg := import("@platforma-sdk/workflow-tengo:exec.package")
10
+ internal := import("@platforma-sdk/workflow-tengo:exec.python.internal")
11
+ runenv := import("@platforma-sdk/workflow-tengo:exec.runenv")
12
+
13
+ _OUTPUT_RUN_ENV := "runEnv"
14
+
15
+ pythonVenvBuilder := func() {
16
+ self := undefined
17
+
18
+ toolset := "pip"
19
+ pythonDescriptor := undefined
20
+ softwareRef := undefined
21
+ dependencies := undefined
22
+ cache := 0
23
+
24
+ self = {
25
+ useToolset: func(name) {
26
+ validation.assertJsonSchema(name, "string",
27
+ "exec.python.useToolset: <name> must be valid name of python packaging toolset (pip, pipenv and so on)")
28
+ ll.assert(name != "", "exec.python.useToolset: toolset name must not be empty")
29
+
30
+ toolset = name
31
+ return self
32
+ },
33
+
34
+ runEnvDescriptor: func(descriptor) {
35
+ validation.assertJsonSchema(descriptor, pkg.runEnvDescriptorScheme, "exec.python.runEnvDescriptor: <descriptor> must be run environment specification")
36
+ ll.assert(descriptor.type == "python", "exec.python.runEnvDescriptor: not a 'python' run environment: %q", descriptor.type)
37
+
38
+ pythonDescriptor = ll.fromStrict(descriptor)
39
+ return self
40
+ },
41
+
42
+ software: func(pkgRef) {
43
+ validation.assertJsonSchema(pkgRef, validation.reference, "exec.python.software: <pkgRef> must be a reference to software package")
44
+
45
+ softwareRef = pkgRef
46
+ return self
47
+ },
48
+
49
+ dependencies: func(deps) {
50
+ validation.assertJsonSchema(deps, { "any": "string" }, "exec.python.dependencies: <deps> must be map of reference file paths")
51
+
52
+ dependencies = deps
53
+ return self
54
+ },
55
+
56
+ /**
57
+ * Sets the cache time in milliseconds.
58
+ *
59
+ * @param millis: number
60
+ */
61
+ cacheMillis: func(millis) {
62
+ ll.assert(is_int(millis) && millis > 0, "exec.python.cacheMillis: cache time must be a number of milliseconds")
63
+ cache = millis * times.millisecond
64
+ return self
65
+ },
66
+
67
+ /**
68
+ * Sets the cache time in seconds.
69
+ *
70
+ * @param seconds: number
71
+ */
72
+ cacheSeconds: func(seconds) {
73
+ ll.assert(is_int(seconds) && seconds > 0, "exec.python.cacheSeconds: cache time must be a number of seconds")
74
+ cache = seconds * times.second
75
+ return self
76
+ },
77
+
78
+ /**
79
+ * Sets the cache time in minutes.
80
+ *
81
+ * @param minutes: number
82
+ */
83
+ cacheMinutes: func(minutes) {
84
+ ll.assert(is_int(minutes) && minutes > 0, "exec.python.cacheMinutes: cache time must be a number of minutes")
85
+ cache = minutes * times.minute
86
+ return self
87
+ },
88
+
89
+ /**
90
+ * Sets the cache time in hours.
91
+ *
92
+ * @param hours: number
93
+ */
94
+ cacheHours: func(hours) {
95
+ ll.assert(is_int(hours) && hours > 0, "exec.python.cacheHours: cache time must be a number of hours")
96
+ cache = hours * times.hour
97
+ return self
98
+ },
99
+
100
+ /**
101
+ * Sets the cache time in days
102
+ *
103
+ * @param days: number
104
+ */
105
+ cacheDays: func(days) {
106
+ ll.assert(is_int(days) && days > 0, "exec.python.cacheDays: cache time must be a number of days")
107
+ cache = days * times.hour * 24
108
+ return self
109
+ },
110
+
111
+ /**
112
+ * @deprecated, use cacheMillis, cacheSeconds, cacheMinutes, cacheHours and cacheDays instead.
113
+ * Sets the cache time.
114
+ *
115
+ * @param time: duration - the cache time from 'times' library.
116
+ */
117
+ cache: func(time) {
118
+ ll.assert(
119
+ is_int(time),
120
+ "exec.python.cache: cache time must be an integer. " +
121
+ "Did you forget to import a standard tengo library 'times'?")
122
+ cache = time
123
+ return self
124
+ },
125
+
126
+ build: func() {
127
+ depsMap := runenv.loadDependencyFiles(softwareRef, dependencies)
128
+
129
+ archive := pkg.get(pythonDescriptor.registry, pythonDescriptor.package).archive()
130
+ pythonPkg := pkg.install(archive).package()
131
+
132
+ pyVenvInputs := {
133
+ toolset: toolset,
134
+ dependencies: depsMap,
135
+ // software: softwareRef,
136
+ pythonDescriptor: pythonDescriptor,
137
+ python: pythonPkg
138
+ }
139
+
140
+ validation.assertJsonSchema(pyVenvInputs, internal.pythonVenvInputSchema, "incomplete python runenv configuration")
141
+
142
+ tpl := render.create(assets.importTemplate("@platforma-sdk/workflow-tengo:exec.python.create-venv"), pyVenvInputs)
143
+
144
+ self := undefined
145
+ self = ll.toStrict(oop.inherit(tpl, {
146
+ /**
147
+ * Python virtual environment with all dependencies installed.
148
+ *
149
+ * @return venv: smart.field - a reference to the runenv with python venv inside.
150
+ */
151
+ venv: func() {
152
+ return tpl.output(_OUTPUT_RUN_ENV, cache)
153
+ }
154
+ }))
155
+
156
+ return self
157
+ }
158
+ }
159
+
160
+ return self
161
+ }
162
+
163
+ export ll.toStrict({
164
+ venvBuilder : pythonVenvBuilder
165
+ })
@@ -8,9 +8,6 @@ oop := import("@platforma-sdk/workflow-tengo:oop")
8
8
  maps := import("@platforma-sdk/workflow-tengo:maps")
9
9
  validation := import("@platforma-sdk/workflow-tengo:validation")
10
10
  pkg := import("@platforma-sdk/workflow-tengo:exec.package")
11
- assets := import("@platforma-sdk/workflow-tengo:assets")
12
- render := import("@platforma-sdk/workflow-tengo:render")
13
- times := import("times")
14
11
 
15
12
  _RTYPE_SAVE_RUN_ENV := { Name: "SaveRunEnv/executor", Version: "1" }
16
13
  _INPUT_SETTINGS := "settings"
@@ -97,15 +94,6 @@ saveBuilder := func(wd) {
97
94
  return self
98
95
  }
99
96
 
100
- pythonVenvInputSchema := {
101
- toolset: "string",
102
- dependencies: {"string": validation.reference},
103
- // software: validation.reference,
104
-
105
- pythonDescriptor: pkg.runEnvDescriptorScheme,
106
- python: validation.reference
107
- }
108
-
109
97
  loadDependencyFiles := func(packageRef, dependencies) {
110
98
  if len(dependencies) == 0 {
111
99
  return {}
@@ -126,157 +114,7 @@ loadDependencyFiles := func(packageRef, dependencies) {
126
114
  return depsMap
127
115
  }
128
116
 
129
- pythonVenv := func() {
130
- self := undefined
131
-
132
- toolset := "pip"
133
- pythonDescriptor := undefined
134
- softwareRef := undefined
135
- dependencies := undefined
136
- cache := 0
137
-
138
- self = {
139
- useToolset: func(name) {
140
- validation.assertJsonSchema(name, "string",
141
- "runenv.python.useToolset: <name> must be valid name of python packaging toolset (pip, pipenv and so on)")
142
- ll.assert(name != "", "runenv.python.useToolset: toolset name must not be empty")
143
-
144
- toolset = name
145
- return self
146
- },
147
-
148
- runEnvDescriptor: func(descriptor) {
149
- validation.assertJsonSchema(descriptor, pkg.runEnvDescriptorScheme, "runenv.python.runEnvDescriptor: <descriptor> must be run environment specification")
150
- ll.assert(descriptor.type == "python", "runenv.python.runEnvDescriptor: not a 'python' run environment: %q", descriptor.type)
151
-
152
- pythonDescriptor = ll.fromStrict(descriptor)
153
- return self
154
- },
155
-
156
- software: func(pkgRef) {
157
- validation.assertJsonSchema(pkgRef, validation.reference, "runenv.python.software: <pkgRef> must be a reference to software package")
158
-
159
- softwareRef = pkgRef
160
- return self
161
- },
162
-
163
- dependencies: func(deps) {
164
- validation.assertJsonSchema(deps, { "any": "string" }, "runenv.python.dependencies: <deps> must be map of reference file paths")
165
-
166
- dependencies = deps
167
- return self
168
- },
169
-
170
- /**
171
- * Sets the cache time in milliseconds.
172
- *
173
- * @param millis: number
174
- */
175
- cacheMillis: func(millis) {
176
- ll.assert(is_int(millis) && millis > 0, "cache time must be a number of milliseconds")
177
- cache = millis * times.millisecond
178
- return self
179
- },
180
-
181
- /**
182
- * Sets the cache time in seconds.
183
- *
184
- * @param seconds: number
185
- */
186
- cacheSeconds: func(seconds) {
187
- ll.assert(is_int(seconds) && seconds > 0, "cache time must be a number of seconds")
188
- cache = seconds * times.second
189
- return self
190
- },
191
-
192
- /**
193
- * Sets the cache time in minutes.
194
- *
195
- * @param minutes: number
196
- */
197
- cacheMinutes: func(minutes) {
198
- ll.assert(is_int(minutes) && minutes > 0, "cache time must be a number of minutes")
199
- cache = minutes * times.minute
200
- return self
201
- },
202
-
203
- /**
204
- * Sets the cache time in hours.
205
- *
206
- * @param hours: number
207
- */
208
- cacheHours: func(hours) {
209
- ll.assert(is_int(hours) && hours > 0, "cache time must be a number of hours")
210
- cache = hours * times.hour
211
- return self
212
- },
213
-
214
- /**
215
- * Sets the cache time in days
216
- *
217
- * @param days: number
218
- */
219
- cacheDays: func(days) {
220
- ll.assert(is_int(days) && days > 0, "cache time must be a number of days")
221
- cache = days * times.hour * 24
222
- return self
223
- },
224
-
225
- /**
226
- * @deprecated, use cacheMillis, cacheSeconds, cacheMinutes, cacheHours and cacheDays instead.
227
- * Sets the cache time.
228
- *
229
- * @param time: duration - the cache time from 'times' library.
230
- */
231
- cache: func(time) {
232
- ll.assert(
233
- is_int(time),
234
- "cache time must be an integer. " +
235
- "Did you forget to import a standard tengo library 'times'?")
236
- cache = time
237
- return self
238
- },
239
-
240
- build: func() {
241
- depsMap := loadDependencyFiles(softwareRef, dependencies)
242
-
243
- archive := pkg.get(pythonDescriptor.registry, pythonDescriptor.package).archive()
244
- pythonPkg := pkg.install(archive).package()
245
-
246
- pyVenvInputs := {
247
- toolset: toolset,
248
- dependencies: smart.createMapResource(depsMap),
249
- // software: softwareRef,
250
- pythonDescriptor: pythonDescriptor,
251
- python: pythonPkg
252
- }
253
-
254
- validation.assertJsonSchema(pyVenvInputs, pythonVenvInputSchema, "incomplete python runenv configuration")
255
-
256
- tpl := render.create(assets.importTemplate("@platforma-sdk/workflow-tengo:exec.python.create-venv"), pyVenvInputs)
257
-
258
- self := undefined
259
- self = ll.toStrict(oop.inherit(tpl, {
260
- /**
261
- * Python virtual environment with all dependencies installed.
262
- *
263
- * @return venv: smart.field - a reference to the runenv with python venv inside.
264
- */
265
- venv: func() {
266
- return tpl.output(_OUTPUT_RUN_ENV, cache)
267
- }
268
- }))
269
-
270
- return self
271
- }
272
- }
273
-
274
- return self
275
- }
276
-
277
117
  export ll.toStrict({
278
118
  saveBuilder : saveBuilder,
279
-
280
- pythonVenv : pythonVenv,
281
- pythonVenvInputSchema : pythonVenvInputSchema
119
+ loadDependencyFiles : loadDependencyFiles
282
120
  })
@@ -705,8 +705,8 @@ field = func(f) {
705
705
  * @param millis: number
706
706
  */
707
707
  setCacheMillis: func(millis) {
708
- ll.assert(is_int(millis),
709
- "smart.field.setCacheMillis: cache time must be a number of milliseconds")
708
+ ll.assert(is_int(millis) && millis > 0,
709
+ "smart.field.setCacheMillis: cache time must be a number of milliseconds (> 0)")
710
710
  return self.setCache(millis * times.millisecond)
711
711
  },
712
712
 
@@ -716,8 +716,8 @@ field = func(f) {
716
716
  * @param seconds: number
717
717
  */
718
718
  setCacheSeconds: func(seconds) {
719
- ll.assert(is_int(seconds),
720
- "smart.field.setCacheSeconds: cache time must be a number of seconds")
719
+ ll.assert(is_int(seconds) && seconds > 0,
720
+ "smart.field.setCacheSeconds: cache time must be a number of seconds (> 0)")
721
721
  return self.setCache(seconds * times.second)
722
722
  },
723
723
 
@@ -727,8 +727,8 @@ field = func(f) {
727
727
  * @param minutes: number
728
728
  */
729
729
  setCacheMinutes: func(minutes) {
730
- ll.assert(is_int(minutes),
731
- "smart.field.setCacheMinutes: cache time must be a number of minutes")
730
+ ll.assert(is_int(minutes) && minutes > 0,
731
+ "smart.field.setCacheMinutes: cache time must be a number of minutes (> 0)")
732
732
  return self.setCache(minutes * times.minute)
733
733
  },
734
734
 
@@ -738,7 +738,7 @@ field = func(f) {
738
738
  * @param hours: number
739
739
  */
740
740
  setCacheHours: func(hours) {
741
- ll.assert(is_int(hours), "smart.field.setCacheHours: cache time must be a number of hours")
741
+ ll.assert(is_int(hours) && hours > 0, "smart.field.setCacheHours: cache time must be a number of hours (> 0)")
742
742
  return self.setCache(hours * times.hour)
743
743
  },
744
744
 
@@ -748,7 +748,7 @@ field = func(f) {
748
748
  * @param days: number
749
749
  */
750
750
  setCacheDays: func(days) {
751
- ll.assert(is_int(days), "smart.field.setCacheDays: cache time must be a number of days")
751
+ ll.assert(is_int(days) && days > 0, "smart.field.setCacheDays: cache time must be a number of days (> 0)")
752
752
  return self.setCache(days * 24 * times.hour)
753
753
  },
754
754
 
@@ -11,6 +11,8 @@ constants := import("@platforma-sdk/workflow-tengo:constants")
11
11
  stateAwait := import("@platforma-sdk/workflow-tengo:tpl.state-await")
12
12
  validation := import("@platforma-sdk/workflow-tengo:validation")
13
13
 
14
+ bquery := import("@platforma-sdk/workflow-tengo:workflow.bquery")
15
+
14
16
  /**
15
17
  * Unmarshal resource according by:
16
18
  * - converting all json resources (potentially nested) into a tengo objects (maps)
@@ -106,7 +108,7 @@ tpl := func() {
106
108
  return smart.resource(_templateId)
107
109
  },
108
110
 
109
- _unmarshallers: [],
111
+ _unmarshallers: [bquery.resultUnmarshaller()],
110
112
 
111
113
  /**
112
114
  * Register a preprocessor of input resource. The preprocessor must have two
@@ -49,7 +49,7 @@ create := func(spec, ctx, ...options) {
49
49
  // @TODO validate options
50
50
 
51
51
  // override defaults
52
- for k, v in options[0]{
52
+ for k, v in options[0] {
53
53
  ops[k] = v
54
54
  }
55
55
  }
@@ -121,7 +121,7 @@ resultUnmarshaller := func() {
121
121
  return undefined
122
122
  }
123
123
 
124
- result := {
124
+ result := {
125
125
  ref: resource.get("ref").getDataAsJson(),
126
126
  spec: resource.get("spec").getDataAsJson()
127
127
  }
@@ -49,8 +49,8 @@ _isStaging := func() {
49
49
  return !_isProduction()
50
50
  }
51
51
 
52
- // register standard inputs preprocessors
53
- self.registerUnmarshaller(bquery.resultUnmarshaller())
52
+ // register standard inputs preprocessors [now added by default for all templates]
53
+ // self.registerUnmarshaller(bquery.resultUnmarshaller())
54
54
 
55
55
  _args := undefined
56
56
 
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/workflow-tengo",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Tengo SDK library",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "./dist/**/*"
17
17
  ],
18
18
  "dependencies": {
19
- "@milaboratories/software-pframes-conv": "2.1.0",
19
+ "@milaboratories/software-pframes-conv": "2.1.2",
20
20
  "@platforma-open/milaboratories.software-small-binaries": "^1.14.6"
21
21
  },
22
22
  "devDependencies": {