API Reference¶
Assets¶
- class fwirl.Asset(key, dependencies, resources=None, group=None, subgroup=None, allow_retry=True, properties=None)[source]¶
Bases:
objectAbstract base class for a single node in an
AssetGraph.Subclass
Assetand implement thetimestamp()andbuild()coroutines to define how fwirl should check whether an asset is up-to-date and how to (re)build it.- Parameters:
key – A unique string identifier for this asset.
dependencies – A list of
Assetobjects that must be up-to-date before this asset can be built.resources – Optional list of
Resourceobjects that will be initialized before and cleaned up after every build.group – Optional grouping label used for display purposes.
subgroup – Optional sub-grouping label used for display purposes.
allow_retry – When
True(the default) a failed asset will be retried on the next build pass; whenFalsea failed asset stays in theFailedstate until manually unpaused.properties – Optional dictionary of JSON-serializable metadata exposed by the UI.
Example:
import fwirl import pendulum as plm class MyAsset(fwirl.Asset): async def timestamp(self): # Return the time the asset was last produced, or # AssetStatus.Unavailable if it does not yet exist. ... async def build(self): # Produce the asset. ...
- get_key()[source]¶
Return the string key that uniquely identifies this asset.
- Returns:
str – The asset’s key.
- class fwirl.ExternalAsset(key, dependencies, min_polling_interval, resources=None, group=None, subgroup=None, allow_retry=True)[source]¶
Bases:
AssetAn
Assetwhose value is managed by an external system.Use
ExternalAssetwhen the underlying data can change at any time outside of fwirl’s control (for example, a file written by another process, or a row in a database updated by a third-party service). fwirl polls the value at most once every min_polling_interval; if the polled value differs from the cached value the asset is automatically marked stale so that downstream assets are rebuilt.Subclasses must implement
get()(to retrieve the current value) anddiff()(to decide whether the new value counts as a change).- Parameters:
key – A unique string identifier for this asset.
dependencies – A list of
Assetobjects that must be up-to-date before this asset can be built.min_polling_interval – A
pendulum.Durationspecifying the minimum time between consecutive polls of the external resource.resources – Optional list of
Resourceobjects.group – Optional grouping label.
subgroup – Optional sub-grouping label.
allow_retry – See
Asset.
- async timestamp()[source]¶
Poll the external resource and return the cached timestamp.
If the minimum polling interval has elapsed,
get()is called. Whendiff()reports a change the asset is marked stale and the new value is staged for the nextbuild()call.- Returns:
A
pendulum.DateTimeof the last accepted value, orAssetStatus.Unavailableif no value has been accepted yet.
- class fwirl.AssetStatus(value)[source]
Bases:
EnumEnumeration of possible states for an
Asset.- Current
The asset is up-to-date with respect to all its dependencies.
- Stale
The asset exists but is out-of-date and needs to be rebuilt.
- Building
The asset is currently being built.
- Paused
The asset has been manually paused and will not be built.
- UpstreamStopped
A dependency is paused or failed, blocking this asset.
- Unavailable
The asset has not yet been built or does not exist.
- Failed
The most recent build attempt for this asset failed.
- Current = 0
- Stale = 1
- Building = 2
- Paused = 3
- UpstreamStopped = 4
- Unavailable = 5
- Failed = 6
Asset Graph¶
- class fwirl.AssetGraph(key, notifiers=None)[source]¶
Bases:
objectA directed acyclic graph of
Assetobjects with a built-in scheduler and messaging interface.AssetGraphis the central object in fwirl. It holds a DAG of assets, tracks their statuses, and orchestrates builds and refreshes both on demand and on a cron-based schedule. It can also receive commands at runtime through RabbitMQ by callingrun().- Parameters:
key – A unique string identifier for this graph. The same key is used as the RabbitMQ routing key when running in server mode.
notifiers –
Optional mapping of notifiers service configurations used to send build notifications. Each entry has the form:
{ "<service_name>": { "params": {...}, # notifiers service params "level": "ERROR", # loguru level string } }
Example:
import fwirl g = fwirl.AssetGraph("my_graph") g.add_assets([asset_a, asset_b]) g.schedule("hourly_build", "build", "0 * * * *") g.run() # blocks; listens for RabbitMQ commands
- add_assets(assets)[source]¶
Add a list of assets (and all their transitive dependencies) to the graph.
The method walks the dependency tree rooted at each asset in assets and inserts every discovered node and edge into the internal DiGraph. Duplicate assets (same key) are silently skipped.
- Parameters:
assets – An iterable of
Assetobjects to add.- Raises:
ValueError – If a self-dependency loop is detected, or if any asset’s
build()ortimestamp()method is not a coroutine.
- remove_assets(assets)[source]¶
Remove a list of assets from the graph.
Downstream assets that depended on any removed node are also removed automatically by NetworkX.
- Parameters:
assets – An iterable of
Assetobjects to remove.
- list_assets(display=True)[source]¶
Return (and optionally log) a formatted list of all assets.
- Parameters:
display – When
True(the default) the string is also emitted via the loguru logger.- Returns:
str – A multi-line string listing each asset key and its current
AssetStatus.
- list_schedules(display=True)[source]¶
Return (and optionally log) a formatted list of all schedules.
- Parameters:
display – When
True(the default) the string is also emitted via the loguru logger.- Returns:
str – A multi-line string listing each schedule name and its
Schedulerepresentation.
- list_jobs(display=True)[source]¶
Return (and optionally log) the current job queue.
- Parameters:
display – When
True(the default) the string is also emitted via the loguru logger.- Returns:
str – A multi-line string describing the currently running job (if any) and the pending job queue.
- schedule(schedule_key, action, cron_string='', asset=None, immediate_once=False)[source]¶
Add a recurring (or one-shot) schedule to the graph.
- Parameters:
schedule_key – A unique string identifier for the schedule.
action –
"refresh"to trigger a status refresh, or"build"to trigger a full build.cron_string – A standard cron expression (e.g.
"0 6 * * *"for 06:00 every day). Ignored when immediate_once isTrue.asset – Optional
Assettargeted by the action. WhenNonethe action applies to all assets.immediate_once – When
Truethe schedule fires once as soon as possible and is then automatically removed.
- unschedule(schedule_key)[source]¶
Remove a schedule from the graph.
- Parameters:
schedule_key – The string key of the schedule to remove.
- pause_schedule(schedule_key)[source]¶
Pause a schedule so that it no longer fires.
- Parameters:
schedule_key – The string key of the schedule to pause.
- pause_asset(asset)[source]¶
Set an asset’s status to
Paused.A paused asset is skipped during builds and its downstream assets are marked
UpstreamStopped.- Parameters:
asset – The
Assetto pause.
- set_allow_retry(asset, allow_retry)[source]¶
Set whether a failed asset is retried on the next build pass.
See the
allow_retryargument ofAsset.- Parameters:
asset – The
Assetto update.allow_retry –
Trueto retry failures automatically,Falseto keep the assetFaileduntil it is manually unpaused.
- unpause_schedule(schedule_key)[source]¶
Resume a previously paused schedule.
- Parameters:
schedule_key – The string key of the schedule to resume.
- unpause_asset(asset)[source]¶
Mark a paused asset as
Staleso it will be rebuilt on the next build pass.- Parameters:
asset – The
Assetto unpause.
- run()[source]¶
Start the graph server and block until a shutdown signal is received.
Launches a background thread that listens for RabbitMQ messages addressed to this graph’s key, and runs the async job scheduler in the main thread. The method returns when:
a
shutdownmessage is received via RabbitMQ, orthe user presses
Ctrl-C.
Typical usage:
g = fwirl.AssetGraph("my_graph") g.add_assets([...]) g.schedule("hourly", "build", "0 * * * *") g.run()
- refresh(assets=None)[source]¶
Synchronously refresh the status of all (or specified) assets.
Checks each asset’s
timestamp()against its dependencies and updatesstatusaccordingly. Does not callbuild().- Parameters:
assets – A single
Assetor list of assets to refresh. WhenNone(the default) every asset in the graph is refreshed.
- build(assets=None)[source]¶
Synchronously build all (or specified) stale and unavailable assets.
Refreshes statuses first, then calls
build()on every asset that is not current.- Parameters:
assets – A single
Assetor list of assets to build (fwirl will also build all upstream dependencies). WhenNone(the default) all assets are considered.
- summarize(display=True)[source]¶
Return (and optionally log) a human-readable status summary.
The summary includes total asset and edge counts broken down by
AssetStatus, grouped by thegroup/subgrouplabels assigned to each asset.- Parameters:
display – When
True(the default) the summary is also emitted via the loguru logger.- Returns:
str – The formatted summary string.
Resources¶
- class fwirl.resource.Resource(key)[source]¶
Bases:
objectAbstract base class for a managed build resource.
Resources represent shared, stateful objects (database connections, file handles, hardware locks, etc.) that must be acquired before a build begins and released when it finishes. Attach one or more
Resourceinstances to anAssetvia itsresourcesconstructor argument; fwirl will callinit()before the build pass andclose()after it completes (or fails).- Parameters:
key – A unique string identifier for this resource.
Example:
import fwirl class DBConnection(fwirl.Resource): def init(self): self.conn = connect_to_db() def close(self): self.conn.close()
Graph Workers¶
- class fwirl.worker.GraphWorker(watched_assets)[source]¶
Bases:
objectAbstract base class for dynamic graph restructuring callbacks.
Attach a
GraphWorkerto anAssetGraphto receive a callback after any of its watched_assets are successfully rebuilt. Implementrestructure()to inspect the graph and return new assets that should be added before fwirl triggers another build pass.This is useful when the set of assets that must be maintained is not known up front but is determined by the content of upstream assets (for example, discovering a list of files to process from a manifest asset).
- Parameters:
watched_assets – An iterable of
Assetobjects whose rebuild should triggerrestructure().
- abstractmethod async restructure(graph)[source]¶
Inspect the graph and optionally add new assets.
This coroutine is called after any of the watched assets finish rebuilding. Use the graph parameter to add new assets and return them so that fwirl can immediately schedule a build for the new nodes.
- Parameters:
graph – The live
AssetGraphinstance.- Returns:
A list of newly added
Assetobjects, or an empty list if no new assets were added.
Schedules¶
- class fwirl.schedule.Schedule(name, func, kwargs, cron_string='* * * * *', immediate_once=False)[source]¶
Bases:
objectA named, optionally-recurring job attached to an
AssetGraph.Scheduleobjects are created internally byAssetGraph.scheduleand are not normally constructed directly by user code.- Parameters:
name – A unique string identifier for this schedule.
func – The async callable to invoke when the schedule fires.
kwargs – Keyword arguments passed to func on each invocation.
cron_string – A standard cron expression (
"* * * * *"by default) that controls when the schedule fires. Ignored when immediate_once isTrue.immediate_once – When
Truethe schedule fires once as soon as possible and is then removed from the graph.
- IMMEDIATE = DateTime(1970, 1, 1, 0, 0, 0, tzinfo=Timezone('UTC'))¶
Remote API¶
fwirl.api.list_graphs discovers running graphs on the local machine.
The remaining functions communicate with a running
AssetGraph server over RabbitMQ. They are also exposed as
CLI commands.
- fwirl.api.summarize(graph_key, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Print a summary of the running asset graph to stdout.
Sends a
summarizemessage to the graph server identified by graph_key and waits for its response.- Parameters:
graph_key – The string key of the running
AssetGraph.rabbit_url – RabbitMQ connection URL. Defaults to
******localhost//.
- fwirl.api.list_graphs()[source]¶
List the graph keys of currently running asset graph servers.
- Returns:
list[str] – Sorted graph keys discovered on the local machine.
- fwirl.api.ls(graph_key, assets=False, schedules=False, jobs=False, rabbit_url='amqp://guest:guest@localhost//')[source]¶
List the contents of a running asset graph.
Sends an
lsmessage to the graph server and prints the response. Pass one or more flags to control which information is included.- Parameters:
graph_key – The string key of the running
AssetGraph.assets – When
True, include the list of assets and their statuses.schedules – When
True, include the list of schedules.jobs – When
True, include the job queue.rabbit_url – RabbitMQ connection URL.
- fwirl.api.build(graph_key, asset_key=None, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Trigger a build on a running asset graph.
Rebuilds all stale or unavailable assets (or the specified asset and its upstream dependencies).
- Parameters:
graph_key – The string key of the running
AssetGraph.asset_key – Optional string key of a specific asset to build. When
None(the default) all assets are built.rabbit_url – RabbitMQ connection URL.
- fwirl.api.refresh(graph_key, asset_key=None, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Trigger a status refresh on a running asset graph.
A refresh checks the timestamps of every asset (or just the specified asset and its downstream dependents) without rebuilding any of them.
- Parameters:
graph_key – The string key of the running
AssetGraph.asset_key – Optional string key of a specific asset to refresh. When
None(the default) all assets are refreshed.rabbit_url – RabbitMQ connection URL.
- fwirl.api.pause(graph_key, key=None, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Pause an asset or schedule in a running asset graph.
A paused asset will not be rebuilt until it is unpaused. A paused schedule will not fire until it is unpaused.
- Parameters:
graph_key – The string key of the running
AssetGraph.key – String key of the asset or schedule to pause.
rabbit_url – RabbitMQ connection URL.
- fwirl.api.unpause(graph_key, key=None, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Resume a previously paused asset or schedule.
- Parameters:
graph_key – The string key of the running
AssetGraph.key – String key of the asset or schedule to unpause.
rabbit_url – RabbitMQ connection URL.
- fwirl.api.schedule(graph_key, schedule_key, action, cron_string, asset_key=None, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Add a new recurring schedule to a running asset graph.
- Parameters:
graph_key – The string key of the running
AssetGraph.schedule_key – A unique string identifier for the new schedule.
action – The action to perform; either
"refresh"or"build".cron_string – A standard cron expression controlling when the schedule fires (e.g.
"0 * * * *"for every hour).asset_key – Optional string key of the asset targeted by the action. When
Nonethe action applies to all assets.rabbit_url – RabbitMQ connection URL.
- fwirl.api.unschedule(graph_key, schedule_key, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Remove an existing schedule from a running asset graph.
- Parameters:
graph_key – The string key of the running
AssetGraph.schedule_key – The string key of the schedule to remove.
rabbit_url – RabbitMQ connection URL.
- fwirl.api.shutdown(graph_key, rabbit_url='amqp://guest:guest@localhost//')[source]¶
Send a shutdown signal to a running asset graph server.
- Parameters:
graph_key – The string key of the running
AssetGraph.rabbit_url – RabbitMQ connection URL.