-
Notifications
You must be signed in to change notification settings - Fork 37
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
Create & Publish: Attribute definitions per instance #860
Create & Publish: Attribute definitions per instance #860
Conversation
…with-Publisher-attributes
Task linked: AY-5552 Publisher attr defs per instance |
def _create_instance( | ||
self, product_type: str, product_name: str, data: Dict[str, Any] | ||
) -> CreatedInstance: | ||
instance = CreatedInstance( | ||
product_type, | ||
product_name, | ||
data, | ||
creator=self, | ||
) | ||
self._add_instance_to_context(instance) | ||
return instance |
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.
Why is this needed?
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.
Just helper method for creators. Not needed, but you don't have to import CreatedInstance
and call _add_instance_to_context
manually to create one.
def get_attr_defs_for_instance(self, instance): | ||
"""Get attribute definitions for an instance. | ||
|
||
Args: | ||
instance (CreatedInstance): Instance for which to get | ||
attribute definitions. | ||
|
||
""" | ||
return self.get_instance_attr_defs() |
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.
So - how dynamic is this? Like, from the CreatedInstance
to what data in it are we allowed to respond to make the returned attribute definitions unique? E.g. technically we can now differentiate attribute defs based on "other attributes" on the instance - however I wonder whether that's intended 'feature'?
- Can we rely on doing something different based on e.g. folder path or task? If so, what happens if someone without resets confirms a target folder path change from within the UI? Does it refresh?
- Can we rely on doing something differently based on e.g.
families
on the instance if it has it? - Can we rely on doing something based off of other attributes on the instance from other plug-ins, I suppose not? Since it'd only update on reset?
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.
Can we rely on doing something differently based on e.g. families on the instance if it has it?
Yes, but if I may request, please do not use families
for it if possible. We can discuss each individual use-case (not here).
Why: In case of USD, you probably should be adding families
based on the definitions, instead of showing definitions based on families? Meaning, you can add "isUsdInstance": True
on instance data to know if is related to USD or not (please take this as very very basic example).
Can we rely on doing something different based on e.g. folder path or task? If so, what happens if someone without resets confirms a target folder path change from within the UI? Does it refresh?
Can we rely on doing something based off of other attributes on the instance from other plug-ins, I suppose not? Since it'd only update on reset?
Both question have same answer. Right now it collects definitions only when instance is created or collected (on create and on reset). For "real time update" we need callbacks. Future PR mentioned in description, which I think might require change of the methods or create context api.
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.
Why: In case of USD, you probably should be adding families based on the definitions, instead of showing definitions based on families? Meaning, you can add "isUsdInstance": True on instance data to know if is related to USD or not (please take this as very very basic example).
I see, but preferably we work towards something similar to families
(like standardizes like that, alsmost like "tags") but for the instance's features instead instead of resulting in TONS and TONS of isUsdInstance=True
and isFbxInstance=True
. Stepping away from pyblish
terminology like families
, yes! But just doing for example targetProductTypes = {"fbx", "usd"}
or whatever name we come up seems like something we can standardize way better. Or maybe better yet, have a dedicated attribute for that on the instance. E.g. being able to do something like:
if instance.supports("usd"):
# bla
Likely overlaps tons with @antirotor work with OpenAssetIO but that's a can of worms I'm afraid to touch. :)
Both question have same answer. Right now it collects definitions only when instance is created or collected (on create and on reset). For "real time update" we need callbacks. Future PR mentioned in description, which I think might require change of the methods or create context api.
👍
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.
Because I don't know the context, I can't react. Only from what you wrote I have 10 following questions that will raise another questions. Maybe with full context I would agree, but at this moment I don't.
It is possible to do anything, we should just discuss what would be the ideal approach, to make it clear from data flow.
Like I've said (wrote) we can discuss that out of this PR, as it is not directly related, and it requires more minds.
So I have some use cases for this that I'd like to implement soon - as a means to testing this PR, but there's one big worry that I have: performance. @iLLiCiTiT Let me explain the use cases:
Having the defaults update related to the instance for attributes may also make #153 and #146 more sensible to implement. |
Calling // File "E:\dev\ayon-core\client\ayon_core\pipeline\create\context.py", line 1037, in reset_instances
// creator.collect_instances()
// File "E:\dev\ayon-maya\client\ayon_maya\api\plugin.py", line 293, in collect_instances
// return self._default_collect_instances()
// File "E:\dev\ayon-maya\client\ayon_maya\api\plugin.py", line 234, in _default_collect_instances
// created_instance = CreatedInstance.from_existing(node_data, self)
// File "E:\dev\ayon-core\client\ayon_core\pipeline\create\structures.py", line 716, in from_existing
// return cls(
// File "E:\dev\ayon-core\client\ayon_core\pipeline\create\structures.py", line 479, in __init__
// creator_attr_defs = creator.get_attr_defs_for_instance(self)
// File "E:\dev\ayon-maya\client\ayon_maya\plugins\create\create_review.py", line 100, in get_attr_defs_for_instance
// print(instance.data_to_store())
// File "E:\dev\ayon-core\client\ayon_core\pipeline\create\structures.py", line 689, in data_to_store
// output["creator_attributes"] = self.creator_attributes.data_to_store()
// File "E:\dev\ayon-core\client\ayon_core\pipeline\create\structures.py", line 654, in creator_attributes
// return self._data["creator_attributes"] If I try to get the folder path or task name for the instance, I can't find it? print(instance.items())
# odict_items([('id', 'pyblish.avalon.instance'), ('productType', 'review'), ('productName', 'reviewMain'), ('active', True), ('creator_identifier', 'io.openpype.creators.maya.review'), ('variant', '')]) Also, |
…er-instance # Conflicts: # client/ayon_core/pipeline/create/structures.py
Should be fixed, but I would recommend to not use |
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.
Hey,
I tested this PR against ynput/ayon-houdini#2
I applied the following modification to these lines: renamed the method + add the if condition.
def get_attr_defs_for_instance(self, instance):
"""get instance attribute definitions.
Attributes defined in this method are exposed in
publish tab in the publisher UI.
"""
if instance["productType"] != "render":
return []
and it I was able to change the attr defs per instances.
My code skips adding review
and render target
parameters for non render products.
non render product | render product |
---|---|
tbh, I find it hard to furtherly test this PR.
I don't know if there is anything else to test? |
I meant it's hard for me to test it with other creator plugins. maybe because I'm not yet familiar with the enhancement in this PR. |
Closing in favor of #935 |
Changelog Description
Create plugins and publish plugins can define attribute definitions per instance. Publish context plugins can also define attributes for instances and instance plugins can define attributes for context.
Additional info
THIS IS NOT FINAL PR
This PR is primarily created to review my current state of work, it might not be merged at the end. Following PR should add option to change instance attributes after creation using callbacks, which might mean that some of the methods will probably change to suit the usecase, which would again mean breaking backwards compatibility.
Testing notes:
Existing plugins should work exactly the same as before this PR.
With changes in this PR it is possible to define different attribute definitions per instance, for create plugin and for publish plugin.
One example could be that an instance have enumerator but with different values, e.g. based on scene location.
I've had some testing scenario, but I'm certain I don't have what might be useful.