diff --git a/CHANGELOG.md b/CHANGELOG.md index d215200..ad55d4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added + +- `read_href` and `blocking.read_href` ([#107](https://github.com/stac-utils/stac-asset/pull/107)) + ## [0.2.1] - 2023-09-05 ### Fixed diff --git a/src/stac_asset/__init__.py b/src/stac_asset/__init__.py index b9e6878..68132e3 100644 --- a/src/stac_asset/__init__.py +++ b/src/stac_asset/__init__.py @@ -21,6 +21,7 @@ download_collection, download_item, download_item_collection, + read_href, ) from .client import Client from .config import Config @@ -62,4 +63,5 @@ "download_collection", "download_item", "download_item_collection", + "read_href", ] diff --git a/src/stac_asset/_functions.py b/src/stac_asset/_functions.py index b2dd255..1dc5286 100644 --- a/src/stac_asset/_functions.py +++ b/src/stac_asset/_functions.py @@ -436,6 +436,29 @@ async def asset_exists( return True +async def read_href( + href: str, config: Optional[Config] = None, clients: Optional[List[Client]] = None +) -> bytes: + """Reads an href and returns its bytes. + + Args: + href: The href to read + config: The download configuration to use + clients: Any pre-configured clients to use + + Returns: + bytes: The bytes from the href + """ + if config is None: + config = Config() + clients_ = Clients(config, clients=clients) + async with await clients_.get_client(href) as client: + data = b"" + async for chunk in client.open_href(href): + data += chunk + return data + + def make_asset_hrefs_relative( stac_object: Union[Item, Collection] ) -> Union[Item, Collection]: diff --git a/src/stac_asset/blocking.py b/src/stac_asset/blocking.py index 1288053..6a0ad64 100644 --- a/src/stac_asset/blocking.py +++ b/src/stac_asset/blocking.py @@ -207,3 +207,19 @@ def asset_exists( bool: Whether the asset exists or not """ return asyncio.run(_functions.asset_exists(asset, config, clients)) + + +def read_href( + href: str, config: Optional[Config] = None, clients: Optional[List[Client]] = None +) -> bytes: + """Reads an href and returns its bytes. + + Args: + href: The href to read + config: The download configuration to use + clients: Any pre-configured clients to use + + Returns: + bytes: The bytes from the href + """ + return asyncio.run(_functions.read_href(href, config, clients)) diff --git a/tests/test_blocking.py b/tests/test_blocking.py index 1ab2b44..58fc88b 100644 --- a/tests/test_blocking.py +++ b/tests/test_blocking.py @@ -1,3 +1,4 @@ +import json from pathlib import Path import stac_asset.blocking @@ -32,9 +33,14 @@ def test_download_asset(tmp_path: Path, item: Item) -> None: assert asset.href == str(tmp_path / "image.jpg") -def test_assert_asset_exists(tmp_path: Path, item: Item) -> None: +def test_assert_asset_exists(item: Item) -> None: stac_asset.blocking.assert_asset_exists(item.assets["data"]) -def test_asset_exists(tmp_path: Path, item: Item) -> None: +def test_asset_exists(item: Item) -> None: assert stac_asset.blocking.asset_exists(item.assets["data"]) + + +def test_read_href(data_path: Path) -> None: + text = stac_asset.blocking.read_href(str(data_path / "item.json")) + Item.from_dict(json.loads(text)) diff --git a/tests/test_functions.py b/tests/test_functions.py index 1996e5c..0bf3211 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -1,3 +1,4 @@ +import json import os.path from asyncio import Queue from pathlib import Path @@ -204,7 +205,12 @@ async def test_asset_exists(item: Item) -> None: assert not await stac_asset.asset_exists(Asset(href="not-a-file")) -async def test_asert_asset_exists(item: Item) -> None: +async def test_assert_asset_exists(item: Item) -> None: await stac_asset.assert_asset_exists(item.assets["data"]) with pytest.raises(ValueError): await stac_asset.assert_asset_exists(Asset(href="not-a-file")) + + +async def test_read_href(data_path: Path) -> None: + text = await stac_asset.read_href(str(data_path / "item.json")) + Item.from_dict(json.loads(text))