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: