Commit f55aadd0 authored by Jan Reimes's avatar Jan Reimes
Browse files

refactor(cli, config, http, router): improve argument handling and validation

* Change OutputFile from Option to Argument for better CLI usage.
* Remove unused warning for --force flag in convert command.
* Add field validator for Adobe client credentials in ProviderSettings.
* Introduce create_uncached_client function for non-cached HTTP requests.
parent d5cf255f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ import typer
APP_NAME_UPPERCASE = "PDF_REMOTE_CONVERTER"

InputFile = Annotated[Path, typer.Argument(help="Input Office file to convert")]
OutputFile = Annotated[Path, typer.Option("--output", "-o", help="Output PDF file")]
OutputFile = Annotated[Path, typer.Argument(help="Output PDF file path")]
Provider = Annotated[
    str | None,
    typer.Option("--provider", "-p", help="Provider: cloudconvert, adobe, zamzar"),
+0 −3
Original line number Diff line number Diff line
@@ -52,9 +52,6 @@ def convert(
            typer.echo(f"Error: {exc}", err=True)
            raise typer.Exit(1) from exc

    if force:
        logger.warning("--force: Bypassing HTTP cache is not yet implemented")

    try:
        result = convert_with_failover(Path(input_file), Path(output_file), providers, force=force)
        typer.echo(f"Converted to {output_file} using {result.provider}")
+14 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ from __future__ import annotations

from pathlib import Path

from pydantic import Field
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


@@ -40,3 +40,16 @@ class ProviderSettings(BaseSettings):
        if self.adobe_client_id and self.adobe_client_secret:
            return (self.adobe_client_id, self.adobe_client_secret)
        return None

    @field_validator("adobe_client_secret")
    @classmethod
    def adobe_requires_both_credentials(cls, v: str | None, info) -> str | None:
        """Validate Adobe requires both client_id and client_secret."""
        client_id = info.data.get("adobe_client_id")
        if client_id and not v:
            msg = "Adobe requires both ADOBE_CLIENT_ID and ADOBE_CLIENT_SECRET"
            raise ValueError(msg)
        if v and not client_id:
            msg = "Adobe requires both ADOBE_CLIENT_ID and ADOBE_CLIENT_SECRET"
            raise ValueError(msg)
        return v
+6 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ from __future__ import annotations

from pathlib import Path

import httpx
from hishel import CacheOptions, SpecificationPolicy, SyncSqliteStorage
from hishel.httpx import SyncCacheClient

@@ -22,3 +23,8 @@ def create_cached_client(cache_dir: Path | None = None) -> SyncCacheClient:
    storage = SyncSqliteStorage(database_path=resolved_cache_dir / "http_cache.sqlite")

    return SyncCacheClient(storage=storage, policy=policy)


def create_uncached_client() -> httpx.Client:
    """Create an HTTP client without caching (for --force flag)."""
    return httpx.Client()
+21 −1
Original line number Diff line number Diff line
@@ -78,7 +78,27 @@ def convert_with_failover(
    providers: list[ProviderBackend],
    force: bool = False,
) -> ConversionResult:
    """Convert with automatic failover to the next provider on error."""
    """Convert with automatic failover to the next provider on error.

    Args:
        input_path: Input Office file to convert.
        output_path: Output PDF file path.
        providers: List of providers to try in order.
        force: If True, bypass HTTP cache (use fresh API calls).

    Returns:
        ConversionResult with output file path, provider name, cache status, and credits used.

    Raises:
        AllProvidersFailedError: When all providers fail conversion.
    """
    from pdf_remote_converter.http import create_uncached_client

    # If force flag is set, use uncached HTTP client for all providers
    if force:
        for provider in providers:
            provider.http_client = create_uncached_client()

    errors: list[tuple[str, Exception]] = []
    for provider in providers:
        try: