pifop v0.1.6
PIFOP Functions JavaScript API
Warning: PIFOP Functions is an experimental feature, and so is this library. You are welcomed to try it out, but USE IT AT YOUR OWN RISK.
Quick start
0. Load script/module
Browser
<script src="https://pifop.com/pifop.js"></script>
Node.js
npm install pifop
const pifop = require("pifop");
1. Execute a PIFOP Function that takes a single input file
pifop.execute("joe/example", "apikey_ABC123", myInput)
.onFinish((execution, event) => {
// Display/use the results here
console.log(execution.result);
});
2. Execute a PIFOP Function that takes multiple input files
pifop.execute("joe/example", "apikey_ABC123")
.setInput("input1", myInput1)
.setInput("input2", myInput2)
.onFinish((execution, event) => {
// Display/use the results here
console.log(execution.result);
});
3. Print terminal output during execution
pifop.execute("joe/example", "apikey_ABC123", myInput)
.onProgress((execution, event) => {
// Display execution log
console.log(event.data.log);
})
.onFinish((execution, event) => {
// Display/use the results here
console.log(execution.result);
});
4. Handle errors
pifop.execute("joe/example", "apikey_ABC123", myInput)
.onFinish((execution, event) => {
// Display/use the results here
console.log(execution.result);
})
.onError((execution, event) => {
// Handle errors here
console.log(event);
});
Documentation
Introduction
This library is a JavaScript client API to the more generic PIFOP Functions REST API. Internally, it works by queueing "atomic" REST API calls (initialization, start, termination, etc) to perform "molecular" actions, and then it notifies you when it has completed something.
The series of atomic actions that are needed to run an execution from start to finish is automatically queued when you create an Execution
with pifop.execute(...)
. All that you have to do is to provide the input files and listen to the events generated during the execution lifetime, as such:
pifop.execute("joe/example", "apikey_ABC123")
.setInput("inputId", myInput)
.onProgress((execution, event) => {/* Do something */})
.onFinish((execution, event) => {/* Do something */})
Execution
Constructors
pifop.execute(funcUID, apiKey, [input])
Creates and returns a self-managed Execution
that will automatically initialize itself, upload the provided input, start the execution and terminate it once it has finished. The returned Execution
is uninitialized, but you don't have to initialize it yourself. Just provide the input and set the event listeners as shown above and you are good to go.
funcUID
: a function Universal Identifier (UID). The UID of a function is astring
with the formatauthor/id
, whereauthor
is the author of the function andid
is the functionid
.apiKey
: an API key for the functionfuncUID
.input
: optional input content. You can only pass the input content as an argument if the Function being called only accepts one input — seewithInput()
to learn more. Otherwise, you must callsetInput()
to set the input content.
pifop.resume(funcUID, apiKey, execId)
Resume an Execution previously created with pifop.execute()
. Only Executions that have already been started can be resumed. Use this constructor as a recovery mechanism in case of a program crash, client disconnection and other kinds of interruption.
Usage example:
pifop.execute("joe/example", "apikey_ABC123", input)
.onStarted((execution) => {
// Store the id of the execution so that
// you can resume it later, if necessary.
})
.onEvent(eventHandler);
// After crash or disconnection...
// Resume execution using its id
let execId = getExecutionId(...);
pifop.resume("joe/example", "apikey_ABC123", execId)
.onEvent(eventHandler);
Instance Methods
setInput(inputId, content), withInput(content)
setInput()
sets the content
of the input inputId
. The provided input is not immediatelly uploaded. Rather, it will be uploaded once the Execution
has been initialized in the server.
withInput()
is an alternative that you can use if, and only if, the Function being called only accepts a single input file. It behaves exactly like setInput()
, except that you can ommit the inputId
in this case.
inputId
: the id of the input file to which thecontent
belongs.content
: the content of the input file. It can be anything acceptable as afetch body
, includingString
,Blob
,ArrayBuffer
,TypedArray
andDataView
.
onStarted(...), onProgress(...), onFinish(...), onError(...)
Family of event listener setters for common events that you may want to listen to. They all take two arguments: onXXXX(listener, [once])
.
listener
: a function that will be called with argumentslistener(execution, event)
.execution
: theExecution
that is related to the event.event
: anEvent
object containing all the details pertaining the event.
once
: optional boolean. Iftrue
, thelistener
will be removed from the execution after being called once. Default:false
.
Event type associated with each setter:
onStarted
: thelistener
will listen to the"execution_started"
event.onProgress
: thelistener
will listen to"execution_info"
events.onFinish
: thelistener
will listen to the"result_ready"
event.onError
: thelistener
will listen to"error"
events.
onEvent(listener, once)
Generic event listener setter. The listener
will be called whenever an event of any kind happens. Use the type
member of the event
to distinguish between events.
Usage example:
pifop.execute("joe/example", "apikey_ABC123", input)
.onEvent((execution, event) => {
switch(event.type) {
case "event_type1": /* Do something */ break;
case "event_type2": /* Do something */ break;
// ...
}
});
setMetadata(key, value)
User-defined arbitrary data. That's for your convenience only. It allows you to associate some data with an execution
, which you can then access later, e.g., on event listeners.
key
: thestring
that will be used as a key to accessing thevalue
.value
: any object whatsoever.
Usage example:
pifop.execute("joe/example", "apikey_ABC123", input)
.setMetadata("my_data", 48)
.onFinish((execution) => {
console.log(execution.metadata["my_data"]); // 48
});
ignoreLog([boolean])
Call this function without arguments if you don't care for the execution log. The execution log is essentially what the execution prints out to the terminal. When the execution log is ignored, it is not periodically retrieved via the getInfo()
function, meaning that no log
will be available in the data
member of the Event
passed to the listener
bound by onProgress()
. The main benefit of this is an improvement on the network performance of your application, as less data will be transfered from PIFOP to your application.
boolean
: optional boolean indicating if you want to ignore the execution log or not. Default:true
.
Usage example:
pifop.execute("joe/example", "apikey_ABC123", input)
.ignoreLog()
.onFinish(/* Do something */);
Events
The listener
arguments in the onXXXX()
family of functions are user-defined functions that will be called when certain events happen during the execution. Event listeners are passed two arguments: listener(object, event)
, where object
is either an Execution
or a Function
, depending on who is listening to that event, and event
is an Event
object.
Event
Properties:
type
: type of the event. See below.operation
: operation that was being perfomed when the event happened.data
: the data related to the event. Each event type will have a differentdata
. See below.objectType
: astring
representing the type of the object related to theoperation
type. Can be"execution"
or"function"
.execution
:Execution
object related to that event.func
:Function
object related to that event.response
: theResponse
that we've got from the server.
Event
Types:
Type | Description |
---|---|
"function_initialized" | The func object has been initialized and is ready to be used. The data member contains the function data. listener setter: function.onInit() |
"execution_initialized" | The execution object has been initialized. The data member contains the execution data. listener setter: execution.onInit() |
"input_uploaded" | Input file has been uploaded to execution . The data member contains the input that has been uploaded. |
"execution_started" | The execution has been started. The data member contains the execution data. |
"execution_info" | Info about the execution has been retrieved. The data member contains the execution data. listener setter: execution.onProgress() |
"execution_ended" | The execution has ended. The data member contains the execution data. |
"result_ready" | The execution has ended and all of its output files have been retrieved. Output files can be found in execution.output , or in execution.result if only one output file has been generated. If the single output is a JSON, execution.result will be the parsed output so you can access its members directly. If the single output is not a JSON, execution.result will be an Output object. |
"output_retrieved" | An output file of execution has been retrieved. The data member contains the output that has been retrieved. |
"execution_stopped" | The execution has been stopped. The data member contains the execution data. |
"error" | Something bad has happened. listener setter: onError() |