Piotr Bieszczad
03/31/2025, 9:56 AMstep.
I wanted to use @check_output_custom , but the validation is not propagated.
Is there a way to do this?
Example:
@check_output_custom(CustomValidator())
def foo(...) -> ...:
...
return result
@pipe_output(
step(foo).named('foo_applied'),
...,
)
def bar(...) -> ...:
return result
Validation is not applied to foo_applied
Thank you in advance for reply
----------------------------------------------------------
Also is there a way of acting upon failure?
E.g I know, that if validation fails in one of the previous steps, than I want to return a flag inference failed at the end of the flow, on top of exiting it.
Basically some functionality for early termination of a flowStefan Krawczyk
03/31/2025, 5:24 PM@check_output_* only works on first class functions in the hamilton DAG, not "steps".
Want to try the following?
def foo(...) -> ...:
...
return result
@check_output_custom(CustomValidator(), target_="foo_applied")
@pipe_output(
step(foo).named('foo_applied'),
...,
)
def transition_cap(...) -> ...:
return resultStefan Krawczyk
03/31/2025, 5:27 PMinference failed at the end of the flow, on top of exiting it.
What is the current behavior you're observing? IIRC it should fail hard, i.e. throw an exception if things fail and stop all execution -- is that what you want?
CC @Elijah Ben IzzyElijah Ben Izzy
03/31/2025, 6:50 PMPiotr Bieszczad
04/01/2025, 5:53 AMPiotr Bieszczad
04/01/2025, 6:50 AMThen you can catch that, which will have some error information, and you can do what you want.I did try this, however logging the error does not seem appealing, as I would like this to be part of expected functionality. Maybe it is wrong design choice on my side, but I believe it can have many use cases. To give an example: Imagine a data flow that takes as input df of cars, uses nodes to filter the cars, and calculates some metrics (e.g total price, or total mass, or some other attribute), of all of the filtered cars. If there are many filters, it would be nice if all of the filters would assert that output contains at least one car, otherwise, the execution is stopped prematurely at that filter node, and all of the
calculate_metric nodes should return a default value of 0 (or whatever was specified for them).Piotr Bieszczad
04/01/2025, 7:00 AM@check_output_custom(CarsExistValidator())
def filter_color(...)
def filter_horse_power(...)
def filter_type(...)
def total_price(...)
def total_mass(...)
@pipe_output(
step(filter_color),
step(filter_type),
step(filter_hp),
step(total_price),
def total_mass_red_suv_200hp(cars: df)
@pipe_output(
step(filter_color),
step(total_mass)
step(filter_type),
step(filter_hp),
step(total_price)
def total_price_blue_light_sport_cheap(cars: df)
And so If there are no blue cars, instead of propagating redundant execution, I would like the total_mass to return 0 in case CarsExistValidator() fails.Stefan Krawczyk
04/01/2025, 6:30 PMStefan Krawczyk
04/01/2025, 6:36 PMThat would not be suitable, as the step(foo) is applied across many different nodes, and I want the validation to always follow this step.@Piotr Bieszczad makes sense. Mind opening up an issue here? Would have to dig into the code to determine the feasibility of this. But at a high level it makes sense. To get you immediately unblocked I think there's a few paths. Before enumerating them, are you using any "adapters" with your code right now?
Piotr Bieszczad
04/02/2025, 6:24 AMGracefulErrorAdapter sounds promising. I will read up on that.Stefan Krawczyk
04/02/2025, 5:35 PMfoo function. It can take in the validator and exercise it for each invocation of that function. It can then throw a specific error that the graceful error adapter could catch / handle.Stefan Krawczyk
04/02/2025, 5:35 PM