Taylor Brown
11/25/2024, 5:01 PMdr.execute with a certain set of parameters, but I didn't know if there was a recommended way to do that, or a way that made the pipelines more self-documenting in a type-safe way. From the [async/joke example blog post](https://blog.dagworks.io/p/async-dataflows-in-hamilton):
from hamilton.async_driver import Builder
dr = await (
Builder()
.with_modules(async_functions)
.build()
)
await dr.execute(["joke_response"], inputs={"topic" : "federal reserve"})
There are a lot of strings for me to get wrong there. I'd prefer to see: joke_response : str = execute_joke_dag(topic="federal reserve").joke_responseElijah Ben Izzy
11/25/2024, 5:26 PMwhat_is functions: https://hamilton.dagworks.io/en/latest/reference/drivers/Driver/#hamilton.driver.Driver.what_is_downstream_of, as well as list_available_variables
3. So it doesn’t execute anything if it senses that it can’t (and errors out). That said, we do have some validation methods if you want to bypass calling execute, E.G. https://hamilton.dagworks.io/en/latest/reference/drivers/Driver/#hamilton.driver.Driver.validate_execution Regarding type-safety, interesting. There would be a lot of code-generation/magic in what you’ve recommended, although we could probably make it easier to build such a class (E.G. cast it to a pydantic dataframe and use that). Some other options:
• You can use function pointers dr.execute([joke_response])["joke_response"]
• Jupyter magic has some capabilities for this as well: https://github.com/DAGWorks-Inc/hamilton/blob/main/examples/jupyter_notebook_magic/example.ipynb — E.G> making it easier to get the strings right.
That said, a wrapper class around the driver that forces it to a dataclass might be really easy to make — there isn’t a good way to get type-hints wired through automatically thought, without manually specifying the types, building a more complex plugin, or using runtime data (E.G. in jupyter)Stefan Krawczyk
11/25/2024, 5:38 PMclass MyClass(pydantic.BaseModel):
joke_response: str
...
dr = await (
Builder()
.with_modules(async_functions)
.with_adapters(PydanticResultBuilder(MyClass))
.build()
)
result: MyClass = await dr.execute(...)
result.joke_responseStefan Krawczyk
11/25/2024, 5:39 PMTaylor Brown
11/25/2024, 7:19 PMfor batch_result of my_modal_function.map(table_batch_iterator) and then writing those batch results to a table.
This works okay, but A) is a fair amount of hard-coded plumbing for something that I might do somewhat commonly, B) doesn't declare its dependencies well, C) is fragile if there is an exception (this is not resumable/cacheable by default).
Hamilton looks like a good lightweight code-first DAG, so I'm pretty excited about that. I'll take a stab at writing the above in Hamilton to see if it helps with any of those issues, but I am hoping to avoid too many newbie mistakes out of the gate, so following a "this is how you do fan-out processing on Modal" example would be helpful.
I appreciate you sending me the sample modal code. It does give me an idea as to what a remote executor would look like. I think I'll try to just "use" modal in my steps for now and see how far I get.
That notebook stuff looks super handy too! I'll look into that!
Thanks @Stefan Krawczyk on the ResultBuilder link. I'm okay to declare types manually for now with a Pydantic object. It just serves as good documentation for myself if nothing else.Elijah Ben Izzy
11/25/2024, 7:30 PMTaylor Brown
11/25/2024, 7:49 PMThis leverages Hamilton as a few big functions. The piece that runs the embeddings in parallel is all done inside a single function, so those assets are not visible."Imagine one of my "steps" involves batch processing 100k rows of data of a dataset (in batches of 1000, for a total of 100 calls), and due to a slow external call, takes over 24 hours to process. To get trackability/interruptability/resumability of what is essentially a large map/reduce DAG, should I think about splitting up this single node into N separate dynamic nodes, each of which has their own cache? I am not currently sure how to make such a long-running parallel-batch-task visible to Hamilton and its machinery.
Taylor Brown
11/25/2024, 7:53 PMElijah Ben Izzy
11/25/2024, 7:55 PMElijah Ben Izzy
11/25/2024, 7:57 PMStefan Krawczyk
11/25/2024, 8:03 PMTaylor Brown
11/25/2024, 8:10 PMStefan Krawczyk
11/25/2024, 8:30 PMTaylor Brown
11/25/2024, 8:31 PMStefan Krawczyk
11/25/2024, 8:33 PMTaylor Brown
11/25/2024, 8:34 PMTaylor Brown
11/25/2024, 8:35 PMTaylor Brown
11/25/2024, 8:38 PMStefan Krawczyk
11/25/2024, 8:41 PMTaylor Brown
11/25/2024, 8:41 PM