Skip to content

Commit b84b2c2

Browse files
committed
Experimental process namespace support Open-EO/openeo-api#348
1 parent 203a091 commit b84b2c2

12 files changed

+282
-58
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Experimental support for process namespaces, see [API#348](https://github.com/Open-EO/openeo-api/pull/348).
12+
913
### Fixed
1014

1115
- Return a better error message if issues with reading batch job results occur in `Job.getResultsAsStac`

openeo.d.ts

+46-20
Original file line numberDiff line numberDiff line change
@@ -1346,12 +1346,13 @@ declare module OpenEO {
13461346
* Operators: - (subtract), + (add), / (divide), * (multiply), ^ (power)
13471347
*
13481348
* It supports all mathematical functions (i.e. expects a number and returns a number) the back-end implements, e.g. `sqrt(x)`.
1349+
* For namespaced processes, use for example `process#namespace(x)` - EXPERIMENTAL!
13491350
*
13501351
* Only available if a builder is specified in the constructor:
13511352
* You can refer to output from processes with a leading `#`, e.g. `#loadco1` if the node to refer to has the key `loadco1`.
13521353
*
13531354
* Only available if a parent node is set via `setNode()`:
1354-
* Parameters can be accessed simply by name.
1355+
* Parameters can be accessed simply by name.
13551356
* If the first parameter is a (labeled) array, the value for a specific index or label can be accessed by typing the numeric index or textual label with a `$` in front, for example `$B1` for the label `B1` or `$0` for the first element in the array. Numeric labels are not supported.
13561357
* You can access subsequent parameters by adding additional `$` at the beginning, e.g. `$$0` to access the first element of an array in the second parameter, `$$$0` for the same in the third parameter etc.
13571358
*
@@ -1430,8 +1431,9 @@ declare module OpenEO {
14301431
* @param {string} processId
14311432
* @param {object.<string, *>} [processArgs={}]
14321433
* @param {?string} [processDescription=null]
1434+
* @param {?string} [processNamespace=null]
14331435
*/
1434-
constructor(parent: Builder, processId: string, processArgs?: any, processDescription?: string | null);
1436+
constructor(parent: Builder, processId: string, processArgs?: any, processDescription?: string | null, processNamespace?: string | null);
14351437
/**
14361438
* The parent builder.
14371439
* @type {Builder}
@@ -1448,6 +1450,11 @@ declare module OpenEO {
14481450
* @type {string}
14491451
*/
14501452
id: string;
1453+
/**
1454+
* The namespace of the process - EXPERIMENTAL!
1455+
* @type {string}
1456+
*/
1457+
namespace: string;
14511458
/**
14521459
* The arguments for the process.
14531460
* @type {object.<string, *>}
@@ -1508,7 +1515,7 @@ declare module OpenEO {
15081515
*
15091516
* @protected
15101517
* @param {?BuilderNode} [parentNode=null]
1511-
* @param {?string} parentParameter
1518+
* @param {?string} [parentParameter=null]
15121519
* @returns {BuilderNode}
15131520
*/
15141521
protected createBuilder(parentNode?: BuilderNode | null, parentParameter?: string | null): BuilderNode;
@@ -1608,7 +1615,7 @@ declare module OpenEO {
16081615
*
16091616
* @async
16101617
* @static
1611-
* @param {?string} version
1618+
* @param {?string} [version=null]
16121619
* @returns {Promise<Builder>}
16131620
* @throws {Error}
16141621
*/
@@ -1637,10 +1644,17 @@ declare module OpenEO {
16371644
*/
16381645
constructor(processes: Array<Process> | Processes, parent?: Builder | null, id?: string);
16391646
/**
1640-
* List of all process specifications.
1647+
* List of all non-namespaced process specifications.
16411648
* @type {Array.<Process>}
16421649
*/
16431650
processes: Array<Process>;
1651+
/**
1652+
* Namespaced process specifications. EXPERIMENTAL!
1653+
* @type {Object.<string, Array.<Process>>}
1654+
*/
1655+
namespacedProcesses: {
1656+
[x: string]: Array<Process>;
1657+
};
16441658
/**
16451659
* The parent builder.
16461660
* @type {?Builder}
@@ -1670,9 +1684,10 @@ declare module OpenEO {
16701684
* Adds a process specification to the builder so that it can be used to create a process graph.
16711685
*
16721686
* @param {Process} process - Process specification compliant to openEO API
1687+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
16731688
* @throws {Error}
16741689
*/
1675-
addProcessSpec(process: Process): void;
1690+
addProcessSpec(process: Process, namespace?: string | null): void;
16761691
/**
16771692
* Sets the parent for this Builder.
16781693
*
@@ -1705,12 +1720,13 @@ declare module OpenEO {
17051720
*/
17061721
addParameter(parameter: any, root?: boolean): void;
17071722
/**
1708-
* Returns the process specification for the given process identifier.
1723+
* Returns the process specification for the given process identifier and namespace.
17091724
*
1710-
* @param {string} id
1725+
* @param {string} id - Process identifier
1726+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
17111727
* @returns {Process}
17121728
*/
1713-
spec(id: string): Process;
1729+
spec(id: string, namespace?: string | null): Process;
17141730
/**
17151731
* Adds a mathematical formula to the process.
17161732
*
@@ -1723,18 +1739,19 @@ declare module OpenEO {
17231739
*/
17241740
math(formula: string): BuilderNode;
17251741
/**
1726-
* Checks whether a process with the given id is supported by the back-end.
1742+
* Checks whether a process with the given id and namespace is supported by the back-end.
17271743
*
1728-
* @param {string} processId - The id of the process to call.
1744+
* @param {string} processId - The id of the process.
1745+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
17291746
* @returns {boolean}
17301747
*/
1731-
supports(processId: string): boolean;
1748+
supports(processId: string, namespace?: string | null): boolean;
17321749
/**
17331750
* Adds another process call to the process chain.
17341751
*
1735-
* @param {string} processId - The id of the process to call.
1736-
* @param {object.<string, *>|Array} args - The arguments as key-value pairs or as array. For objects, they keys must be the parameter names and the values must be the arguments. For arrays, arguments must be specified in the same order as in the corresponding process.
1737-
* @param {?string} description - An optional description for the process call.
1752+
* @param {string} processId - The id of the process to call. To access a namespaced process, use the `process@namespace` notation.
1753+
* @param {object.<string, *>|Array} [args={}] - The arguments as key-value pairs or as array. For objects, they keys must be the parameter names and the values must be the arguments. For arrays, arguments must be specified in the same order as in the corresponding process.
1754+
* @param {?string} [description=null] - An optional description for the process call.
17381755
* @returns {BuilderNode}
17391756
*/
17401757
process(processId: string, args?: any | any[], description?: string | null): BuilderNode;
@@ -1872,27 +1889,32 @@ declare module OpenEO {
18721889
*/
18731890
listCollectionItems(collectionId: string, spatialExtent?: Array<number> | null, temporalExtent?: Array<any> | null, limit?: number | null): AsyncGenerator<any, void, unknown>;
18741891
/**
1875-
* List all processes available on the back-end.
1892+
* List processes available on the back-end.
1893+
*
1894+
* Requests pre-defined processes by default.
1895+
* Set the namespace parameter to request processes from a specific namespace.
18761896
*
1877-
* Data is cached in memory.
1897+
* Pre-defined processes are cached in memory.
18781898
*
18791899
* @async
1900+
* @param {?string} [namespace=null] - Namespace of the processes (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
18801901
* @returns {Promise<Processes>} - A response compatible to the API specification.
18811902
* @throws {Error}
18821903
*/
1883-
listProcesses(): Promise<Processes>;
1904+
listProcesses(namespace?: string | null): Promise<Processes>;
18841905
/**
18851906
* Get information about a single process.
18861907
*
18871908
* @async
18881909
* @param {string} processId - Collection ID to request further metadata for.
1910+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
18891911
* @returns {Promise<?Process>} - A single process as object, or `null` if none is found.
18901912
* @throws {Error}
18911913
* @see Connection#listProcesses
18921914
*/
1893-
describeProcess(processId: string): Promise<Process | null>;
1915+
describeProcess(processId: string, namespace?: string | null): Promise<Process | null>;
18941916
/**
1895-
* Returns an object to simply build user-defined processes.
1917+
* Returns an object to simply build user-defined processes based upon pre-defined processes.
18961918
*
18971919
* @async
18981920
* @param {string} id - A name for the process.
@@ -2572,6 +2594,10 @@ declare module OpenEO {
25722594
export type Processes = {
25732595
processes: Array<Process>;
25742596
links: Array<Link>;
2597+
/**
2598+
* EXPERIMENTAL!
2599+
*/
2600+
namespaces: Array<string> | null;
25752601
};
25762602
/**
25772603
* An openEO processing chain.

src/builder/builder.js

+44-16
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class Builder {
8383
*
8484
* @async
8585
* @static
86-
* @param {?string} version
86+
* @param {?string} [version=null]
8787
* @returns {Promise<Builder>}
8888
* @throws {Error}
8989
*/
@@ -123,10 +123,15 @@ class Builder {
123123
*/
124124
constructor(processes, parent = null, id = undefined) {
125125
/**
126-
* List of all process specifications.
126+
* List of all non-namespaced process specifications.
127127
* @type {Array.<Process>}
128128
*/
129129
this.processes = [];
130+
/**
131+
* Namespaced process specifications. EXPERIMENTAL!
132+
* @type {object.<string, Array.<Process>>}
133+
*/
134+
this.namespacedProcesses = {};
130135
/**
131136
* The parent builder.
132137
* @type {?Builder}
@@ -176,13 +181,20 @@ class Builder {
176181
* Adds a process specification to the builder so that it can be used to create a process graph.
177182
*
178183
* @param {Process} process - Process specification compliant to openEO API
184+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
179185
* @throws {Error}
180186
*/
181-
addProcessSpec(process) {
187+
addProcessSpec(process, namespace = null) {
182188
if (!Utils.isObject(process)) {
183189
throw new Error("Process '" + process.id + "' must be an object.");
184190
}
185-
if (typeof this[process.id] === 'undefined') {
191+
if (namespace && namespace !== 'backend' && namespace !== 'user') {
192+
if (!this.namespacedProcesses[namespace]) {
193+
this.namespacedProcesses[namespace] = [];
194+
}
195+
this.namespacedProcesses[namespace].push(process);
196+
}
197+
else if (typeof this[process.id] === 'undefined') {
186198
this.processes.push(process);
187199
/**
188200
* Implicitly calls the process with the given name on the back-end by adding it to the process.
@@ -281,13 +293,22 @@ class Builder {
281293
}
282294

283295
/**
284-
* Returns the process specification for the given process identifier.
296+
* Returns the process specification for the given process identifier and namespace.
285297
*
286-
* @param {string} id
298+
* @param {string} id - Process identifier
299+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
287300
* @returns {Process}
288301
*/
289-
spec(id) {
290-
return this.processes.find(process => process.id === id);
302+
spec(id, namespace = null) {
303+
if (namespace && namespace !== 'backend' && namespace !== 'user') {
304+
if (!this.namespacedProcesses[namespace]) {
305+
return;
306+
}
307+
return this.namespacedProcesses[namespace].find(process => process.id === id);
308+
}
309+
else {
310+
return this.processes.find(process => process.id === id);
311+
}
291312
}
292313

293314
/**
@@ -308,25 +329,32 @@ class Builder {
308329
}
309330

310331
/**
311-
* Checks whether a process with the given id is supported by the back-end.
332+
* Checks whether a process with the given id and namespace is supported by the back-end.
312333
*
313-
* @param {string} processId - The id of the process to call.
334+
* @param {string} processId - The id of the process.
335+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
314336
* @returns {boolean}
315337
*/
316-
supports(processId) {
317-
return Utils.isObject(this.spec(processId));
338+
supports(processId, namespace = null) {
339+
return Utils.isObject(this.spec(processId, namespace));
318340
}
319341

320342
/**
321343
* Adds another process call to the process chain.
322344
*
323-
* @param {string} processId - The id of the process to call.
324-
* @param {object.<string, *>|Array} args - The arguments as key-value pairs or as array. For objects, they keys must be the parameter names and the values must be the arguments. For arrays, arguments must be specified in the same order as in the corresponding process.
325-
* @param {?string} description - An optional description for the process call.
345+
* @param {string} processId - The id of the process to call. To access a namespaced process, use the `process@namespace` notation.
346+
* @param {object.<string, *>|Array} [args={}] - The arguments as key-value pairs or as array. For objects, they keys must be the parameter names and the values must be the arguments. For arrays, arguments must be specified in the same order as in the corresponding process.
347+
* @param {?string} [description=null] - An optional description for the process call.a
326348
* @returns {BuilderNode}
327349
*/
328350
process(processId, args = {}, description = null) {
329-
let node = new BuilderNode(this, processId, args, description);
351+
let namespace = null;
352+
if (processId.includes('@')) {
353+
let rest;
354+
[processId, ...rest] = processId.split('@');
355+
namespace = rest.join('@');
356+
}
357+
let node = new BuilderNode(this, processId, args, description, namespace);
330358
this.nodes[node.id] = node;
331359
return node;
332360
}

src/builder/formula.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const BuilderNode = require('./node');
88
* Operators: - (subtract), + (add), / (divide), * (multiply), ^ (power)
99
*
1010
* It supports all mathematical functions (i.e. expects a number and returns a number) the back-end implements, e.g. `sqrt(x)`.
11+
* For namespaced processes, use for example `process#namespace(x)` - EXPERIMENTAL!
1112
*
1213
* Only available if a builder is specified in the constructor:
1314
* You can refer to output from processes with a leading `#`, e.g. `#loadco1` if the node to refer to has the key `loadco1`.

src/builder/node.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ class BuilderNode {
1313
* @param {string} processId
1414
* @param {object.<string, *>} [processArgs={}]
1515
* @param {?string} [processDescription=null]
16+
* @param {?string} [processNamespace=null]
1617
*/
17-
constructor(parent, processId, processArgs = {}, processDescription = null) {
18+
constructor(parent, processId, processArgs = {}, processDescription = null, processNamespace = null) {
1819
/**
1920
* The parent builder.
2021
* @type {Builder}
@@ -26,7 +27,7 @@ class BuilderNode {
2627
* @type {Process}
2728
* @readonly
2829
*/
29-
this.spec = this.parent.spec(processId);
30+
this.spec = this.parent.spec(processId, processNamespace);
3031
if (!Utils.isObject(this.spec)) {
3132
throw new Error("Process doesn't exist: " + processId);
3233
}
@@ -36,6 +37,11 @@ class BuilderNode {
3637
* @type {string}
3738
*/
3839
this.id = parent.generateId(processId);
40+
/**
41+
* The namespace of the process - EXPERIMENTAL!
42+
* @type {string}
43+
*/
44+
this.namespace = processNamespace;
3945
/**
4046
* The arguments for the process.
4147
* @type {object.<string, *>}
@@ -176,7 +182,7 @@ class BuilderNode {
176182
*
177183
* @protected
178184
* @param {?BuilderNode} [parentNode=null]
179-
* @param {?string} parentParameter
185+
* @param {?string} [parentParameter=null]
180186
* @returns {BuilderNode}
181187
*/
182188
createBuilder(parentNode = null, parentParameter = null) {
@@ -228,6 +234,9 @@ class BuilderNode {
228234
process_id: this.spec.id,
229235
arguments: {}
230236
};
237+
if (this.namespace) {
238+
obj.namespace = this.namespace;
239+
}
231240
for(let name in this.arguments) {
232241
if (typeof this.arguments[name] !== 'undefined') {
233242
obj.arguments[name] = this.exportArgument(this.arguments[name], name);

0 commit comments

Comments
 (0)