CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-typer

Typer, build great CLIs. Easy to code. Based on Python type hints.

Overview
Eval results
Files

file-handling.mddocs/

File Handling

Specialized file type classes for handling different types of file I/O operations in CLI applications. These classes provide type hints and specialized behavior for file parameters.

Capabilities

Text File Types

File type classes for handling text files with different access modes.

class FileText(io.TextIOWrapper):
    """
    Text file type for reading text files.
    
    This class extends io.TextIOWrapper and is used as a type hint
    for CLI parameters that should accept text files for reading.
    """

class FileTextWrite(FileText):
    """
    Text file type for writing text files.
    
    This class extends FileText and is used as a type hint
    for CLI parameters that should accept text files for writing.
    """

Binary File Types

File type classes for handling binary files with different access modes.

class FileBinaryRead(io.BufferedReader):
    """
    Binary file type for reading binary files.
    
    This class extends io.BufferedReader and is used as a type hint
    for CLI parameters that should accept binary files for reading.
    """

class FileBinaryWrite(io.BufferedWriter):
    """
    Binary file type for writing binary files.
    
    This class extends io.BufferedWriter and is used as a type hint
    for CLI parameters that should accept binary files for writing.
    """

Usage Examples

Text File Processing

import typer
from typer import FileText, FileTextWrite

def process_text(
    input_file: FileText = typer.Argument(..., help="Input text file"),
    output_file: FileTextWrite = typer.Option("output.txt", "--output", "-o", help="Output text file")
):
    """Process a text file and write results to another text file."""
    content = input_file.read()
    processed = content.upper()  # Example processing
    output_file.write(processed)
    
    typer.echo(f"Processed {input_file.name} -> {output_file.name}")

if __name__ == "__main__":
    typer.run(process_text)

Binary File Operations

import typer
from typer import FileBinaryRead, FileBinaryWrite

def copy_binary(
    source: FileBinaryRead = typer.Argument(..., help="Source binary file"),
    dest: FileBinaryWrite = typer.Argument(..., help="Destination binary file")
):
    """Copy a binary file to another location."""
    while True:
        chunk = source.read(8192)  # Read in 8KB chunks
        if not chunk:
            break
        dest.write(chunk)
    
    typer.echo(f"Copied {source.name} -> {dest.name}")

if __name__ == "__main__":
    typer.run(copy_binary)

File Type with Standard Input/Output

import typer
import sys
from typer import FileText, FileTextWrite

def filter_lines(
    input_file: FileText = typer.Option(sys.stdin, "--input", "-i", help="Input file (default: stdin)"),
    output_file: FileTextWrite = typer.Option(sys.stdout, "--output", "-o", help="Output file (default: stdout)"),
    pattern: str = typer.Option("", "--pattern", "-p", help="Pattern to filter")
):
    """Filter lines from input file that contain the pattern."""
    for line in input_file:
        if pattern in line:
            output_file.write(line)

if __name__ == "__main__":
    typer.run(filter_lines)

File Processing with Context Management

import typer
from pathlib import Path
from typer import FileText, FileTextWrite
from typing import Optional

def merge_files(
    files: list[Path] = typer.Argument(..., help="Files to merge"),
    output: Optional[FileTextWrite] = typer.Option(None, "--output", "-o", help="Output file")
):
    """Merge multiple text files into one."""
    output_file = output or sys.stdout
    
    for file_path in files:
        with open(file_path, 'r') as f:
            content = f.read()
            output_file.write(f"=== {file_path} ===\n")
            output_file.write(content)
            output_file.write("\n\n")
    
    if output:
        typer.echo(f"Merged {len(files)} files to {output.name}")
    else:
        typer.echo(f"Merged {len(files)} files to stdout")

if __name__ == "__main__":
    typer.run(merge_files)

File Encoding and Error Handling

import typer
from typer import FileText, FileTextWrite

def convert_encoding(
    input_file: FileText = typer.Argument(..., help="Input file"),
    output_file: FileTextWrite = typer.Argument(..., help="Output file"),
    input_encoding: str = typer.Option("utf-8", help="Input file encoding"),
    output_encoding: str = typer.Option("utf-8", help="Output file encoding")
):
    """Convert file encoding."""
    try:
        # Read with specified input encoding
        with open(input_file.name, 'r', encoding=input_encoding) as f:
            content = f.read()
        
        # Write with specified output encoding
        with open(output_file.name, 'w', encoding=output_encoding) as f:
            f.write(content)
            
        typer.echo(f"Converted {input_file.name} from {input_encoding} to {output_encoding}")
        
    except UnicodeDecodeError as e:
        typer.echo(f"Error reading file with {input_encoding} encoding: {e}", err=True)
        raise typer.Exit(1)
    except UnicodeEncodeError as e:
        typer.echo(f"Error writing file with {output_encoding} encoding: {e}", err=True)
        raise typer.Exit(1)

if __name__ == "__main__":
    typer.run(convert_encoding)

Advanced File Parameter Configuration

import typer
from pathlib import Path
from typer import FileText, FileTextWrite

def process_config(
    config_file: FileText = typer.Option(
        ...,
        "--config", "-c",
        exists=True,
        readable=True,
        help="Configuration file"
    ),
    output_file: FileTextWrite = typer.Option(
        "result.txt",
        "--output", "-o", 
        writable=True,
        help="Output file"
    ),
    log_file: FileTextWrite = typer.Option(
        None,
        "--log",
        writable=True,
        help="Log file (optional)"
    )
):
    """Process configuration with file validation."""
    import json
    
    try:
        config = json.load(config_file)
        typer.echo(f"Loaded config from {config_file.name}")
        
        # Process configuration
        result = {"processed": True, "config": config}
        json.dump(result, output_file, indent=2)
        
        if log_file:
            from datetime import datetime
            log_file.write(f"Processed config at {datetime.now()}\n")
            
    except json.JSONDecodeError as e:
        typer.echo(f"Invalid JSON in config file: {e}", err=True)
        raise typer.Exit(1)

if __name__ == "__main__":
    typer.run(process_config)

Streaming File Processing

import typer
from typer import FileText, FileTextWrite

def process_large_file(
    input_file: FileText = typer.Argument(..., help="Large input file"),
    output_file: FileTextWrite = typer.Argument(..., help="Output file"),
    chunk_size: int = typer.Option(1024, help="Processing chunk size")
):
    """Process large files in chunks to manage memory."""
    processed_lines = 0
    
    while True:
        lines = input_file.readlines(chunk_size)
        if not lines:
            break
            
        # Process chunk
        processed_chunk = ''.join(line.strip() + '\n' for line in lines if line.strip())
        output_file.write(processed_chunk)
        
        processed_lines += len(lines)
        if processed_lines % 1000 == 0:
            typer.echo(f"Processed {processed_lines} lines...")
    
    typer.echo(f"Processing complete. Total lines: {processed_lines}")

if __name__ == "__main__":
    typer.run(process_large_file)

Install with Tessl CLI

npx tessl i tessl/pypi-typer

docs

color-constants.md

core-application.md

file-handling.md

index.md

parameter-configuration.md

terminal-utilities.md

testing-support.md

tile.json