"""Generate a presigned S3 PUT URL for a gpuq job's output tarball. Reads the rclone remote's credentials locally (never leaves this machine); the URL is a write-once capability to a single object name — safe to embed in job files that run on untrusted rented nodes. Usage: gpuq_presign.py [--hours 48] Prints the URL on stdout. """ import argparse import configparser from pathlib import Path import boto3 from botocore.config import Config ap = argparse.ArgumentParser() ap.add_argument("worker") ap.add_argument("job") ap.add_argument("--hours", type=int, default=48) ap.add_argument("--bucket", default="jspace") args = ap.parse_args() cfg = configparser.ConfigParser() cfg.read(Path.home() / ".config/rclone/rclone.conf") r = cfg["jspace"] s3 = boto3.client( "s3", endpoint_url=r["endpoint"], aws_access_key_id=r["access_key_id"], aws_secret_access_key=r["secret_access_key"], config=Config(signature_version="s3v4"), ) url = s3.generate_presigned_url( "put_object", Params={"Bucket": args.bucket, "Key": f"gpuq/{args.worker}/out/{args.job}_out.tgz"}, ExpiresIn=args.hours * 3600, ) print(url)