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

# Scheduling and triggering

Metaflow flows can be started by a **time-based schedule** or by an **event** published from another flow. The decorators below are project-aware variants that register the schedule or trigger under the current project and branch.

Apply different schedules depending on which branch the flow is deployed to. If the branch doesn't match any pattern, no schedule is applied (the decorator is a no-op).

This wraps Metaflow's [`@schedule`](https://docs.metaflow.org/production/scheduling-metaflow-flows/introduction) with branch-aware routing: production can run on a tight cron while staging runs daily and feature branches get no schedule at all.

```python theme={null}
from obproject import ProjectFlow, project_schedule

@project_schedule({
    "main": {"cron": "0 8 * * 1-5", "timezone": "America/New_York"},
    "develop": {"daily": True},
    "release/*": {"hourly": True},
})
class MyFlow(ProjectFlow):
    @step
    def start(self):
        self.next(self.end)
```

Parameter

Type

Description

`schedule_map`

dict

Maps branch glob patterns to schedule specs

Each schedule spec is a dict with keys matching Metaflow's `@schedule` parameters:

Key

Type

Description

`cron`

str

Cron expression (e.g., `"0 8 * * 1-5"`)

`daily`

bool

Run daily (default if empty spec `{}` is given)

`weekly`

bool

Run weekly

`hourly`

bool

Run hourly

`timezone`

str

IANA timezone (e.g., `"America/New_York"`)

### Behavior

* Patterns are matched using `fnmatch` glob syntax (e.g., `release/*` matches `release/v2`)
* First matching pattern wins (dict insertion order), so place more specific patterns first
* If no pattern matches the deployed branch, no schedule is created
* Cannot be combined with an explicit `@schedule` decorator on the same flow

Subscribe a flow to project events published by other flows via `prj.publish_event()`:

```python theme={null}
from obproject import ProjectFlow, project_trigger

@project_trigger(event="model_trained")
class EvaluationFlow(ProjectFlow):
    @step
    def start(self):
        # Triggered when "model_trained" event is published
        self.next(self.end)
```

The decorator resolves the full event name (`prj.{project}.{branch}.{event}`) from project config, so triggers are automatically scoped to the same branch.
