From f92e584b89a1a88cf64eb401fb2b64c45249a059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Vall=C3=A9s?= Date: Fri, 8 Mar 2024 17:48:49 +0100 Subject: [PATCH] wip: add List operator with Filter task --- pkg/list/v0/config/definitions.json | 19 ++++++ pkg/list/v0/config/tasks.json | 73 +++++++++++++++++++++++ pkg/list/v0/main.go | 90 +++++++++++++++++++++++++++++ pkg/main.go | 2 + 4 files changed, 184 insertions(+) create mode 100644 pkg/list/v0/config/definitions.json create mode 100644 pkg/list/v0/config/tasks.json create mode 100644 pkg/list/v0/main.go diff --git a/pkg/list/v0/config/definitions.json b/pkg/list/v0/config/definitions.json new file mode 100644 index 0000000..aa8d01d --- /dev/null +++ b/pkg/list/v0/config/definitions.json @@ -0,0 +1,19 @@ +[ + { + "available_tasks": [ + "TASK_FILTER" + ], + "custom": false, + "documentation_url": "", + "icon": "assets/list.svg", + "id": "list", + "public": true, + "spec": {}, + "title": "List", + "description": "Manipulate lists, filtering or summarizing their elements", + "uid": "5a98a721-a0df-4871-93f5-db31fd5628a6", + "version": "0.0.1", + "source_url": "https://github.com/instill-ai/operator/blob/main/pkg/list/v0", + "release_stage": "RELEASE_STAGE_COMING_SOON" + } +] diff --git a/pkg/list/v0/config/tasks.json b/pkg/list/v0/config/tasks.json new file mode 100644 index 0000000..7fda012 --- /dev/null +++ b/pkg/list/v0/config/tasks.json @@ -0,0 +1,73 @@ +{ + "TASK_FILTER": { + "instillShortDescription": "Select the elements of the list that satisfy a given condition", + "title": "Filter", + "input": { + "instillUIOrder": 0, + "properties": { + "filter": { + "title": "Filter", + "description": "A condition to be applied to each element in the list", + "type": "string", + "instillAcceptFormats": [ + "string" + ], + "instillUIMultiline": false, + "instillUIOrder": 0, + "instillUpstreamTypes": [ + "value", + "reference", + "template" + ] + }, + "list": { + "type": "array", + "title": "List", + "description": "The input list to be filtered. TODO check accept formats for arbitrary element type", + "instillAcceptFormats": [ + "array:string" + ], + "instillUIOrder": 1, + "instillUpstreamTypes": [ + "value", + "reference" + ], + "items": { + "instillUIMultiline": false, + "type": "string" + }, + "minItems": 1 + } + }, + "required": [ + "filter", + "list" + ], + "title": "Input", + "type": "object" + }, + "output": { + "title": "Output", + "description": "Output", + "instillUIOrder": 0, + "properties": { + "filtered_list": { + "description": "A list containing only the elements that fulfilled the condition", + "instillEditOnNodeFields": [], + "instillUIOrder": 0, + "required": [], + "title": "Results", + "type": "array", + "instillFormat": "array:semi-structured/json", + "items": { + "instillFormat": "semi-structured/json" + } + } + }, + "required": [ + "filtered_list" + ], + "type": "object" + } + } +} diff --git a/pkg/list/v0/main.go b/pkg/list/v0/main.go new file mode 100644 index 0000000..62f87ce --- /dev/null +++ b/pkg/list/v0/main.go @@ -0,0 +1,90 @@ +package list + +import ( + _ "embed" + "fmt" + "sync" + + "github.com/gofrs/uuid" + "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" + + "github.com/instill-ai/component/pkg/base" + "github.com/instill-ai/x/errmsg" +) + +const ( + taskFilter = "TASK_FILTER" +) + +var ( + //go:embed config/definitions.json + definitionsJSON []byte + //go:embed config/tasks.json + tasksJSON []byte + + once sync.Once + op base.IOperator +) + +type operator struct { + base.Operator +} + +type execution struct { + base.Execution + execute func(*structpb.Struct) (*structpb.Struct, error) +} + +// Init returns an implementation of IOperator that processes JSON objects. +func Init(logger *zap.Logger) base.IOperator { + once.Do(func() { + op = &operator{ + Operator: base.Operator{ + Component: base.Component{Logger: logger}, + }, + } + err := op.LoadOperatorDefinitions(definitionsJSON, tasksJSON, nil) + if err != nil { + logger.Fatal(err.Error()) + } + }) + return op +} + +func (o *operator) CreateExecution(defUID uuid.UUID, task string, config *structpb.Struct, logger *zap.Logger) (base.IExecution, error) { + e := &execution{} + + switch task { + case taskFilter: + e.execute = e.filter + default: + return nil, errmsg.AddMessage( + fmt.Errorf("not supported task: %s", task), + fmt.Sprintf("%s task is not supported.", task), + ) + } + + e.Execution = base.CreateExecutionHelper(e, o, defUID, task, config, logger) + + return e, nil +} + +func (e *execution) filter(_ /* in */ *structpb.Struct) (*structpb.Struct, error) { + return nil, errmsg.AddMessage(fmt.Errorf("unsupported task"), "The filter task is not available yet for execution.") +} + +func (e *execution) Execute(inputs []*structpb.Struct) ([]*structpb.Struct, error) { + outputs := make([]*structpb.Struct, len(inputs)) + + for i, input := range inputs { + output, err := e.execute(input) + if err != nil { + return nil, err + } + + outputs[i] = output + } + + return outputs, nil +} diff --git a/pkg/main.go b/pkg/main.go index d89ff9f..f22d2f6 100644 --- a/pkg/main.go +++ b/pkg/main.go @@ -12,6 +12,7 @@ import ( "github.com/instill-ai/operator/pkg/end/v0" "github.com/instill-ai/operator/pkg/image/v0" "github.com/instill-ai/operator/pkg/json/v0" + "github.com/instill-ai/operator/pkg/list/v0" "github.com/instill-ai/operator/pkg/start/v0" "github.com/instill-ai/operator/pkg/text/v0" ) @@ -40,6 +41,7 @@ func Init(logger *zap.Logger) base.IOperator { operator.(*Operator).ImportDefinitions(json.Init(logger)) operator.(*Operator).ImportDefinitions(image.Init(logger)) operator.(*Operator).ImportDefinitions(text.Init(logger)) + operator.(*Operator).ImportDefinitions(list.Init(logger)) }) return operator