diff --git a/CHANGELOG.md b/CHANGELOG.md index 29dbcbe..768d1a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.4.4 + +## New Features + +* `sign` will now sign VRT-like strings, like those returned by GDAL's [STACIT](https://gdal.org/drivers/raster/stacit.html) driver. + # 0.4.3 ## Bug Fixes diff --git a/planetary_computer/__init__.py b/planetary_computer/__init__.py index 5d748d4..9a33625 100644 --- a/planetary_computer/__init__.py +++ b/planetary_computer/__init__.py @@ -11,6 +11,7 @@ ) from planetary_computer.settings import set_subscription_key +from planetary_computer.version import __version__ __all__ = [ "set_subscription_key", @@ -20,4 +21,5 @@ "sign_item", "sign_url", "sign", + "__version__", ] diff --git a/planetary_computer/sas.py b/planetary_computer/sas.py index bfd2617..b022ab4 100644 --- a/planetary_computer/sas.py +++ b/planetary_computer/sas.py @@ -1,3 +1,4 @@ +import re from datetime import datetime, timezone from typing import Any, Dict, Optional import warnings @@ -11,7 +12,13 @@ from pystac_client import ItemSearch from planetary_computer.settings import Settings -from planetary_computer.utils import parse_blob_url, parse_adlfs_url, is_fsspec_asset +from planetary_computer.utils import ( + parse_blob_url, + parse_adlfs_url, + is_fsspec_asset, + is_vrt_string, + asset_xpr, +) BLOB_STORAGE_DOMAIN = ".blob.core.windows.net" @@ -73,13 +80,41 @@ def sign(obj: Any) -> Any: @sign.register(str) +def sign_string(url: str) -> str: + """Sign a URL or VRT-like string containing URLs with a Shared Access (SAS) Token + + Signing with a SAS token allows read access to files in blob storage. + + Args: + url (str): The HREF of the asset as a URL or a GDAL VRT + + Single URLs can be found on a STAC Item's Asset ``href`` value. Only URLs to + assets in Azure Blob Storage are signed, other URLs are returned unmodified. + + GDAL VRTs can combine many data sources into a single mosaic. A VRT can be + built quickly from the GDAL STACIT driver + https://gdal.org/drivers/raster/stacit.html. Each URL to Azure Blob Storage + within the VRT is signed. + + Returns: + str: The signed HREF or VRT + """ + if is_vrt_string(url): + return sign_vrt_string(url) + else: + return sign_url(url) + + def sign_url(url: str) -> str: - """Sign a URL with a Shared Access (SAS) Token, which allows for read access. + """Sign a URL or with a Shared Access (SAS) Token + + Signing with a SAS token allows read access to files in blob storage. Args: - url (str): The HREF of the asset in the format of a URL. - This can be found on STAC Item's Asset 'href' value. Only URLs to assets - in Azure Blob Storage are signed, other URLs are returned unmodified. + url (str): The HREF of the asset as a URL + + Single URLs can be found on a STAC Item's Asset ``href`` value. Only URLs to + assets in Azure Blob Storage are signed, other URLs are returned unmodified. Returns: str: The signed HREF @@ -93,6 +128,46 @@ def sign_url(url: str) -> str: return token.sign(url).href +def _repl_vrt(m: re.Match) -> str: + # replace all blob-storages URLs with a signed version. + return sign_url(m.string[slice(*m.span())]) + + +def sign_vrt_string(vrt: str) -> str: + """Sign a VRT-like string containing URLs with a Shared Access (SAS) Token + + Signing with a SAS token allows read access to files in blob storage. + + Args: + vrt (str): The GDAL VRT + + GDAL VRTs can combine many data sources into a single mosaic. A VRT can be + built quickly from the GDAL STACIT driver + https://gdal.org/drivers/raster/stacit.html. Each URL to Azure Blob Storage + within the VRT is signed. + + Returns: + str: The signed VRT + + Examples + -------- + >>> from osgeo import gdal + >>> from pathlib import Path + >>> search = ( + ... "STACIT:\"https://planetarycomputer.microsoft.com/api/stac/v1/search?" + ... "collections=naip&bbox=-100,40,-99,41" + ... "&datetime=2019-01-01T00:00:00Z%2F..\":asset=image" + ... ) + >>> gdal.Translate("out.vrt", search) + >>> signed_vrt = planetary_computer.sign(Path("out.vrt").read_text()) + >>> print(signed_vrt) + + ... + + """ + return asset_xpr.sub(_repl_vrt, vrt) + + @sign.register(Item) def sign_item(item: Item) -> Item: """Sign all assets within a PySTAC item diff --git a/planetary_computer/utils.py b/planetary_computer/utils.py index 03bc162..171e6d0 100644 --- a/planetary_computer/utils.py +++ b/planetary_computer/utils.py @@ -1,3 +1,5 @@ +import re + from typing import Tuple, Optional from urllib.parse import ParseResult, urlunparse, urlparse @@ -57,3 +59,18 @@ def is_fsspec_asset(asset: pystac.Asset) -> bool: return "account_name" in asset.extra_fields.get( "table:storage_options", {} ) or "account_name" in asset.extra_fields.get("xarray:storage_options", {}) + + +def is_vrt_string(s: str) -> bool: + """ + Check whether a string looks like a VRT + """ + return s.strip().startswith("") + + +asset_xpr = re.compile( + r"https://(?P[A-z0-9]+?)" + r"\.blob\.core\.windows\.net/" + r"(?P.+?)" + r"/(?P[^<]+)" +) diff --git a/planetary_computer/version.py b/planetary_computer/version.py index ea74af8..7625c52 100644 --- a/planetary_computer/version.py +++ b/planetary_computer/version.py @@ -1,2 +1,3 @@ -__version__ = "0.4.3" """Library version""" + +__version__ = "0.4.4" diff --git a/requirements-dev.txt b/requirements-dev.txt index 322af62..605bf06 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,6 @@ -black==20.8b1 -flake8==3.8.4 +black==21.10b0 +flake8==4.0.1 ipdb==0.13.7 -mypy==0.790 -setuptools==56.0.0 +mypy==0.910 +types-requests==2.26.0 +setuptools==58.5.3 diff --git a/setup.cfg b/setup.cfg index 076b589..26b97e7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = planetary-computer -version = 0.4.3 +version = 0.4.4 license_file = LICENSE author = microsoft author_email = planetarycomputer@microsoft.com diff --git a/tests/data-files/stacit.vrt b/tests/data-files/stacit.vrt new file mode 100644 index 0000000..2b9d626 --- /dev/null +++ b/tests/data-files/stacit.vrt @@ -0,0 +1,886 @@ + + PROJCS["NAD83 / UTM zone 14N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-99],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26914"]] + 4.0896540000000002e+05, 6.0000000000000009e-01, 0.0000000000000000e+00, 4.4355894000000004e+06, 0.0000000000000000e+00, -6.0000000000000264e-01 + + Red + Red + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_ne_14_060_20190709.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_se_14_060_20190709.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_se_14_060_20190709.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_sw_14_060_20190709.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39100/m_3910008_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_nw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_ne_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40100/m_4010064_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_se_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_sw_14_060_20190711.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39098/m_3909801_nw_14_060_20190713.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40098/m_4009857_sw_14_060_20190713.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_nw_14_060_20190828.tif + 1 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_ne_14_060_20190828.tif + 1 + + + + + + Green + Green + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_ne_14_060_20190709.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_se_14_060_20190709.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_se_14_060_20190709.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_sw_14_060_20190709.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39100/m_3910008_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_nw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_ne_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40100/m_4010064_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_se_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_sw_14_060_20190711.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39098/m_3909801_nw_14_060_20190713.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40098/m_4009857_sw_14_060_20190713.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_nw_14_060_20190828.tif + 2 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_ne_14_060_20190828.tif + 2 + + + + + + Blue + Blue + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_ne_14_060_20190709.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_se_14_060_20190709.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_se_14_060_20190709.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_sw_14_060_20190709.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39100/m_3910008_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_nw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_ne_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40100/m_4010064_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_se_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_sw_14_060_20190711.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39098/m_3909801_nw_14_060_20190713.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40098/m_4009857_sw_14_060_20190713.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_nw_14_060_20190828.tif + 3 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_ne_14_060_20190828.tif + 3 + + + + + + + near-infrared + + NIR + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_ne_14_060_20190709.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_se_14_060_20190709.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_se_14_060_20190709.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009964_sw_14_060_20190709.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909907_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39100/m_3910008_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909906_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909905_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909904_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909903_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909902_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_nw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909901_ne_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40100/m_4010064_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009963_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009962_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009961_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009960_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009959_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009958_se_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40099/m_4009957_sw_14_060_20190711.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39098/m_3909801_nw_14_060_20190713.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/40098/m_4009857_sw_14_060_20190713.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_nw_14_060_20190828.tif + 4 + + + + + /vsicurl/https://naipeuwest.blob.core.windows.net/naip/v002/ks/2019/ks_60cm_2019/39099/m_3909908_ne_14_060_20190828.tif + 4 + + + + + diff --git a/tests/test_signing.py b/tests/test_signing.py index d436d30..8677464 100644 --- a/tests/test_signing.py +++ b/tests/test_signing.py @@ -174,6 +174,12 @@ def test_sign_tabular_item(self) -> None: ) self.assertRootResolved(item) + def test_sign_vrt(self) -> None: + vrt_string = Path(HERE / "data-files/stacit.vrt").read_text() + self.assertEqual(vrt_string.count("?st"), 0) + result = pc.sign(vrt_string) + self.assertGreater(result.count("?st"), 0) + class TestUtils(unittest.TestCase): def test_parse_adlfs_url(self) -> None: