镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Stream data from S3 storage to native python object - #109

Draft
pkdash wants to merge 15 commits into
6483-add-s3-protocol-supportfrom
6484-stream-data-to-native-py-object
Draft

pkdash wants to merge 15 commits into
6483-add-s3-protocol-supportfrom
6484-stream-data-to-native-py-object

Conversation

@pkdash

@pkdash pkdash commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

TODO:

  • Add test for each of the supported python data objects
  • Update API documentation
  • Add example notebook

Comment thread hsclient/hydroshare.py Outdated
response = self._hs_session.get('/hsapi/userInfo/', status_code=200)
return response.json()

def stream_data_object(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome and you took it further than just zarr/xarray! I think though that this code could be refactored a bit to use a pattern that is easier to extend and less brittle than the multiple conditionals in this method.

We could do something like a base reader class with child classes for each reader type. The reader classes each document what extensions they support, and implement a read() method. Something like:

class StreamReader:
    extensions = ()
    default_object_type = None
    object_types = ()

    def validate_object_type(self, object_type: str | None) -> str:
        ...
        (returns object type, default or selected if valid)

    def read(self, hs, s3_path: str, reader_kwargs: dict[str, Any]) -> Any:
        raise NotImplementedError

and then a child class implements the read method:

class CsvReader(StreamReader):
    extensions = (".csv",)
    default_object_type = "pandas"
    object_types = ("pandas",)

    def read(self, hs, s3_path, reader_kwargs):
        pd = hs._require_module(pandas, "pandas")
        with hs._s3_client.open(s3_path) as f:
            return pd.read_csv(f, **reader_kwargs)

It becomes very obvious how to add a new reader and the code is a bit more self-documenting. And we don't have to worry about breaking the conditional logic. We can register each reader to an extension:

STREAM_READERS = {
    ".csv": CsvReader(),
    ".parquet": ParquetReader(),
  ...
}

Fetch the reader for the extension, and then call it's methods to validate the object type and read in the data. Logic for each reader stays local to its class.

Apologies for being so prescriptive -- I don't think it has to be implemented exactly like this, but I wanted to give a concrete example so my suggestion wasn't too confusing!

What do you think?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it is much better. Thanks!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for refactoring -- lgtm!

@pkdash
pkdash force-pushed the 6484-stream-data-to-native-py-object branch from b2b1221 to 7d84654 Compare October 17, 2026 22:20
Comment thread hsclient/hydroshare.py


class CsvReader(StreamReader):
extensions = (".csv",)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is totally fine for now, just leaving a note for future expansion -- we could likely handle .txt, .psv, and .tsv here as well but we would need a way to accept a separator argument!

@pkdash
pkdash force-pushed the 6483-add-s3-protocol-support branch from 6f1f92d to 27fb56b Compare October 21, 2026 23:02

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

POC for streaming resource data to native library objects

2 participants