feat: multi-input multi-resource type operators - #1248
michael-johnston wants to merge 56 commits into
Conversation
- ADOResourceReference - this is a model that refers to a resource in the metastore i.e. an id and a kind. The model is not frozen, and kind can be None, allowing kind to be deduced after model instantion. - ADOResourcePropertyDescriptor - this is a model that says a identifier (str) has a particular type. The model is frozen, kind must be given. The use of this is to carry information about the type of an ado operator function parameter.
Prior to this change only a single DiscoverySpace could be specified as an ADOResource input to an operation. This change allows any number of resources of any kind to be passed DiscoveryOperationResourceConfiguration: - New "input" field allows specifying, for named operator input parameters, the ADO resource in the metadstore that should be used to pass a value to that parameter. - validation: the input field can (conditionally via a context) be validated against the operator i.e. check the parameters named exist, check the kind of the resource referenced matches the parameters type. Also if the kind in reference is None, this sets it with the correct kind. OperatorMetadata: New field required_resource_inputs for holding the operator parameters that required ADO resources, and the kind of resource. Used to do the validation above.
In preflight check for operation ids
- Defines rich types for ado resources (DataContainer and DiscoverySpace for now) - Converts a resource reference (resource id + kind) to the rich type instance
Prior to this there was a single rule for all operators types - only 1 discovery space alloed. The module expresses the expanded rules for resource inputs for each operator type e.g. fuse must have 2+ discovery spaces. It also provides a function validate_resource_inputs_for_operation_type to validate if a set of resource inputs are valid for a given operation type
Previously we had strict function signature defined in a protocol. Now operators can have more general signature new validation is required - validate_operator_call_shape: Checks the operator function has some number of resource inputs, followed by operationInfo, followed by keyword args - validate_resource_input_types: Checks that a set of proposed inputs to an operator match what it wants - validate_operator_registration: Combines the three checks (two above + validate_resource_inputs_for_operation_type)
Also add new collections for compare and fuse operators
instead of pydantic.BaseModel
Also - pass metastore explicitly - use GenericOptionaParameters not dict
Instead of kwargs
wrong name
Also use orchestrate_core interface
Also use GenericOperatorParameters
Also use GenericOperatorParameters
Previously wrappers took and passed a dump of the operators parameters. Now it takes and passes the actual object. In addition with multiple inputs its not guaranteed the metastore can be accessed (previously was always available as only discoveryspace's could be passed). Now retrieve the context to use via FunctionOperationInfo or use active context if that isn't available. Create metastore from this.
So it can be retrieved in other places in the code. However this will not work in multi-process jobs.
Instead as fall back look for resources that carry the context with them.
Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
|
@AlessandroPomponio docs to be updated once the implementation is deemed good enough. |
Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
AlessandroPomponio
left a comment
There was a problem hiding this comment.
Initial set of comments
| def _operator_input_name_for_kind( | ||
| operation_data: dict, | ||
| kind: CoreResourceKinds, | ||
| ) -> str: | ||
| """Resolve the operator input parameter name for a resource *kind*. | ||
|
|
||
| Uses the operator's ``required_resource_inputs``. When several inputs share | ||
| *kind*, prefers an input not yet present in ``operation_data["inputs"]``. | ||
|
|
||
| Args: | ||
| operation_data: Raw operation resource configuration dict (YAML). | ||
| kind: Resource kind to bind (e.g. discoveryspace, datacontainer). | ||
|
|
||
| Returns: | ||
| The input parameter identifier to set. | ||
|
|
||
| Raises: | ||
| ValueError: If the operator has no matching input, or multiple matching | ||
| inputs are unset / ambiguous. | ||
| """ |
There was a problem hiding this comment.
I find this function to be a bit weird: it returns the identifier of a parameter of kind kind if:
- It's the only one matching the kind (no check on whether it was set or not)
- It's the only one unset matching the kind
What I mean with this is that this function is very specific but the name doesn't really convey it. This part of the docstring does a lot of heavy lifting:
When several inputs share kind, prefers an input not yet present in
operation_data["inputs"].
This function is used only in one place for now and it's private, so I'm not sure if I'd keep this separate, given how many caveats it has to be understandable
There was a problem hiding this comment.
This exists due to the current implementation of `--with
before changing lets figure out how with will work.
Co-authored-by: Alessandro Pomponio <10339005+AlessandroPomponio@users.noreply.github.com> Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
Signed-off-by: Michael Johnston <66301584+michael-johnston@users.noreply.github.com>
…aj_generalize_operators
This PR introduces multi-input multi-resource type operators.
It also changes the type of the operator functions
parametersparameter to be instances of the operators parameter model instead of a dictionary (answers #647)Example new function definition.
Note: Here we use
OperatorInputTypeto denote the allowed input types e.g. DiscoverySpace (see more below) and GenericOperatorParameters as a placeholder for the specific parameter model of the operatorPrior to this PR operators could only work on a single input resource, which had to be of type DiscoverySpace and named discoverySpace. Further the parameters for the operator were passed as keyword args i.e.
Operator Input Types
ADO resources that can be operated on are now associated with a "rich" type that will be passed to the operator. In the PR we have two resources that can be operated on
Note: Its a particular property of DataContainerResource that it can be its own rich type.
Setting inputs in operation.yaml
The PR removes the DiscoveryOperationConfiguration
spacesfield and introduce the more generalinputfield.before
now, for an operator with two DiscoverySpace input params called space_one and space_two
In practice
kindcan be inferred when the YAML is read so users can omit it.For existing operators that previously had a YAML section like
Users will now set
Non-breaking changes
spacesfield is kept as a computed field, so any code relying on querying it in metastore does not need to be changedinputfield if read. Not breakingspacesfield in YAML it will be auto-updated to new format. This will only be valid for operators talking a single space with a parameter called discoverySpace (all existing operators)Breaking changes
Code Changes
The code changes fall into three groups:
spaces[0]), including storing relationships, and handling cases where the rich resource type does not provide a way to acces the metastore