@platforma-sdk/workflow-tengo 5.5.2 → 5.5.3

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.
Files changed (45) hide show
  1. package/dist/tengo/lib/exec.R.internal.lib.tengo +93 -24
  2. package/dist/tengo/lib/exec.R.lib.tengo +12 -10
  3. package/dist/tengo/lib/exec.runcmd.lib.tengo +36 -10
  4. package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
  5. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  6. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  7. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  8. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  9. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  10. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  11. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  14. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  15. package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
  16. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  17. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  25. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  26. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  27. package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
  28. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  39. package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
  40. package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
  41. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  42. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  43. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  44. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  45. package/package.json +1 -1
@@ -1,12 +1,11 @@
1
1
  ll := import("@platforma-sdk/workflow-tengo:ll")
2
- feats := import("@platforma-sdk/workflow-tengo:feats")
3
2
 
4
3
  validation := import("@platforma-sdk/workflow-tengo:validation")
5
- runcmd := import("@platforma-sdk/workflow-tengo:exec.runcmd")
6
4
  path := import("@platforma-sdk/workflow-tengo:path")
5
+ smart := import("@platforma-sdk/workflow-tengo:smart")
6
+
7
+ runcmd := import("@platforma-sdk/workflow-tengo:exec.runcmd")
7
8
  desc := import("@platforma-sdk/workflow-tengo:exec.descriptor")
8
- constants := import("@platforma-sdk/workflow-tengo:exec.constants")
9
- pkg := import("@platforma-sdk/workflow-tengo:exec.package")
10
9
 
11
10
  rVenvInputSchema := {
12
11
  operationMode: "string",
@@ -14,37 +13,107 @@ rVenvInputSchema := {
14
13
  dependencies: {"any": "string"},
15
14
  software: validation.reference,
16
15
 
17
- rDescriptor: desc.runEnvScheme,
16
+ rRunEnvDescriptor: desc.runEnvScheme,
18
17
  R: validation.reference
19
18
  }
20
19
 
21
- runRBuilder := func(operationMode, wd, rPackage, rDescriptor) {
22
- t := feats.commandExpressions ? constants.ARG_TYPE_EXPRESSION : constants.ARG_TYPE_VAR
23
- rule := feats.commandExpressions ? "R" : "{R}"
20
+ ARG_VAR_R := "R" // abs path to 'R' run environment runtime
21
+ ARG_VAR_R_VENV := "rVenv" // abs path to 'R' portable virtual environment, restored on runner side
22
+
23
+ RENV_ROOT_DIR_NAME := "renv-root" // directory inside R run environment package, where RENV_PATHS_ROOT is stored.
24
+
25
+ _expr := func(varName) {
26
+ return "{" + varName + "}"
27
+ }
28
+
29
+
30
+
31
+
32
+
33
+
34
+ runRPlan := func(refsPrefix, rPkgRef, rRunEnvDescriptor, rVenvRef) {
35
+ validation.assertType(refsPrefix, "string", "exec.R.runRPlan: <refsPrefix> is expected to be string with prefix for all default references attached to R-based command")
36
+ validation.assertType(rPkgRef, validation.reference, "exec.R.runRPlan: <rPkgRef> is expected to be reference to R run environment package")
37
+ validation.assertType(rRunEnvDescriptor, desc.runEnvScheme, "exec.R.runRPlan: <rRunEnvDescriptor> is expected to be run environment descriptor")
38
+ validation.assert(rRunEnvDescriptor.type == "R", "exec.R.runRPlan: <rRunEnvDescriptor> is expected to be R run environment descriptor")
39
+ if (!is_undefined(rVenvRef)) {
40
+ validation.assertType(rVenvRef, validation.reference, "exec.R.runRPlan: <rVenvRef> is expected to be reference to R virtual environment")
41
+ }
42
+
43
+ plan := runcmd.createRunCommandPlan()
24
44
 
25
- builder := runcmd.builder(wd).
26
- inQueue(pkg.DEFAULT_ALLOCATION_QUEUE).
27
- cpu(pkg.DEFAULT_ALLOCATION_CPU).
28
- mem(pkg.DEFAULT_ALLOCATION_RAM).
29
- ref("r-run-environment", rPackage).
30
- substitutionRule(rule, "r-run-environment").
31
- addPathTyped(t, path.join("{R}", rDescriptor.binDir)).
32
- envTyped("RHOME", t, "{R}").
33
- envTyped("R_HOME_DIR", t, "{R}").
34
- envTyped("RENV_PATHS_ROOT", t, path.join("{R}", "renv-root")).
35
- envTyped("RENV_PATHS_BINARY", t, path.join("{R}", "renv-root", "binaries")).
36
- envTyped("RENV_PATHS_SOURCE", t, path.join("{R}", "renv-root", "sources")).
37
- envTyped("RENV_PATHS_CACHE", t, path.join("{R}", "renv-root", "cache"))
45
+ rRefKey := refsPrefix + "/R-runtime"
46
+ rEnvRefKey := refsPrefix + "/R-virtual-env"
38
47
 
48
+ rBinDir := path.join(_expr(ARG_VAR_R), rRunEnvDescriptor.binDir)
49
+ renvRootArg := path.join(_expr(ARG_VAR_R), RENV_ROOT_DIR_NAME)
39
50
 
51
+ plan.
52
+ refVar(ARG_VAR_R, rRefKey, rPkgRef).
53
+ addPathExpression(rBinDir).
54
+ envExpression("RHOME", _expr(ARG_VAR_R)). // RScript uses this variable instead of R_HOME_DIR or R_HOME
55
+ envExpression("R_HOME_DIR", _expr(ARG_VAR_R)). // R starter sh script uses this to correctly set R_HOME and many others
56
+ envExpression("RENV_PATHS_ROOT", renvRootArg).
57
+ envExpression("RENV_PATHS_BINARY", path.join(renvRootArg, "binaries")).
58
+ envExpression("RENV_PATHS_SOURCE", path.join(renvRootArg, "sources")).
59
+ envExpression("RENV_PATHS_CACHE", path.join(renvRootArg, "cache"))
40
60
 
61
+ if (!is_undefined(rVenvRef)) {
62
+ plan.
63
+ refVar(ARG_VAR_R_VENV, rEnvRefKey, rVenvRef).
64
+ envExpression("RENV_PATHS_RENV", path.join(_expr(ARG_VAR_R_VENV), "r-venv")).
65
+ envExpression("RENV_PATHS_LOCKFILE", path.join(_expr(ARG_VAR_R_VENV), "renv.lock"))
66
+ }
41
67
 
42
- builder.envTyped("RENV_CONFIG_REPOS_OVERRIDE", t, path.join("{R}", "packages"))
43
68
 
44
- return builder
69
+
70
+
71
+ plan.envExpression("RENV_CONFIG_REPOS_OVERRIDE", path.join("{R}", "packages"))
72
+
73
+ return plan
74
+ }
75
+
76
+ activateRenvInWD := func(wd, queue, computeResources, plan) {
77
+ validation.assertType(wd, validation.reference, "exec.R.activateRenvInWD: <wd> must be a reference to workdir")
78
+ validation.assertType(queue, "string", "exec.R.activateRenvInWD: <queue> must be a string")
79
+ validation.assertType(computeResources,
80
+ ["or",
81
+ validation.reference,
82
+ { "cpu": "number", "ram": ["or", "number", "string"] }
83
+ ],
84
+ "exec.R.activateRenvInWD: <computeResources> must be a reference to allocation, or a map with cpu and ram"
85
+ )
86
+ validation.assertType(plan, runcmd.RUN_CMD_PLAN_STATE_OR_OBJECT_SCHEMA, "exec.R.activateRenvInWD: <plan> must be a run command plan or state")
87
+
88
+ activateRenv := runcmd.builder(wd, plan).
89
+ cmd("R").
90
+ inQueue(queue).
91
+ resetArgs().
92
+ arg("--no-echo").
93
+ arg("--no-restore").
94
+ arg("-e").arg("renv::activate()")
95
+
96
+ if (smart.isReference(computeResources)) {
97
+ activateRenv.allocation(computeResources)
98
+ } else {
99
+ activateRenv.
100
+ cpu(computeResources.cpu).
101
+ mem(computeResources.ram)
102
+ }
103
+
104
+ return activateRenv.build().workdir
45
105
  }
46
106
 
47
107
  export ll.toStrict({
108
+
109
+ ARG_VAR_R : ARG_VAR_R,
110
+ ARG_VAR_R_VENV : ARG_VAR_R_VENV,
111
+ RENV_ROOT_DIR_NAME : RENV_ROOT_DIR_NAME,
112
+
113
+
48
114
  rVenvInputSchema : rVenvInputSchema,
49
- runRBuilder : runRBuilder
115
+
116
+
117
+ runRPlan : runRPlan,
118
+ activateRenvInWD : activateRenvInWD
50
119
  })
@@ -19,7 +19,7 @@ rVenvBuilder := func() {
19
19
 
20
20
  opMode := "remote"
21
21
  toolset := "renv"
22
- rDescriptor := undefined
22
+ rRunEnvDescriptor := undefined
23
23
  softwareRef := undefined
24
24
  dependencies := undefined
25
25
  cache := 0
@@ -47,9 +47,9 @@ rVenvBuilder := func() {
47
47
 
48
48
  runEnvDescriptor: func(descriptor) {
49
49
  validation.assertType(descriptor, desc.runEnvScheme, "exec.R.runEnvDescriptor: <descriptor> must be run environment specification")
50
- ll.assert(descriptor.type == "R", "exec.R.runEnvDescriptor: not a 'R' run environment: %q", descriptor.type)
50
+ ll.assert(descriptor.type == "R", "exec.R.runEnvDescriptor: incorrect run environment type. Expected 'R', got %q", descriptor.type)
51
51
 
52
- rDescriptor = ll.fromStrict(descriptor)
52
+ rRunEnvDescriptor = ll.fromStrict(descriptor)
53
53
  return self
54
54
  },
55
55
 
@@ -138,20 +138,19 @@ rVenvBuilder := func() {
138
138
  },
139
139
 
140
140
  build: func() {
141
- archive := pkg.get(rDescriptor.registry, rDescriptor.package).archive()
142
- rPkg := pkg.install(archive).package()
141
+ archiveRef := pkg.get(rRunEnvDescriptor.registry, rRunEnvDescriptor.package).archive()
142
+ rPkgRef := pkg.install(archiveRef).package()
143
143
 
144
144
  rVenvInputs := {
145
145
  operationMode: opMode,
146
146
  toolset: toolset,
147
147
  dependencies: dependencies,
148
148
  software: softwareRef,
149
- rDescriptor: rDescriptor,
150
- R: rPkg
149
+ rRunEnvDescriptor: rRunEnvDescriptor,
150
+ R: rPkgRef
151
151
  }
152
152
 
153
153
  validation.assertType(rVenvInputs, internal.rVenvInputSchema, "incomplete R runenv configuration")
154
-
155
154
  tpl := render.create(createRenvTpl, rVenvInputs)
156
155
 
157
156
  self := undefined
@@ -171,7 +170,8 @@ rVenvBuilder := func() {
171
170
 
172
171
 
173
172
  R: func() {
174
- return rPkg
173
+
174
+ return rPkgRef
175
175
  }
176
176
  }))
177
177
 
@@ -184,5 +184,7 @@ rVenvBuilder := func() {
184
184
 
185
185
 
186
186
  export ll.toStrict({
187
- rVenvBuilder : rVenvBuilder
187
+ rVenvBuilder : rVenvBuilder,
188
+ runRPlan : internal.runRPlan,
189
+ activateRenvInWD : internal.activateRenvInWD
188
190
  })
@@ -44,13 +44,27 @@ RUN_CMD_PLAN_OPTIONS_SCHEMA := {
44
44
  "dockerEntrypoint,?": ["string"]
45
45
  }
46
46
 
47
- RUN_CMD_PLAN_SCHEMA := {
47
+ RUN_CMD_PLAN_STATE_SCHEMA := {
48
48
  "refs": RUN_CMD_PLAN_REFS_SCHEMA,
49
49
  "options": RUN_CMD_PLAN_OPTIONS_SCHEMA
50
50
  }
51
51
 
52
+ _isRunCommandPlanObject := func(obj) {
53
+ return ll.isStrict(obj) && maps.containsKey(obj, "_type") && obj["_type"] == "runcmd.plan"
54
+ }
55
+
56
+ _validateIsRunCommandPlanObject := func(obj, keyPath, stack) {
57
+ if !_isRunCommandPlanObject(obj) {
58
+ return validation.fail(keyPath, "item %q is not a run command plan object", obj)
59
+ }
60
+
61
+ return validation.success
62
+ }
63
+
64
+ RUN_CMD_PLAN_STATE_OR_OBJECT_SCHEMA := [ "or", RUN_CMD_PLAN_STATE_SCHEMA, _validateIsRunCommandPlanObject ]
65
+
52
66
  _initStateFromPlan := func(state, initState, context) {
53
- validation.assertType(initState, RUN_CMD_PLAN_SCHEMA, "invalid initial state for " + context)
67
+ validation.assertType(initState, RUN_CMD_PLAN_STATE_SCHEMA, "invalid initial state for " + context)
54
68
 
55
69
  initOptions := initState.options
56
70
  state.options.cmd = maps.clone(initOptions.cmd)
@@ -119,6 +133,8 @@ _createAbstractRunCommandPlan := func(state, returnSelfFn) {
119
133
  self := undefined
120
134
 
121
135
  self = ll.toStrict({
136
+ _type: "runcmd.plan",
137
+
122
138
 
123
139
 
124
140
 
@@ -492,6 +508,9 @@ builder := func(workdir, ...initialState) {
492
508
 
493
509
  if len(initialState) == 1 {
494
510
  initState := initialState[0]
511
+ if (_isRunCommandPlanObject(initState)) {
512
+ initState = initState.state()
513
+ }
495
514
  _initStateFromPlan(state, initState, "run command builder")
496
515
  } else {
497
516
  ll.assert(len(initialState) == 0, "builder accepts at most two arguments")
@@ -642,10 +661,13 @@ builder := func(workdir, ...initialState) {
642
661
 
643
662
 
644
663
 
645
- ll.assert(is_undefined(allocation) || (is_undefined(cpu) && is_undefined(ram)),
646
- "runcmd.builder.build: allocation cannot be set along with cpu or ram")
664
+ hasAllocation := !is_undefined(allocation)
665
+ hasCpuRamRequest := !is_undefined(cpu) || !is_undefined(ram)
666
+
667
+ ll.assert(!(hasAllocation && hasCpuRamRequest), // none specified is OK: default queue limits would be applied.
668
+ "runcmd.builder.build: allocation and CPU/RAM request are mutually exclusive for the same command run")
647
669
 
648
- ll.assert(!is_undefined(queue), "queue must be set")
670
+ ll.assert(!is_undefined(queue), "runcmd.builder.build: queue is required for any command run")
649
671
 
650
672
  useBatch := limits.useBatch(queue)
651
673
 
@@ -728,13 +750,17 @@ builder := func(workdir, ...initialState) {
728
750
  }
729
751
 
730
752
  export ll.toStrict({
753
+
754
+ ARG_SCHEMA: ARG_SCHEMA,
755
+ RUN_CMD_PLAN_REFS_SCHEMA: RUN_CMD_PLAN_REFS_SCHEMA,
756
+ RUN_CMD_PLAN_OPTIONS_SCHEMA: RUN_CMD_PLAN_OPTIONS_SCHEMA,
757
+ RUN_CMD_PLAN_STATE_SCHEMA: RUN_CMD_PLAN_STATE_SCHEMA,
758
+ RUN_CMD_PLAN_STATE_OR_OBJECT_SCHEMA: RUN_CMD_PLAN_STATE_OR_OBJECT_SCHEMA,
759
+
760
+
731
761
  builder: builder,
732
762
  simpleArg: simpleArg,
733
763
  variableArg: variableArg,
734
764
  expressionArg: expressionArg,
735
- createRunCommandPlan: createRunCommandPlan,
736
- ARG_SCHEMA: ARG_SCHEMA,
737
- RUN_CMD_PLAN_REFS_SCHEMA: RUN_CMD_PLAN_REFS_SCHEMA,
738
- RUN_CMD_PLAN_OPTIONS_SCHEMA: RUN_CMD_PLAN_OPTIONS_SCHEMA,
739
- RUN_CMD_PLAN_SCHEMA: RUN_CMD_PLAN_SCHEMA
765
+ createRunCommandPlan: createRunCommandPlan
740
766
  })
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/workflow-tengo",
3
- "version": "5.5.2",
3
+ "version": "5.5.3",
4
4
  "description": "Tengo SDK library",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",