Azure provide many options for storing data. For cloud-native workflows favored by the Planetary Computer, Azure Blob Storage is a good choice. In this example we'll compute NDVI for a single image and write the results to a container in Azure Blob Storage as a single-band COG. Note that your storage and compute should be located in the same Azure region. The Planetary Computer Hub and data reside in the West Europe region.
We need something to write. To simulate a workload, let's load in a single NAIP image from the Planetary Computer's data catalog using rioxarray and compute the NDVI using xrspatial.
import matplotlib.pyplot as plt
import pystac_client
import planetary_computer
import rioxarray
import xrspatial
catalog = pystac_client.Client.open(
"https://planetarycomputer.microsoft.com/api/stac/v1/",
modifier=planetary_computer.sign_inplace,
)
item = catalog.get_collection("naip").get_item(
"fl_m_2608005_nw_17_060_20191215_20200113"
)
ds = (
rioxarray.open_rasterio(item.assets["image"].href)
.assign_coords(band=["red", "green", "blue", "nir"])
.load()
.astype(float)
)
ndvi = xrspatial.ndvi(ds.sel(band="red"), ds.sel(band="nir"))
fig, ax = plt.subplots(figsize=(15, 10))
ndvi.isel(y=slice(1000), x=slice(1000)).plot.imshow(ax=ax)
ax.set_axis_off()
ax.set(title=f"NDVI for {item.id=}");
Now we'll use the azure.storage.blob
Python library to write this data to blob storage.
In this case we'll write to the pc-scratch
container in the pcstoraccount
storage account. This is a private container so we need to somehow authorize the access to the storage account. There are several ways to achieve this, but we'll use a SAS token that was generated in the Azure Portal. Make sure to include the necessary permissions for what you're trying to accomplish (including write new files, perhaps to delete existing ones).
This SAS token should be considered sensitive and kept secret. We recommend against storing secrets in plain-text on the Planetary Computer Hub. For this interactive example, we'll manually paste it into the Python session using getpass.getpass
. If you deploy your own Hub, you'd have additional options available, including granting access to an Azure Key Vault that could store the secrets.
import getpass
import azure.storage.blob
sas_token = getpass.getpass() # prompts for the sas_token
container_client = azure.storage.blob.ContainerClient(
"https://pcstoraccount.blob.core.windows.net",
container_name="pc-scratch",
credential=sas_token,
)
Now we're ready to write the ndvi
data to a single-band COG and upload that to Blob Storage. We write data to an in-memory io.BytesIO
buffer, which can be uploaded to Azure Blob Storage with container_client.upload_blob
.
import io
with io.BytesIO() as buffer:
ndvi.rio.to_raster(buffer, driver="COG")
buffer.seek(0)
blob_client = container_client.get_blob_client("ndvi-wb.tif")
blob_client.upload_blob(buffer, overwrite=True)
Now the data is available in Azure Blob Storage, in our private storage container. To read the data, can use another SAS token (e.g. a read-only one) or the same one, assuming it has read permissions. The blob is available at https://<account-name>.blob.core.windows.net/<container-name>/ndvi-wb.tif
. It can be accessed by appending a SAS token with like https://<account-name>.blob.core.windows.net/<container-name>/ndvi-wb.tif?<SAS-token>
. The blob_client.url
already has the SAS token appended, so we can hand that straight to rioxarray.open_rasterio
.
rioxarray.open_rasterio(blob_client.url)
<xarray.DataArray (band: 1, y: 12250, x: 11050)> [135362500 values with dtype=float32] Coordinates: * band (band) int64 1 * x (x) float64 5.494e+05 5.494e+05 5.494e+05 ... 5.56e+05 5.56e+05 * y (y) float64 2.987e+06 2.987e+06 ... 2.979e+06 2.979e+06 spatial_ref int64 0 Attributes: AREA_OR_POINT: Area TIFFTAG_IMAGEDESCRIPTION: OrthoVista TIFFTAG_RESOLUTIONUNIT: 1 (unitless) TIFFTAG_SOFTWARE: Trimble Germany GmbH TIFFTAG_XRESOLUTION: 1 TIFFTAG_YRESOLUTION: 1 scale_factor: 1.0 add_offset: 0.0 long_name: ndvi
For more on Azure Blob Storage, see the Python quickstart and the general introduction to Blob Storage. For more on the tools used in this example, see the documentation for rioxarray, xarray, and rasterio, and xarray-spatial.