> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wherobots.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run RasterFlow as a Job

> Submit RasterFlow workflows as Job Runs using the Wherobots Runs REST API for automated, production-scale raster processing.

<Badge color="purple">Private Preview</Badge>

<br />

<br />

<CardGroup cols={2}>
  <Card title="RasterFlow Overview" icon="file-lines" href="/develop/rasterflow/">
    Learn about RasterFlow's key features and capabilities
  </Card>

  <Card title="Runs REST API" icon="bolt" href="/reference/runs/">
    Full reference for the Runs REST API
  </Card>

  <Card title="Workload History" icon="chart-line" href="/develop/workload-history">
    Monitor your job runs
  </Card>

  <Card title="Runtimes" icon="server" href="/develop/runtimes">
    Choose the right runtime for your workload
  </Card>
</CardGroup>

RasterFlow workflows can be submitted as [Job Runs](/reference/runs/) using the Wherobots Runs REST API. This lets you run RasterFlow workflows as automated, standalone jobs outside of a notebook, which is useful for production pipelines, scheduled processing, and CI/CD integration.

## Benefits

Running RasterFlow workflows as jobs provides several advantages over interactive notebook execution:

<AccordionGroup>
  <Accordion title="Automation" icon="clock">
    Schedule and trigger RasterFlow workflows programmatically.
  </Accordion>

  <Accordion title="Production readiness" icon="rocket">
    Run workflows in a managed environment without interactive notebooks.
  </Accordion>

  <Accordion title="Integration" icon="puzzle-piece">
    Incorporate RasterFlow into existing data pipelines and CI/CD systems.
  </Accordion>

  <Accordion title="Monitoring" icon="chart-line">
    Track job status and results through the [Workload History](/develop/workload-history) dashboard.
  </Accordion>
</AccordionGroup>

## Before you start

Before submitting RasterFlow jobs, ensure you have the following:

* An account within a Professional or Enterprise Edition Organization. For more information, see [Create a Wherobots Account](/get-started/wherobots-cloud/create-account).
* A Wherobots API key. For more information, see [API keys](/get-started/wherobots-cloud/api-keys/).
* Access to [Wherobots Managed Storage](/develop/storage-management/storage/#wherobots-managed-storage) for uploading scripts and storing results.
* RasterFlow enabled for your organization.

<Callout icon="key" color="#af87ef" iconType="regular">
  RasterFlow is currently in Private Preview. Wherobots is rolling out RasterFlow to a select group of Organizations. If you are interested in gaining early access to these new capabilities and helping shape the future of the product, [register your interest here](https://wherobots.com/rasterflow-preview/).
</Callout>

## Overview

Submitting a RasterFlow workflow as a job involves three steps:

1. **Write a job script**: Create a standalone Python script containing your RasterFlow workflow
2. **Upload the script**: Upload the script to Wherobots Managed Storage so it can be referenced by the Job Run.
3. **Submit the job**: Submit the job using the Runs REST API

## Write the job script

Create a Python script that contains your RasterFlow workflow. This script will be executed by the Wherobots Job Run environment. It should be self-contained—all imports, configuration, and processing logic must be included in the script.

The following example runs the [Fields of the World (FTW)](https://fieldsofthe.world/) model on Haskell County, Kansas using RasterFlow.

<Info>
  This is a subset of the code included in the [Fields of the World solution notebook](https://cloud.wherobots.com/model-hub/fields-of-the-world).
  See the [FTW tutorial](/tutorials/example-notebooks/rasterflow-ftw) for more details on the model and its outputs.
</Info>

```python title="rasterflow_ftw_job.py" wrap lines=TRUE theme={"system"}
#!/usr/bin/env python3
"""
RasterFlow FTW Job Script - Extract field boundaries using Fields of the World model

This script runs the Fields of the World (FTW) model on Haskell County, Kansas
and vectorizes the results using Wherobots RasterFlow.
"""

import os
import wkls
import geopandas as gpd
from datetime import datetime
from rasterflow_remote import RasterflowClient
from rasterflow_remote.data_models import ModelRecipes, VectorizeMethodEnum

def main():
    print("Starting RasterFlow FTW Job...")

    # Initialize RasterFlow client
    rf_client = RasterflowClient(cache=False)

    # Generate AOI for Haskell County, Kansas
    print("Generating AOI for Haskell County, Kansas...")
    gdf = gpd.read_file(wkls['us']['ks']['Haskell County'].geojson())
    aoi_path = os.getenv("USER_S3_PATH") + "haskell_job.parquet"
    gdf.to_parquet(aoi_path)
    print(f"AOI saved to: {aoi_path}")

    # Run FTW model
    print("Running Fields of the World model...")
    model_outputs = rf_client.build_and_predict_mosaic_recipe(
        aoi=aoi_path,
        start=datetime(2023, 1, 1),
        end=datetime(2024, 1, 1),
        crs_epsg=3857,
        model_recipe=ModelRecipes.FTW,
    )
    print(f"Model outputs saved to: {model_outputs}")

    print("RasterFlow FTW Job completed successfully!")
    print(f"Results:")
    print(f"  Model outputs: {model_outputs}")

    return {
         "model_outputs": model_outputs,
    }

if __name__ == "__main__":
    main()
```

<Expandable title="how to customize this workflow">
  **Update the following lines for your use case:**

  * In **line 25**, replace `wkls['us']['ks']['Haskell County']` with your own area of interest.
  * In **line 26**, replace `"haskell_job.parquet"` with your desired output filename.
  * In **lines 33–37**, update the `start`, `end`, `crs_epsg`, and `model_recipe` parameters to match your workflow.
</Expandable>

### Upload the script

Upload the job script to your [Wherobots Managed Storage](/develop/storage-management/storage/#wherobots-managed-storage) so it can be referenced by the Job Run.

Your upload method will depend on where you created the script:

<Tabs>
  <Tab title="Wherobots Cloud">
    If you wrote and saved the job script (in this example `rasterflow_ftw_job.py`) in the Wherobots Cloud notebook environment, upload the job script to Managed Storage using `s3fs`.

    1. Start a new notebook in [Wherobots Cloud](https://cloud.wherobots.com).

    2. Paste the following code snippet into a notebook cell in the same directory as `rasterflow_ftw_job.py`.

       ```python lines=TRUE theme={"system"}
       import os
       import s3fs

       fs = s3fs.S3FileSystem(profile="default")

       # Define the destination path on S3
       s3_script_path = os.getenv("USER_S3_PATH") + "rasterflow_ftw_job.py"
       fs.put("rasterflow_ftw_job.py", s3_script_path)
       ```

           <Expandable title="how to customize this upload script">
             **Update the following lines:**

             * In **line 8**, replace `"rasterflow_ftw_job.py"` with the destination filename for your script in Managed Storage.
             * In **line 9**, replace `"rasterflow_ftw_job.py"` with the local filename of your job script.
           </Expandable>

    3. Run the cell to upload `rasterflow_ftw_job.py`.

       Go to [Storage](https://cloud.wherobots.com/storage) in the Wherobots Cloud interface to confirm that the file is uploaded to your Managed Storage.
  </Tab>

  <Tab title="Local Machine">
    If you wrote and saved the job script (in this example `rasterflow_ftw_job.py`) on your local machine or outside of Wherobots Cloud, upload the job script directly from the Wherobots Cloud interface:

    1. Navigate to [**Storage**](https://cloud.wherobots.com/storage) in Wherobots Cloud.
    2. Click the **Upload** button.
    3. Select your `rasterflow_ftw_job.py` script from your local machine.

       Go to [Storage](https://cloud.wherobots.com/storage) in the Wherobots Cloud interface to confirm that the file is uploaded to your Managed Storage.
  </Tab>
</Tabs>

## Submit the job

Once `rasterflow_ftw_job.py` is uploaded to Managed Storage, submit it as a Job Run using the [Runs REST API](/api-reference/runs/create-run).

1. Create the following environment variables:

   <Warning>
     Never hardcode your API key in scripts or source code. Always load it from an environment variable or a secrets manager. The example below reads the key from the `WHEROBOTS_API_KEY` environment variable.
   </Warning>

   | Variable            | Description                                                                                               |
   | :------------------ | :-------------------------------------------------------------------------------------------------------- |
   | `WHEROBOTS_API_KEY` | Your Wherobots API key. See [API keys](/get-started/wherobots-cloud/api-keys/) for how to create one.     |
   | `USER_S3_PATH`      | Your Wherobots managed storage path. Available as a built-in environment variable in Wherobots notebooks. |

2. Run the following script to submit a job that references your uploaded `rasterflow_ftw_job.py`.

   <Info>
     The submission script uses the `requests` library. If it is not already installed in your environment, install it with `pip install requests`.
   </Info>

   ```python title="submit_rasterflow_job.py" wrap lines="TRUE" theme={"system"}
   #!/usr/bin/env python3
   """
   Submit a RasterFlow workflow as a Job Run using the Wherobots Runs REST API.

   This script submits a job that runs the Fields of the World (FTW) model
   on Haskell County, Kansas.

   This is a subset of the code included in the Solution Notebook for the Fields of the World model.
   See https://cloud.wherobots.com/model-hub/fields-of-the-world for more details.
   """

   import os
   import requests
   from datetime import datetime


   def submit_rasterflow_job(
       api_key: str,  # Loaded from WHEROBOTS_API_KEY env var in main()
       script_s3_path: str,
       region: str = "aws-us-west-2",
       runtime: str = "micro",
       job_name: str = "rasterflow-ftw-job",
       timeout_seconds: int = 3600
   ) -> dict:
       """
       Submit a RasterFlow workflow using the Wherobots Runs REST API.

       Args:
           api_key: Wherobots API key
           script_s3_path: S3 path to the Python script file
           region: Compute region (default: aws-us-west-2)
           runtime: Wherobots runtime size (default: micro). RasterFlow manages its own compute, so use micro unless also running WherobotsDB workloads.
           job_name: Name for the job run
           timeout_seconds: Job timeout in seconds (default: 3600)

       Returns:
           dict: API response containing job run details
       """

       # API endpoint
       url = f"https://api.cloud.wherobots.com/runs?region={region}"

       # Headers
       headers = {
           "accept": "application/json",
           "X-API-Key": api_key,
           "Content-Type": "application/json"
       }

       # Job payload
       payload = {
           "runtime": runtime,
           "name": job_name,
           "runPython": {
               "uri": script_s3_path
           },
           "timeoutSeconds": timeout_seconds,
           "environment": {
               "dependencies": [
               ]
           }
       }

       # Make the request
       print(f"Submitting job to: {url}")
       print(f"Job name: {job_name}")
       print(f"Runtime: {runtime}")
       print(f"Script path: {script_s3_path}")

       response = requests.post(url, headers=headers, json=payload)

       # Handle response
       if response.status_code == 200 or response.status_code == 201:
           result = response.json()
           print(f"Job submitted successfully!")
           print(f"Job ID: {result.get('id')}")
           print(f"Status: {result.get('status')}")
           return result
       else:
           print(f"Job submission failed!")
           print(f"Status Code: {response.status_code}")
           print(f"Response: {response.text}")
           response.raise_for_status()


   def main():
       """Main function to run the job submission script."""

       # Configuration - Update these values
       API_KEY = os.getenv("WHEROBOTS_API_KEY")
       USER_S3_PATH = os.getenv("USER_S3_PATH")

       # Validate required environment variables
       if API_KEY is None or API_KEY == "":
           raise ValueError(
               "WHEROBOTS_API_KEY environment variable is required. "
               "Get your API key from https://cloud.wherobots.com/settings#api-keys"
           )

       if USER_S3_PATH is None or USER_S3_PATH == "":
           raise ValueError(
               "USER_S3_PATH environment variable is required. "
               "This should be your Wherobots managed storage path."
           )

       SCRIPT_S3_PATH = USER_S3_PATH + "rasterflow_ftw_job.py"

       print("=== RasterFlow FTW Job Submission ===")
       print("This script will submit a job to run the Fields of the World model")
       print("on Haskell County, Kansas using Wherobots RasterFlow.\n")

       print(f"Make sure you have uploaded rasterflow_ftw_job.py to: {SCRIPT_S3_PATH}")
       print("The job script should already be available in this directory.\n")

       # Submit the job
       result = submit_rasterflow_job(
           api_key=API_KEY,
           script_s3_path=SCRIPT_S3_PATH,
           job_name=f"rasterflow-ftw-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
       )

       print(f"\nJob submission completed!")
       print(f"Monitor your job at: https://cloud.wherobots.com/job-runs")


   if __name__ == "__main__":
       exit(main())
   ```

   <Expandable title="how to customize this job submission">
     **Update the highlighted lines for your use case:**

     * In **line 20**, replace `"aws-us-west-2"` with your desired [compute region](/develop/runtimes/).
     * In **line 21**, replace `"micro"` with the [runtime](/develop/runtimes/) size for your workload. For RasterFlow-only jobs, use `micro` — see the tip below.
     * In **line 22**, replace `"rasterflow-ftw-job"` with a name for your job run.
     * In **line 23**, replace `3600` with your desired timeout in seconds.
     * In **line 49**, set the `WHEROBOTS_API_KEY` environment variable with your [API key](/get-started/wherobots-cloud/api-keys/). The script reads it at runtime — never hardcode it.
     * In **line 50**, replace `"rasterflow_ftw_job.py"` with the filename of your uploaded script.

     <Tip>
       RasterFlow manages its own compute resources for raster processing, so the Wherobots Runtime size does not affect RasterFlow workflow performance. Use the **Micro** runtime to minimize cost. Only select a larger runtime if your job also performs vector processing with WherobotsDB (e.g., spatial SQL with SedonaContext).
     </Tip>
   </Expandable>

   <Expandable title="Request parameters">
     The key parameters in the job submission payload are:

     <ParamField path="runtime" type="string" required>
       The [Wherobots runtime](/develop/runtimes/) size for the job. RasterFlow manages its own compute resources, so the runtime size does not affect RasterFlow workflow performance. Use `micro` unless you are also performing vector processing with WherobotsDB in the same job.
     </ParamField>

     <ParamField path="name" type="string" required>
       A unique name for the job run. Must be 8–255 characters matching `^[a-zA-Z0-9_-.]+$`.
     </ParamField>

     <ParamField path="runPython.uri" type="string" required>
       The S3 path to the Python script in [Wherobots Managed Storage](/develop/storage-management/storage/#wherobots-managed-storage).
     </ParamField>

     <ParamField path="timeoutSeconds" type="integer">
       Maximum execution time in seconds. Defaults to `3600` (1 hour).
     </ParamField>

     <ParamField path="environment" type="object">
       Optional runtime environment configuration, including dependencies. See [Environment keys](/reference/runs/#environment-keys).
     </ParamField>

     For the complete list of request parameters, see the [Runs REST API reference](/api-reference/runs/create-run).
   </Expandable>

## Monitor the job

After submitting a job, you can monitor its progress in several ways:

* **Workload History**: Use the [**Workload History**](https://cloud.wherobots.com/workloads) dashboard for a broader view of all workloads across your organization.
* **REST API**: Query the job status programmatically using the [Runs REST API](/reference/runs/).

## Next steps

The following resources will help you further explore RasterFlow and its related capabilities:

<AccordionGroup>
  <Accordion title="Explore built-in models" icon="box">
    See all available built-in models in [RasterFlow Models](/develop/rasterflow/rasterflow-models).
  </Accordion>

  <Accordion title="Runs REST API reference" icon="bolt">
    Review [all available parameters](/reference/runs/) for the Runs REST API.
  </Accordion>

  <Accordion title="Automate with Apache Airflow" icon="rotate">
    Set up automated pipelines with the [Wherobots Apache Airflow Provider](/develop/airflow-provider) using the [WherobotsRunOperator](/develop/run-operator).
  </Accordion>

  <Accordion title="Choose the right runtime" icon="server">
    Learn about [Runtimes](/develop/runtimes/) to choose the right compute resources for your workflows.
  </Accordion>
</AccordionGroup>

## API reference

For detailed RasterFlow API documentation, see:

<AccordionGroup>
  <Accordion title="Client API Reference" icon="bolt">
    `RasterflowClient` methods — see [Client API Reference](/reference/rasterflow/client)
  </Accordion>

  <Accordion title="Data Models Reference" icon="cubes">
    Enums and configuration objects — see [Data Models Reference](/reference/rasterflow/data-models)
  </Accordion>

  <Accordion title="Model Registry Reference" icon="database">
    Working with model registries — see [Model Registry Reference](/reference/rasterflow/model-registry)
  </Accordion>

  <Accordion title="Exceptions Reference" icon="exclamation-triangle">
    Error handling — see [Exceptions Reference](/reference/rasterflow/exceptions)
  </Accordion>
</AccordionGroup>
