Files
Copies/batch_status.py
T
2026-08-20 15:18:08 +02:00

94 lines
2.9 KiB
Python

from __future__ import annotations
import argparse
from collections.abc import Sequence
from pathlib import Path
from google import genai
import config
from copienator import (
CliError,
ExitCode,
atomic_write_bytes,
execute,
standard_parser,
)
def _client():
if not config.API_KEY:
raise CliError("GEMINI_API_KEY is not configured")
return genai.Client(api_key=config.API_KEY)
def list_jobs(*, client=None) -> ExitCode:
client = client or _client()
print("Fetching recent batch jobs...")
jobs = list(client.batches.list())
for job in jobs:
state = job.state.name if hasattr(job.state, "name") else job.state
print(f"{job.name}: {state}")
if getattr(job, "display_name", None):
print(f" Display name: {job.display_name}")
if state == "JOB_STATE_FAILED" and getattr(job, "error", None):
print(f" Error: {job.error}")
destination = getattr(job, "dest", None)
if state == "JOB_STATE_SUCCEEDED" and getattr(
destination, "file_name", None
):
print(f" Output file: {destination.file_name}")
if not jobs:
print("No batch jobs found.")
return ExitCode.SUCCESS
def download_job(
job_name: str,
*,
output: Path | None = None,
client=None,
) -> ExitCode:
client = client or _client()
job = client.batches.get(name=job_name)
state = job.state.name if hasattr(job.state, "name") else job.state
print(f"State: {state}")
if state != "JOB_STATE_SUCCEEDED":
if state == "JOB_STATE_FAILED" and getattr(job, "error", None):
print(f"Error: {job.error}")
return ExitCode.PARTIAL
destination = getattr(job, "dest", None)
file_name = getattr(destination, "file_name", None)
if not file_name:
print("Job succeeded but no output file was found.")
return ExitCode.PARTIAL
payload = client.files.download(file=file_name)
output_path = output or Path(f"results_{job_name.replace('/', '_')}.jsonl")
atomic_write_bytes(output_path, payload)
print(f"Saved batch results to {output_path}")
return ExitCode.SUCCESS
def build_parser() -> argparse.ArgumentParser:
parser = standard_parser("List or download Gemini correction batch jobs")
parser.add_argument("--download", metavar="JOB_NAME")
parser.add_argument("--output", type=Path, help="Downloaded JSONL destination")
return parser
def main(argv: Sequence[str] | None = None) -> int:
parser = build_parser()
def handle(args: argparse.Namespace) -> ExitCode:
if args.output is not None and not args.download:
raise CliError("--output requires --download", ExitCode.INVALID_ARGUMENTS)
if args.download:
return download_job(args.download, output=args.output)
return list_jobs()
return execute(parser, argv, handle)
if __name__ == "__main__":
raise SystemExit(main())