Sign kerchunk-style reference mappings (#35)
This commit is contained in:
Родитель
3d67a64fba
Коммит
27037bcb9a
|
@ -1,3 +1,9 @@
|
|||
# 0.4.5
|
||||
|
||||
## New Features
|
||||
|
||||
* `sign` will now sign [Kerchunk](kerchunk)-style dictionaries of references.
|
||||
|
||||
# 0.4.4
|
||||
|
||||
## New Features
|
||||
|
@ -49,3 +55,4 @@
|
|||
[gh-25]: https://github.com/microsoft/planetary-computer-sdk-for-python/issues/25
|
||||
[gh-30]: https://github.com/microsoft/planetary-computer-sdk-for-python/pull/30
|
||||
[xarray-assets]: https://github.com/stac-extensions/xarray-assets
|
||||
[kerchunk]: https://fsspec.github.io/kerchunk/
|
|
@ -1,6 +1,8 @@
|
|||
import re
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, Optional
|
||||
from typing import Any, Dict, Optional, Mapping
|
||||
import collections.abc
|
||||
import copy
|
||||
import warnings
|
||||
|
||||
from functools import singledispatch
|
||||
|
@ -70,12 +72,13 @@ def sign(obj: Any) -> Any:
|
|||
|
||||
Args:
|
||||
obj (Any): The object to sign. Must be one of:
|
||||
str (URL), Asset, Item, ItemCollection, or ItemSearch
|
||||
str (URL), Asset, Item, ItemCollection, or ItemSearch, or a mapping.
|
||||
Returns:
|
||||
Any: A copy of the object where all relevant URLs have been signed
|
||||
"""
|
||||
raise TypeError(
|
||||
"Invalid type, must be one of: str, Asset, Item, ItemCollection, or ItemSearch"
|
||||
"Invalid type, must be one of: str, Asset, Item, ItemCollection, "
|
||||
"ItemSearch, or mapping"
|
||||
)
|
||||
|
||||
|
||||
|
@ -277,6 +280,38 @@ def _search_and_sign(search: ItemSearch) -> ItemCollection:
|
|||
return sign(search.get_all_items())
|
||||
|
||||
|
||||
@sign.register(collections.abc.Mapping)
|
||||
def sign_reference_file(references: Mapping) -> Mapping:
|
||||
"""
|
||||
Sign a Kerchunk-style dictionary of references.
|
||||
|
||||
Args:
|
||||
references (Mapping): The dictionary containing the references.
|
||||
|
||||
Returns:
|
||||
references (Mapping): The dictionary, now with signed URLs.
|
||||
|
||||
This method will sign all of the URLs under the ``"templates"`` key. Mappings
|
||||
with other keys will be returned unchanged. See https://fsspec.github.io/kerchunk/
|
||||
for more.
|
||||
"""
|
||||
# TODO(python3.8): Use TypedDict instead of Mapping to limit the kinds we accept.
|
||||
# If we accept other mapping types in the future, we'll need to dispatch within
|
||||
# the function.
|
||||
if set(references) == {"version", "templates", "refs"}:
|
||||
references = copy.deepcopy(references)
|
||||
|
||||
for k, v in references["templates"].items():
|
||||
references["templates"][k] = sign_url(v)
|
||||
|
||||
else:
|
||||
raise TypeError(
|
||||
"When providing a mapping, the keys should be 'version', 'templates', "
|
||||
"and 'refs'."
|
||||
)
|
||||
return references
|
||||
|
||||
|
||||
def get_token(account_name: str, container_name: str) -> SASToken:
|
||||
"""
|
||||
Get a token for a container in a storage account.
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
"""Library version"""
|
||||
|
||||
__version__ = "0.4.4"
|
||||
__version__ = "0.4.5"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[metadata]
|
||||
name = planetary-computer
|
||||
version = 0.4.4
|
||||
version = 0.4.5
|
||||
license_file = LICENSE
|
||||
author = microsoft
|
||||
author_email = planetarycomputer@microsoft.com
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"version": 1,
|
||||
"templates": {
|
||||
"a": "https://nasagddp.blob.core.windows.net/nex-gddp-cmip6/NEX/GDDP-CMIP6/ACCESS-CM2/historical/r1i1p1f1/hurs/hurs_day_ACCESS-CM2_historical_r1i1p1f1_gn_1950.nc",
|
||||
"b": "https://nasagddp.blob.core.windows.net/nex-gddp-cmip6/NEX/GDDP-CMIP6/ACCESS-CM2/historical/r1i1p1f1/hurs/hurs_day_ACCESS-CM2_historical_r1i1p1f1_gn_1951.nc"
|
||||
},
|
||||
"refs": {
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import json
|
||||
import unittest
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
from pathlib import Path
|
||||
|
@ -57,6 +58,12 @@ def get_sample_item_collection() -> ItemCollection:
|
|||
return ItemCollection([get_sample_item()])
|
||||
|
||||
|
||||
def get_sample_references() -> dict:
|
||||
with open(os.fspath(HERE.joinpath("data-files/sample-reference-file.json"))) as f:
|
||||
references = json.load(f)
|
||||
return references
|
||||
|
||||
|
||||
class TestSigning(unittest.TestCase):
|
||||
def assertRootResolved(self, item: Item) -> None:
|
||||
root_link = item.get_root_link()
|
||||
|
@ -180,6 +187,22 @@ class TestSigning(unittest.TestCase):
|
|||
result = pc.sign(vrt_string)
|
||||
self.assertGreater(result.count("?st"), 0)
|
||||
|
||||
def test_sign_references_file(self) -> None:
|
||||
references = get_sample_references()
|
||||
result = pc.sign(references)
|
||||
for v in result["templates"].values():
|
||||
self.assertSigned(v)
|
||||
|
||||
def test_sign_other_mapping_raises(self) -> None:
|
||||
with self.assertRaisesRegex(TypeError, "When providing a mapping"):
|
||||
pc.sign({"version": None})
|
||||
|
||||
with self.assertRaisesRegex(TypeError, "When providing a mapping"):
|
||||
pc.sign({})
|
||||
|
||||
with self.assertRaisesRegex(TypeError, "When providing a mapping"):
|
||||
pc.sign({"version": None, "templates": None, "refs": None, "extra": None})
|
||||
|
||||
|
||||
class TestUtils(unittest.TestCase):
|
||||
def test_parse_adlfs_url(self) -> None:
|
||||
|
|
Загрузка…
Ссылка в новой задаче