"""Root typer application — command registration and banner.""" from __future__ import annotations from typing import Annotated, Optional import typer from freepik_cli import __version__ from freepik_cli.commands import config as config_cmd from freepik_cli.commands.analyze import describe_image from freepik_cli.commands.edit import expand_image, relight_image, style_transfer from freepik_cli.commands.generate import generate_icon, generate_image, generate_video from freepik_cli.commands.upscale import upscale_image, upscale_video from freepik_cli.utils.console import console, print_banner from freepik_cli.utils.config import FreepikConfig app = typer.Typer( name="freepik", help=( "[bold magenta]Freepik AI[/bold magenta] — generate images, videos, and more " "from the command line.\n\n" "[dim]Set your API key:[/dim] [cyan]export FREEPIK_API_KEY=your_key[/cyan]\n" "[dim]Get an API key:[/dim] https://www.freepik.com/api" ), rich_markup_mode="rich", no_args_is_help=True, pretty_exceptions_enable=True, pretty_exceptions_show_locals=False, pretty_exceptions_short=True, add_completion=True, ) # ── Flat commands ────────────────────────────────────────────────────────────── app.command( "generate-image", help="[bold]Generate an image[/bold] from a text prompt using AI models.", rich_help_panel="Generation", )(generate_image) app.command( "generate-video", help="[bold]Generate a video[/bold] by animating a source image using AI.", rich_help_panel="Generation", )(generate_video) app.command( "generate-icon", help="[bold]Generate an icon[/bold] from a text prompt in various styles.", rich_help_panel="Generation", )(generate_icon) app.command( "upscale-image", help="[bold]Upscale and enhance[/bold] an image using AI.", rich_help_panel="Enhancement", )(upscale_image) app.command( "upscale-video", help="[bold]Upscale a video[/bold] to higher resolution using AI.", rich_help_panel="Enhancement", )(upscale_video) app.command( "expand-image", help="[bold]Expand an image[/bold] by adding new content around its edges (outpainting).", rich_help_panel="Editing", )(expand_image) app.command( "relight", help="[bold]Relight an image[/bold] using AI-controlled lighting. [dim](Premium)[/dim]", rich_help_panel="Editing", )(relight_image) app.command( "style-transfer", help="[bold]Apply an artistic style[/bold] from one image onto another. [dim](Premium)[/dim]", rich_help_panel="Editing", )(style_transfer) app.command( "describe-image", help="[bold]Describe an image[/bold] and generate a text prompt from it.", rich_help_panel="Analysis", )(describe_image) # ── Nested config sub-app ────────────────────────────────────────────────────── app.add_typer( config_cmd.app, rich_help_panel="Settings", ) # ── Root callback ────────────────────────────────────────────────────────────── @app.callback(invoke_without_command=True) def main( ctx: typer.Context, version: Annotated[ bool, typer.Option("--version", "-v", help="Show version and exit", is_eager=True), ] = False, ) -> None: """ [bold magenta]Freepik AI[/bold magenta] — generate images, videos, icons, and more. """ cfg = FreepikConfig.load() if version: print_banner() console.print(f"[dim]Version:[/dim] [bold]{__version__}[/bold]\n") raise typer.Exit() if ctx.invoked_subcommand is None: if cfg.show_banner: print_banner() console.print(ctx.get_help()) elif cfg.show_banner and ctx.invoked_subcommand not in ("config",): print_banner()