Skip to content

feat: migrate CLI from argparse to typer#49

Open
ambicuity wants to merge 1 commit intoSUPAIDEAS:mainfrom
ambicuity:feat/typer-cli-migration
Open

feat: migrate CLI from argparse to typer#49
ambicuity wants to merge 1 commit intoSUPAIDEAS:mainfrom
ambicuity:feat/typer-cli-migration

Conversation

@ambicuity
Copy link
Copy Markdown
Contributor

@ambicuity ambicuity commented Feb 21, 2026

Summary

Closes #38

Migrates the CLI from the Python standard-library argparse to Typer, providing richer help output (via Rich), automatic type enforcement, and coloured terminal output.

Changes

  • passifypdf/cli.py - fully rewritten with Typer: typed Annotated parameters, exists=True validation for the input file, --force/-f flag, --version/-v via eager callback, and a get_typer_app() helper
    • passifypdf/encryptpdf.py - main() now delegates to app() (the Typer instance); encrypt_pdf() is unchanged
    • tests/unittests/test_cli.py - 10 new unit tests using typer.testing.CliRunner (help, version, success, force bypass, user prompt accept/decline, missing args, non-existent input, error propagation)
    • pyproject.toml - added typer[standard]>=0.12.0 and typing_extensions>=4.0

Testing

All 14 tests pass.

- Rewrote passifypdf/cli.py using Typer with typed parameters,
  automatic input-file validation (exists=True), colored output
  via Rich, and --force/-f flag for output collision handling
- Added --version/-v flag via eager callback with importlib.metadata
- Updated passifypdf/encryptpdf.py: main() now delegates to typer app;
  encrypt_pdf() core logic is unchanged for backward compatibility
- Added 10 unit tests in tests/unittests/test_cli.py using
  typer.testing.CliRunner covering: help, version, success,
  force bypass, user prompt accept/decline, missing args,
  nonexistent input, and encrypt_pdf exception propagation
- Added typer and typing_extensions to pyproject.toml dependencies
Copilot AI review requested due to automatic review settings February 21, 2026 02:25
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the CLI from Python's standard library argparse to Typer, aiming to provide richer help output, automatic type enforcement, and colored terminal output. However, the implementation has several critical issues that need to be addressed before merging.

Changes:

  • Replaced argparse-based CLI with Typer implementation providing type-safe options and rich terminal output
  • Updated entry point in encryptpdf.py to delegate to Typer app
  • Added typer and typing-extensions dependencies
  • Created comprehensive unit tests for the new CLI

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
passifypdf/cli.py Complete rewrite from argparse to Typer with enhanced features like file existence validation and overwrite prompting
passifypdf/encryptpdf.py Updated main() entry point to delegate to Typer app instead of argparse
pyproject.toml Added typer[standard] and typing-extensions dependencies
tests/unittests/test_cli.py New comprehensive test suite covering CLI functionality including happy path, error cases, and user interaction scenarios
uv.lock Added uv package manager lock file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread passifypdf/cli.py
Comment on lines +91 to +97
logger.info(
"Congratulations!\nPDF file encrypted successfully and saved as '%s'",
output,
)
except Exception as e:
logger.error("Error: %s", e)
raise typer.Exit(code=1)
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI uses logger.info() and logger.error() but logging is never configured, so these messages won't be visible to users. The old implementation used print() to display messages to stdout/stderr. Either switch back to using typer.echo() and typer.secho() (which are Typer's recommended output methods), or add logging configuration. For a CLI tool, typer.echo() is more appropriate for user-facing messages.

Copilot uses AI. Check for mistakes.
"""Unit tests for the Typer-based CLI module."""

from pathlib import Path
from typing import Generator
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Generator type is imported but never used in the test file. Remove this unused import.

Suggested change
from typing import Generator

Copilot uses AI. Check for mistakes.
Comment thread passifypdf/cli.py
raise typer.Exit()


@app.command()
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using @app.command() creates a subcommand, which means users might need to run passifypdf encrypt --input ... instead of passifypdf --input .... This breaks backward compatibility with the documented usage in README.md (line 40) which shows direct option usage without a subcommand. To maintain backward compatibility and provide a simpler CLI, use @app.callback() instead of @app.command(), or use app.command(name="") to make it the default command that doesn't require typing "encrypt".

Suggested change
@app.command()
@app.callback()

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactoring: Migrate argparse to click or typer

2 participants