chen0427ok commented on code in PR #59291: URL: https://github.com/apache/airflow/pull/59291#discussion_r2611565846
########## task-sdk/src/airflow/sdk/definitions/param_config_loader.py: ########## @@ -0,0 +1,243 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Utilities for loading DAG parameter options from external configuration files.""" + +from __future__ import annotations + +import configparser +import json +from pathlib import Path +from typing import Any + + +def load_options_from_ini( + file_path: str | Path, + filter_conditions: dict[str, Any] | None = None, + key_field: str = "section", +) -> list[str]: + """ + Load dropdown options from an INI configuration file. + + This function reads an INI file and extracts option values based on the specified + parameters. It can filter sections based on key-value pairs and choose which field + to use as the option value. + + :param file_path: Path to the INI configuration file + :param filter_conditions: Optional dictionary of key-value pairs to filter sections. + Only sections where all specified keys match the given values will be included. + Example: {"TYPE": "Script"} will only include sections where TYPE=Script + :param key_field: Which field to use as the option value. Special value "section" + uses the section name itself. Otherwise, uses the value of the specified key + within each section. + :return: List of option values extracted from the INI file + :raises FileNotFoundError: If the specified file does not exist + :raises ValueError: If the INI file is malformed + + Example INI file (interfaces.ini):: + + [InterfaceA] + TYPE = Script + DESCRIPTION = Script interface A + + [InterfaceB] + TYPE = EBICS + DESCRIPTION = Electronic banking interface + + Example usage:: + + # Get all section names where TYPE=Script + options = load_options_from_ini( + "config/interfaces.ini", filter_conditions={"TYPE": "Script"}, key_field="section" + ) + # Returns: ["InterfaceA"] + + # Get all DESCRIPTION values + options = load_options_from_ini("config/interfaces.ini", key_field="DESCRIPTION") + # Returns: ["Script interface A", "Electronic banking interface"] + """ + file_path = Path(file_path) + if not file_path.exists(): + raise FileNotFoundError(f"Configuration file not found: {file_path}") Review Comment: Thanks for the review and the great suggestion! I agree that consolidating them into a single load_options_from_file function will reduce code duplication and make it easier to maintain. I'll refactor the code to merge the validation and filtering logic. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
