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

[Question] [API] How can i get all params (option function call) from the kcl code #254

Closed
reckless-huang opened this issue Mar 14, 2024 · 26 comments · Fixed by kcl-lang/kcl#1135
Labels
enhancement New feature or request question Further information is requested

Comments

@reckless-huang
Copy link
Contributor

for example,i have a kclfile

apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
    name = "nginx"
    labels.app = "nginx"
}
spec = {
    replicas = 3
    selector.matchLabels = metadata.labels
    template.metadata.labels = metadata.labels
    template.spec.containers = [
        {
            name = metadata.name
            image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest"
            ports = [{ containerPort = 80 }]
        }
    ]
}

how to get a params list :
env str default is "prod"

@Peefy Peefy added the question Further information is requested label Mar 14, 2024
@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

Hi @reckless-huang

At present, it is not possible to obtain the value of prod for all options mixed in the code snippet. However, we construct a schema to represent all variables through the code structure, similar to this

Schema Params:
  aa: int=1
  bb: int=2

params: Params = option("params")

Then obtain the document of the Params schema through the kcl doc tool or the document API.

@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

Additionally, could you please provide me with more specific scenarios and use cases? So that we can identify some best practices.

@reckless-huang
Copy link
Contributor Author

I am developing a template system to process yaml files in our release process. The current tech stack is python+jinjia2. First, a jinjia template is defined, and then we use the following code to get the variables in the template:

def getjinja2vars(context):
    '''
    Get variables of type jinja2 str. To be extended.
    @param context:
    @return:
    '''
    # Common {{ abc }} => abc
    pattern1 = r'\{\{ ([\w\s]+) \}\}'
    var1 = re.findall(pattern1, context)
    # {% if abc == 2 %} => abc
    pattern2 = r'\{\%\s*if\s+(\S+)\s+'
    var2 = re.findall(pattern2, context)

    var1.extend(var2)
    return list(set(var1))

The code above gets the keys of the variables in jinja, and then completes the assignment of the keys through some logic, and finally renders the template and submits it. Therefore, if I want to switch to kcl, I need kcl to provide the same capability to get the variables defined in the template.

@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

I see. In our current template abstraction system, we always define a Params schema to standardize user input, which allows us to enjoy the benefits of KCL type systems rather than just extracting regular expressions. Some examples are what we did in the KRM-KCL specification. https://github.com/kcl-lang/krm-kcl

@reckless-huang
Copy link
Contributor Author

How can I get the variable information defined in the schema in the KCL model, just like I use regular filtering of variable names in jinjia?

I see. In our current template abstraction system, we always define a Params schema to standardize user input, which allows us to enjoy the benefits of KCL type systems rather than just extracting regular expressions. Some examples are what we did in the KRM-KCL specification. https://github.com/kcl-lang/krm-kcl

@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

How can I get the variable information defined in the schema in the KCL model, just like I use regular filtering of variable names in jinjia?

There are two ways

@reckless-huang
Copy link
Contributor Author

How can I get the variable information defined in the schema in the KCL model, just like I use regular filtering of variable names in jinjia?

There are two ways

Both of these methods seem to have a high threshold. I understand that parsing variables from templates is something that must be done before rendering, but why don't cue and kcl provide direct APIs for accessing them?

@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

How can I get the variable information defined in the schema in the KCL model, just like I use regular filtering of variable names in jinjia?

There are two ways

Both of these methods seem to have a high threshold. I understand that parsing variables from templates is something that must be done before rendering, but why don't cue and kcl provide direct APIs for accessing them?

Make sense. For example, in KCL, if you want to directly use a certain parameter or API, such as ListOptions, to obtain a list of all parameters, right?

@reckless-huang
Copy link
Contributor Author

How can I get the variable information defined in the schema in the KCL model, just like I use regular filtering of variable names in jinjia?

There are two ways

Both of these methods seem to have a high threshold. I understand that parsing variables from templates is something that must be done before rendering, but why don't cue and kcl provide direct APIs for accessing them?

Make sense. For example, in KCL, if you want to directly use a certain parameter or API, such as ListOptions, to obtain a list of all parameters, right?

yes !
exp
ListOptions(file, code string) ([]args, err )

@Peefy
Copy link
Contributor

Peefy commented Mar 14, 2024

All right. Actually, we already have such an implementation within KCL at present https://github.com/kcl-lang/kcl/blob/main/kclvm/runtime/src/api/kclvm.rs#L270 However, due to bandwidth limitations, we have not yet exposed higher level APIs, and perhaps we may support such API calls next week.

@Peefy Peefy added the enhancement New feature or request label Mar 14, 2024
@Peefy Peefy changed the title can i get all params with kcl tpl [Question] [APi] How can i get all params (option function call) from the kcl code Mar 14, 2024
@Peefy Peefy changed the title [Question] [APi] How can i get all params (option function call) from the kcl code [Question] [API] How can i get all params (option function call) from the kcl code Mar 14, 2024
@Peefy
Copy link
Contributor

Peefy commented Mar 15, 2024

We've release kcl-go v0.8.1 See this function https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options.go#L12 and examples https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options_test.go#L8 to get all params (function option calling) from the kcl file or code.

@reckless-huang
Copy link
Contributor Author

We've release kcl-go v0.8.1 See this function https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options.go#L12 and examples https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options_test.go#L8 to get all params (function option calling) from the kcl file or code.

image too large ,go get timeout

@Peefy
Copy link
Contributor

Peefy commented Mar 16, 2024

Sorry, we are working hard on lighter KCL. 🙏 kcl-lang/kcl#291

@reckless-huang
Copy link
Contributor Author

We've release kcl-go v0.8.1 See this function https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options.go#L12 and examples https://github.com/kcl-lang/kcl-go/blob/main/pkg/loader/options_test.go#L8 to get all params (function option calling) from the kcl file or code.

image image
	ops, err := loader.ListFileOptions("hello.k")
	if err != nil {
		panic(err)
	}
	for _, op := range ops {
		fmt.Println(op.Name)
	}

Eroor func not exist!

@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

Sorry, can you run rm -r ~/Library/Preferences/bin and try again?

@reckless-huang
Copy link
Contributor Author

Sorry, can you run rm -r ~/Library/Preferences/bin and try again?

image I tried deleting these files, but the regenerated files are still incorrect after running. Do I need to update my local kcl? The displayed version is still 8.0.0.

@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

Make sense. I suggest deleting all KCL related legacy files including which kcl and ~/Library/Preferences/bin in your local area and then running the go code again.

@reckless-huang
Copy link
Contributor Author

I noticed that I replied under a topic that has already been closed. Do I need to create a new issue?

@Peefy Peefy reopened this Mar 19, 2024
@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

Just here, although this should be an installation issue.

@reckless-huang
Copy link
Contributor Author

It worked after I deleted the local kcl. It seems that there is logic that prioritizes using the kcl within the path.

@reckless-huang
Copy link
Contributor Author

	ops, err := loader.ListFileOptions("option.k")
	if err != nil {
		panic(err)
	}
	for _, op := range ops {
		//fmt.Println(op.Name)
		//fmt.Println(op.Type)
		//fmt.Println(op.Required)
		//fmt.Println(op.DefaultValue)
		fmt.Printf("变量名为%s类型是%v默认值为%v是否必填%v\n", op.Name, op.Type, op.DefaultValue, op.Required)
	}

kclcode

a = option("key1")
b = option("key2")
config = {
    metadata.name = option("name", type="str")
}

output
变量名为key1类型是默认值为是否必填false
变量名为key2类型是默认值为是否必填false
变量名为name类型是str默认值为是否必填false

The default value, type, and required value should not all be empty. Its right show?

@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

Yes, the default logic uses KCL in PATH, but it can be set through additional environment variables. I am refactoring this logic to make it easier to control through code. See the issue: #257

@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

This is the correct logic. The option function is not mandatory by default, and you can set additional parameters for it. e.g.

a = option("key1", default="value1", help="this is the message for key1")

@reckless-huang
Copy link
Contributor Author

The simple demo package is 90MB in size, which seems a bit large.

@Peefy
Copy link
Contributor

Peefy commented Mar 19, 2024

Sorry, we are working hard on lighter KCL. 🙏 kcl-lang/kcl#291 It is expected that the size will be reduced by half by then.

This is because we used LLVM for AOT compilation for performance and compilation caching, which resulted in unfriendly cross platform, and therefore included the binary size of all platforms in KCL Go SDK.

@reckless-huang
Copy link
Contributor Author

That’s excellent; thank you to the KCL team for your hard work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants