Skip to content

Commit 54072f7

Browse files
gcampclaude
andcommitted
Add --json output option for scripting/agent use
- Add --json flag for structured JSONL output - Enhance help with examples and format documentation - Bump version to 1.2.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 5af6223 commit 54072f7

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

image_upload_transit.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import uuid
1818
from pathlib import Path
1919

20-
VERSION = "1.1.0"
20+
VERSION = "1.2.0"
2121
CONFIG_DIR = Path.home() / ".config" / "image-upload-transit"
2222

2323
IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".avif", ".heic", ".bmp", ".tiff", ".tif", ".svg"}
@@ -234,22 +234,58 @@ def main() -> int:
234234
parser = argparse.ArgumentParser(
235235
description="Upload images/videos to GCS with short transitapp.com URLs",
236236
prog="image-upload-transit",
237+
epilog="""
238+
Examples:
239+
%(prog)s image.png Upload a single image
240+
%(prog)s *.jpg Upload multiple images
241+
%(prog)s -s screenshot.png Upload to staging environment
242+
%(prog)s --json photo.jpg Output result as JSON (for scripting/agents)
243+
244+
JSON Output Format (--json):
245+
Success: {"file": "image.png", "url": "https://img.transitapp.com/abc123.png", "success": true}
246+
Error: {"file": "bad.txt", "error": "Unsupported file type", "success": false}
247+
Multiple files produce one JSON object per line (JSONL format).
248+
249+
Supported formats: images (jpg, png, gif, webp, avif, heic, bmp, tiff, svg) and videos (mp4, mov, webm).
250+
Size limits: 25MB for images, 100MB for videos.
251+
""",
252+
formatter_class=argparse.RawDescriptionHelpFormatter,
237253
)
238254
parser.add_argument("files", nargs="*", help="Files to upload")
239255
parser.add_argument("-s", "--staging", action="store_true", help="Use staging environment")
240256
parser.add_argument("-v", "--version", action="version", version=f"%(prog)s {VERSION}")
257+
parser.add_argument("--json", action="store_true", help="Output results as JSON (one object per line, for scripting/agents)")
241258
parser.add_argument("--refresh-credentials", action="store_true", help="Force re-fetch credentials from 1Password")
242259

243260
args = parser.parse_args()
244261

262+
def output_result(file: str, url: str = None, err: str = None) -> None:
263+
if args.json:
264+
result = {"file": file, "success": err is None}
265+
if url:
266+
result["url"] = url
267+
if err:
268+
result["error"] = err
269+
print(json.dumps(result))
270+
elif err:
271+
error(err)
272+
else:
273+
success(f"{file} -> {url}")
274+
245275
if args.refresh_credentials and not args.files:
246276
try:
247277
get_credentials(is_staging=args.staging, force_refresh=True)
248278
env_name = "staging" if args.staging else "production"
249-
success(f"Credentials refreshed for {env_name}")
279+
if args.json:
280+
print(json.dumps({"action": "refresh_credentials", "environment": env_name, "success": True}))
281+
else:
282+
success(f"Credentials refreshed for {env_name}")
250283
return 0
251284
except CredentialsError as e:
252-
error(str(e))
285+
if args.json:
286+
print(json.dumps({"action": "refresh_credentials", "error": str(e), "success": False}))
287+
else:
288+
error(str(e))
253289
return 2
254290

255291
if not args.files:
@@ -262,19 +298,22 @@ def main() -> int:
262298
try:
263299
credentials = get_credentials(is_staging=args.staging, force_refresh=args.refresh_credentials)
264300
except CredentialsError as e:
265-
error(str(e))
301+
if args.json:
302+
print(json.dumps({"error": str(e), "success": False}))
303+
else:
304+
error(str(e))
266305
return 2
267306

268307
exit_code = 0
269308
for filepath in args.files:
270309
try:
271310
url = upload_file(filepath, bucket, base_url, credentials)
272-
success(f"{filepath} -> {url}")
311+
output_result(filepath, url=url)
273312
except ValueError as e:
274-
error(str(e))
313+
output_result(filepath, err=str(e))
275314
exit_code = 1
276315
except CredentialsError as e:
277-
error(str(e))
316+
output_result(filepath, err=str(e))
278317
return 2
279318

280319
return exit_code

0 commit comments

Comments
 (0)