|
90 | 90 | Output: |
91 | 91 | Returns a dictionary of metrics keyed by experiment key. |
92 | 92 |
|
| 93 | + optimizer-report |
| 94 | + Generate a report for an optimizer instance. |
| 95 | +
|
| 96 | + Usage: |
| 97 | + cometx admin optimizer-report OPTIMIZER_ID |
| 98 | + cometx admin optimizer-report OPTIMIZER_ID --app |
| 99 | +
|
| 100 | + Arguments: |
| 101 | + OPTIMIZER_ID (required) |
| 102 | + The optimizer instance ID to generate a report for. |
| 103 | +
|
| 104 | + Options: |
| 105 | + --app |
| 106 | + Launch interactive Streamlit web app instead of generating JSON file. |
| 107 | +
|
| 108 | + Output: |
| 109 | + Without --app: |
| 110 | + Generates a JSON file containing all dashboard/data items: |
| 111 | + - optimizer-report-{OPTIMIZER_ID}.json |
| 112 | +
|
| 113 | + With --app: |
| 114 | + Launches an interactive web interface where you can: |
| 115 | + - View optimizer dashboard with statistics |
| 116 | + - Filter by status |
| 117 | + - Navigate through paginated job assignments |
| 118 | + - View summary statistics |
| 119 | +
|
93 | 120 | Global Options (available for all commands): |
94 | 121 | --api-key KEY |
95 | 122 | Set the COMET_API_KEY for authentication. |
|
113 | 140 | cometx admin gpu-report my-workspace --start-date 2024-01-01 |
114 | 141 | cometx admin gpu-report my-workspace --start-date 2024-01-01 --end-date 2024-12-31 |
115 | 142 | cometx admin gpu-report workspace1/project1 workspace2 --start-date 2024-01-01 --metrics sys.gpu.0.gpu_utilization |
| 143 | + cometx admin optimizer-report abc123def456 |
| 144 | + cometx admin optimizer-report abc123def456 --app |
116 | 145 |
|
117 | 146 | """ |
118 | 147 |
|
119 | 148 | import argparse |
120 | 149 | import json |
| 150 | +import os |
121 | 151 | import sys |
122 | 152 | from urllib.parse import urlparse |
123 | 153 |
|
124 | 154 | from comet_ml import API |
125 | 155 |
|
126 | 156 | from .admin_gpu_report import main as gpu_report_main |
| 157 | +from .admin_optimizer_report import generate_json_report |
127 | 158 | from .admin_usage_report import generate_usage_report |
128 | 159 |
|
129 | 160 | ADDITIONAL_ARGS = False |
@@ -347,6 +378,54 @@ def get_parser_arguments(parser): |
347 | 378 | action="store_true", |
348 | 379 | ) |
349 | 380 |
|
| 381 | + # optimizer-report subcommand |
| 382 | + optimizer_report_description = """Generate a report for an optimizer instance. |
| 383 | +
|
| 384 | +Arguments: |
| 385 | + OPTIMIZER_ID (required) |
| 386 | + The optimizer instance ID to generate a report for. |
| 387 | +
|
| 388 | +Options: |
| 389 | + --app |
| 390 | + Launch interactive Streamlit web app instead of generating JSON file. |
| 391 | +
|
| 392 | +Output: |
| 393 | + Without --app: |
| 394 | + Generates a JSON file containing all dashboard/data items: |
| 395 | + - optimizer-report-{OPTIMIZER_ID}.json |
| 396 | +
|
| 397 | + With --app: |
| 398 | + Launches an interactive web interface where you can: |
| 399 | + - View optimizer dashboard with statistics |
| 400 | + - Filter by status |
| 401 | + - Navigate through paginated job assignments |
| 402 | + - View summary statistics |
| 403 | +
|
| 404 | +Examples: |
| 405 | + cometx admin optimizer-report abc123def456 |
| 406 | + cometx admin optimizer-report abc123def456 --app |
| 407 | +""" |
| 408 | + optimizer_parser = subparsers.add_parser( |
| 409 | + "optimizer-report", |
| 410 | + help="Generate a report for an optimizer instance", |
| 411 | + description=optimizer_report_description, |
| 412 | + formatter_class=argparse.RawDescriptionHelpFormatter, |
| 413 | + ) |
| 414 | + # Add global arguments to subparser so they show in help |
| 415 | + add_global_arguments(optimizer_parser) |
| 416 | + optimizer_parser.add_argument( |
| 417 | + "OPTIMIZER_ID", |
| 418 | + help="The optimizer instance ID to generate a report for", |
| 419 | + metavar="OPTIMIZER_ID", |
| 420 | + type=str, |
| 421 | + ) |
| 422 | + optimizer_parser.add_argument( |
| 423 | + "--app", |
| 424 | + help="Launch interactive Streamlit web app instead of generating JSON file", |
| 425 | + default=False, |
| 426 | + action="store_true", |
| 427 | + ) |
| 428 | + |
350 | 429 |
|
351 | 430 | def admin(parsed_args, remaining=None): |
352 | 431 | # Called via `cometx admin ...` |
@@ -391,8 +470,6 @@ def admin(parsed_args, remaining=None): |
391 | 470 | elif parsed_args.ACTION == "usage-report": |
392 | 471 | if parsed_args.app: |
393 | 472 | # Launch Streamlit app |
394 | | - import os |
395 | | - import sys |
396 | 473 |
|
397 | 474 | # Set environment variables if --api-key or --url-override were provided |
398 | 475 | if parsed_args.api_key: |
@@ -478,6 +555,76 @@ def admin(parsed_args, remaining=None): |
478 | 555 |
|
479 | 556 | traceback.print_exc() |
480 | 557 | return |
| 558 | + elif parsed_args.ACTION == "optimizer-report": |
| 559 | + optimizer_id = parsed_args.OPTIMIZER_ID |
| 560 | + |
| 561 | + if parsed_args.app: |
| 562 | + # Launch Streamlit app |
| 563 | + # Set environment variables if --api-key or --url-override were provided |
| 564 | + if parsed_args.api_key: |
| 565 | + os.environ["COMET_API_KEY"] = parsed_args.api_key |
| 566 | + if parsed_args.url_override: |
| 567 | + os.environ["COMET_URL_OVERRIDE"] = parsed_args.url_override |
| 568 | + |
| 569 | + # Run the Streamlit app using streamlit's CLI |
| 570 | + try: |
| 571 | + import streamlit.web.cli as stcli |
| 572 | + |
| 573 | + # Get the path to admin_optimizer_report.py |
| 574 | + optimizer_app_path = os.path.join( |
| 575 | + os.path.dirname(os.path.abspath(__file__)), |
| 576 | + "admin_optimizer_report.py", |
| 577 | + ) |
| 578 | + |
| 579 | + # Set optimizer ID in environment so the app can access it |
| 580 | + # Use COMET_OPTIMIZER_ID if not already set |
| 581 | + if "COMET_OPTIMIZER_ID" not in os.environ: |
| 582 | + os.environ["COMET_OPTIMIZER_ID"] = optimizer_id |
| 583 | + |
| 584 | + # Launch streamlit with the app (Streamlit will automatically open the browser) |
| 585 | + sys.argv = ["streamlit", "run", optimizer_app_path] |
| 586 | + stcli.main() |
| 587 | + except Exception as e: |
| 588 | + print(f"ERROR launching Streamlit app: {e}") |
| 589 | + if parsed_args.debug: |
| 590 | + raise |
| 591 | + return |
| 592 | + else: |
| 593 | + # Generate JSON report |
| 594 | + try: |
| 595 | + # Get API key and optimizer URL from config or arguments |
| 596 | + from comet_ml.config import get_config, get_optimizer_address |
| 597 | + |
| 598 | + config_obj = get_config() |
| 599 | + |
| 600 | + # Get API key from parsed args, config, or environment |
| 601 | + api_key = parsed_args.api_key |
| 602 | + if not api_key: |
| 603 | + try: |
| 604 | + api_key = config_obj["comet.api_key"] |
| 605 | + except (KeyError, TypeError): |
| 606 | + api_key = os.environ.get("COMET_API_KEY") |
| 607 | + |
| 608 | + # Get optimizer URL from config |
| 609 | + optimizer_url = get_optimizer_address(config_obj) |
| 610 | + |
| 611 | + result = generate_json_report( |
| 612 | + optimizer_id=optimizer_id, |
| 613 | + api_key=api_key, |
| 614 | + optimizer_url=optimizer_url, |
| 615 | + ) |
| 616 | + if result: |
| 617 | + print(f"\nOptimizer report generated successfully: {result}") |
| 618 | + else: |
| 619 | + print("ERROR: Failed to generate optimizer report") |
| 620 | + return |
| 621 | + except Exception as e: |
| 622 | + print("ERROR: " + str(e)) |
| 623 | + if parsed_args.debug: |
| 624 | + import traceback |
| 625 | + |
| 626 | + traceback.print_exc() |
| 627 | + return |
481 | 628 |
|
482 | 629 | except KeyboardInterrupt: |
483 | 630 | if parsed_args.debug: |
|
0 commit comments