Skip to content

Storage Event Triggers

Trigger workflow jobs automatically whenever new objects are created or modified in a storage bucket, enabling event-driven data processing pipelines.

Creating a Storage Event Task

Storage Event Tasks are automations triggered when objects are created or modified in a storage location. In Python, use tilebox.workflows.automations.StorageEventTask as your task base class instead of the regular tilebox.workflows.Task. In Go, register an executable task with the same task identifier as the automation prototype.

Storage Locations

Storage Event tasks are triggered when objects are created or modified in a storage location. Tilebox supports these types:

Storage location CLI type Event delivery
AWS S3 aws-s3 Amazon SNS
Google Cloud Storage gcs Google Cloud Pub/Sub
Azure Blob Storage azure-blob Azure Event Grid
Local local Tilebox CLI filesystem watcher

Registering a Storage Location

For cloud storage, connect a storage location and delivery subscription in the Console, then configure your provider to forward object-created notifications. The guide covers S3/SNS, GCS/Pub/Sub, and Azure Blob/Event Grid, including resources and permissions needed before saving in Tilebox.

Tilebox registration does not provision cloud resources or grant object-read access. Provider retries and overlapping subscriptions can create duplicate jobs; tasks should be safe to retry.

Local Storage Locations

Local storage locations let you test storage-event automations or process files on your own machine. Register a directory with the CLI, then watch it for new or modified files:

bash
mkdir -p local-input
tilebox storage-location create local --path ./local-input --name "Local input"
tilebox storage-location watch <storage-location-id>

Use the location ID returned by create. The CLI stores an absolute path and sends events while watch is running. It does not upload or share the files. Run the task runner on the same machine with access to that directory.

Listing Available Storage Locations

List registered storage locations with the CLI or an SDK:

Example Python output (abbreviated) plaintext
[
    StorageLocation(
        location="gcs-bucket-fab3fa2",
        type=StorageType.GCS,
    ),
    StorageLocation(
        location="s3-bucket-263af15",
        type=StorageType.S3,
    ),
    StorageLocation(
        location='/path/to/a/local/folder',
        type=StorageType.FS,
    ),
]

Python examples use StorageType.S3 for AWS S3 and StorageType.FS for local storage.

Reading Files from a Storage Location

Inside a StorageEventTask, self.trigger.storage provides access to the storage location that sent the event. Pass self.trigger.location to its read() method to retrieve the object’s bytes. For example, this task reads an object from a connected GCS bucket and logs its size:

Python
from tilebox.workflows import ExecutionContext
from tilebox.workflows.automations import StorageEventTask


class ReadObject(StorageEventTask):
    def execute(self, context: ExecutionContext) -> None:
        path = self.trigger.location
        data = self.trigger.storage.read(path)
        context.logger.info("Read object", path=path, size_bytes=len(data))

The runner needs permission to read the bucket’s objects. Configure Google Cloud authentication in the runner’s environment. For an example using local files, follow Test storage automations locally.

Registering a Storage Event Trigger

Register a storage-event automation in the Tilebox Console or with the Python SDK. Each matching event submits a job containing an instance of the registered task prototype.

This example registers the LogObjectCreation task defined above. Replace <storage-location-id> with the ID of your GCS location from the CLI or SDK listing:

Python
from uuid import UUID

from tilebox.workflows import Client

client = Client()
automations = client.automations()
location_id = UUID("<storage-location-id>")
gcs_bucket = next(
    location for location in automations.storage_locations()
    if location.id == location_id
)

storage_event_automation = automations.create_storage_event_automation(
    "log-object-creations",  # name of the storage event automation
    LogObjectCreation(head_bytes=20),  # the task (and its input parameters) to run repeatedly
    triggers=[
        # you can specify a glob pattern:
        # run every time a .txt file is created anywhere in the gcs bucket
        (gcs_bucket, "**.txt"),  
    ],
)

Glob Patterns

Storage automations use gobwas/glob with / as the path separator. Matching is case-sensitive and applies to the entire object path within the storage location, such as incoming/image.tif, rather than an absolute filesystem path or bucket URL.

* matches zero or more characters within one path segment; ? matches one character. Neither crosses /. ** matches across separators, but does not make adjacent slashes optional: **/*.txt requires a slash, so it does not match hello.txt. Use **.txt to include files at the root and in subdirectories.

Here are some examples of valid glob patterns:

Pattern Matches
** Every object path, including files at the root and in subdirectories
*.ext Any file ending in .ext in the root directory
**/*.ext Any file ending in .ext in any subdirectory, but not in the root directory
**.ext Any file ending in .ext in any subdirectory, including the root directory
folder/* Any file directly in a folder subdirectory
folder/** Any file directly or recursively part of a folder subdirectory
[a-z].txt Matches a.txt, b.txt, etc.
**.{tif,tiff} Any file ending in .tif or .tiff at any depth

The local watcher’s .gitignore rules are a separate filter: they control which file events reach Tilebox. Automation globs determine which of those events trigger jobs.

Test a Glob Online

Paste the following example into the Go Playground and click Run. It uses the same glob library version and separator as Tilebox. Change the pattern and sample paths to test your own rules; no local Go installation is needed.

Go Playground text
-- go.mod --
module example.com/glob-test

go 1.22.0

require github.com/gobwas/glob v1.0.0

-- main.go --
package main

import (
    "fmt"

    "github.com/gobwas/glob"
)

func main() {
    pattern := glob.MustCompile("**/*.txt", '/')
    for _, path := range []string{"hello.txt", "nested/hello.txt", "nested/image.tif"} {
        fmt.Printf("%q: %t\n", path, pattern.Match(path))
    }
}

This prints false, true, and false respectively. Changing the pattern to **.txt also matches hello.txt. Testers using other engines, such as minimatch, can give different results for **/.

Start a Storage Event runner

With the Storage Event automation registered, a job is submitted whenever a storage event occurs. But unless a runner is available to execute the Storage Event task the submitted jobs remain in a task queue. Once an eligible runner becomes available, all jobs in the queue are executed.

Triggering an Event

Creating an object in the bucket where the task is registered results in a job being submitted:

Creating an object bash
echo "Hello World" > my-object.txt
gcloud storage cp my-object.txt gs://gcs-bucket-fab3fa2

Inspecting the runner output reveals that the job was submitted and the task executed:

Output plaintext
2024-09-25 16:51:45,621 INFO A new object was created: my-object.txt
2024-09-25 16:51:45,857 INFO The object's file size is 12 bytes
2024-09-25 16:51:45,858 INFO The object's first 20 bytes are: b'Hello World\n'

Inspecting in the Console

The Tilebox Console provides an easy way to inspect all registered storage event automations.

Tilebox Workflows automations in the Tilebox Console

Deleting Storage Event automations

To delete a registered storage event automation from Python, use automations.delete. You can also delete storage-event automations from the Tilebox Console. After deletion, no new jobs will be submitted by the storage event trigger. Past jobs already triggered will still remain queued.

Python
from tilebox.workflows import Client

client = Client()
automations = client.automations()

# delete the automation as returned by create_storage_event_automation
automations.delete(storage_event_automation)

# or manually by id:
automations.delete("0190bafc-b3b8-88c4-008b-a5db044380d0")

Submitting Storage Event jobs manually

In Python, you can submit Storage Event tasks as regular tasks for testing purposes or as part of a larger workflow. To do so, instantiate the task with a specific storage location and object name using the once method.

Python
job_client = client.jobs()

task = LogObjectCreation(head_bytes=20)

# submitting it directly won't work; raises ValueError:
# job_client.submit("manual-storage-event-job", task)

# instead, we specify a trigger condition, and submit a job manually
job_client.submit(
    "manual-storage-event-job",
    # simulate an event that occurred in the gcs bucket for the object "my-object.txt"
    task.once(gcs_bucket, "my-object.txt"),
)

Type to search…