Skip to content

Commit 19641d9

Browse files
committed
chore: Update json mode implementation on CLI and add additional support
1 parent e541c40 commit 19641d9

13 files changed

Lines changed: 79 additions & 51 deletions

File tree

src/together/lib/cli/api/endpoints/hardware.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
from __future__ import annotations
22

33
import re
4-
import json as json_lib
54
from typing import Any, Dict, List
65

76
import click
87
from tabulate import tabulate
98

9+
from rich import print_json
1010
from together import Together, omit
11+
from together._utils._json import openapi_dumps
1112
from together.types import EndpointListHardwareResponse
1213
from together.lib.cli.api._utils import handle_api_errors
13-
from together.lib.utils.serializer import datetime_serializer
1414
from together.lib.cli.api.endpoints._utils import handle_endpoint_api_errors
1515

1616

@@ -36,8 +36,7 @@ def hardware(client: Together, model: str | None, json: bool, available: bool) -
3636
if hardware.availability is not None and hardware.availability.status == "available"
3737
]
3838
if json:
39-
json_output = [hardware.model_dump() for hardware in hardware_options.data]
40-
click.echo(json_lib.dumps(json_output, default=datetime_serializer, indent=2))
39+
print_json(openapi_dumps(hardware_options.data).decode("utf-8"))
4140
else:
4241
_format_hardware_options(hardware_options, show_availability=model is not None)
4342

src/together/lib/cli/api/endpoints/list.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from __future__ import annotations
22

3-
import json as json_lib
43
from typing import Literal
54

65
import click
76

7+
from rich import print_json
8+
from together._utils._json import openapi_dumps
89
from together import Together, omit
910
from together.lib.cli.api._utils import handle_api_errors
10-
from together.lib.utils.serializer import datetime_serializer
1111
from together.lib.cli.api.endpoints._utils import handle_endpoint_api_errors
1212

1313

@@ -49,11 +49,7 @@ def list(
4949
)
5050

5151
if json:
52-
click.echo(
53-
json_lib.dumps(
54-
[endpoint.model_dump() for endpoint in endpoints.data], default=datetime_serializer, indent=2
55-
)
56-
)
52+
print_json(openapi_dumps(endpoints.data).decode("utf-8"))
5753
return
5854

5955
if not endpoints:

src/together/lib/cli/api/endpoints/retrieve.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from together import Together
44
from together.lib.cli.api._utils import handle_api_errors
5-
from together.lib.utils.serializer import datetime_serializer
5+
from rich import print_json
6+
from together._utils._json import openapi_dumps
67
from together.lib.cli.api.endpoints._utils import handle_endpoint_api_errors
78

89

@@ -18,8 +19,6 @@ def retrieve(ctx: click.Context, endpoint_id: str, json: bool) -> None:
1819

1920
endpoint = client.endpoints.retrieve(endpoint_id)
2021
if json:
21-
import json as json_lib
22-
23-
click.echo(json_lib.dumps(endpoint.model_dump(), indent=2, default=datetime_serializer))
22+
print_json(openapi_dumps(endpoint.model_dump()).decode("utf-8"))
2423
else:
2524
ctx.obj.print_endpoint(endpoint)

src/together/lib/cli/api/endpoints/start.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from together import Together
66
from together.lib.cli.api._utils import handle_api_errors
7-
from together.lib.utils.serializer import datetime_serializer
7+
from rich import print_json
8+
from together._utils._json import openapi_dumps
89
from together.lib.cli.api.endpoints._utils import handle_endpoint_api_errors
910

1011

@@ -20,7 +21,7 @@ def start(client: Together, endpoint_id: str, wait: bool, json: bool) -> None:
2021
response = client.endpoints.update(endpoint_id, state="STARTED")
2122

2223
if json:
23-
click.echo(json_lib.dumps(response.model_dump(), default=datetime_serializer, indent=2))
24+
print_json(openapi_dumps(response.model_dump()).decode("utf-8"))
2425
return
2526

2627
click.echo("Successfully marked endpoint as starting", err=True)

src/together/lib/cli/api/endpoints/update.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
from together import Together
1010
from together.lib.cli.api._utils import handle_api_errors
11-
from together.lib.utils.serializer import datetime_serializer
11+
from rich import print_json
12+
from together._utils._json import openapi_dumps
1213
from together.lib.cli.api.endpoints._utils import handle_endpoint_api_errors
1314

1415

@@ -69,7 +70,7 @@ def update(
6970
response = client.endpoints.update(endpoint_id, **kwargs)
7071

7172
if json:
72-
click.echo(json_lib.dumps(response.model_dump(), default=datetime_serializer, indent=2))
73+
print_json(openapi_dumps(response.model_dump()).decode("utf-8"))
7374
return
7475

7576
# Print what was updated

src/together/lib/cli/api/evals/list.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from together import Together, omit
77
from together.lib.cli.api._utils import handle_api_errors
8+
from rich import print_json
9+
from together._utils._json import openapi_dumps
810

911

1012
@click.command()
@@ -18,19 +20,25 @@
1820
type=int,
1921
help="Limit number of results (max 100).",
2022
)
23+
@click.option("--json", is_flag=True, help="Print output in JSON format")
2124
@click.pass_context
2225
@handle_api_errors("Evals")
2326
def list(
2427
ctx: click.Context,
2528
status: Union[Literal["pending", "queued", "running", "completed", "error", "user_error"], None],
2629
limit: Union[int, None],
30+
json: bool,
2731
) -> None:
2832
"""List evals"""
2933

3034
client: Together = ctx.obj
3135

3236
response = client.evals.list(status=status or omit, limit=limit or omit)
3337

38+
if json:
39+
print_json(openapi_dumps(response).decode("utf-8"))
40+
return
41+
3442
display_list: List[Dict[str, Any]] = []
3543
for job in response:
3644
if job.parameters:
Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
1-
import json
2-
1+
from typing import Any
32
import click
43

54
from together import Together
65
from together.lib.cli.api._utils import handle_api_errors
7-
from together.lib.utils.serializer import datetime_serializer
6+
from rich import print_json, print
7+
from together._utils._json import openapi_dumps
88

99

1010
@click.command()
1111
@click.pass_context
1212
@click.argument("evaluation_id", type=str, required=True)
13+
@click.option("--json", is_flag=True, help="Print output in JSON format")
1314
@handle_api_errors("Evals")
14-
def retrieve(ctx: click.Context, evaluation_id: str) -> None:
15+
def retrieve(ctx: click.Context, evaluation_id: str, json: bool) -> None:
1516
"""Get details of a specific evaluation job"""
1617

1718
client: Together = ctx.obj
1819

1920
response = client.evals.retrieve(evaluation_id)
2021

21-
click.echo(json.dumps(response.model_dump(exclude_none=True), default=datetime_serializer, indent=4))
22+
if json:
23+
print_json(openapi_dumps(response.model_dump(exclude_none=True)).decode("utf-8"))
24+
else:
25+
print_dict(response.to_dict())
26+
27+
28+
def print_dict(data: Any, indent: int = 0) -> None:
29+
if isinstance(data, dict):
30+
for key, value in data.items():
31+
if isinstance(value, dict):
32+
print(f"{' ' * indent}[bold dim]{key}:[/bold dim]")
33+
print_dict(value, indent=indent+2)
34+
elif isinstance(value, list):
35+
print(f"{' ' * indent}[bold dim]{key}:[/bold dim]")
36+
for index, item in enumerate(value):
37+
print(f"{' ' * indent}[bold dim][{index}]:[/bold dim]")
38+
print_dict(item, indent=indent+2)
39+
else:
40+
print(f"{' ' * indent}[bold dim]{key}:[/bold dim] {value}")
41+
else:
42+
print(f"{' ' * indent}{data}")
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
1-
import json
2-
1+
from typing import Any
32
import click
43

54
from together import Together
5+
from rich import print_json, print
6+
from together._utils._json import openapi_dumps
67
from together.lib.cli.api._utils import handle_api_errors
78

89

910
@click.command()
1011
@click.pass_context
1112
@click.argument("evaluation_id", type=str, required=True)
13+
@click.option("--json", is_flag=True, help="Print output in JSON format")
1214
@handle_api_errors("Evals")
13-
def status(ctx: click.Context, evaluation_id: str) -> None:
15+
def status(ctx: click.Context, evaluation_id: str, json: bool) -> None:
1416
"""Get the status and results of a specific evaluation job"""
1517

1618
client: Together = ctx.obj
1719

1820
response = client.evals.status(evaluation_id)
1921

20-
click.echo(json.dumps(response.model_dump(exclude_none=True), indent=4))
22+
if json:
23+
print_json(openapi_dumps(response).decode("utf-8"))
24+
return
25+
else:
26+
print(f"[bold dim]Status:[/bold dim] [green]{response.status}[/green]")
27+
print_dict(response.results.to_dict() if response.results else {})
28+
29+
def print_dict(data: dict[str, Any], indent: int = 0) -> None:
30+
for key, value in data.items():
31+
if isinstance(value, dict):
32+
print(f"{' ' * indent}[bold dim]{key}:[/bold dim]")
33+
print_dict(value, indent=indent+2)
34+
else:
35+
print(f"{' ' * indent}[bold dim]{key}:[/bold dim] {value}")

src/together/lib/cli/api/fine_tuning/retrieve.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
import click
44
from rich import print as rprint, print_json
5-
from rich.json import JSON
65

76
from together import Together
87
from together._utils._json import openapi_dumps
98
from together.lib.cli.api._utils import handle_api_errors, generate_progress_bar
10-
from together.lib.utils.serializer import datetime_serializer
119

1210

1311
@click.command()
@@ -28,7 +26,7 @@ def retrieve(ctx: click.Context, fine_tune_id: str, json: bool) -> None:
2826
# remove events from response for cleaner output
2927
response.events = None
3028

31-
rprint(JSON.from_data(response.model_dump(exclude_none=True), default=datetime_serializer))
29+
print_json(openapi_dumps(response).decode("utf-8"))
3230
progress_text = generate_progress_bar(response, datetime.now(timezone.utc), use_rich=True)
3331
prefix = f"Status: [bold]{response.status}[/bold],"
3432
rprint(f"{prefix} {progress_text}")

src/together/lib/cli/api/models/list.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from together import Together, omit
88
from together._response import APIResponse as APIResponse
99
from together.lib.cli.api._utils import handle_api_errors
10-
from together.lib.utils.serializer import datetime_serializer
10+
from rich import print_json
11+
from together._utils._json import openapi_dumps
1112

1213

1314
@click.command()
@@ -30,8 +31,7 @@ def list(ctx: click.Context, type: Optional[str], json: bool) -> None:
3031
models_list = client.models.list(dedicated=type == "dedicated" if type else omit)
3132

3233
if json:
33-
items = [model.model_dump() for model in models_list]
34-
click.echo(json_lib.dumps(items, indent=2, default=datetime_serializer))
34+
print_json(openapi_dumps(models_list).decode("utf-8"))
3535
return
3636

3737
display_list: List[Dict[str, Any]] = []

0 commit comments

Comments
 (0)