From 9241230662c0ea2db22b486560e1ddaaf77fe51c Mon Sep 17 00:00:00 2001 From: Lukas Bindreiter Date: Fri, 19 Jun 2026 16:40:47 +0200 Subject: [PATCH] Improve user guides --- .../python/tilebox.datasets/Client.mdx | 3 - .../python/tilebox.workflows/Client.mdx | 3 - assets/storage/s2_quicklook.jpg | Bin 26452 -> 37504 bytes assets/storage/usgs_quicklook.jpg | Bin 11817 -> 70548 bytes changelog.mdx | 4 +- datasets/concepts/datasets.mdx | 10 +- datasets/ingest.mdx | 2 +- docs.json | 11 +- guides/cookbook.mdx | 65 +++-- guides/datasets/access-sentinel2-data.mdx | 176 +++++++----- guides/datasets/access-usgs-landsat-data.mdx | 138 ++++++++++ .../datasets/build-spatiotemporal-catalog.mdx | 141 +++++++++- guides/datasets/create.mdx | 101 ------- guides/datasets/ingest-format.mdx | 3 +- .../ingest-into-spatiotemporal-catalog.mdx | 175 ++++++++++++ guides/datasets/ingest.mdx | 257 ------------------ guides/datasets/query-satellite-data.mdx | 84 ++++-- guides/workflows/deploy-to-your-compute.mdx | 33 ++- .../workflows/execute-tasks-in-parallel.mdx | 172 ++++++++++++ index.mdx | 4 +- quickstart.mdx | 8 +- .../build-and-deploy/project-structure.mdx | 26 +- 22 files changed, 889 insertions(+), 527 deletions(-) create mode 100644 guides/datasets/access-usgs-landsat-data.mdx delete mode 100644 guides/datasets/create.mdx create mode 100644 guides/datasets/ingest-into-spatiotemporal-catalog.mdx delete mode 100644 guides/datasets/ingest.mdx create mode 100644 guides/workflows/execute-tasks-in-parallel.mdx diff --git a/api-reference/python/tilebox.datasets/Client.mdx b/api-reference/python/tilebox.datasets/Client.mdx index 759078c..7dfd95e 100644 --- a/api-reference/python/tilebox.datasets/Client.mdx +++ b/api-reference/python/tilebox.datasets/Client.mdx @@ -47,8 +47,5 @@ client = Client( url="https://api.tilebox.com", token="YOUR_TILEBOX_API_KEY", ) - -# use HTTP/1.1 if your network blocks or breaks gRPC over HTTP/2 -client = Client(transport="http1") ``` diff --git a/api-reference/python/tilebox.workflows/Client.mdx b/api-reference/python/tilebox.workflows/Client.mdx index 5963d71..8ec93c4 100644 --- a/api-reference/python/tilebox.workflows/Client.mdx +++ b/api-reference/python/tilebox.workflows/Client.mdx @@ -93,9 +93,6 @@ client = Client( name="sentinel-2-runner", ) -# use HTTP/1.1 if your network blocks or breaks gRPC over HTTP/2 -client = Client(transport="http1") - # access sub clients job_client = client.jobs() cluster_client = client.clusters() diff --git a/assets/storage/s2_quicklook.jpg b/assets/storage/s2_quicklook.jpg index 24a6b3d25c6d15ce7e252e0a084a88a6fbc3daa0..71251a5bde7932847178dcc26dc33127a678ce92 100644 GIT binary patch delta 37137 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 delta 25995 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

apemv###MBm!> zoyk&<;jt#!V(|~<)XD#S?YsZ;$&nWBcG#v-JJrNn$Hl;B2(((MceT)O_QUXeVmFP7 zvCNsh4gvLH|5B_>sv~W54A(}T-sj921*&n_$Mr;F$+WR@CA{m|4E~o)G*ye4`>n-J zIU(#vU9?XUF>pOd%A}uo9QRbHm_nc8{vCJ$?VDEWLJOJUT|$}TYl9fuzY{YWXn$j+ zyzAq4LV6_5HSJBA9I5$EDdPLlLKJ6RvPFhisR`#>I{jIS&SpL~o^w@yx3zDOo7=L1 zwXC>P_KSF0CRh4+o=#TT$epqHdAW^OH8tnjvT)8yS8M8*Pn}*bNNK&{(RIiprB7_EE7d{fjnG~`6j?|tFbF91r7uhcUYu^y_p!KNn^hU zdx-7mRjxVo^%^QpTco-Q67uSL-%kuJ?2PC!1-}GO@PUr@Q66^JT&6e3yos!Uh*ScZ z?$vNsYLR1zT_V3}pFBcBG{B9kcE zxI=o@4=y(7-WJy&w#GI`JpW3b|D;I|bx>64;pY)ZdY0-V<8_|TXHPhS9`4j9aI9eBYZ_HtJCViABvQ>W#`fvg?1u1Vz$O

Al-8cTA^cOw&w}SqZj#J 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 z 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 diff --git a/changelog.mdx b/changelog.mdx index b1b3ea3..214e274 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -172,7 +172,7 @@ mode: center - [Spatio Temporal datasets documentation](https://docs.tilebox.com/datasets/types/spatiotemporal) - All open data now supports spatio-temporal queries - - [Create your own spatio-temporal datasets](/guides/datasets/create) + - [Create your own spatio-temporal datasets](/guides/datasets/build-spatiotemporal-catalog) - [Ingesting spatio-temporal data](/datasets/ingest) @@ -198,5 +198,5 @@ mode: center 3. Use client.ingest() to ingest a `xarray.Dataset` or `pandas.DataFrame` 4. Query away! - For detailed instructions, check out the [Creating a dataset](/guides/datasets/create) how-to guide. + For detailed instructions, check out the [Build a spatio-temporal catalog](/guides/datasets/build-spatiotemporal-catalog) how-to guide. diff --git a/datasets/concepts/datasets.mdx b/datasets/concepts/datasets.mdx index 3331fb4..dd840dd 100644 --- a/datasets/concepts/datasets.mdx +++ b/datasets/concepts/datasets.mdx @@ -11,11 +11,11 @@ icon: database ## Related Guides - - Learn how to create a Timeseries dataset using the Tilebox Console. + + Learn how to create a custom dataset catalog with the Python SDK. - - Learn how to ingest an existing CSV dataset into a Timeseries dataset collection. + + Learn how to ingest GeoParquet metadata into an existing spatio-temporal catalog. @@ -151,7 +151,7 @@ Once you have your dataset object, you can use it to [list the available collect ## Creating / Updating a dataset -You can create a dataset using the [Tilebox Console](/guides/datasets/create) or by using one of the available [client SDKs](/sdks/introduction). +You can create a dataset using one of the available [client SDKs](/sdks/introduction), or use the [Tilebox Console](/console) when you prefer a visual schema editor. ```python Python diff --git a/datasets/ingest.mdx b/datasets/ingest.mdx index 7407f26..0e6ff2f 100644 --- a/datasets/ingest.mdx +++ b/datasets/ingest.mdx @@ -19,7 +19,7 @@ The examples on this page assume that you have access to a [Timeseries dataset]( - Check out the [Creating a dataset](/guides/datasets/create) guide for an example of how to create such a dataset. + Check out the [Build a spatio-temporal catalog](/guides/datasets/build-spatiotemporal-catalog) guide for an example of how to create such a dataset. **MyCustomDataset schema** diff --git a/docs.json b/docs.json index 259b25c..6fb061b 100644 --- a/docs.json +++ b/docs.json @@ -147,18 +147,19 @@ { "group": "Datasets", "pages": [ - "guides/datasets/access-sentinel2-data", "guides/datasets/query-satellite-data", - "guides/datasets/create", - "guides/datasets/ingest", - "guides/datasets/ingest-format", - "guides/datasets/build-spatiotemporal-catalog" + "guides/datasets/access-sentinel2-data", + "guides/datasets/access-usgs-landsat-data", + "guides/datasets/build-spatiotemporal-catalog", + "guides/datasets/ingest-into-spatiotemporal-catalog", + "guides/datasets/ingest-format" ] }, { "group": "Workflows", "pages": [ "guides/workflows/run-your-first-workflow", + "guides/workflows/execute-tasks-in-parallel", "guides/workflows/build-and-deploy-workflow", "guides/workflows/deploy-to-your-compute", "guides/workflows/debug-failed-run", diff --git a/guides/cookbook.mdx b/guides/cookbook.mdx index 02d16ee..d7a075a 100644 --- a/guides/cookbook.mdx +++ b/guides/cookbook.mdx @@ -12,40 +12,49 @@ export const cookbookSections = [ description: "Find, model, ingest, and query geospatial metadata with Tilebox Datasets.", guides: [ { - title: "Access Sentinel-2 data", - href: "/guides/datasets/access-sentinel2-data", - description: "Query Sentinel-2 metadata by area and time range.", + title: "Query open satellite data", + href: "/guides/datasets/query-satellite-data", + description: "Explore open data catalogs and query Sentinel-2 metadata by time and location.", icon: "satellite", level: "Beginner", time: "5 min", - tags: ["Open data", "Sentinel-2", "Spatial filters", "Python SDK"], + tags: ["Open data", "Sentinel-2", "Metadata queries", "Spatial filters"], }, { - title: "Query satellite data by time and location", - href: "/guides/datasets/query-satellite-data", - description: "Narrow open data catalogs before downloading product files.", + title: "Access Copernicus data", + href: "/guides/datasets/access-sentinel2-data", + description: "Download Copernicus product files with the storage client, using Sentinel-2 as an example.", icon: "magnifying-glass-location", level: "Beginner", - time: "5 min", - tags: ["Open data", "Temporal filters", "Spatial filters", "Storage clients"], + time: "10 min", + tags: ["Copernicus", "Storage clients", "Sentinel-2", "Product files"], }, { - title: "Creating a dataset", - href: "/guides/datasets/create", - description: "Create a custom dataset and define its schema in the Console.", - icon: "database", + title: "Access USGS Landsat data", + href: "/guides/datasets/access-usgs-landsat-data", + description: "Download USGS Landsat product files with the storage client, using Landsat 8 as an example.", + icon: "satellite-dish", level: "Beginner", - time: "5 min", - tags: ["Datasets", "Dataset schemas", "Console", "Timeseries datasets"], + time: "10 min", + tags: ["USGS", "Landsat 8", "Storage clients", "Product files"], + }, + { + title: "Build a spatio-temporal catalog", + href: "/guides/datasets/build-spatiotemporal-catalog", + description: "Create, document, ingest, and query a custom geospatial catalog with the Python SDK.", + icon: "globe", + level: "Intermediate", + time: "20 min", + tags: ["Spatio-temporal datasets", "Dataset schemas", "Ingestion", "Python SDK"], }, { - title: "Ingesting data", - href: "/guides/datasets/ingest", - description: "Ingest GeoParquet data into a Tilebox timeseries dataset.", + title: "Ingest into a spatio-temporal catalog", + href: "/guides/datasets/ingest-into-spatiotemporal-catalog", + description: "Prepare GeoParquet metadata and ingest it into an existing spatio-temporal catalog.", icon: "up-from-bracket", level: "Beginner", time: "15 min", - tags: ["Ingestion", "Timeseries datasets", "GeoParquet", "Python SDK"], + tags: ["Ingestion", "Spatio-temporal datasets", "GeoParquet", "Python SDK"], }, { title: "Ingesting from common file formats", @@ -56,15 +65,6 @@ export const cookbookSections = [ time: "20 min", tags: ["Ingestion", "DataFrames", "xarray", "File formats"], }, - { - title: "Build a spatio-temporal catalog", - href: "/guides/datasets/build-spatiotemporal-catalog", - description: "Create a geospatial catalog that can be queried by time and geometry.", - icon: "globe", - level: "Intermediate", - time: "15 min", - tags: ["Spatio-temporal datasets", "Geometry", "Ingestion", "Catalogs"], - }, ], }, { @@ -80,6 +80,15 @@ export const cookbookSections = [ time: "10 min", tags: ["Tasks", "Jobs", "Direct runners", "Python SDK"], }, + { + title: "Execute tasks in parallel", + href: "/guides/workflows/execute-tasks-in-parallel", + description: "Submit many subtasks and process them with several direct runners at the same time.", + icon: "arrows-split-up-and-left", + level: "Beginner", + time: "15 min", + tags: ["Tasks", "Subtasks", "Direct runners", "Parallelism"], + }, { title: "Build and deploy a workflow project", href: "/guides/workflows/build-and-deploy-workflow", diff --git a/guides/datasets/access-sentinel2-data.mdx b/guides/datasets/access-sentinel2-data.mdx index 2e60586..ba299d2 100644 --- a/guides/datasets/access-sentinel2-data.mdx +++ b/guides/datasets/access-sentinel2-data.mdx @@ -1,111 +1,145 @@ --- -title: Access Sentinel-2 data -description: Query Sentinel-2 satellite imagery metadata from a Tilebox dataset, filtering results by geographic area and time range to find exactly the data you need. +title: Access Copernicus data +description: Download Copernicus Data Space products with the Tilebox Copernicus storage client, using Sentinel-2 as an example. icon: database --- -This guide assume you already [signed up](https://console.tilebox.com/sign-up) for a Tilebox account (free) and [created an API key](https://console.tilebox.com/settings/api-keys). +Use this guide when you already have a Copernicus datapoint from a Tilebox metadata query and want to access the product files behind it. The example uses Sentinel-2 Level-2A data, but the same storage client pattern applies to Copernicus products supported by Tilebox. -## Install Tilebox package +Tilebox indexes product metadata as datasets. Product files remain in the Copernicus Data Space Ecosystem, so file access uses the `CopernicusStorageClient` with Copernicus S3 credentials. - -```bash uv -uv add tilebox -``` -```bash pip -pip install tilebox -``` -```bash poetry -poetry add tilebox="*" -``` -```bash pipenv -pipenv install tilebox -``` - +## Prerequisites + +- You have a [Tilebox API key](/authentication). +- You have installed the [Python SDK](/sdks/python/install). +- You have a [Copernicus Data Space](https://dataspace.copernicus.eu/) account. +- You have generated Copernicus [S3 credentials](https://eodata-s3keysmanager.dataspace.copernicus.eu/panel/s3-credentials). -## Access Sentinel-2 metadata +```bash +uv add tilebox shapely +``` -Query the Sentinel-2A satellite for level 2A data of October 2025 that cover the state of Colorado. +## Select a Sentinel-2 datapoint - - Replace `YOUR_TILEBOX_API_KEY` with your actual API key, or omit the `token` parameter entirely if the `TILEBOX_API_KEY` environment variable is set. - +Start with a small metadata query and select one datapoint to access. For a deeper guide to open data discovery and metadata filtering, see [Query open data metadata](/guides/datasets/query-satellite-data). - ```python Python -from shapely import MultiPolygon +from shapely import Polygon from tilebox.datasets import Client -area = MultiPolygon( +area = Polygon( [ - (((-109.05, 41.00), (-109.045, 37.0), (-102.05, 37.0), (-102.05, 41.00), (-109.05, 41.00)),), + (-109.05, 37.0), + (-102.05, 37.0), + (-102.05, 41.0), + (-109.05, 41.0), + (-109.05, 37.0), ] ) -client = Client(token="YOUR_TILEBOX_API_KEY") +client = Client() collection = client.dataset("open_data.copernicus.sentinel2_msi").collection("S2A_S2MSI2A") -data = collection.query( + +scenes = collection.query( temporal_extent=("2025-10-01", "2025-11-01"), spatial_extent=area, show_progress=True, ) -print(data) + +selected = scenes.where(scenes.cloud_cover < 10, drop=True).isel(time=0) +print(selected.granule_name.item()) ``` - - -```plaintext Output - Size: 75kB -Dimensions: (time: 169) -Coordinates: - * time (time) datetime64[ns] 1kB 2025-10-02T18:07:51.0240... -Data variables: (12/23) - id (time) -The output shows that the query returned 169 data points metadata. The metadata is returned as an `xarray.Dataset`. + + These credentials are Copernicus Data Space S3 credentials, not your Tilebox API key. + -Now you can check the metadata and decide which data points you want to download. +## Download the complete product -## Download the data from Copernicus Data Space +Use `download` when you need the complete Sentinel-2 product directory. The storage client resolves the product location from the Tilebox datapoint metadata and downloads the matching files into the local cache directory. -Tilebox stores and indexes metadata about datasets but doesn't store the data files. -Sentinel-2 data is stored in the Copernicus Data Space Ecosystem (CDSE). If you never used the CDSE before, [create an account](https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/auth?client_id=cdse-public&response_type=code&scope=openid&redirect_uri=https%3A//dataspace.copernicus.eu/account/confirmed/1) and then generate [S3 credentials here](https://eodata-s3keysmanager.dataspace.copernicus.eu/panel/s3-credentials). +```python Python +product_path = storage.download(selected) + +print(f"Downloaded {product_path.name} to {product_path}") +print("Contents:") +for path in product_path.iterdir(): + print(f"- {path.relative_to(product_path)}") +``` + +```plaintext Output +Downloaded S2A_MSIL2A_20251002T180751_N0511_R084_T13TEE_20251002T225842.SAFE to data/Sentinel-2/MSI/L2A/2025/10/02/S2A_MSIL2A_20251002T180751_N0511_R084_T13TEE_20251002T225842.SAFE +Contents: +- manifest.safe +- GRANULE +- INSPIRE.xml +- MTD_MSIL2A.xml +- DATASTRIP +- HTML +- rep_info +- S2A_MSIL2A_20251002T180751_N0511_R084_T13TEE_20251002T225842-ql.jpg +``` + +## Download selected product files + +Sentinel-2 products contain many files, including metadata, masks, quicklook images, and bands at different resolutions. Use `list_objects` and `download_objects` when you only need specific files. - ```python Python -from tilebox.storage import CopernicusStorageClient +objects = storage.list_objects(selected) -storage_client = CopernicusStorageClient( - access_key="YOUR_ACCESS_KEY", - secret_access_key="YOUR_SECRET_ACCESS_KEY", -) +wanted_bands = ["B02_10m", "B03_10m", "B04_10m", "B08_10m"] +band_objects = [ + obj for obj in objects + if any(band in obj for band in wanted_bands) +] -for _, datapoint in data.groupby("time"): - downloaded_data = storage_client.download(datapoint) - print(f"Downloaded data to {downloaded_data}") +for obj in band_objects: + print(obj) + +downloaded_files = storage.download_objects(selected, band_objects) +print(downloaded_files) ``` - -This code will download all 169 data points to a cache folder. Now you can work with the data, visualize it, and run your custom processor on it. +Use this pattern when a workflow only needs a few bands or metadata files. It reduces transfer time and local storage compared with downloading the full `.SAFE` product. + +## Preview the product + +Many Copernicus products include a quicklook image. In a notebook, use `quicklook` to display the product preview without downloading the full product first. -## Next Steps +```python Python +storage.quicklook(selected) +``` + + + Sentinel-2 quicklook image + + +## Next steps - - Check out available open data datasets on Tilebox + + Find Copernicus products by time, location, and metadata fields. + + + Learn about the other Tilebox storage clients for open data products. + + + Download Landsat product files with the USGS Landsat storage client. diff --git a/guides/datasets/access-usgs-landsat-data.mdx b/guides/datasets/access-usgs-landsat-data.mdx new file mode 100644 index 0000000..38fa5f3 --- /dev/null +++ b/guides/datasets/access-usgs-landsat-data.mdx @@ -0,0 +1,138 @@ +--- +title: Access USGS Landsat data +description: Download USGS Landsat products with the Tilebox Landsat storage client, using Landsat 8 as an example. +icon: satellite-dish +--- + +Use this guide when you already have a Landsat datapoint from a Tilebox metadata query and want to access the product files behind it. The example uses Landsat 8 Collection 2 Level-2 surface reflectance data. + +Tilebox indexes Landsat metadata as datasets. Product files remain in the USGS public cloud archive, so file access uses the `USGSLandsatStorageClient` and your AWS requester-pays setup. + +## Prerequisites + +- You have a [Tilebox API key](/authentication). +- You have installed the [Python SDK](/sdks/python/install). +- You have AWS credentials configured in your environment. +- Your AWS account can access [requester-pays S3 buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/RequesterPaysBuckets.html). + +```bash +uv add tilebox shapely +``` + + + USGS Landsat data is stored in a requester-pays S3 bucket. AWS charges for requests and data transfer according to your AWS account settings. + + +## Select a Landsat 8 datapoint + +Start with a small metadata query and select one datapoint to access. For a deeper guide to open data discovery and metadata filtering, see [Query open data metadata](/guides/datasets/query-satellite-data). + +```python Python +from shapely import Polygon +from tilebox.datasets import Client + +area = Polygon( + [ + (-109.05, 37.0), + (-102.05, 37.0), + (-102.05, 41.0), + (-109.05, 41.0), + (-109.05, 37.0), + ] +) + +client = Client() +collection = client.dataset("open_data.usgs.landsat8_oli_tirs").collection("L2_SR") + +scenes = collection.query( + temporal_extent=("2024-08-01", "2024-08-15"), + spatial_extent=area, + show_progress=True, +) + +selected = scenes.where(scenes.cloud_cover < 10, drop=True).isel(time=0) +print(selected.granule_name.item()) +``` + +## Create the Landsat storage client + +Create a `USGSLandsatStorageClient`. The client uses AWS credentials from your environment, such as `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` when needed. + +```python Python +from tilebox.storage import USGSLandsatStorageClient + +storage = USGSLandsatStorageClient() +``` + +## Download the complete product + +Use `download` when you need the complete Landsat product directory. The storage client resolves the product location from the Tilebox datapoint metadata and downloads the matching files into the local cache. + +```python Python +product_path = storage.download(selected) + +print(f"Downloaded {product_path.name} to {product_path}") +print("Contents:") +for path in product_path.iterdir(): + print(f"- {path.relative_to(product_path)}") +``` + +```plaintext Output +Downloaded LC08_L2SP_033033_20240808_20240814_02_T1 to ~/.cache/tilebox/collection02/level-2/standard/oli-tirs/2024/033/033/LC08_L2SP_033033_20240808_20240814_02_T1 +Contents: +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B1.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B2.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B3.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B4.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B5.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B6.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_SR_B7.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_QA_PIXEL.TIF +- LC08_L2SP_033033_20240808_20240814_02_T1_MTL.json +- LC08_L2SP_033033_20240808_20240814_02_T1_thumb_small.jpeg +``` + +## Download selected product files + +Landsat products contain surface reflectance bands, quality masks, thermal bands, metadata, and preview images. Use `list_objects` and `download_objects` when you only need specific files. + +```python Python +objects = storage.list_objects(selected) + +rgb_bands = ["B4", "B3", "B2"] +rgb_objects = [ + obj for obj in objects + if any(obj.endswith(f"_{band}.TIF") for band in rgb_bands) +] + +for obj in rgb_objects: + print(obj) + +downloaded_files = storage.download_objects(selected, rgb_objects) +print(downloaded_files) +``` + +Use this pattern when a workflow only needs a few bands, masks, or metadata files. It reduces transfer time and local storage compared with downloading the full product. + +## Preview the product + +Many Landsat products include a thumbnail image. In a notebook, use `quicklook` to display the product preview without downloading the full product first. + +```python Python +storage.quicklook(selected) +``` + + + USGS Landsat quicklook image + + +## Next steps + + + + Find Landsat products by time, location, and metadata fields. + + + Learn about the other Tilebox storage clients for open data products. + + diff --git a/guides/datasets/build-spatiotemporal-catalog.mdx b/guides/datasets/build-spatiotemporal-catalog.mdx index a209757..e97c8ca 100644 --- a/guides/datasets/build-spatiotemporal-catalog.mdx +++ b/guides/datasets/build-spatiotemporal-catalog.mdx @@ -1,25 +1,137 @@ --- title: Build a spatio-temporal catalog -description: Create a custom spatio-temporal dataset and ingest geospatial metadata that can be queried by time and location. +description: Create a custom spatio-temporal dataset catalog with the Python SDK, document its schema, ingest geospatial metadata, and query it by time and location. icon: globe --- Use a spatio-temporal dataset when each datapoint has both a time and a geometry. This is useful for internal imagery catalogs, derived products, ground truth data, regions of interest, and processing outputs that need geospatial lookup. -This guide shows the shape of the workflow. For the full ingestion guide, see [Ingesting data](/guides/datasets/ingest). +This guide creates an imagery catalog from code. You will define the dataset schema with the Python SDK, add field descriptions and examples for generated schema documentation, create a collection, ingest geospatial metadata, and query the catalog by time and location. + +## Prerequisites + +- You have a [Tilebox API key](/authentication). +- You have installed the [Python SDK](/sdks/python/install). + +```bash +uv add tilebox geopandas shapely +``` + +## Define the catalog schema + +Start by choosing the spatio-temporal dataset kind and the custom fields for your catalog. Tilebox adds the required `time`, `id`, `ingestion_time`, and `geometry` fields automatically. + +The example catalog tracks imagery products with a provider product ID, a storage location, cloud cover, and processing level. Field descriptions and example values become part of the generated schema documentation. + +```python Python +from tilebox.datasets import Client +from tilebox.datasets.data.datasets import DatasetKind + +client = Client() + +fields = [ + { + "name": "product_id", + "type": str, + "description": "Stable product or scene identifier from the source catalog.", + "example_value": "LC08_L2SP_033033_20240808_20240814_02_T1", + }, + { + "name": "location", + "type": str, + "description": "Storage path, object key, or provider-specific product location.", + "example_value": "s3://example-bucket/landsat/LC08_L2SP_033033_20240808_20240814_02_T1", + }, + { + "name": "cloud_cover", + "type": float, + "description": "Cloud cover percentage for the product footprint.", + "example_value": "3.2", + }, + { + "name": "processing_level", + "type": str, + "description": "Processing level or product type assigned by the source provider.", + "example_value": "L2_SR", + }, +] +``` + +Use field names that are stable and descriptive. Changing or removing fields after ingesting datapoints requires emptying the affected collections first, because existing datapoints must continue to match the dataset schema. ## Create the dataset -Create a dataset in the [Tilebox Console](https://console.tilebox.com/datasets/my-datasets) and choose the **Spatio-temporal** kind. Tilebox adds the required `time`, `id`, `ingestion_time`, and `geometry` fields automatically. +Call `create_or_update_dataset` with the dataset kind, code name, field list, and display name. The code name becomes the stable identifier used in SDK calls. + +```python Python +dataset = client.create_or_update_dataset( + kind=DatasetKind.SPATIOTEMPORAL, + code_name="internal_imagery_catalog", + fields=fields, + name="Internal imagery catalog", +) + +print(dataset) +``` + +If a dataset with the same code name already exists, `create_or_update_dataset` updates it instead of creating a duplicate. This makes the snippet safe to keep in a setup script. + + + The Python SDK currently sets the dataset display name and schema. Field-level `description` and `example_value` entries populate the generated schema documentation. Use the Tilebox Console when you want to add rich Markdown documentation to the dataset page. + + +## Inspect the generated schema documentation + +Tilebox uses the dataset kind and field annotations to document the schema. Required fields are added by the dataset kind, and your custom fields appear with their descriptions and examples. -Add fields that describe the products you want to catalog, such as: +For this catalog, the complete schema includes: | Field | Type | Purpose | | --- | --- | --- | -| `product_id` | `string` | Stable product or scene identifier. | -| `location` | `string` | Storage path, object key, or provider location. | -| `cloud_cover` | `float64` | Optional quality or filtering field. | -| `processing_level` | `string` | Product processing level or category. | +| `time` | Required | Timestamp associated with the datapoint. | +| `id` | Required | Tilebox-generated UUID for the datapoint. | +| `ingestion_time` | Required | Time when Tilebox ingested the datapoint. | +| `geometry` | Required | Geometry used for spatial queries. | +| `product_id` | Custom | Stable product or scene identifier. | +| `location` | Custom | Storage path or provider product location. | +| `cloud_cover` | Custom | Cloud cover percentage for filtering. | +| `processing_level` | Custom | Provider processing level or product type. | + +The descriptions and example values you provided in the SDK call appear in the dataset schema documentation. + +## Add richer dataset documentation + +Use field descriptions for schema-level documentation. Use the Console documentation editor when you want longer Markdown documentation for the dataset, such as provenance notes, quality caveats, ingestion rules, or examples for downstream users. + + + Tilebox Console dataset documentation editor + Tilebox Console dataset documentation editor + + +Open the dataset in the Console, click the edit pencil on the documentation section, and add Markdown content. A short documentation block often includes: + +```md Markdown +# Internal imagery catalog + +This dataset indexes analysis-ready imagery products used by the operations team. + +## Source + +Products are copied from the provider archive after validation. + +## Usage notes + +Use `cloud_cover < 10` for workflows that require mostly cloud-free scenes. +``` + +## Create a collection + +After creating the dataset, create a collection to hold datapoints. Collections let you organize datapoints within the same schema, for example by provider, product family, or processing pipeline. + +```python Python +collection = dataset.get_or_create_collection("landsat_level_2") +print(collection) +``` ## Prepare datapoints @@ -36,6 +148,10 @@ products = products.rename( "path": "location", } ) + +products = products[ + ["time", "geometry", "product_id", "location", "cloud_cover", "processing_level"] +] ``` ## Ingest the catalog @@ -43,12 +159,6 @@ products = products.rename( Ingest the prepared records into a collection. ```python Python -from tilebox.datasets import Client - -client = Client() -dataset = client.dataset("my_org.imagery_catalog") -collection = dataset.collection("processed-scenes") - collection.ingest(products) ``` @@ -76,4 +186,7 @@ matches = collection.query( Load CSV, Parquet, GeoParquet, and NetCDF data before ingestion. + + Prepare GeoParquet metadata and ingest it into this catalog. + diff --git a/guides/datasets/create.mdx b/guides/datasets/create.mdx deleted file mode 100644 index ec58f39..0000000 --- a/guides/datasets/create.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Creating a dataset -description: Walk through creating a custom dataset in the Tilebox Console, from choosing the right dataset kind to defining your schema fields and organizing groups. -icon: database ---- - -This page guides you through the process of creating a dataset in Tilebox using the [Tilebox Console](/console). - -## Related documentation - - - - Learn about Tilebox datasets and how to use them. - - - Learn about Timeseries datasets, which link each data point to a specific point in time. - - - -## Creating a dataset in the Console - - - - Create a dataset in Tilebox by going to [My datasets](https://console.tilebox.com/datasets/my-datasets) and clicking the `Create dataset` button. - - - Choose a [dataset kind](/datasets/concepts/datasets#dataset-types) from the dropdown menu. Required fields for the selected dataset kind are automatically added. - - - Tilebox Console - Tilebox Console - - - - Complete these fields: - - - `Name` is the name of your dataset. - - `Code name` is a unique identifier for the dataset within your team. It's automatically generated, but you can adjust it if needed. - - `Description` is a brief description of the dataset purpose. - - - Tilebox Console - Tilebox Console - - - - Specify the fields for your dataset. - - Each field has these properties: - - `Name` is the name of the field (by convention it is recommended to be in `snake_case`). - - `Type` is the data type of the field. - - `Array` can be set to indicate that the field contains multiple values of the specified type. - - `Description` is an optional brief description of the field. You can use it to provide more context and details about the data. - - `Example value` is an optional example for this field. It can be useful for documentation purposes. - - - Tilebox Console - Tilebox Console - - - - Once you're done completing the fields, click "Create" to create and save the dataset. You are redirected to your newly created dataset. - - - -## Automatic dataset schema documentation - -By specifying the fields for your dataset, including the data type, description, and an example value for each one, Tilebox -is capable of automatically generating a documentation page for your dataset schema. - - - Dataset schema overview - Dataset schema overview - - -## Adding extra documentation - -You can also add custom documentation to your dataset, providing more context and details about the data included data. -This documentation supports rich formatting, including links, tables, code snippets, and more. - - - Tilebox Console - Tilebox Console - - -To add documentation, click the edit pencil button on the dataset page to open the documentation editor. -You can use Markdown to format your documentation; you can include links, tables, code snippets, and other Markdown features. - - - If you don't see the edit pencil button, you don't have the required permissions to edit the - documentation. - - -Once you are done editing the documentation, click the `Save` button to save your changes. - -## Changing the dataset schema - -You can always add new fields to a dataset. - -If you want to remove or edit existing fields, you'll first need to empty all collections in the dataset, to ensure that -no existing data points relying on those fields exist. Then, you can freely edit the dataset schema in the console. diff --git a/guides/datasets/ingest-format.mdx b/guides/datasets/ingest-format.mdx index 5dbbe80..a424398 100644 --- a/guides/datasets/ingest-format.mdx +++ b/guides/datasets/ingest-format.mdx @@ -68,7 +68,7 @@ data = gpd.read_parquet("modis_MCD12Q1.geoparquet") - For a step-by-step guide of ingesting a GeoParquet file, check out our [Ingesting data](/guides/datasets/ingest) guide. + For a step-by-step guide to ingesting a GeoParquet file, see [Ingest into a spatio-temporal catalog](/guides/datasets/ingest-into-spatiotemporal-catalog). ### Feather @@ -135,4 +135,3 @@ collection = dataset.get_or_create_collection("Measurements") collection.ingest(data) ``` - diff --git a/guides/datasets/ingest-into-spatiotemporal-catalog.mdx b/guides/datasets/ingest-into-spatiotemporal-catalog.mdx new file mode 100644 index 0000000..5202b02 --- /dev/null +++ b/guides/datasets/ingest-into-spatiotemporal-catalog.mdx @@ -0,0 +1,175 @@ +--- +title: Ingest into a spatio-temporal catalog +sidebarTitle: Ingest into a catalog +description: Prepare GeoParquet metadata and ingest it into an existing Tilebox spatio-temporal catalog. +icon: up-from-bracket +--- + +Use this guide after [Build a spatio-temporal catalog](/guides/datasets/build-spatiotemporal-catalog). It assumes you already created a spatio-temporal dataset and now want to load geospatial metadata into one of its collections. + +The example starts from a GeoParquet file, reshapes it to match the catalog schema, ingests it into Tilebox, and runs a time and location query against the new collection. + + + If your source data uses a different file format, see [Ingesting from common file formats](/guides/datasets/ingest-format) for examples of loading CSV, Parquet, GeoParquet, and NetCDF data before ingestion. + + +## Prerequisites + +- You have a [Tilebox API key](/authentication). +- You have installed the [Python SDK](/sdks/python/install). +- You have created the catalog from [Build a spatio-temporal catalog](/guides/datasets/build-spatiotemporal-catalog), or an equivalent spatio-temporal dataset with matching fields. + +```bash +uv add tilebox geopandas lonboard shapely +``` + +## Download the example metadata + +The example metadata is available as a [GeoParquet](https://geoparquet.org/) file: + +```bash +curl -L \ + -o modis_MCD12Q1.geoparquet \ + https://storage.googleapis.com/tbx-web-assets-2bad228/docs/data-samples/modis_MCD12Q1.geoparquet +``` + +This file contains MODIS land cover product metadata, including timestamps and product footprints. + +## Read and preview the source data + +Read the GeoParquet file with Geopandas. The resulting `GeoDataFrame` includes a `geometry` column, which Tilebox uses for spatial indexing in spatio-temporal datasets. + +```python Python +import geopandas as gpd + +source = gpd.read_parquet("modis_MCD12Q1.geoparquet") +source.head(5) +``` + +```plaintext Output + time end_time granule_name geometry horizontal_tile_number vertical_tile_number tile_id +0 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h00v08... POLYGON ((-180 10, -180 0, -170 0, ... 0 8 51000008 +1 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h00v09... POLYGON ((-180 0, -180 -10, ... 0 9 51000009 +``` + +You can inspect the footprints before ingestion with `lonboard`. + +```python Python +from lonboard import viz + +viz(source, map_kwargs={"show_tooltip": True}) +``` + + + Explore the MODIS dataset + Explore the MODIS dataset + + +## Match the catalog schema + +Prepare a DataFrame with the fields required by the catalog. This example targets the schema from [Build a spatio-temporal catalog](/guides/datasets/build-spatiotemporal-catalog): `time`, `geometry`, `product_id`, `location`, `cloud_cover`, and `processing_level`. + +```python Python +products = source.copy() + +products["product_id"] = products["granule_name"] +products["location"] = products["granule_name"].map( + lambda name: f"modis://MCD12Q1/{name}" +) +products["cloud_cover"] = 0.0 +products["processing_level"] = "MCD12Q1" + +products = products[ + ["time", "geometry", "product_id", "location", "cloud_cover", "processing_level"] +] + +products.head(5) +``` + +Keep the DataFrame columns aligned with the dataset schema. Required fields such as `id` and `ingestion_time` are generated by Tilebox during ingestion, so you do not include them in the input DataFrame. + +## Connect to the catalog collection + +Access the catalog dataset and create or reuse a collection for the MODIS products. + +```python Python +from tilebox.datasets import Client + +client = Client() +dataset = client.dataset("internal_imagery_catalog") +collection = dataset.get_or_create_collection("modis_land_cover") +``` + +Replace `internal_imagery_catalog` with the code name of your catalog if you used a different value in the previous guide. + +## Ingest the products + +Ingest the prepared DataFrame into the collection. Tilebox validates each row against the dataset schema before storing it. + +```python Python +datapoint_ids = collection.ingest(products) +print(f"Successfully ingested {len(datapoint_ids)} datapoints.") +``` + +```plaintext Output +Successfully ingested 7245 datapoints. +``` + +## Query the ingested catalog + +After ingestion, query the collection by time and location. The query model is the same one used by Tilebox open data catalogs. + +```python Python +from shapely import Polygon + +area = Polygon( + [ + (-124.45, 49.19), + (-120.88, 29.31), + (-66.87, 24.77), + (-65.34, 47.84), + (-124.45, 49.19), + ] +) + +matches = collection.query( + temporal_extent=("2015-01-01", "2020-01-01"), + spatial_extent=area, +) + +matches[["product_id", "processing_level", "location"]] +``` + +```plaintext Output + Size: 18kB +Dimensions: (time: 110) +Coordinates: + * time (time) datetime64[ns] 2015-01-01 ... 2019-01-01 +Data variables: + product_id (time) object 'MCD12Q1.A2015001.h10v03...' ... + processing_level (time) object 'MCD12Q1' 'MCD12Q1' ... + location (time) object 'modis://MCD12Q1/MCD12Q1.A2015001...' ... +``` + +## View the data in the Console + +You can also inspect ingested datapoints in the Tilebox Console. Open the dataset, select the collection, and click a datapoint to inspect its fields and geometry. + + + Explore the MODIS dataset + Explore the MODIS dataset + + +## Next steps + + + + Create and document the catalog schema used by this guide. + + + Learn more about querying datasets by time, location, collection, and ID. + + + Load CSV, Parquet, GeoParquet, and NetCDF data before ingestion. + + diff --git a/guides/datasets/ingest.mdx b/guides/datasets/ingest.mdx deleted file mode 100644 index 6cb7655..0000000 --- a/guides/datasets/ingest.mdx +++ /dev/null @@ -1,257 +0,0 @@ ---- -title: Ingesting data -description: Walk through the full process of ingesting GeoParquet data into a Tilebox timeseries dataset, from downloading source files to previewing the results. -icon: up-from-bracket ---- - - - - This guide is also available as a Google Colab notebook. Click here for an interactive version. - - - -This page guides you through the process of ingesting data into a Tilebox dataset. Starting from an existing -dataset available as file in the [GeoParquet](https://geoparquet.org/) format, you'll go through the process of -ingesting that data into Tilebox as a [Timeseries](/datasets/types/timeseries) dataset. - - - If you have your data in a different format, check out the [Ingesting from common file formats](/guides/datasets/ingest-format) examples of how to ingest it. - - -## Related documentation - - - - Learn about Tilebox datasets and how to use them. - - - Learn how to ingest data into a Tilebox dataset. - - - -## Downloading the example dataset - -The dataset used in this example is available as a [GeoParquet](https://geoparquet.org/) file. You can download it -from here: [modis_MCD12Q1.geoparquet](https://storage.googleapis.com/tbx-web-assets-2bad228/docs/data-samples/modis_MCD12Q1.geoparquet). - -## Installing the necessary packages - -This example uses a couple of python packages for reading parquet files and for visualizing the dataset. Install the -required packages using your preferred package manager. For new projects, Tilebox recommend using [uv](https://docs.astral.sh/uv/). - - -```bash uv -uv add tilebox-datasets geopandas lonboard -``` -```bash pip -pip install tilebox-datasets geopandas lonboard -``` -```bash poetry -poetry add tilebox-datasets="*" geopandas="*" lonboard="*" -``` -```bash pipenv -pipenv install tilebox-datasets geopandas lonboard -``` - - -## Reading and previewing the dataset - -The dataset is available as a [GeoParquet](https://geoparquet.org/) file. You can read it using the `geopandas.read_parquet` function. - - -```python Python -import geopandas as gpd - -modis_data = gpd.read_parquet("modis_MCD12Q1.geoparquet") -modis_data.head(5) -``` - - - -```plaintext Output - time end_time granule_name geometry horizontal_tile_number vertical_tile_number tile_id file_size checksum checksum_type day_night_flag browse_granule_id published_at -0 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h00v08.061.2022146024956.hdf POLYGON ((-180 10, -180 0, -170 0, -172.62252 ... 0 8 51000008 275957 941243048 CKSUM Day None 2022-06-23 10:54:43.824000+00:00 -1 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h00v09.061.2022146024922.hdf POLYGON ((-180 0, -180 -10, -172.62252 -10, -1... 0 9 51000009 285389 3014510714 CKSUM Day None 2022-06-23 10:54:44.697000+00:00 -2 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h00v10.061.2022146032851.hdf POLYGON ((-180 -10, -180 -20, -180 -20, -172.6... 0 10 51000010 358728 2908215698 CKSUM Day None 2022-06-23 10:54:44.669000+00:00 -3 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h01v08.061.2022146025203.hdf POLYGON ((-172.62252 10, -170 0, -160 0, -162.... 1 8 51001008 146979 1397661843 CKSUM Day None 2022-06-23 10:54:44.309000+00:00 -4 2001-01-01 00:00:00+00:00 2001-12-31 23:59:59+00:00 MCD12Q1.A2001001.h01v09.061.2022146025902.hdf POLYGON ((-170 0, -172.62252 -10, -162.46826 -... 1 9 51001009 148935 2314263965 CKSUM Day None 2022-06-23 10:54:44.023000+00:00 -``` - - -## Exploring it visually - -Geopandas comes with a built in explorer to visually explore the dataset. - - -```python Python -from lonboard import viz - -viz(modis_data, map_kwargs={"show_tooltip": True}) -``` - - - - Explore the MODIS dataset - Explore the MODIS dataset - - -## Create a Tilebox dataset - -Now you'll create a [Spatio-temporal](/datasets/types/spatiotemporal) dataset with the same schema as the given MODIS dataset. -To do so, you'll use the [Tilebox Console](/console), navigate to `My Datasets` and click `Create Dataset`. Then select -`Spatio-temporal Dataset` as the dataset type. - - - For more information on creating a dataset, check out the [Creating a dataset](/guides/datasets/create) guide for a - Step by step guide. - - -Now, to match the given MODIS dataset, you'll specify the following fields: - -| Field | Type | Note | -| --- | --- | --- | -| `granule_name` | string | MODIS granule name | -| `end_time` | Timestamp | Measurement end time | -| `horizontal_tile_number` | int64 | Horizontal modis tile number (0-35) | -| `vertical_tile_number` | int64 | Vertical modis tile number (0-17) | -| `tile_id` | int64 | Modis Tile ID | -| `file_size` | uint64 | File size of the product in bytes | -| `checksum` | string | Hash checksum of the file | -| `checksum_type` | string | Checksum algorithm (MD5 / CKSUM) | -| `day_night_flag` | int64 | Day / Night / Both | -| `browse_granule_id` | string | Optional granule ID for browsing | -| `published_at` | Timestamp | The time the product was published | - -In the console, this will look like the following: - - - Tilebox Console - Tilebox Console - - -## Access the dataset from Python - -Your newly created dataset is now available. You can access it from Python. For this, you'll need to know the dataset slug, -which was assigned automatically based on the specified `code_name`. To find out the slug, navigate to the dataset overview -in the console. - - - Dataset slug display in the console - Dataset slug display in the console - - -You can now instantiate the dataset client and access the dataset. - - -```python Python -from tilebox.datasets import Client - -client = Client() -dataset = client.dataset("tilebox.modis") # replace with your dataset slug -``` - - -## Create a collection - -Next, you'll create a collection to insert your data into. - - -```python Python -collection = dataset.get_or_create_collection("MCD12Q1") -``` - - -## Ingest the data - -Now, you'll finally ingest the MODIS data into the collection. - - -```python Python -datapoint_ids = collection.ingest(modis_data) -print(f"Successfully ingested {len(datapoint_ids)} datapoints!") -``` - - - -```plaintext Output -Successfully ingested 7245 datapoints! -``` - - -## Query the newly ingested data - -You can now query the newly ingested data. You can query a subset of the data for a specific time range. - - - Since the data is now stored directly in the Tilebox dataset, you can query and access it from anywhere. - - - -```python Python -from shapely import Polygon - -area = Polygon( # area roughly covering the US - ((-124.45, 49.19), (-120.88, 29.31), (-66.87, 24.77), (-65.34, 47.84), (-124.45, 49.19)), -) - -data = collection.query( - temporal_extent=("2015-01-01", "2020-01-01"), - spatial_extent=area -) -data -``` - - - -```plaintext Output - Size: 28kB -Dimensions: (time: 110) -Coordinates: - * time (time) datetime64[ns] 880B 2015-01-01 ... 2019-01-01 -Data variables: (12/14) - id (time) - - - For more information on accessing and querying data, check out [querying data](/datasets/query/querying-data). - - -## View the data in the console - -You can also view your data in the Console, by navigate to the dataset, selecting the collection and then clicking -on one of the data points. - - - Explore the MODIS dataset - Explore the MODIS dataset - - -## Next steps - -Congrats. You've successfully ingested data into Tilebox. You can now explore the data in the console and use it for -further processing and analysis. - - - - Learn all about [querying your newly created dataset](https://docs.tilebox.com/datasets/query) - - - Explore the different dataset types available in Tilebox - - - Check out a growing number of publicly available open data datasets on Tilebox - - diff --git a/guides/datasets/query-satellite-data.mdx b/guides/datasets/query-satellite-data.mdx index f9c1eec..d417192 100644 --- a/guides/datasets/query-satellite-data.mdx +++ b/guides/datasets/query-satellite-data.mdx @@ -1,12 +1,12 @@ --- -title: Query satellite data by time and location -description: Find satellite metadata in a Tilebox open data catalog by combining temporal and spatial filters. +title: Query open satellite data +description: Explore available Tilebox open data catalogs and query Sentinel-2 metadata by time and location. icon: satellite --- -Use this guide when you know the area and time range you care about and want to find matching satellite products before downloading any files. +Use this guide when you want to find satellite products in Tilebox open data catalogs before downloading any files. You will first inspect the available open data datasets, then query Sentinel-2 metadata by time and location. -Tilebox Datasets stores searchable metadata for open data catalogs. Querying metadata first lets you narrow a large catalog to the scenes that match your workflow, notebook, or agent task. +Tilebox Datasets stores searchable metadata for open Earth observation catalogs. Metadata queries are the fastest way to narrow a large catalog to the scenes that match your workflow, notebook, or agent task. ## Prerequisites @@ -17,6 +17,47 @@ Tilebox Datasets stores searchable metadata for open data catalogs. Querying met uv add tilebox shapely ``` +## Explore available open data datasets + +Tilebox exposes open data catalogs through the same dataset API as your private datasets. To get a list of available open data satellite datasets, run the following snippet. + +```python Python +from tilebox.datasets import Client + +client = Client() +datasets = client.datasets() +print(datasets.open_data) +``` + +The output groups datasets by provider. Open data datasets include Copernicus Sentinel missions, USGS Landsat products, ASF SAR products, and other public catalogs that Tilebox has indexed. + +```plaintext Output +asf: + ers_sar: European Remote Sensing Satellite (ERS) Synthetic Aperture Radar ... +copernicus: + sentinel1_sar: The Sentinel-1 mission is the European Radar Observatory ... + sentinel2_msi: Sentinel-2 is equipped with an optical instrument payload ... + sentinel3_olci: OLCI (Ocean and Land Colour Instrument) is an optical ... + ... +usgs: + ... + landsat8_oli_tirs: Landsat-8 Operational Land Imager and Thermal Infrared ... + landsat9_oli_tirs: Landsat-9 Operational Land Imager and Thermal Infrared ... +``` + +You can also browse open data datasets in the [Tilebox Console](https://console.tilebox.com/datasets/open-data) when you want descriptions, provider details, the dataset schema, and available collections before writing code. + +## Select the Sentinel-2 catalog + +Access the Sentinel-2 MSI dataset by its slug. The dataset contains collections for Sentinel-2 products such as `S2A_S2MSI2A`. + +```python Python +sentinel2 = client.dataset("open_data.copernicus.sentinel2_msi") + +for name, collection in sentinel2.collections().items(): + print(name, collection) +``` + ## Define the search area Create a polygon for the area you want to inspect. This example uses a bounding box around Colorado. @@ -26,10 +67,12 @@ from shapely import Polygon area = Polygon( [ + # lon, lat (-109.05, 37.0), (-102.05, 37.0), (-102.05, 41.0), (-109.05, 41.0), + # close the square (repeat the first element) (-109.05, 37.0), ] ) @@ -37,13 +80,9 @@ area = Polygon( ## Query Sentinel-2 metadata -Select the Sentinel-2 MSI open data catalog and query a collection by time and location. +Query the Sentinel-2 Level-2A collection by time and location. This returns metadata for matching scenes; it does not download image products. ```python Python -from tilebox.datasets import Client - -client = Client() -sentinel2 = client.dataset("open_data.copernicus.sentinel2_msi") collection = sentinel2.collection("S2A_S2MSI2A") scenes = collection.query( @@ -55,32 +94,27 @@ scenes = collection.query( print(scenes[["granule_name", "processing_level", "product_type"]]) ``` -The result is an `xarray.Dataset` containing scene metadata. Use it to inspect candidate scenes, filter by metadata fields, or pass selected datapoints to a storage client. +The result is an `xarray.Dataset` containing scene metadata. Use it to inspect candidate scenes, filter by metadata fields, or pass selected datapoints to a workflow task. -## Download matching products +## Filter the metadata result -Metadata queries do not download product files. Use a [storage client](/datasets/storage/clients) when you want to read or download the files referenced by a datapoint. +Metadata results behave like regular `xarray.Dataset` objects. You can filter, sort, or select scenes before deciding what to process next. ```python Python -from pathlib import Path -from tilebox.storage import CopernicusStorageClient - -storage = CopernicusStorageClient( - cache_directory=Path("./data"), - s3_access_key_id="YOUR_COPERNICUS_ACCESS_KEY", - s3_secret_access_key="YOUR_COPERNICUS_SECRET_KEY", -) +low_cloud = scenes.where(scenes.cloud_cover < 10, drop=True) +latest = low_cloud.sortby("time").isel(time=-1) -first_scene = scenes.isel(time=0) -path = storage.download(first_scene) -print(path) +print(latest.granule_name.item()) +print(latest.cloud_cover.item()) ``` +Metadata queries do not download product files. Use a [storage client](/datasets/storage/clients) when you want to read or download the files referenced by a datapoint. + ## Next steps - - Follow a longer Sentinel-2 example with output inspection. + + Download Copernicus product files with the storage client. Configure provider-specific clients for product access. diff --git a/guides/workflows/deploy-to-your-compute.mdx b/guides/workflows/deploy-to-your-compute.mdx index d501a03..90fbb03 100644 --- a/guides/workflows/deploy-to-your-compute.mdx +++ b/guides/workflows/deploy-to-your-compute.mdx @@ -51,15 +51,44 @@ tilebox runner start --cluster workflow-dev --debug The runner watches its cluster, downloads missing release artifacts, starts the workflow runtime, and advertises the tasks it can execute. Updating a deployment changes what the runner can execute without rebuilding the runner process. +## Bundle the release runner in a container + +For cloud or Kubernetes deployments, package the release runner into a small container image. The image only needs Python, `uv`, the Tilebox command-line tool, and any system dependencies your workflow runtime needs. The workflow code itself comes from the deployed workflow release. + +```dockerfile Dockerfile +FROM python:3.13-slim +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ + +# Install system dependencies. +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl git git-lfs openssh-client \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean + +RUN curl -fsSL https://cli.tilebox.com/install.sh | TILEBOX_INSTALL_DIR=/usr/local/bin TILEBOX_NO_INSTALL_COMPLETIONS=1 sh + +# Required at runtime: set TILEBOX_CLUSTER to a valid cluster slug and +# TILEBOX_API_KEY to an API key that can read deployments and claim tasks. +ENV TILEBOX_CLUSTER="" +ENV TILEBOX_API_KEY="" + +CMD ["tilebox", "runner", "start"] +``` + +Build and publish this image with your normal container workflow. At runtime, provide `TILEBOX_CLUSTER` and `TILEBOX_API_KEY` through your deployment system rather than baking secrets into the image. + +In Kubernetes, run the image as a `Deployment` and store `TILEBOX_API_KEY` in a `Secret`. Set `TILEBOX_CLUSTER` through the pod environment and scale replicas to increase runner concurrency. In Google Cloud, run the same image on Cloud Run jobs, GKE, or Compute Engine depending on your workload constraints. In AWS, run it on ECS, EKS, or EC2 and inject the API key through your secret manager or task definition. + ## Scale runner processes -Start multiple runners for the same cluster when you want more parallelism. +Scale the number of runner containers or virtual machine instances when you want more parallelism. In Kubernetes, increase the `Deployment` replica count. In GCP or AWS, use the scaling controls of the service that runs the container, such as Cloud Run, GKE, ECS, EKS, or an auto-scaling VM group. Each runner process connects to the same cluster and claims compatible tasks independently. + +As an alternative for local testing or constrained environments, you can run multiple runner processes inside one container or shell session. Use `tilebox parallel` only for that case. ```bash tilebox parallel -n 4 -- tilebox runner start --cluster workflow-dev ``` -You can also run runners through your own process manager, VM image, container platform, or scheduler. Tilebox does not require the compute process to run in Tilebox-managed infrastructure. +Tilebox does not require the runner process to run in Tilebox-managed infrastructure. Use the process manager, scheduler, or container platform that fits your compute environment. ## Verify cluster alignment diff --git a/guides/workflows/execute-tasks-in-parallel.mdx b/guides/workflows/execute-tasks-in-parallel.mdx new file mode 100644 index 0000000..9abfa31 --- /dev/null +++ b/guides/workflows/execute-tasks-in-parallel.mdx @@ -0,0 +1,172 @@ +--- +title: Execute tasks in parallel +description: Submit multiple workflow subtasks and process them faster by running multiple direct runners at the same time. +icon: arrows-split-up-and-left +--- + +Use this guide when a workflow can split work into independent tasks. You will create a small workflow that submits 20 sleep subtasks, submit one job, run it with one direct runner, and then run the same workflow with five direct runners in parallel. + +The example is intentionally simple. `time.sleep` stands in for real work such as downloading scenes, processing tiles, calling a model, or writing output files. + +## Prerequisites + +- You have a [Tilebox API key](/authentication). +- You have installed [`uv`](https://docs.astral.sh/uv/). +- You have installed the [Tilebox command-line tool](/agents-and-ai-tools/tilebox-cli) if you want to use `tilebox parallel`. + +```bash +export TILEBOX_API_KEY="YOUR_TILEBOX_API_KEY" +``` + +## Create the workflow file + +Create a file named `parallel_workflow.py`. The script uses inline `uv` dependencies, so you can run it directly with `uv run parallel_workflow.py`. + +```python parallel_workflow.py +# /// script +# dependencies = ["cyclopts", "tilebox"] +# /// + +import time + +from cyclopts import App +from tilebox.workflows import Client, ExecutionContext, Runner, Task + + +app = App() + + +class ParallelSleepWorkflow(Task): + count: int + seconds: float + + def execute(self, context: ExecutionContext) -> None: + context.logger.info( + "Submitting sleep subtasks", + count=self.count, + seconds=self.seconds, + ) + context.submit_subtasks( + [ + SleepTask(index=index, seconds=self.seconds) + for index in range(self.count) + ] + ) + + +class SleepTask(Task): + index: int + seconds: float + + def execute(self, context: ExecutionContext) -> None: + context.current_task.display = f"SleepTask({self.index})" + context.logger.info("Starting sleep task", index=self.index) + time.sleep(self.seconds) + context.logger.info("Finished sleep task", index=self.index) + + +runner = Runner(tasks=[ParallelSleepWorkflow, SleepTask]) + + +def submit_job(count: int, seconds: float) -> None: + client = Client() + job = client.jobs().submit( + "parallel-sleep-workflow", + ParallelSleepWorkflow(count=count, seconds=seconds), + ) + print(f"Submitted job: {job.id}") + print(f"Open in Console: https://console.tilebox.com/workflows/jobs/{job.id}") + + +def run_runner() -> None: + client = Client() + runner.connect_to(client).run_all() + + +@app.default +def main(submit: bool = False, count: int = 20, seconds: float = 5.0) -> None: + """Run a direct runner, or submit a new job with --submit.""" + if submit: + submit_job(count=count, seconds=seconds) + return + + run_runner() + + +if __name__ == "__main__": + app() +``` + +The root task, `ParallelSleepWorkflow`, does not do the slow work itself. It submits many independent `SleepTask` subtasks. Tilebox tracks the tasks in one job and lets any eligible runner claim queued work. + +## Submit a job + +Submit one job with 20 subtasks. The script exits after submitting the job, so no work is executed yet. + +```bash +uv run parallel_workflow.py --submit --count 20 --seconds 5 +``` + +Copy the job ID from the output. You can inspect it in the Console while runners process the queue. + +```plaintext Output +Submitted job: 019f2c8c-3df2-4ed0-9d8f-8a4f19c47a7c +Open in Console: https://console.tilebox.com/workflows/jobs/ +``` + +## Run one direct runner + +Start one direct runner from the same file. + +```bash +uv run parallel_workflow.py +``` + +The runner executes tasks, but only one after the other, and exits when no more work is available. With one runner, the sleep subtasks don't run in parallel at all. + +## Run five direct runners + +Submit another job, then start five runner processes for the same workflow file. + +```bash +uv run parallel_workflow.py --submit --count 20 --seconds 5 +tilebox parallel -n 5 -- uv run parallel_workflow.py +``` + +This starts five direct runners. Each process registers the same task classes and asks Tilebox for work. Tilebox assigns queued tasks across the available runners, so multiple `SleepTask` instances run at the same time. + + + Takeaway: use `tilebox parallel -n 5 -- uv run parallel_workflow.py` to start five local direct runners for the same workflow file. + + +## What to expect + +The first runner to claim `ParallelSleepWorkflow` submits the subtasks. After that, all runners can claim compatible `SleepTask` tasks from the same job. + +In the Console, you should see: + +- one root task that submits the subtask fan-out +- many `SleepTask(index)` tasks +- multiple tasks running at overlapping times when five runners are active +- logs from each task attached to the same job + +For command-line inspection, query logs or spans for the job: + +```bash +tilebox job logs --json +tilebox job spans --json +``` + +## Next steps + + + + Learn how runners claim queued tasks and how direct runners differ from release runners. + + + Learn how parent tasks submit subtasks, define dependencies, and report progress. + + + Inspect task state, logs, traces, runner context, and cluster alignment. + + diff --git a/index.mdx b/index.mdx index 1e8df1a..cb595b2 100644 --- a/index.mdx +++ b/index.mdx @@ -73,7 +73,7 @@ export const HomeSearch = () => { Get API Key - + Ingest data @@ -276,7 +276,7 @@ export const HomeSearch = () => { - + diff --git a/quickstart.mdx b/quickstart.mdx index 13bfeef..f4c0de0 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -117,11 +117,11 @@ If you prefer to work locally, follow these steps to get started. Review the following guides to learn more about the modules that make up Tilebox: - - Learn how to create a Timeseries dataset using the Tilebox Console. + + Learn how to create a custom dataset catalog with the Python SDK. - - Learn how to ingest an existing CSV dataset into a Timeseries dataset collection. + + Learn how to ingest GeoParquet metadata into an existing spatio-temporal catalog. Inspect task state, logs and traces when a workflow job fails. diff --git a/workflows/build-and-deploy/project-structure.mdx b/workflows/build-and-deploy/project-structure.mdx index 108ba82..0e13360 100644 --- a/workflows/build-and-deploy/project-structure.mdx +++ b/workflows/build-and-deploy/project-structure.mdx @@ -29,11 +29,33 @@ Use a layout where task code and the runner definition are importable from the p +## Define the Python project + +Use a minimal `pyproject.toml` with the dependencies your workflow needs. For this example, only the Tilebox Python package is required. + +```toml pyproject.toml +[project] +name = "my-workflow" +version = "0.1.0" +requires-python = ">=3.11" +dependencies = [ + "tilebox", +] +``` + +Create the package directory and an empty `__init__.py` file so Python can import `my_workflow.runner` from the project root. + +```bash +mkdir -p my_workflow +touch my_workflow/__init__.py +uv lock +``` + ## Define tasks Put task classes in a module that can be imported during release validation. -```python Python +```python my_workflow/tasks.py # my_workflow/tasks.py from tilebox.workflows import ExecutionContext, Task @@ -56,7 +78,7 @@ Use explicit identifiers for workflow code that will be published. A stable iden Create a module that exports a `Runner` object. This object defines the task registrations for the workflow, and release builds import it during validation. -```python Python +```python my_workflow/runner.py # my_workflow/runner.py from tilebox.workflows import Runner from tilebox.workflows.cache import LocalFileSystemCache