plato-sdk-v2 2.8.0__py3-none-any.whl → 2.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
plato/v2/sync/sandbox.py CHANGED
@@ -622,6 +622,28 @@ class SandboxClient:
622
622
  raise ValueError("No job ID found")
623
623
  self.console.print(f"job_id: {job_id}")
624
624
 
625
+ # For artifact mode, we need to get simulator_name from session details BEFORE generating public URL
626
+ # Note: get_session_details returns a dict, not a Pydantic model
627
+ if not simulator_name:
628
+ session_details = get_session_details.sync(
629
+ client=self._http,
630
+ session_id=session_id,
631
+ x_api_key=self.api_key,
632
+ )
633
+ jobs = (
634
+ session_details.get("jobs")
635
+ if isinstance(session_details, dict)
636
+ else getattr(session_details, "jobs", None)
637
+ )
638
+ if jobs:
639
+ for j in jobs:
640
+ service = j.get("service") if isinstance(j, dict) else getattr(j, "service", None)
641
+ if service:
642
+ simulator_name = service
643
+ break
644
+ if not simulator_name:
645
+ raise ValueError(f"No simulator name found in session details for job ID {job_id}")
646
+
625
647
  # Get public URL with router target formatting (logic inlined)
626
648
  public_url = None
627
649
  try:
@@ -635,7 +657,7 @@ class SandboxClient:
635
657
  url = result.url if hasattr(result, "url") else str(result)
636
658
  if not url:
637
659
  raise ValueError(f"No public URL found in result dict for job ID {job_id}")
638
- if "_plato_router_target=" not in url:
660
+ if "_plato_router_target=" not in url and simulator_name:
639
661
  target_param = f"_plato_router_target={simulator_name}.web.plato.so"
640
662
  if "?" in url:
641
663
  url = f"{url}&{target_param}"
@@ -667,24 +689,6 @@ class SandboxClient:
667
689
  heartbeat_pid = None
668
690
  heartbeat_pid = _start_heartbeat_process(session_id, self.api_key)
669
691
 
670
- # Parse out the simulator_name from service field in jobs in session details.
671
- session_details = get_session_details.sync(
672
- client=self._http,
673
- session_id=session_id,
674
- x_api_key=self.api_key,
675
- )
676
- if hasattr(session_details, "jobs"):
677
- # session_details["jobs"] if dict, or session_details.jobs if object
678
- jobs = (
679
- session_details["jobs"] if isinstance(session_details, dict) else getattr(session_details, "jobs", None)
680
- )
681
- if jobs:
682
- for j in jobs:
683
- service = j.get("service") if isinstance(j, dict) else getattr(j, "service", None)
684
- if service:
685
- simulator_name = service
686
- break
687
-
688
692
  # Convert absolute paths to relative for state storage
689
693
  def _to_relative(abs_path: str | None) -> str | None:
690
694
  if not abs_path or not self.working_dir:
@@ -759,26 +763,39 @@ class SandboxClient:
759
763
  checkpoint_request = CreateCheckpointRequest()
760
764
 
761
765
  if mode == "config":
762
- # read plato-config.yml
766
+ # read plato-config.yml - need parsed for extracting values
763
767
  plato_config_path = self.working_dir / "plato-config.yml"
764
- with open(plato_config_path, "rb") as f:
765
- plato_config = yaml.safe_load(f)
766
- checkpoint_request.plato_config = plato_config
768
+ plato_config_raw = plato_config_path.read_text()
769
+ plato_config = yaml.safe_load(plato_config_raw)
767
770
 
768
- # convert plato-config to pydantic model
771
+ # New format - extract just the dataset portion
769
772
  plato_config_model = PlatoConfig.model_validate(plato_config)
770
- dataset_compute = plato_config_model.datasets[dataset].compute
773
+ dataset_config = plato_config_model.datasets[dataset]
774
+ # Convert dataset config back to dict for YAML serialization
775
+ dataset_dict = dataset_config.model_dump(exclude_none=True, by_alias=True)
776
+ checkpoint_request.plato_config = yaml.dump(dataset_dict, default_flow_style=False)
777
+
778
+ dataset_compute = dataset_config.compute
771
779
  if not dataset_compute:
772
780
  raise ValueError(f"Compute configuration is required for dataset '{dataset}'")
773
781
  checkpoint_request.internal_app_port = dataset_compute.app_port
774
782
  checkpoint_request.messaging_port = dataset_compute.plato_messaging_port
775
783
  # we dont set target
776
784
 
777
- # read flows.yml
778
- flows_path = self.working_dir / "flows.yml"
779
- with open(flows_path, "rb") as f:
780
- flows = yaml.safe_load(f)
781
- checkpoint_request.flows = flows
785
+ # Read flows from the path specified in plato-config metadata
786
+ # API expects YAML string, not parsed dict
787
+ # Only set flows if file exists AND has content, otherwise leave as None to inherit from parent
788
+ dataset_metadata = dataset_config.metadata
789
+ flows_file_path = dataset_metadata.flows_path if dataset_metadata else None
790
+ if flows_file_path:
791
+ # flows_path is relative to working_dir
792
+ flows_path = self.working_dir / flows_file_path
793
+ if flows_path.exists():
794
+ flows_content = flows_path.read_text().strip()
795
+ if flows_content:
796
+ checkpoint_request.flows = flows_content
797
+ else:
798
+ self.console.print(f"[yellow]Warning: flows file not found at {flows_path}[/yellow]")
782
799
 
783
800
  return sessions_snapshot.sync(
784
801
  client=self._http,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plato-sdk-v2
3
- Version: 2.8.0
3
+ Version: 2.8.2
4
4
  Summary: Python SDK for the Plato API
5
5
  Author-email: Plato <support@plato.so>
6
6
  License-Expression: MIT
@@ -419,9 +419,9 @@ plato/cli/agent.py,sha256=5qA0T1n0H0JQ5ZB-fAVKm3Nw-y_M-GiSQx1OTcKgkrI,44050
419
419
  plato/cli/audit_ui.py,sha256=AfnC3wngGV3ujg9POHNYQhal2S6Hr0ZhcXrAAxtVfMg,12307
420
420
  plato/cli/chronos.py,sha256=OTS-xcmH0U99sMHrABqtJMOdOEhHil5hv_yO3YNgrS8,27824
421
421
  plato/cli/main.py,sha256=f-L_Q6MWA8ylGrOcEsJU5HRK1JaDUeh6ONWSaKwag10,6800
422
- plato/cli/pm.py,sha256=RMZdxIYi1YV4T35soYuYgLqg65ja4sPDw8K9zx3ZLBU,53045
422
+ plato/cli/pm.py,sha256=9j0S2ATPGS3GGbl0530YaQJSVN4dnGaDXVt-j42mJ7A,52589
423
423
  plato/cli/proxy.py,sha256=c1t1ljZvArTnFba-NprCj2tma4XneEqRDQCbwzQ9GD4,6803
424
- plato/cli/sandbox.py,sha256=B9QPHvtXaiUlGa0zY5kYd9-TvE4YbC8kYO1WNgLqFcM,26250
424
+ plato/cli/sandbox.py,sha256=sTPsbDEZywvYFMOGOCphDd2nZvDj21xA8MgmfBTjX88,26731
425
425
  plato/cli/utils.py,sha256=PIZnJYuhojbARoRA2Tk3KfB5Tycg1uwlPLhut5Es0ew,6900
426
426
  plato/cli/verify.py,sha256=fGmKAh9SB2s7Q67oI9q26_gYxZh4JzGMCS4PyfMqb-g,22930
427
427
  plato/cli/world.py,sha256=bH-ReNhGdjcba5rXijLfhAKFwsk3GzlQQEtXUFWOZbw,8822
@@ -446,7 +446,7 @@ plato/v1/cli/__init__.py,sha256=om4b7PxgsoI7rEwuQelmQkqPdhMVn53_5qEN8kvksYw,105
446
446
  plato/v1/cli/agent.py,sha256=r5Eh2e2-rUIGjK5uevnGKqScABtFK-Spomrrytj-3og,44053
447
447
  plato/v1/cli/chronos.py,sha256=lzFY0nomP1AY14i8oc8OvWOdq9ydCiE3dN2XrSupvA4,27827
448
448
  plato/v1/cli/main.py,sha256=Yqy1vn4sGyAWKNpDVcLl9pbzkMn89tYVBIxFU30ZtPk,6905
449
- plato/v1/cli/pm.py,sha256=lHdi88vFiZt-_GJzQoqNIyaoDuQzg34faBIpfbMbNUA,55740
449
+ plato/v1/cli/pm.py,sha256=oLcfoSRSFcByzYlaswbJE683uKpsd1RMUi8to8FmLLY,344
450
450
  plato/v1/cli/proxy.py,sha256=WmCt0R9Gos1q0FZTQSsbloNC3-Cnx6Yb60RZF1BzC18,12178
451
451
  plato/v1/cli/sandbox.py,sha256=3TkXBTdYNV45XvnG4F4QzETz908i3vuSswTVCaBY-WU,101035
452
452
  plato/v1/cli/ssh.py,sha256=9ypjn5kQuaTcVjsWMDIUDyehXRH9fauk_z-C3mXzYJ8,2381
@@ -513,7 +513,7 @@ plato/v2/sync/chronos.py,sha256=ChXpasjRzAZjoYTimpPqYydnwEk-IgdxR0SDXDOZbUM,1207
513
513
  plato/v2/sync/client.py,sha256=rsrU7_RhE-syf3FMNw5LaxmF7rYw2GBzC_TPpd-6thk,4986
514
514
  plato/v2/sync/environment.py,sha256=WnDzbyEHpwCSEP8XnfNSjIYS7rt7lYR4HGJjzprZmTQ,5066
515
515
  plato/v2/sync/flow_executor.py,sha256=N41-WCWIJVcCR2UmPUEiK7roNacYoeONkRXpR7lUgT8,13941
516
- plato/v2/sync/sandbox.py,sha256=yRwkms1_qsHjhbLZQ7FiaLgFme2tMw8YM2xg2-ZZS04,53734
516
+ plato/v2/sync/sandbox.py,sha256=jDvlCFtmX5Pz3bi-PiHycfdjUY0ninfx2xz436NUP0o,54901
517
517
  plato/v2/sync/session.py,sha256=FYVxgGZ3eL_YpoJiUgJamrt-jVaBqJITzFzepOKMRjA,35065
518
518
  plato/v2/utils/__init__.py,sha256=XLeFFsjXkm9g2raMmo7Wt4QN4hhCrNZDJKnpffJ4LtM,38
519
519
  plato/v2/utils/db_cleanup.py,sha256=JMzAAJz0ZnoUXtd8F4jpQmBpJpos2__RkgN_cuEearg,8692
@@ -526,7 +526,7 @@ plato/worlds/base.py,sha256=-RR71bSxEFI5yydtrtq-AAbuw98CIjvmrbztqzB9oIc,31041
526
526
  plato/worlds/build_hook.py,sha256=KSoW0kqa5b7NyZ7MYOw2qsZ_2FkWuz0M3Ru7AKOP7Qw,3486
527
527
  plato/worlds/config.py,sha256=O1lUXzxp-Z_M7izslT8naXgE6XujjzwYFFrDDzUOueI,12736
528
528
  plato/worlds/runner.py,sha256=r9B2BxBae8_dM7y5cJf9xhThp_I1Qvf_tlPq2rs8qC8,4013
529
- plato_sdk_v2-2.8.0.dist-info/METADATA,sha256=ouPYAxE-Lp1XW9dhodGVz5E-cPdN-jEFRPjkYnsooNM,8652
530
- plato_sdk_v2-2.8.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
531
- plato_sdk_v2-2.8.0.dist-info/entry_points.txt,sha256=iynJvTkU7E4MZNtSozVF0Wh083yPm6cuKV362Ol_ez8,133
532
- plato_sdk_v2-2.8.0.dist-info/RECORD,,
529
+ plato_sdk_v2-2.8.2.dist-info/METADATA,sha256=ARvX_fQyqW0AhorrZ2H9MTLTdayuVeIj5loPTiaqtMo,8652
530
+ plato_sdk_v2-2.8.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
531
+ plato_sdk_v2-2.8.2.dist-info/entry_points.txt,sha256=iynJvTkU7E4MZNtSozVF0Wh083yPm6cuKV362Ol_ez8,133
532
+ plato_sdk_v2-2.8.2.dist-info/RECORD,,