-
Notifications
You must be signed in to change notification settings - Fork 115
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
[KED-2035] Expose parameter metadata #275
Conversation
This is great, thank you! So if I were to click on a single parameter node on the chart, which type of endpoint would I get? I assume it'd be the single |
Yes! In Kedro side, there are 2 ways to define parameters. Let's say in my example_test_data_ratio: 0.2
example_num_train_iter: 10000
example_learning_rate: 0.01 If I want to access all of them in one of my Kedro nodes, I can use a keyword
But image if I have 1000 parameters in my From Kedro Viz UI, both Hope this helps :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
ah okay interesting, thanks! Looks like you can access them both from clicking nodes on the graph then. It'd be great for these to have the same structure if possible, but I can't think of a way I'd do it better. I guess when receiving the data, we can just use To explain better what I mean: // params:xxx
{
// these are fine:
"parameters": 0.2
"parameters": 'this is a string'
"parameters": true
// these would cause problems, because I can't distinguish them from the full dictionary:
"parameters": [0, 1, 2, 3]
"parameters": { a: 1, b: 2 }
} The more I think about it, the more I think that this structure is running too many risks in assuming that these are distinguishable. If we want to be more clear about distinguishing them, maybe we should use a different property name, e.g. However you could also make the case that they just don't need to be distinguished, and then we can just display whatever the content is? Depends whether we should just display multiple parameters as code, or separate them and design them differently |
To give you more example, parameters can be nested. example_test_data_ratio:
nested1: 0.2
nested2: 0.3
nested3: 0.4
example_num_train_iter: 10000
example_learning_rate: 0.01 Hitting {
"parameters": {
"nested1": 0.2,
"nested2": 0.3,
"nested3": 0.4
}
} and {
"parameters": {
"example_learning_rate": 0.01,
"example_num_train_iter": 10000,
"example_test_data_ratio": {
"nested1": 0.2,
"nested2": 0.3,
"nested3": 0.4
}
}
} Viz UI will look the same as above screenshot (just metadata is nested) |
@921kiyo cool in that case, as mentioned on Slack, I propose that for single params, you just include a single key/value pair. instead of this: {
parameters: 0.01,
} do this instead: {
parameters: {
"example_learning_rate": 0.01,
}
} So that way, the formatting is consistent and we can treat them the same way. |
package/kedro_viz/server.py
Outdated
# In case of 'params:' prefix | ||
parameters_metadata = { | ||
"parameters": { | ||
next(iter(parameters)): next(iter(parameters.values())).load() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The readability is not great here. Can you reduce the nesting by doing
key, value = next(iter(parameters.items()))
package/kedro_viz/server.py
Outdated
# return empty JSON for parameters type | ||
return jsonify({}) | ||
parameters = node["obj"] | ||
if isinstance(parameters, dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of such isinstance
here. Can we maybe explicitly save parameter name in the dict we put in _JSON_NODES
?
Something like:
if "parameter_name" in node:
# handle "params:..."
else:
# handle "parameters"
@limdauto wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I could do that but how do you get "parameter_name" in this function? we can only access to parameter_name
from next(iter(parameters.items()))
correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant I don't particularly like the fact that instead of the object we put the dictionary with name and object. Parameter name can have its own top-level key rather than being squeezed into the obj
key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DmitriiDeriabinQB Hope I understand you correctly, but it sounds like you're asking for the single-parameter endpoint to have a different structure from the multiple-parameter endpoint, is that right? Kiyo had it like that originally, but I asked him to change it.
If you think about this from the front-end perspective, we might want to separate out different keys to display them differently in the viz meta panel when clicking on a 'Parameters' node - e.g.:
but if you click on a single node, we might want to display it the same way, but if it's not in the same format we might not be able to recognise it as a distinct type just from the structure, because a parameter can be one of lots of different types. So we're using the same structure to keep it simple on the front end. Does that help? Hope I haven't misunderstood you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@richardwestenra I'm still keeping the format you asked, his suggestion was more about how to generate it in code :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@richardwestenra yeah, I read through your discussion with Kiyo above and understand the solution. I wasn't talking about the format it is exposed to the frontend but rather the way the data stored in the backend. I'm moderately cautious about the complexity of the data wrangling logic on Python side since the data itself is quite trivial.
TLDR: It's purely the discussion about the Python side of things and should not affect the API contract.
Co-authored-by: Dmitrii Deriabin <[email protected]>
package/kedro_viz/server.py
Outdated
if "parameter_name" in node: | ||
# In case of 'params:' prefix | ||
parameters_metadata = { | ||
"parameters": {node["parameter_name"]: node["obj"].load()} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry could you remind me what does node["obj"].load()
do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node["obj"]
is MemoryDataSet, so it will load the value of params:key parameter (e.g. 0.2
)
@@ -539,8 +541,15 @@ def nodes_metadata(node_id): | |||
dataset_metadata = _get_dataset_metadata(node) | |||
return jsonify(dataset_metadata) | |||
|
|||
# return empty JSON for parameters type | |||
return jsonify({}) | |||
if "parameter_name" in node: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much better (to me personally at least), thanks @921kiyo 👍
Description
As an extension for metadata side panel, we are exposing parameters metadata to Viz. Here are examples of the endpoints and and outputs.
http://127.0.0.1:4141/api/nodes/d577578a
(endpoint forparams:xxx
)http://127.0.0.1:4141/api/nodes/f1f1425b
(endpoint forparameters
)Development notes
QA notes
Modified unit tests
Checklist
RELEASE.md
fileLegal notice
I acknowledge and agree that, by checking this box and clicking "Submit Pull Request":
I submit this contribution under the Apache 2.0 license and represent that I am entitled to do so on behalf of myself, my employer, or relevant third parties, as applicable.
I certify that (a) this contribution is my original creation and / or (b) to the extent it is not my original creation, I am authorised to submit this contribution on behalf of the original creator(s) or their licensees.
I certify that the use of this contribution as authorised by the Apache 2.0 license does not violate the intellectual property rights of anyone else.