Skip to content

CLI

The typedframes command-line interface runs the Rust-based static checker on Python source files.

Basic usage

# Check a single file
typedframes check pipeline.py

# Check an entire directory (builds a cross-file project index)
typedframes check src/

# Check without building the project index (each file checked independently)
typedframes check src/ --no-index

# Enable untracked-dataframe warnings for bare DataFrame loads (off by default)
typedframes check src/ --strict-ingest

# Output formats
typedframes check src/ --output-format text    # default — ty-style, auto-colored in terminal
typedframes check src/ --output-format json    # machine-readable JSON
typedframes check src/ --output-format github  # GitHub Actions annotations

Supported file formats

The checker reads column information from load calls for all common formats:

# pandas
pd.read_csv("data.csv", usecols=["a", "b"])
pd.read_parquet("data.parquet", columns=["a", "b"])
pd.read_json("data.json", dtype={"a": int, "b": str})
pd.read_excel("data.xlsx", usecols=["a", "b"])

# polars
pl.read_csv("data.csv", columns=["a", "b"])
pl.read_parquet("data.parquet", columns=["a", "b"])
pl.read_json("data.json", schema={"a": int, "b": str})

Any usecols= (pandas) or columns= / schema= (polars) argument teaches the checker which columns are available, regardless of file format.

Output format

src/pipeline.py:42:8: error[unknown-column] Column 'revenue' not in OrderSchema
src/pipeline.py:57:8: error[reserved-name] Column 'user_id' renamed to 'customer_id', use 'customer_id'
src/pipeline.py:10:1: warning[untracked-dataframe] columns unknown at lint time; specify usecols= or annotate

The format matches ty and ruff: file:line:col: severity[code] message. Most editors, CI systems, and LSP clients parse this automatically. Colors are applied when the output is a terminal (TTY); piping or redirecting strips them.

Error codes

Code Meaning Default
unknown-column Column not found in schema or inferred set Always shown
reserved-name Column was renamed — use the new name Always shown
untracked-dataframe Bare DataFrame load — no column info for checker Off (use --strict-ingest)
dropped-unknown-column Dropped column doesn't exist in schema Off (use --strict-ingest)

Project-level configuration

Add to pyproject.toml to disable all warnings project-wide:

[tool.typedframes]
enabled  = true
warnings = false

typedframes.cli.main(argv=None)

Entry point for the typedframes CLI.

Source code in src/typedframes/cli.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def main(argv: list[str] | None = None) -> None:
    """Entry point for the typedframes CLI."""
    parser = argparse.ArgumentParser(prog="typedframes", description="Static analysis for DataFrame column schemas.")
    subparsers = parser.add_subparsers(dest="command")

    check_parser = subparsers.add_parser("check", help="Check Python files for column errors.")
    check_parser.add_argument("path", type=Path, help="File or directory to check.")
    check_parser.add_argument("--strict", action="store_true", help="Exit with code 1 if any errors are found.")
    check_parser.add_argument(
        "--output-format",
        choices=["text", "json", "github"],
        default="text",
        dest="output_format",
        help="Output format: text (default), json, or github (GitHub Actions annotations).",
    )
    # --json kept as a hidden alias for backward compatibility
    check_parser.add_argument(
        "--json",
        dest="output_format",
        action="store_const",
        const="json",
        help=argparse.SUPPRESS,
    )
    check_parser.add_argument("--no-index", action="store_true", help="Disable cross-file index.")
    check_parser.add_argument(
        "--no-warnings",
        action="store_true",
        help="Suppress all warnings (dropped-unknown-column and any enabled ingestion warnings).",
    )
    check_parser.add_argument(
        "--strict-ingest",
        action="store_true",
        help="Include untracked-dataframe warnings for bare DataFrame loads without usecols= or columns=.",
    )

    args = parser.parse_args(argv)

    if args.command != "check":
        parser.print_help()
        sys.exit(2)

    _run_check(args)