dag-factory
repository·main·Indexed 23 days ago
https://github.com/astronomer/dag-factoryA library for Apache Airflow® that enables the declarative construction of DAGs via YAML configuration files. It allows users to manage complex workflows, including those using the TaskFlow API and traditional operators, without writing Python code. Compatible with Python 3.10.0+, Apache Airflow 2.9+, and Apache Airflow 3.
What's inside dag-factory
- dag-factory is a library for Apache Airflow® that allows you to construct Directed Acyclic Graphs (DAGs) declaratively using configuration files (YAML). This approach enables users to create complex workflows without needing to write Python code or deeply understand Airflow primitives, helping to avoid code duplication.
Telemetry status on Astronomer platforms
mainTelemetry is disabled by default on specific Astronomer environments via the
SCARF_NO_ANALYTICS=Trueenvironment variable:Astro Runtime
- Airflow 3-based images: Astro Runtime 3.0-2 and newer.
- Airflow 2-based images: Astro Runtime 11.18.0+ (11.x line), 12.9.0+ (12.x line), and all 13.x releases.
Astro Private Cloud (APC)
Telemetry is disabled by default in all deployments, regardless of the Astro Runtime version, by setting both
SCARF_NO_ANALYTICS=TrueandDO_NOT_TRACK=True.Project structure and configuration files
mainAn Astro project generated via
astro dev initcontains the following directory structure and configuration files:dags/: Contains Python files for your Airflow DAGs.include/: Directory for additional files required by your project.plugins/: Directory for custom or community Airflow plugins.Dockerfile: Contains the versioned Astro Runtime Docker image. Use this to specify runtime overrides or additional commands.packages.txt: List OS-level packages to be installed in your environment.requirements.txt: List Python packages to be installed via pip.airflow_settings.yaml: A local-only file used to specify Airflow Connections, Variables, and Pools without using the Airflow UI.
Key elements of workflow configuration
mainWhen defining workflows in DAG Factory using YAML, you use several core keys to structure your DAG. The primary elements are:
dag_id: A unique identifier for your DAG.default_args: A dictionary of common arguments applied to all tasks within the DAG.schedule: The execution schedule for the DAG.tasks: A definition of the Airflow tasks included in the workflow.task_groups: A definition of Airflow task groups used to organize related tasks.
Representing Airflow TaskFlow API in DAG Factory YAML
mainDAG Factory allows you to represent Airflow workflows that use the TaskFlow API (Python decorators like
@task) using YAML instead of Python.While the Airflow TaskFlow API is designed to transform Python functions into tasks with intuitive data passing, DAG Factory achieves the same result by using the underlying Airflow operators in a YAML declaration.
Key differences and behaviors:
- Topology: The resulting Airflow Graph view and the underlying operators used are identical between a Python TaskFlow DAG and a DAG Factory YAML DAG.
- Dynamic Task Mapping: Both implementations support Airflow's Dynamic Task Mapping (generating tasks for each item in a list).
- Code View: In the Airflow UI, the 'Code' view for a YAML-based DAG will show the Python loader script (the file that references the YAML) rather than the logic itself.
- Troubleshooting: To mitigate the lack of logic in the 'Code' view, DAG Factory automatically appends the YAML content to the DAG's documentation in the Airflow UI, making the configuration visible for troubleshooting.
Configure Conditional Dataset Scheduling
mainYou can use logical operators within the
schedulekey of a consumer DAG to create complex trigger conditions. This requires dag-factory 0.22.0+ and Apache Airflow 2.9+.Supported logical operators:
- AND (
&): The DAG triggers only after all specified datasets have been updated. - OR (
|): The DAG triggers when any of the specified datasets is updated.
These operators allow you to define dynamic workflows where a DAG might depend on multiple datasets being ready simultaneously or just one of several options being available.
- AND (
Configure DAG scheduling in DAG-Factory
mainDAG-Factory allows you to define how your DAGs are triggered using the
schedulefield in your YAML configuration. To use scheduling, you must specify atypeand provide the configuration under avaluekey.Important Rules:
- Every schedule block must specify a
type. - Configuration details must reside under the
valuekey. - You should define only one schedule type per DAG.
Supported Schedule Types:
cron: Standard cron string (e.g.,0 0 * * *).timedelta: Fixed time intervals (e.g., every 6 hours).relativedelta: Calendar-aware intervals (e.g., every 1st of the month).timetable: Advanced Airflow timetables for custom trigger logic.assets: Triggering based on the readiness of Airflow assets.datasets: Triggering based on the readiness of Airflow datasets.
- Every schedule block must specify a
Use hierarchical `defaults.yml` files
mainDAG Factory can automatically pick up a
defaults.ymlfile located in the same directory as your DAG YAML file. You can also usedefaults_config_pathto point to a parent directory to implement a hierarchical configuration.Precedence Order in Hierarchy: Arguments in a
defaults.ymlfile closer to the DAG YAML file take precedence over those in files higher up the directory tree.Example Directory Structure:
sample_project └── a ├── b │ ├── c │ │ ├── defaults.yml <-- Highest precedence for DAGs in 'c' │ │ └── some_dags.yml │ └── defaults.yml <-- Medium precedence └── defaults.yml <-- Lowest precedenceDefine custom Python objects in YAML using __type__
mainDAG-Factory allows you to instantiate native Python objects directly within your YAML configuration files. This enables you to use advanced Airflow features (like Kubernetes pod overrides or specific operator configurations) that require complex Python types without writing additional Python code.
To define a custom object, use the special
__type__key. The value of__type__must be the fully qualified type name (e.g.,module.submodule.ClassName). You can then define other keys within that same YAML block to represent the attributes/arguments of that Python object. This process is recursive, meaning you can nest custom objects within each other.Compare Traditional Operators in Airflow vs. DAG Factory
mainDAG Factory allows you to define workflows using YAML instead of Python, while still utilizing the same underlying Airflow operators (e.g.,
BashOperator,PythonOperator,KubernetesPodOperator).Key Differences
- Language: Traditional Airflow uses Python to declare workflows; DAG Factory uses YAML.
- Graph Topology: The resulting Airflow Graph view is identical regardless of whether you use Python or YAML, as the underlying operator logic remains the same.
- Code View: In the Airflow UI, the 'Code' view for a Python DAG shows the original Python source. For a DAG Factory DAG, the 'Code' view shows the Python file that loads the YAML.
- Troubleshooting: To mitigate the lack of direct YAML visibility in the Airflow 'Code' view, DAG Factory automatically appends the YAML content to the DAG's documentation field, making it easier to inspect the configuration directly in the Airflow UI.
Define custom Python objects in YAML using generalized object syntax
mainDAG Factory allows you to define complex Python objects (like
datetime,timedelta, or AirflowAssetobjects) directly in your YAML configuration. This is achieved using a generalized object syntax where you specify the class via a__type__key.General Syntax
__type__: The full Python import path of the class (e.g.,datetime.datetime).__args__: A list used for passing positional arguments to the class constructor.- Keyword Arguments: Any other key provided at the same level as
__type__is treated as a keyword argument or attribute for the object.
Nesting and Lists
- You can nest generalized objects to any depth to mirror complex Python object graphs.
- To define a list of objects, use
__type__: builtins.listand provide anitemskey containing the list elements.
object_name: __type__: <python.import.path.ClassName> __args__: - <positional_arg1> <keyword_arg1>: <value1>Use Airflow Params for dynamic runtime configuration
mainAirflow Params allow you to pass dynamic configuration to tasks within a DAG at runtime. This enables tasks to be flexible by using templated values that are injected during execution.
Key capabilities include:
- Defining params at both the DAG and task levels.
- Using Jinja templating to access and manipulate param values.
- Customizing task behavior without requiring code changes.
Use params when you need to reuse the same DAG with different input values or when you need to change a task's behavior dynamically during execution.