Skip to content

Commit e80df45

Browse files
authored
feat(cli): enhance flow display with schema rendering support (#427)
* feat: add flow schema processing pyfunction * feat: show flow schema in cli command * feat(cli): enhance flow display with schema rendering support * refactor: use Flow pymethod to get schema * refactor: simplify value type handling
1 parent 7638c43 commit e80df45

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

python/cocoindex/cli.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import asyncio
12
import click
23
import datetime
34

45
from rich.console import Console
6+
from rich.table import Table
57

68
from . import flow, lib, setting
79
from .setup import sync_setup, drop_setup, flow_names_with_setup, apply_setup_changes
@@ -56,11 +58,26 @@ def ls(show_all: bool):
5658
@click.option("--color/--no-color", default=True)
5759
def show(flow_name: str | None, color: bool):
5860
"""
59-
Show the flow spec in a readable format with colored output.
61+
Show the flow spec in a readable format with colored output,
62+
including the schema.
6063
"""
61-
fl = _flow_by_name(flow_name)
64+
flow = _flow_by_name(flow_name)
6265
console = Console(no_color=not color)
63-
console.print(fl._render_text())
66+
console.print(flow._render_text())
67+
68+
table = Table(
69+
title=f"Schema for Flow: {flow.name}",
70+
show_header=True,
71+
header_style="bold magenta"
72+
)
73+
table.add_column("Field", style="cyan")
74+
table.add_column("Type", style="green")
75+
table.add_column("Attributes", style="yellow")
76+
77+
for field_name, field_type, attr_str in flow._render_schema():
78+
table.add_row(field_name, field_type, attr_str)
79+
80+
console.print(table)
6481

6582
@cli.command()
6683
def setup():

python/cocoindex/flow.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,9 @@ def _render_text(self) -> Text:
503503
return self._format_flow(flow_dict)
504504
except json.JSONDecodeError:
505505
return Text(flow_spec_str)
506+
507+
def _render_schema(self) -> list[tuple[str, str, str]]:
508+
return self._lazy_engine_flow().get_schema()
506509

507510
def __str__(self):
508511
return str(self._render_text())

src/py/mod.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::prelude::*;
22

3+
use crate::base::schema::{FieldSchema, ValueType};
34
use crate::base::spec::VectorSimilarityMetric;
45
use crate::execution::query;
56
use crate::lib_context::{clear_lib_context, get_auth_registry, init_lib_context};
@@ -13,6 +14,7 @@ use pyo3::{exceptions::PyException, prelude::*};
1314
use pyo3_async_runtimes::tokio::future_into_py;
1415
use std::collections::btree_map;
1516
use std::fmt::Write;
17+
use std::sync::Arc;
1618

1719
mod convert;
1820
pub use convert::*;
@@ -193,6 +195,58 @@ impl Flow {
193195
Ok(())
194196
})
195197
}
198+
199+
pub fn get_schema(&self) -> Vec<(String, String, String)> {
200+
let schema = &self.0.flow.data_schema;
201+
let mut result = Vec::new();
202+
203+
fn process_fields(
204+
fields: &[FieldSchema],
205+
prefix: &str,
206+
result: &mut Vec<(String, String, String)>,
207+
) {
208+
for field in fields {
209+
let field_name = format!("{}{}", prefix, field.name);
210+
211+
let mut field_type = match &field.value_type.typ {
212+
ValueType::Basic(basic) => format!("{}", basic),
213+
ValueType::Table(t) => format!("{}", t.kind),
214+
ValueType::Struct(_) => "Struct".to_string(),
215+
};
216+
217+
if field.value_type.nullable {
218+
field_type.push('?');
219+
}
220+
221+
let attr_str = if field.value_type.attrs.is_empty() {
222+
String::new()
223+
} else {
224+
field
225+
.value_type
226+
.attrs
227+
.keys()
228+
.map(|k| k.to_string())
229+
.collect::<Vec<_>>()
230+
.join(", ")
231+
};
232+
233+
result.push((field_name.clone(), field_type, attr_str));
234+
235+
match &field.value_type.typ {
236+
ValueType::Struct(s) => {
237+
process_fields(&s.fields, &format!("{}.", field_name), result);
238+
}
239+
ValueType::Table(t) => {
240+
process_fields(&t.row.fields, &format!("{}[].", field_name), result);
241+
}
242+
ValueType::Basic(_) => {}
243+
}
244+
}
245+
}
246+
247+
process_fields(&schema.schema.fields, "", &mut result);
248+
result
249+
}
196250
}
197251

198252
#[pyclass]

0 commit comments

Comments
 (0)