Trigger a factory
Factories are in preview. If you want changes or improvements, talk to the Union team.
Triggers on factories require flyteplugins-union 0.15.0 or later.
A factory can materialize itself. A trigger starts a materialization when a source gets a new version, or on a schedule. Add triggers with factory.on and pass them to the factory:
sensors = factory.Factory(
"sensors",
daily,
triggers=[
factory.on(readings), # each new version of the readings source
factory.on(flyte.Cron("0 1 * * *"), daily), # every night at 01:00
],
)Each trigger starts an ordinary materialization, and a partition that is already up to date is a cache hit. The rest of this page covers the details: which partitions a source event or a schedule materializes, filters, lags and timezones, names, and limits.
Declare triggers
factory.on(event, *targets) takes a source handle, a flyte.Cron, or a flyte.FixedRate, and optionally the artifacts to materialize. Every form, on one graph:
import flyte
from flyteplugins.union import factory
readings = factory.source("readings", type=flyte.io.File, partitions={"date": factory.Daily, "site": str})
summary = factory.build("summary").using(summarize, readings=readings)
daily = factory.build("rollup").using(rollup, summaries=summary.all("site"))
sensors = factory.Factory(
"sensors",
daily,
triggers=[
factory.on(readings),
factory.on(readings, summary, site="north", name="north-only"),
factory.on(flyte.FixedRate(60), name="hourly"),
factory.on(flyte.Cron("0 1 * * *"), daily, lag=factory.TimeRange(days=1), name="yesterday"),
],
)flyte factory deploy registers the triggers with the factory. A triggered materialization is an ordinary run, listed on the factory’s Materializations tab. Its Triggers tab lists the factory’s triggers. When nothing has changed, every build is a cache hit, so a trigger that fires often costs little.
When a source gets a new version
factory.on(source) fires when a new version of that source is published. It materializes the partition the new version belongs to:
- The partition comes from the event. When
readings[2026-09-28, north]is published,rollupis materialized for 2026-09-28. On a key the source doesn’t carry, the target is materialized for every value the registry knows. - Targets default to what the factory produces downstream of the source. Name targets to narrow it, as
north-onlydoes withsummary. A target doesn’t have to be one of the artifacts listed inFactory(...). - Filter by partition with keyword arguments:
site="north"fires only for versions whosesiteisnorth. Filters match string keys.nameandlagare the function’s own arguments, so a key with either name can’t be filtered on.
Only a source can fire a trigger. To act on each new version of something the factory builds, add a build that reads it: materializing the new build builds what it reads first.
On a schedule
factory.on(flyte.Cron(...)) and factory.on(flyte.FixedRate(...)) fire on a schedule, and targets default to everything the factory produces:
- The partition is the fire time, rounded down to the target’s granularity. A daily target that fires at 14:00 builds that day.
lag=moves it back.yesterdayfires at 01:00 and builds the previous day, when that day’s data is complete.- The day is named in the schedule’s timezone.
flyte.Cron("0 22 * * *", timezone="America/Los_Angeles")builds that day in Los Angeles, not the next day in UTC.
A schedule that fires every hour on a factory whose inputs rarely change is a cheap way to keep it fresh: most runs are all cache hits and finish in seconds.
Names and inputs
Each trigger has a name. It defaults to one derived from the event, such as on-readings or every-60m. Pass name= to choose one, using lowercase letters, digits, and -. A trigger with several targets registers one trigger per target, named <name>-<target>.
A factory with triggers gets a few extra inputs that the triggers fill in: trigger, at, and one at_<key> for each partition key a source event carries. You don’t set them yourself. A factory without triggers keeps its original inputs.
Limits
- A source must be in the factory’s project and domain to fire a trigger.
- One source event starts one run per target. A trigger with many targets starts that many runs, and they share cache hits for what they have in common.