refactor: simplify CLI command logic by extracting helper functions (#13)
Tests / test_and_lint (push) Successful in 14s
Tests / test_and_lint (push) Successful in 14s
Reviewed-on: #13 Co-authored-by: Mathias <mathias2784@web.de>
This commit was merged in pull request #13.
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
def main() -> None:
|
||||
print("Hello from photools3!")
|
||||
from .cli import app
|
||||
|
||||
|
||||
def main():
|
||||
app()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
from .cli import app
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
from typing import Annotated, Any
|
||||
|
||||
import typer
|
||||
|
||||
from photools3.llm_session import LlmSessionCaptionsAndKeywords
|
||||
from photools3.photo import Photo
|
||||
|
||||
app = typer.Typer(help="PhotoTools3: A CLI for image processing.")
|
||||
|
||||
|
||||
@app.callback(invoke_without_command=True)
|
||||
def main(
|
||||
ctx: typer.Context,
|
||||
version: bool | None = typer.Option(None, "--version", is_eager=True),
|
||||
):
|
||||
"""
|
||||
Main entry point for PhotoTools3 CLI.
|
||||
"""
|
||||
if version:
|
||||
typer.echo("photools3 version 0.1.0")
|
||||
raise typer.Exit()
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
typer.echo(ctx.get_help())
|
||||
raise typer.Exit()
|
||||
|
||||
|
||||
@app.command("keywords")
|
||||
def keywords(
|
||||
file_path: Annotated[Path, typer.Argument(..., help="Path to the image file")],
|
||||
):
|
||||
"""Extract keywords from a single image."""
|
||||
if not file_path.exists():
|
||||
typer.echo(f"Error: File '{file_path}' does not exist.", err=True)
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
try:
|
||||
typer.echo(f"Processing: {file_path}")
|
||||
result = _run_keywords_extraction(file_path)
|
||||
_print_results(result)
|
||||
except Exception as e: # noqa: BLE001
|
||||
typer.echo(f"Error processing image: {e}", err=True)
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
|
||||
def _run_keywords_extraction(file_path: Path) -> Any:
|
||||
"""Handles the core logic of loading the photo and calling the LLM."""
|
||||
session = LlmSessionCaptionsAndKeywords()
|
||||
photo = Photo(file_path)
|
||||
return session.call([photo])
|
||||
|
||||
|
||||
def _print_results(result: Any) -> None:
|
||||
"""Formats and prints the extraction results to the console."""
|
||||
typer.echo("\n--- Results ---")
|
||||
if isinstance(result, dict):
|
||||
caption = result.get("caption", "No caption found.")
|
||||
tags = result.get("tags", [])
|
||||
typer.echo(f"Caption: {caption}")
|
||||
typer.echo(f"Tags: {', '.join(tags)}")
|
||||
else:
|
||||
typer.echo(str(result))
|
||||
typer.echo("---------------")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
@@ -129,6 +129,7 @@ class LlmSessionCaptionsAndKeywords(LlmSession):
|
||||
" - Do not add any other text outside of this JSON format!\n"
|
||||
"- When writing captions, ONLY describe what is visible on the photo. Do not interpret!\n"
|
||||
"- Only use keywords from the keyword list, appended below.\n"
|
||||
"- Answer in German.\n"
|
||||
"\n"
|
||||
"## Keyword list"
|
||||
"\n"
|
||||
|
||||
Reference in New Issue
Block a user