Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tuple idl #5720

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions flyteidl/clients/go/assets/admin.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions flyteidl/clients/go/coreutils/extract_literal.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ func ExtractFromLiteral(literal *core.Literal) (interface{}, error) {
}
}
return mapResult, nil
case *core.Literal_Tuple:
tupleValue := literalValue.Tuple.Literals
tupleResult := make(map[string]interface{}, len(tupleValue))
for key, val := range tupleValue {
if tupleElem, err := ExtractFromLiteral(val); err == nil {
tupleResult[key] = tupleElem
} else {
return nil, err
}
}
return tupleResult, nil
}
return nil, fmt.Errorf("unsupported literal type %T", literal)
}
26 changes: 26 additions & 0 deletions flyteidl/clients/go/coreutils/extract_literal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,30 @@ func TestFetchLiteral(t *testing.T) {
assert.NoError(t, err)
assert.Nil(t, extractedLiteralVal)
})

t.Run("Tuple", func(t *testing.T) {
literalVal := map[string]interface{}{
"field1": int64(1),
"field2": "string_value",
}
var literalType = &core.LiteralType{
Type: &core.LiteralType_TupleType{
TupleType: &core.TupleType{
TupleName: "DefaultTupleName",
Order: []string{
"field1", "field2",
},
Fields: map[string]*core.LiteralType{
"field1": {Type: &core.LiteralType_Simple{Simple: core.SimpleType_INTEGER}},
"field2": {Type: &core.LiteralType_Simple{Simple: core.SimpleType_STRING}},
},
},
},
}
lit, err := MakeLiteralForType(literalType, literalVal)
assert.NoError(t, err)
extractedLiteralVal, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
assert.Equal(t, literalVal, extractedLiteralVal)
})
}
71 changes: 71 additions & 0 deletions flyteidl/clients/go/coreutils/literals.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ func MakeDefaultLiteralForType(typ *core.LiteralType) (*core.Literal, error) {
},
}
return res, nil
case *core.LiteralType_TupleType:
return MakeLiteralForType(typ, nil)
}

return nil, fmt.Errorf("failed to convert to a known Literal. Input Type [%v] not supported", typ.String())
Expand Down Expand Up @@ -425,6 +427,15 @@ func MustMakeLiteral(v interface{}) *core.Literal {
return p
}

func MustMakeLiteralForType(t *core.LiteralType, v interface{}) *core.Literal {
p, err := MakeLiteralForType(t, v)
if err != nil {
panic(err)
}

return p
}

func MakeLiteralMap(v map[string]interface{}) (*core.LiteralMap, error) {

literals := make(map[string]*core.Literal, len(v))
Expand All @@ -442,6 +453,25 @@ func MakeLiteralMap(v map[string]interface{}) (*core.LiteralMap, error) {
}, nil
}

func MakeLiteralTuple(name string, order []string, v map[string]interface{}) (*core.LiteralTupleMap, error) {
literals := make(map[string]*core.Literal, len(v))
for key, val := range v {
l, err := MakeLiteral(val)
if err != nil {
return nil, err
}

literals[key] = l
}

return &core.LiteralTupleMap{
TupleName: name,
Order: order,
Literals: literals,
}, nil

}

func MakeLiteralForSchema(path storage.DataReference, columns []*core.SchemaType_SchemaColumn) *core.Literal {
return &core.Literal{
Value: &core.Literal_Scalar{
Expand Down Expand Up @@ -637,6 +667,47 @@ func MakeLiteralForType(t *core.LiteralType, v interface{}) (*core.Literal, erro
return nil, fmt.Errorf("incorrect union value [%s], supported values %+v", v, newT.UnionType.Variants)
}

case *core.LiteralType_TupleType:
// TO_DISCUSS: How to handle the tuple interface in Inputs field of flytectl?
//
// [Example usage]
// inputs:
// tuple_data:
// key1: "foo"
// key2: 123

vMap, ok := v.(map[string]interface{})
if !ok {
return nil, errors.Errorf("Expected a map[string]interface{} for tuple type, got [%v]", v)
Comment on lines +670 to +681
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain more?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this part, the LiteralType is already given, so the name of the tuple and the order of each field should be already defined. The only thing that is missing is the value of each field.
Therefore, we only need to provide the value of each tuple field (via the key-value pair of each field) in flytectl for the registered task or workflow for further execution needs.

}
// check whether all the key provided by vMap is valid.
for key := range vMap {
if _, ok := t.GetTupleType().GetFields()[key]; !ok {
return nil, fmt.Errorf("key %s not found in tuple type", key)
}
}

literals := make(map[string]*core.Literal, len(vMap))
// iterate over the fields in the tuple type
for key, fieldType := range t.GetTupleType().GetFields() {
l, err := MakeLiteralForType(fieldType, vMap[key])
if err != nil {
return nil, err
}
literals[key] = l
}
l = &core.Literal{
Value: &core.Literal_Tuple{
Tuple: &core.LiteralTupleMap{
TupleName: t.GetTupleType().GetTupleName(),
Order: t.GetTupleType().GetOrder(),
Literals: literals,
},
},
}

return l, nil

default:
return nil, fmt.Errorf("unsupported type %s", t.String())
}
Expand Down
44 changes: 44 additions & 0 deletions flyteidl/clients/go/coreutils/literals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,4 +761,48 @@ func TestMakeLiteralForType(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, expectedVal, actualVal)
})

t.Run("Tuple", func(t *testing.T) {
var literalType = &core.LiteralType{
Type: &core.LiteralType_TupleType{
TupleType: &core.TupleType{
TupleName: "DefaultTupleName",
Order: []string{
"int_field",
"str_field",
},
Fields: map[string]*core.LiteralType{
"str_field": {Type: &core.LiteralType_Simple{Simple: core.SimpleType_STRING}},
"int_field": {Type: &core.LiteralType_Simple{Simple: core.SimpleType_INTEGER}},
},
},
},
}
expectedLV := &core.Literal{Value: &core.Literal_Tuple{
Tuple: &core.LiteralTupleMap{
TupleName: "DefaultTupleName",
Order: []string{
"int_field",
"str_field",
},
Literals: map[string]*core.Literal{
"int_field": {Value: &core.Literal_Scalar{Scalar: &core.Scalar{
Value: &core.Scalar_Primitive{Primitive: &core.Primitive{Value: &core.Primitive_Integer{Integer: 1}}}}}},
"str_field": {Value: &core.Literal_Scalar{Scalar: &core.Scalar{
Value: &core.Scalar_Primitive{Primitive: &core.Primitive{Value: &core.Primitive_StringValue{StringValue: "hello"}}}}}},
},
},
}}
lv, err := MakeLiteralForType(literalType, map[string]interface{}{
"int_field": 1,
"str_field": "hello",
})
assert.NoError(t, err)
assert.Equal(t, expectedLV, lv)
expectedVal, err := ExtractFromLiteral(expectedLV)
assert.NoError(t, err)
actualVal, err := ExtractFromLiteral(lv)
assert.NoError(t, err)
assert.Equal(t, expectedVal, actualVal)
})
}
Loading