|
1 | | -"""Command Line Interface for `openml` to configure its settings.""" |
| 1 | +"""Command Line Interface for `openml` to configure its settings and browse resources.""" |
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
|
9 | 9 | from pathlib import Path |
10 | 10 | from urllib.parse import urlparse |
11 | 11 |
|
| 12 | +import openml |
12 | 13 | from openml import config |
13 | 14 | from openml.__version__ import __version__ |
14 | 15 |
|
@@ -300,6 +301,79 @@ def configure_field( # noqa: PLR0913 |
300 | 301 | verbose_set(field, value) |
301 | 302 |
|
302 | 303 |
|
| 304 | +def list_flows_cli(args: argparse.Namespace) -> None: |
| 305 | + """List OpenML flows with optional filtering.""" |
| 306 | + df = openml.flows.list_flows( |
| 307 | + offset=args.offset, |
| 308 | + size=args.size, |
| 309 | + tag=args.tag, |
| 310 | + uploader=args.uploader, |
| 311 | + ) |
| 312 | + if df.empty: |
| 313 | + print("No flows found matching the given criteria.") |
| 314 | + else: |
| 315 | + print(df.to_string()) |
| 316 | + |
| 317 | + |
| 318 | +def info_flow_cli(args: argparse.Namespace) -> None: |
| 319 | + """Display detailed information about a specific OpenML flow.""" |
| 320 | + flow = openml.flows.get_flow(args.flow_id) |
| 321 | + print(flow) |
| 322 | + |
| 323 | + |
| 324 | +def handle_flows(args: argparse.Namespace) -> None: |
| 325 | + """Dispatch flows subcommands.""" |
| 326 | + actions = { |
| 327 | + "list": list_flows_cli, |
| 328 | + "info": info_flow_cli, |
| 329 | + } |
| 330 | + action = getattr(args, "flows_action", None) |
| 331 | + if action is None: |
| 332 | + # Print help when no subcommand is given |
| 333 | + args._parser_flows.print_help() |
| 334 | + else: |
| 335 | + actions[action](args) |
| 336 | + |
| 337 | + |
| 338 | +def list_datasets_cli(args: argparse.Namespace) -> None: |
| 339 | + """List OpenML datasets with optional filtering.""" |
| 340 | + df = openml.datasets.list_datasets( |
| 341 | + offset=args.offset, |
| 342 | + size=args.size, |
| 343 | + tag=args.tag, |
| 344 | + status=args.status, |
| 345 | + data_name=args.data_name, |
| 346 | + ) |
| 347 | + if df.empty: |
| 348 | + print("No datasets found matching the given criteria.") |
| 349 | + else: |
| 350 | + print(df.to_string()) |
| 351 | + |
| 352 | + |
| 353 | +def info_dataset_cli(args: argparse.Namespace) -> None: |
| 354 | + """Display detailed information about a specific OpenML dataset.""" |
| 355 | + dataset = openml.datasets.get_dataset( |
| 356 | + args.dataset_id, |
| 357 | + download_data=False, |
| 358 | + download_qualities=True, |
| 359 | + download_features_meta_data=True, |
| 360 | + ) |
| 361 | + print(dataset) |
| 362 | + |
| 363 | + |
| 364 | +def handle_datasets(args: argparse.Namespace) -> None: |
| 365 | + """Dispatch datasets subcommands.""" |
| 366 | + actions = { |
| 367 | + "list": list_datasets_cli, |
| 368 | + "info": info_dataset_cli, |
| 369 | + } |
| 370 | + action = getattr(args, "datasets_action", None) |
| 371 | + if action is None: |
| 372 | + args._parser_datasets.print_help() |
| 373 | + else: |
| 374 | + actions[action](args) |
| 375 | + |
| 376 | + |
303 | 377 | def configure(args: argparse.Namespace) -> None: |
304 | 378 | """Calls the right submenu(s) to edit `args.field` in the configuration file.""" |
305 | 379 | set_functions = { |
@@ -329,7 +403,7 @@ def not_supported_yet(_: str) -> None: |
329 | 403 |
|
330 | 404 |
|
331 | 405 | def main() -> None: |
332 | | - subroutines = {"configure": configure} |
| 406 | + subroutines = {"configure": configure, "flows": handle_flows, "datasets": handle_datasets} |
333 | 407 |
|
334 | 408 | parser = argparse.ArgumentParser() |
335 | 409 | # Add a global --version flag to display installed version and exit |
@@ -368,7 +442,109 @@ def main() -> None: |
368 | 442 | help="The value to set the FIELD to.", |
369 | 443 | ) |
370 | 444 |
|
| 445 | + # --- flows subcommand --- |
| 446 | + parser_flows = subparsers.add_parser( |
| 447 | + "flows", |
| 448 | + description="Browse and search OpenML flows (models).", |
| 449 | + ) |
| 450 | + flows_subparsers = parser_flows.add_subparsers(dest="flows_action") |
| 451 | + |
| 452 | + parser_flows_list = flows_subparsers.add_parser( |
| 453 | + "list", |
| 454 | + description="List OpenML flows with optional filtering.", |
| 455 | + ) |
| 456 | + parser_flows_list.add_argument( |
| 457 | + "--size", |
| 458 | + type=int, |
| 459 | + default=10, |
| 460 | + help="Maximum number of flows to return (default: 10).", |
| 461 | + ) |
| 462 | + parser_flows_list.add_argument( |
| 463 | + "--offset", |
| 464 | + type=int, |
| 465 | + default=None, |
| 466 | + help="Number of flows to skip, for pagination.", |
| 467 | + ) |
| 468 | + parser_flows_list.add_argument( |
| 469 | + "--tag", |
| 470 | + type=str, |
| 471 | + default=None, |
| 472 | + help="Only list flows with this tag.", |
| 473 | + ) |
| 474 | + parser_flows_list.add_argument( |
| 475 | + "--uploader", |
| 476 | + type=str, |
| 477 | + default=None, |
| 478 | + help="Only list flows uploaded by this user.", |
| 479 | + ) |
| 480 | + |
| 481 | + parser_flows_info = flows_subparsers.add_parser( |
| 482 | + "info", |
| 483 | + description="Display detailed information about a specific flow.", |
| 484 | + ) |
| 485 | + parser_flows_info.add_argument( |
| 486 | + "flow_id", |
| 487 | + type=int, |
| 488 | + help="The ID of the flow to display.", |
| 489 | + ) |
| 490 | + |
| 491 | + # --- datasets subcommand --- |
| 492 | + parser_datasets = subparsers.add_parser( |
| 493 | + "datasets", |
| 494 | + description="Browse and search OpenML datasets.", |
| 495 | + ) |
| 496 | + datasets_subparsers = parser_datasets.add_subparsers(dest="datasets_action") |
| 497 | + |
| 498 | + parser_datasets_list = datasets_subparsers.add_parser( |
| 499 | + "list", |
| 500 | + description="List OpenML datasets with optional filtering.", |
| 501 | + ) |
| 502 | + parser_datasets_list.add_argument( |
| 503 | + "--size", |
| 504 | + type=int, |
| 505 | + default=10, |
| 506 | + help="Maximum number of datasets to return (default: 10).", |
| 507 | + ) |
| 508 | + parser_datasets_list.add_argument( |
| 509 | + "--offset", |
| 510 | + type=int, |
| 511 | + default=None, |
| 512 | + help="Number of datasets to skip, for pagination.", |
| 513 | + ) |
| 514 | + parser_datasets_list.add_argument( |
| 515 | + "--tag", |
| 516 | + type=str, |
| 517 | + default=None, |
| 518 | + help="Only list datasets with this tag.", |
| 519 | + ) |
| 520 | + parser_datasets_list.add_argument( |
| 521 | + "--status", |
| 522 | + type=str, |
| 523 | + default=None, |
| 524 | + choices=["active", "in_preparation", "deactivated"], |
| 525 | + help="Filter by dataset status (default: active).", |
| 526 | + ) |
| 527 | + parser_datasets_list.add_argument( |
| 528 | + "--data-name", |
| 529 | + type=str, |
| 530 | + default=None, |
| 531 | + help="Filter by dataset name.", |
| 532 | + ) |
| 533 | + |
| 534 | + parser_datasets_info = datasets_subparsers.add_parser( |
| 535 | + "info", |
| 536 | + description="Display detailed information about a specific dataset.", |
| 537 | + ) |
| 538 | + parser_datasets_info.add_argument( |
| 539 | + "dataset_id", |
| 540 | + type=int, |
| 541 | + help="The ID of the dataset to display.", |
| 542 | + ) |
| 543 | + |
371 | 544 | args = parser.parse_args() |
| 545 | + # Attach subparsers so handlers can print help when no action is given |
| 546 | + args._parser_flows = parser_flows |
| 547 | + args._parser_datasets = parser_datasets |
372 | 548 | subroutines.get(args.subroutine, lambda _: parser.print_help())(args) |
373 | 549 |
|
374 | 550 |
|
|
0 commit comments