{"id":9295,"library":"sas-airflow-provider","title":"SAS Airflow Provider","description":"The SAS Airflow Provider enables Apache Airflow users to create tasks for executing SAS Studio Flows and Jobs on a SAS Viya environment. It provides operators to interact with SAS assets, allowing for orchestration and monitoring of SAS processes within Airflow DAGs. Currently at version 0.0.23, the library is under active development with frequent updates addressing new features and improvements.","status":"active","version":"0.0.23","language":"en","source_language":"en","source_url":"https://github.com/sassoftware/sas-airflow-provider","tags":["airflow","sas","etl","data-orchestration","provider","viya"],"install":[{"cmd":"pip install sas-airflow-provider","lang":"bash","label":"Install from PyPI"}],"dependencies":[{"reason":"This is an Airflow provider, requiring Apache Airflow to function.","package":"apache-airflow","optional":false},{"reason":"Requires Python 3.7 or newer.","package":"python","optional":false}],"imports":[{"note":"SASStudioOperator supersedes SASStudioFlowOperator, which is deprecated. New functionality will only be added to SASStudioOperator.","wrong":"from sas_airflow_provider.operators.sas_studio_flow import SASStudioFlowOperator","symbol":"SASStudioOperator","correct":"from sas_airflow_provider.operators.sas_studio import SASStudioOperator"},{"symbol":"SASJobExecutionOperator","correct":"from sas_airflow_provider.operators.sas_job_execution import SASJobExecutionOperator"},{"symbol":"SASComputeCreateSessionOperator","correct":"from sas_airflow_provider.operators.sas_compute_session import SASComputeCreateSessionOperator"}],"quickstart":{"code":"import pendulum\nfrom airflow.models.dag import DAG\nfrom sas_airflow_provider.operators.sas_studio import SASStudioOperator\nimport os\n\n# NOTE: For a real deployment, configure your SAS connection in the Airflow UI.\n# (Admin -> Connections, Connection Id: 'sas_default', Connection Type: 'SAS')\n# Fill in Host, Login, Password or use 'Extra' JSON for OAuth token.\n# Example 'Extra' for OAuth: {\"token\": \"your_oauth_token_here\"}\n# Or for global variable: {\"token_variable\": \"airflow_variable_name\"}\n# The connection below is for demonstration if env vars are used for local testing.\n\n# Mock environment variables for connection for local testing (NOT PRODUCTION BEST PRACTICE)\nos.environ['AIRFLOW_CONN_SAS_DEFAULT'] = (\n    'sas://' + \n    os.environ.get('SAS_DEFAULT_LOGIN', 'user') + \n    ':' + \n    os.environ.get('SAS_DEFAULT_PASSWORD', 'password') + \n    '@' + \n    os.environ.get('SAS_DEFAULT_HOST', 'https://your-sas-viya-host.com')\n)\n\nwith DAG(\n    dag_id=\"sas_studio_flow_example\",\n    start_date=pendulum.datetime(2023, 1, 1, tz=\"UTC\"),\n    catchup=False,\n    schedule=None,\n    tags=[\"sas\", \"studio\", \"example\"],\n) as dag:\n    run_my_sas_flow = SASStudioOperator(\n        task_id=\"run_sas_studio_flow_task\",\n        path=\"/Public/my_airflow_test_flow\", # Replace with your actual SAS Studio Flow path\n        connection_id=\"sas_default\",\n        exec_type=\"flow\", # Can also be 'program' for SAS programs\n        # Optional: pass macro variables to the flow\n        # macro_variables={\"input_param\": \"airflow_value\"},\n        # Optional: retrieve SAS logs to Airflow\n        # job_exec_log=True,\n    )\n","lang":"python","description":"This quickstart demonstrates how to define a simple Airflow DAG using the `SASStudioOperator` to execute a SAS Studio Flow. Before running, you must configure a 'SAS' connection in the Airflow UI (Admin -> Connections) with `Connection Id` set to `sas_default`, providing your SAS Viya host, login, and password, or an OAuth token in the 'Extra' JSON field. For local testing, mock environment variables are included, but this is not recommended for production."},"warnings":[{"fix":"Replace `SASStudioFlowOperator` with `SASStudioOperator` in your DAG definitions. Adjust parameters as necessary, noting that `SASStudioOperator` supports both flows and programs via the `exec_type` parameter.","message":"The `SASStudioFlowOperator` is deprecated. Users should migrate to `SASStudioOperator` for all SAS Studio flow and program executions. New features will only be added to `SASStudioOperator`.","severity":"deprecated","affected_versions":"<0.0.5"},{"fix":"Set the `NO_PROXY='*'` environment variable before running Airflow in standalone mode on macOS. Example: `export NO_PROXY=\"*\"`.","message":"When running Airflow standalone on macOS, you might encounter issues with `urllib` and process forking. This can lead to connection problems with the SAS provider.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Investigate network configuration (WAF, firewalls, load balancers) for idle timeout settings. Consider re-architecting long-running SAS jobs to be initiated in the background, with Airflow separately polling for status and retrieving results to maintain active communication. Ensure relevant IPs are whitelisted in firewalls.","message":"SAS connection issues (e.g., 'Connection reset by peer') for long-running jobs are often caused by WAF/firewall timeouts or network load balancers terminating idle TCP connections. TCP keep-alive settings may not be sufficient for all network configurations.","severity":"breaking","affected_versions":"All versions"},{"fix":"Consult Airflow's security documentation. Utilize secrets backend integrations (e.g., HashiCorp Vault, AWS Secrets Manager) for production environments to manage credentials securely, or leverage the `token_variable` field in the connection's extra JSON to retrieve access tokens from global Airflow variables.","message":"Storing sensitive information (passwords, tokens) directly in Airflow connections carries security risks. Airflow connections are stored in the metadata database, which needs to be secured.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Review and adjust network device idle timeout settings. For long-running SAS jobs, explore options to send periodic keep-alive signals or refactor the Airflow task to initiate the job and then poll for its completion status in separate, shorter-lived requests. Ensure your Airflow environment's IP is whitelisted.","cause":"Network intermediaries (WAF, firewalls, load balancers) terminating seemingly idle TCP connections after a timeout, even if the SAS job is still running.","error":"requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))"},{"fix":"Verify network connectivity between your Airflow environment and the SAS Viya host, specifically to the SASLogon endpoint. Ensure that all necessary ports are open and that firewalls are not blocking the connection. Confirm correct host and certificate configurations.","cause":"Firewall rules or network configurations preventing the Airflow worker from reaching the SASLogon service or Viya environment during OAuth token exchange.","error":"SAS connection failed during OAuth token acquisition: 'Failed to establish a new connection: [Errno 111] Connection refused' or network connection reset."},{"fix":"Check Airflow scheduler logs for parsing errors related to your DAG file. Ensure the `sas-airflow-provider` package is correctly installed in the Python environment where Airflow (scheduler and workers) is running. Verify the DAG file is in the `dags_folder` specified in `airflow.cfg`.","cause":"Common causes include syntax errors in the DAG file, the DAG file not being in the configured DAGs folder, or an unhandled exception during DAG parsing. Airflow providers must also be installed in the Airflow environment.","error":"DAG not appearing in Airflow UI after deploying 'sas-airflow-provider' operators."}]}