XD-DENG commented on a change in pull request #12704:
URL: https://github.com/apache/airflow/pull/12704#discussion_r532818688



##########
File path: airflow/cli/simple_table.py
##########
@@ -14,11 +14,78 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+import json
+from typing import Any, Callable, Dict, List, Optional, Union
 
+import yaml
 from rich.box import ASCII_DOUBLE_HEAD
+from rich.console import Console
+from rich.syntax import Syntax
 from rich.table import Table
 
 
+class AirflowConsole(Console):
+    """Airflow rich console"""
+
+    def print_as_json(self, data: Dict):
+        """Renders dict as json text representation"""
+        json_content = json.dumps(data)
+        self.print(Syntax(json_content, "json", theme="ansi_dark"), 
soft_wrap=True)
+
+    def print_as_yaml(self, data: Dict):
+        """Renders dict as yaml text representation"""
+        yaml_content = yaml.dump(data)
+        self.print(Syntax(yaml_content, "yaml", theme="ansi_dark"), 
soft_wrap=True)
+
+    def print_as_table(self, data: List[Dict]):
+        """Renders list of dictionaries as table"""
+        if not data:
+            self.print("No data found")
+            return
+
+        table = SimpleTable(
+            show_header=True,
+        )
+        for col in data[0].keys():
+            table.add_column(col)
+
+        for row in data:
+            table.add_row(*[str(d) for d in row.values()])
+        self.print(table)
+
+    def _normalize_data(self, value: Any, output: str) -> Union[list, str, 
dict]:
+        if isinstance(value, (tuple, list)):
+            if output == "table":
+                return ",".join(self._normalize_data(x, output) for x in value)
+            return [self._normalize_data(x, output) for x in value]
+        if isinstance(value, dict) and output != "table":
+            return {k: self._normalize_data(v, output) for k, v in 
value.items()}
+        return str(value)
+
+    def print_as(self, data: List[Union[Dict, Any]], output: str, mapper: 
Optional[Callable] = None):
+        """Prints provided using format specified by output argument"""
+        output_to_renderer = {
+            "json": self.print_as_json,
+            "yaml": self.print_as_yaml,
+            "table": self.print_as_table,
+        }
+        renderer = output_to_renderer.get(output)
+        if not renderer:
+            raise ValueError(
+                f"Unknown formatter: {output}. Allowed options: 
{list(output_to_renderer.keys())}"
+            )
+
+        if not all(isinstance(d, dict) for d in data) and not mapper:
+            raise ValueError("To tabulate non-dictionary data you need to 
provider `mapper` function")

Review comment:
       ```suggestion
               raise ValueError("To tabulate non-dictionary data you need to 
provide `mapper` function")
   ```

##########
File path: docs/usage-cli.rst
##########
@@ -174,3 +174,40 @@ You will see a similar result as in the screenshot below.
 .. figure:: img/usage_cli_imgcat.png
 
     Preview of DAG in iTerm2
+
+Formatting commands output
+--------------------------
+
+Some Airflow commands like ``dags list`` or ``tasks states-for-dag-run`` 
support ``--output`` flag which allow users

Review comment:
       ```suggestion
   Some Airflow commands like ``airflow dags list`` or ``airflow tasks 
states-for-dag-run`` support ``--output`` flag which allow users
   ```
   
   This is really minor difference. But I'm trying to think from a 100% newbie 
perspective: "here is the command, I can simply copy and paste. Oops, why it 
doesn't work".

##########
File path: UPDATING.md
##########
@@ -52,6 +52,39 @@ assists users migrating to a new version.
 
 ## Master
 
+### Changes to output argument in commands
+
+Instead of using [tabulate](https://pypi.org/project/tabulate/) to render 
commands output
+we use [rich](https://github.com/willmcgugan/rich). Due to this change the 
`--output` argument
+will no longer accept formats of tabulate tables. Instead it accepts:
+
+- `table` - will render the output in predefined table
+- `json` - will render the output as a json
+- `yaml` - will render the output as yaml
+
+By doing this we increased consistency and gave users possibility to 
manipulate the
+output programmatically (when using json or yaml).
+
+Affected commands:
+
+- `airflow dags list`
+- `airflow dags report`
+- `airflow dags list-runs`
+- `airflow dags list-jobs`
+- `airflow connections list`
+- `airflow connections get`
+- `airflow pools list`
+- `airflow pools get`
+- `airflow pools set`
+- `airflow pools delete`
+- `airflow pools export`
+- `airflow role list`
+- `airflow providers list`
+- `airflow providers get`
+- `airflow tasks states-for-dag-run`
+- `airflow users list`
+- `airflow variables list`

Review comment:
       `airflow pools import` and `airflow providers hooks` should be in this 
list as well?




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to