f24d138ab4
Sophisticated Python CLI for generating and manipulating images and video via the Freepik API, built with typer + rich. Commands: - generate-image: text-to-image with 8 models (flux-2-pro, mystic, seedream, etc.) - generate-video: image-to-video with 7 models (kling, minimax, runway, etc.) - generate-icon: text-to-icon in solid/outline/color/flat/sticker styles - upscale-image: 3 modes (precision-v2, precision, creative) + 2x/4x scale - upscale-video: standard/turbo modes - expand-image: outpainting with per-side pixel offsets - relight: AI-controlled relighting (Premium) - style-transfer: artistic style application (Premium) - describe-image: reverse-engineer an image into a prompt - config set/get/show/reset: configuration management Features: Rich Live polling panel, exponential backoff, --wait/--no-wait, auto-timestamped output filenames, streaming download with progress bar, FREEPIK_API_KEY env var support, venv-based setup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
"""config set/get/show/reset commands."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Annotated, Optional
|
|
|
|
import typer
|
|
from rich.prompt import Confirm
|
|
|
|
from freepik_cli.utils.config import CONFIG_FILE, FreepikConfig
|
|
from freepik_cli.utils.console import console, print_config_table, print_config_toml, print_error, print_warning
|
|
|
|
app = typer.Typer(
|
|
name="config",
|
|
help="[bold]Manage[/bold] Freepik CLI configuration.",
|
|
rich_markup_mode="rich",
|
|
no_args_is_help=True,
|
|
)
|
|
|
|
|
|
@app.command("show")
|
|
def config_show(
|
|
toml: Annotated[
|
|
bool,
|
|
typer.Option("--toml", help="Output as TOML syntax instead of a table"),
|
|
] = False,
|
|
) -> None:
|
|
"""[bold]Show[/bold] all current configuration values."""
|
|
config = FreepikConfig.load()
|
|
d = config.to_display_dict()
|
|
if toml:
|
|
print_config_toml(d)
|
|
else:
|
|
print_config_table(d)
|
|
console.print(f"\n[dim]Config file:[/dim] {CONFIG_FILE}")
|
|
|
|
|
|
@app.command("get")
|
|
def config_get(
|
|
key: Annotated[str, typer.Argument(help="Config key to retrieve")],
|
|
) -> None:
|
|
"""[bold]Get[/bold] the value of a single configuration key."""
|
|
config = FreepikConfig.load()
|
|
d = config.to_display_dict()
|
|
if key not in d:
|
|
print_error(
|
|
f"Unknown config key: '{key}'",
|
|
hint=f"Run [cyan]freepik config show[/cyan] to see all available keys.",
|
|
)
|
|
raise typer.Exit(1)
|
|
|
|
value = d[key]
|
|
if key == "api_key" and value:
|
|
masked = f"{'*' * 8}{str(value)[-4:]}"
|
|
console.print(f"[dim]{key}[/dim] = [bold]{masked}[/bold] [dim](masked)[/dim]")
|
|
elif value is None:
|
|
console.print(f"[dim]{key}[/dim] = [dim]not set[/dim]")
|
|
else:
|
|
console.print(f"[dim]{key}[/dim] = [bold]{value}[/bold]")
|
|
|
|
|
|
@app.command("set")
|
|
def config_set(
|
|
key: Annotated[str, typer.Argument(help="Config key to update")],
|
|
value: Annotated[str, typer.Argument(help="New value")],
|
|
) -> None:
|
|
"""
|
|
[bold]Set[/bold] a configuration value.
|
|
|
|
[dim]Examples:[/dim]
|
|
freepik config set default_image_model mystic
|
|
freepik config set default_output_dir ~/images
|
|
freepik config set poll_timeout 300
|
|
|
|
[dim]Note:[/dim] The API key is never saved to disk. Use the
|
|
[cyan]FREEPIK_API_KEY[/cyan] environment variable instead.
|
|
"""
|
|
config = FreepikConfig.load()
|
|
try:
|
|
config.set_value(key, value)
|
|
console.print(f"[success]✓[/success] Set [cyan]{key}[/cyan] = [bold]{value}[/bold]")
|
|
console.print(f"[dim]Saved to:[/dim] {CONFIG_FILE}")
|
|
except ValueError as exc:
|
|
print_error(str(exc))
|
|
raise typer.Exit(1)
|
|
|
|
|
|
@app.command("reset")
|
|
def config_reset(
|
|
yes: Annotated[
|
|
bool,
|
|
typer.Option("--yes", "-y", help="Skip confirmation prompt"),
|
|
] = False,
|
|
) -> None:
|
|
"""[bold]Reset[/bold] all configuration to defaults."""
|
|
if not yes:
|
|
confirmed = Confirm.ask(
|
|
"[warning]Reset all configuration to defaults?[/warning]",
|
|
console=console,
|
|
default=False,
|
|
)
|
|
if not confirmed:
|
|
console.print("[dim]Aborted.[/dim]")
|
|
return
|
|
|
|
if CONFIG_FILE.exists():
|
|
CONFIG_FILE.unlink()
|
|
console.print(f"[success]✓[/success] Configuration reset. Deleted: [path]{CONFIG_FILE}[/path]")
|
|
else:
|
|
print_warning("No config file found — already at defaults.")
|
|
|
|
|
|
@app.command("path")
|
|
def config_path() -> None:
|
|
"""Show the path to the configuration file."""
|
|
console.print(f"[path]{CONFIG_FILE}[/path]")
|
|
if CONFIG_FILE.exists():
|
|
console.print("[dim](file exists)[/dim]")
|
|
else:
|
|
console.print("[dim](file does not exist — using defaults)[/dim]")
|