let's narrow down the scope to be "a user wants to store assets as parquet files on s3", for example pipeline like
in api.py, we will three internal representations
- AssetAddress: pointer to an addressable asset
- AssetStore: user-defined write/read
- AddressStore: instance-level mapping (StepOutputHandle -> AssetAddress)
foo 1-4 describe a more complicated situation where the user wants to store assets from different data type into different format to different storage in a run.