Typer, build great CLIs. Easy to code. Based on Python type hints.
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.
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.
"""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.
"""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)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)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)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)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)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)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