databricks-sdk 0.52.0__py3-none-any.whl → 0.54.0__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.

Potentially problematic release.


This version of databricks-sdk might be problematic. Click here for more details.

@@ -785,6 +785,98 @@ class CreateForecastingExperimentResponse:
785
785
  return cls(experiment_id=d.get("experiment_id", None))
786
786
 
787
787
 
788
+ @dataclass
789
+ class CreateLoggedModelRequest:
790
+ experiment_id: str
791
+ """The ID of the experiment that owns the model."""
792
+
793
+ model_type: Optional[str] = None
794
+ """The type of the model, such as ``"Agent"``, ``"Classifier"``, ``"LLM"``."""
795
+
796
+ name: Optional[str] = None
797
+ """The name of the model (optional). If not specified one will be generated."""
798
+
799
+ params: Optional[List[LoggedModelParameter]] = None
800
+ """Parameters attached to the model."""
801
+
802
+ source_run_id: Optional[str] = None
803
+ """The ID of the run that created the model."""
804
+
805
+ tags: Optional[List[LoggedModelTag]] = None
806
+ """Tags attached to the model."""
807
+
808
+ def as_dict(self) -> dict:
809
+ """Serializes the CreateLoggedModelRequest into a dictionary suitable for use as a JSON request body."""
810
+ body = {}
811
+ if self.experiment_id is not None:
812
+ body["experiment_id"] = self.experiment_id
813
+ if self.model_type is not None:
814
+ body["model_type"] = self.model_type
815
+ if self.name is not None:
816
+ body["name"] = self.name
817
+ if self.params:
818
+ body["params"] = [v.as_dict() for v in self.params]
819
+ if self.source_run_id is not None:
820
+ body["source_run_id"] = self.source_run_id
821
+ if self.tags:
822
+ body["tags"] = [v.as_dict() for v in self.tags]
823
+ return body
824
+
825
+ def as_shallow_dict(self) -> dict:
826
+ """Serializes the CreateLoggedModelRequest into a shallow dictionary of its immediate attributes."""
827
+ body = {}
828
+ if self.experiment_id is not None:
829
+ body["experiment_id"] = self.experiment_id
830
+ if self.model_type is not None:
831
+ body["model_type"] = self.model_type
832
+ if self.name is not None:
833
+ body["name"] = self.name
834
+ if self.params:
835
+ body["params"] = self.params
836
+ if self.source_run_id is not None:
837
+ body["source_run_id"] = self.source_run_id
838
+ if self.tags:
839
+ body["tags"] = self.tags
840
+ return body
841
+
842
+ @classmethod
843
+ def from_dict(cls, d: Dict[str, Any]) -> CreateLoggedModelRequest:
844
+ """Deserializes the CreateLoggedModelRequest from a dictionary."""
845
+ return cls(
846
+ experiment_id=d.get("experiment_id", None),
847
+ model_type=d.get("model_type", None),
848
+ name=d.get("name", None),
849
+ params=_repeated_dict(d, "params", LoggedModelParameter),
850
+ source_run_id=d.get("source_run_id", None),
851
+ tags=_repeated_dict(d, "tags", LoggedModelTag),
852
+ )
853
+
854
+
855
+ @dataclass
856
+ class CreateLoggedModelResponse:
857
+ model: Optional[LoggedModel] = None
858
+ """The newly created logged model."""
859
+
860
+ def as_dict(self) -> dict:
861
+ """Serializes the CreateLoggedModelResponse into a dictionary suitable for use as a JSON request body."""
862
+ body = {}
863
+ if self.model:
864
+ body["model"] = self.model.as_dict()
865
+ return body
866
+
867
+ def as_shallow_dict(self) -> dict:
868
+ """Serializes the CreateLoggedModelResponse into a shallow dictionary of its immediate attributes."""
869
+ body = {}
870
+ if self.model:
871
+ body["model"] = self.model
872
+ return body
873
+
874
+ @classmethod
875
+ def from_dict(cls, d: Dict[str, Any]) -> CreateLoggedModelResponse:
876
+ """Deserializes the CreateLoggedModelResponse from a dictionary."""
877
+ return cls(model=_from_dict(d, "model", LoggedModel))
878
+
879
+
788
880
  @dataclass
789
881
  class CreateModelRequest:
790
882
  name: str
@@ -1404,6 +1496,42 @@ class DeleteExperimentResponse:
1404
1496
  return cls()
1405
1497
 
1406
1498
 
1499
+ @dataclass
1500
+ class DeleteLoggedModelResponse:
1501
+ def as_dict(self) -> dict:
1502
+ """Serializes the DeleteLoggedModelResponse into a dictionary suitable for use as a JSON request body."""
1503
+ body = {}
1504
+ return body
1505
+
1506
+ def as_shallow_dict(self) -> dict:
1507
+ """Serializes the DeleteLoggedModelResponse into a shallow dictionary of its immediate attributes."""
1508
+ body = {}
1509
+ return body
1510
+
1511
+ @classmethod
1512
+ def from_dict(cls, d: Dict[str, Any]) -> DeleteLoggedModelResponse:
1513
+ """Deserializes the DeleteLoggedModelResponse from a dictionary."""
1514
+ return cls()
1515
+
1516
+
1517
+ @dataclass
1518
+ class DeleteLoggedModelTagResponse:
1519
+ def as_dict(self) -> dict:
1520
+ """Serializes the DeleteLoggedModelTagResponse into a dictionary suitable for use as a JSON request body."""
1521
+ body = {}
1522
+ return body
1523
+
1524
+ def as_shallow_dict(self) -> dict:
1525
+ """Serializes the DeleteLoggedModelTagResponse into a shallow dictionary of its immediate attributes."""
1526
+ body = {}
1527
+ return body
1528
+
1529
+ @classmethod
1530
+ def from_dict(cls, d: Dict[str, Any]) -> DeleteLoggedModelTagResponse:
1531
+ """Deserializes the DeleteLoggedModelTagResponse from a dictionary."""
1532
+ return cls()
1533
+
1534
+
1407
1535
  @dataclass
1408
1536
  class DeleteModelResponse:
1409
1537
  def as_dict(self) -> dict:
@@ -2103,6 +2231,64 @@ class FileInfo:
2103
2231
  return cls(file_size=d.get("file_size", None), is_dir=d.get("is_dir", None), path=d.get("path", None))
2104
2232
 
2105
2233
 
2234
+ @dataclass
2235
+ class FinalizeLoggedModelRequest:
2236
+ status: LoggedModelStatus
2237
+ """Whether or not the model is ready for use. ``"LOGGED_MODEL_UPLOAD_FAILED"`` indicates that
2238
+ something went wrong when logging the model weights / agent code)."""
2239
+
2240
+ model_id: Optional[str] = None
2241
+ """The ID of the logged model to finalize."""
2242
+
2243
+ def as_dict(self) -> dict:
2244
+ """Serializes the FinalizeLoggedModelRequest into a dictionary suitable for use as a JSON request body."""
2245
+ body = {}
2246
+ if self.model_id is not None:
2247
+ body["model_id"] = self.model_id
2248
+ if self.status is not None:
2249
+ body["status"] = self.status.value
2250
+ return body
2251
+
2252
+ def as_shallow_dict(self) -> dict:
2253
+ """Serializes the FinalizeLoggedModelRequest into a shallow dictionary of its immediate attributes."""
2254
+ body = {}
2255
+ if self.model_id is not None:
2256
+ body["model_id"] = self.model_id
2257
+ if self.status is not None:
2258
+ body["status"] = self.status
2259
+ return body
2260
+
2261
+ @classmethod
2262
+ def from_dict(cls, d: Dict[str, Any]) -> FinalizeLoggedModelRequest:
2263
+ """Deserializes the FinalizeLoggedModelRequest from a dictionary."""
2264
+ return cls(model_id=d.get("model_id", None), status=_enum(d, "status", LoggedModelStatus))
2265
+
2266
+
2267
+ @dataclass
2268
+ class FinalizeLoggedModelResponse:
2269
+ model: Optional[LoggedModel] = None
2270
+ """The updated logged model."""
2271
+
2272
+ def as_dict(self) -> dict:
2273
+ """Serializes the FinalizeLoggedModelResponse into a dictionary suitable for use as a JSON request body."""
2274
+ body = {}
2275
+ if self.model:
2276
+ body["model"] = self.model.as_dict()
2277
+ return body
2278
+
2279
+ def as_shallow_dict(self) -> dict:
2280
+ """Serializes the FinalizeLoggedModelResponse into a shallow dictionary of its immediate attributes."""
2281
+ body = {}
2282
+ if self.model:
2283
+ body["model"] = self.model
2284
+ return body
2285
+
2286
+ @classmethod
2287
+ def from_dict(cls, d: Dict[str, Any]) -> FinalizeLoggedModelResponse:
2288
+ """Deserializes the FinalizeLoggedModelResponse from a dictionary."""
2289
+ return cls(model=_from_dict(d, "model", LoggedModel))
2290
+
2291
+
2106
2292
  @dataclass
2107
2293
  class ForecastingExperiment:
2108
2294
  """Represents a forecasting experiment with its unique identifier, URL, and state."""
@@ -2340,6 +2526,31 @@ class GetLatestVersionsResponse:
2340
2526
  return cls(model_versions=_repeated_dict(d, "model_versions", ModelVersion))
2341
2527
 
2342
2528
 
2529
+ @dataclass
2530
+ class GetLoggedModelResponse:
2531
+ model: Optional[LoggedModel] = None
2532
+ """The retrieved logged model."""
2533
+
2534
+ def as_dict(self) -> dict:
2535
+ """Serializes the GetLoggedModelResponse into a dictionary suitable for use as a JSON request body."""
2536
+ body = {}
2537
+ if self.model:
2538
+ body["model"] = self.model.as_dict()
2539
+ return body
2540
+
2541
+ def as_shallow_dict(self) -> dict:
2542
+ """Serializes the GetLoggedModelResponse into a shallow dictionary of its immediate attributes."""
2543
+ body = {}
2544
+ if self.model:
2545
+ body["model"] = self.model
2546
+ return body
2547
+
2548
+ @classmethod
2549
+ def from_dict(cls, d: Dict[str, Any]) -> GetLoggedModelResponse:
2550
+ """Deserializes the GetLoggedModelResponse from a dictionary."""
2551
+ return cls(model=_from_dict(d, "model", LoggedModel))
2552
+
2553
+
2343
2554
  @dataclass
2344
2555
  class GetMetricHistoryResponse:
2345
2556
  metrics: Optional[List[Metric]] = None
@@ -2782,6 +2993,49 @@ class ListExperimentsResponse:
2782
2993
  )
2783
2994
 
2784
2995
 
2996
+ @dataclass
2997
+ class ListLoggedModelArtifactsResponse:
2998
+ files: Optional[List[FileInfo]] = None
2999
+ """File location and metadata for artifacts."""
3000
+
3001
+ next_page_token: Optional[str] = None
3002
+ """Token that can be used to retrieve the next page of artifact results"""
3003
+
3004
+ root_uri: Optional[str] = None
3005
+ """Root artifact directory for the logged model."""
3006
+
3007
+ def as_dict(self) -> dict:
3008
+ """Serializes the ListLoggedModelArtifactsResponse into a dictionary suitable for use as a JSON request body."""
3009
+ body = {}
3010
+ if self.files:
3011
+ body["files"] = [v.as_dict() for v in self.files]
3012
+ if self.next_page_token is not None:
3013
+ body["next_page_token"] = self.next_page_token
3014
+ if self.root_uri is not None:
3015
+ body["root_uri"] = self.root_uri
3016
+ return body
3017
+
3018
+ def as_shallow_dict(self) -> dict:
3019
+ """Serializes the ListLoggedModelArtifactsResponse into a shallow dictionary of its immediate attributes."""
3020
+ body = {}
3021
+ if self.files:
3022
+ body["files"] = self.files
3023
+ if self.next_page_token is not None:
3024
+ body["next_page_token"] = self.next_page_token
3025
+ if self.root_uri is not None:
3026
+ body["root_uri"] = self.root_uri
3027
+ return body
3028
+
3029
+ @classmethod
3030
+ def from_dict(cls, d: Dict[str, Any]) -> ListLoggedModelArtifactsResponse:
3031
+ """Deserializes the ListLoggedModelArtifactsResponse from a dictionary."""
3032
+ return cls(
3033
+ files=_repeated_dict(d, "files", FileInfo),
3034
+ next_page_token=d.get("next_page_token", None),
3035
+ root_uri=d.get("root_uri", None),
3036
+ )
3037
+
3038
+
2785
3039
  @dataclass
2786
3040
  class ListModelsResponse:
2787
3041
  next_page_token: Optional[str] = None
@@ -3008,6 +3262,56 @@ class LogInputsResponse:
3008
3262
  return cls()
3009
3263
 
3010
3264
 
3265
+ @dataclass
3266
+ class LogLoggedModelParamsRequest:
3267
+ model_id: Optional[str] = None
3268
+ """The ID of the logged model to log params for."""
3269
+
3270
+ params: Optional[List[LoggedModelParameter]] = None
3271
+ """Parameters to attach to the model."""
3272
+
3273
+ def as_dict(self) -> dict:
3274
+ """Serializes the LogLoggedModelParamsRequest into a dictionary suitable for use as a JSON request body."""
3275
+ body = {}
3276
+ if self.model_id is not None:
3277
+ body["model_id"] = self.model_id
3278
+ if self.params:
3279
+ body["params"] = [v.as_dict() for v in self.params]
3280
+ return body
3281
+
3282
+ def as_shallow_dict(self) -> dict:
3283
+ """Serializes the LogLoggedModelParamsRequest into a shallow dictionary of its immediate attributes."""
3284
+ body = {}
3285
+ if self.model_id is not None:
3286
+ body["model_id"] = self.model_id
3287
+ if self.params:
3288
+ body["params"] = self.params
3289
+ return body
3290
+
3291
+ @classmethod
3292
+ def from_dict(cls, d: Dict[str, Any]) -> LogLoggedModelParamsRequest:
3293
+ """Deserializes the LogLoggedModelParamsRequest from a dictionary."""
3294
+ return cls(model_id=d.get("model_id", None), params=_repeated_dict(d, "params", LoggedModelParameter))
3295
+
3296
+
3297
+ @dataclass
3298
+ class LogLoggedModelParamsRequestResponse:
3299
+ def as_dict(self) -> dict:
3300
+ """Serializes the LogLoggedModelParamsRequestResponse into a dictionary suitable for use as a JSON request body."""
3301
+ body = {}
3302
+ return body
3303
+
3304
+ def as_shallow_dict(self) -> dict:
3305
+ """Serializes the LogLoggedModelParamsRequestResponse into a shallow dictionary of its immediate attributes."""
3306
+ body = {}
3307
+ return body
3308
+
3309
+ @classmethod
3310
+ def from_dict(cls, d: Dict[str, Any]) -> LogLoggedModelParamsRequestResponse:
3311
+ """Deserializes the LogLoggedModelParamsRequestResponse from a dictionary."""
3312
+ return cls()
3313
+
3314
+
3011
3315
  @dataclass
3012
3316
  class LogMetric:
3013
3317
  key: str
@@ -3170,6 +3474,56 @@ class LogModelResponse:
3170
3474
  return cls()
3171
3475
 
3172
3476
 
3477
+ @dataclass
3478
+ class LogOutputsRequest:
3479
+ run_id: str
3480
+ """The ID of the Run from which to log outputs."""
3481
+
3482
+ models: Optional[List[ModelOutput]] = None
3483
+ """The model outputs from the Run."""
3484
+
3485
+ def as_dict(self) -> dict:
3486
+ """Serializes the LogOutputsRequest into a dictionary suitable for use as a JSON request body."""
3487
+ body = {}
3488
+ if self.models:
3489
+ body["models"] = [v.as_dict() for v in self.models]
3490
+ if self.run_id is not None:
3491
+ body["run_id"] = self.run_id
3492
+ return body
3493
+
3494
+ def as_shallow_dict(self) -> dict:
3495
+ """Serializes the LogOutputsRequest into a shallow dictionary of its immediate attributes."""
3496
+ body = {}
3497
+ if self.models:
3498
+ body["models"] = self.models
3499
+ if self.run_id is not None:
3500
+ body["run_id"] = self.run_id
3501
+ return body
3502
+
3503
+ @classmethod
3504
+ def from_dict(cls, d: Dict[str, Any]) -> LogOutputsRequest:
3505
+ """Deserializes the LogOutputsRequest from a dictionary."""
3506
+ return cls(models=_repeated_dict(d, "models", ModelOutput), run_id=d.get("run_id", None))
3507
+
3508
+
3509
+ @dataclass
3510
+ class LogOutputsResponse:
3511
+ def as_dict(self) -> dict:
3512
+ """Serializes the LogOutputsResponse into a dictionary suitable for use as a JSON request body."""
3513
+ body = {}
3514
+ return body
3515
+
3516
+ def as_shallow_dict(self) -> dict:
3517
+ """Serializes the LogOutputsResponse into a shallow dictionary of its immediate attributes."""
3518
+ body = {}
3519
+ return body
3520
+
3521
+ @classmethod
3522
+ def from_dict(cls, d: Dict[str, Any]) -> LogOutputsResponse:
3523
+ """Deserializes the LogOutputsResponse from a dictionary."""
3524
+ return cls()
3525
+
3526
+
3173
3527
  @dataclass
3174
3528
  class LogParam:
3175
3529
  key: str
@@ -3241,23 +3595,287 @@ class LogParamResponse:
3241
3595
 
3242
3596
 
3243
3597
  @dataclass
3244
- class Metric:
3245
- """Metric associated with a run, represented as a key-value pair."""
3598
+ class LoggedModel:
3599
+ """A logged model message includes logged model attributes, tags, registration info, params, and
3600
+ linked run metrics."""
3246
3601
 
3247
- dataset_digest: Optional[str] = None
3248
- """The dataset digest of the dataset associated with the metric, e.g. an md5 hash of the dataset
3249
- that uniquely identifies it within datasets of the same name."""
3602
+ data: Optional[LoggedModelData] = None
3603
+ """The params and metrics attached to the logged model."""
3250
3604
 
3251
- dataset_name: Optional[str] = None
3252
- """The name of the dataset associated with the metric. E.g. “my.uc.table@2”
3253
- “nyc-taxi-dataset”, “fantastic-elk-3”"""
3605
+ info: Optional[LoggedModelInfo] = None
3606
+ """The logged model attributes such as model ID, status, tags, etc."""
3254
3607
 
3255
- key: Optional[str] = None
3256
- """The key identifying the metric."""
3608
+ def as_dict(self) -> dict:
3609
+ """Serializes the LoggedModel into a dictionary suitable for use as a JSON request body."""
3610
+ body = {}
3611
+ if self.data:
3612
+ body["data"] = self.data.as_dict()
3613
+ if self.info:
3614
+ body["info"] = self.info.as_dict()
3615
+ return body
3257
3616
 
3258
- model_id: Optional[str] = None
3259
- """The ID of the logged model or registered model version associated with the metric, if
3260
- applicable."""
3617
+ def as_shallow_dict(self) -> dict:
3618
+ """Serializes the LoggedModel into a shallow dictionary of its immediate attributes."""
3619
+ body = {}
3620
+ if self.data:
3621
+ body["data"] = self.data
3622
+ if self.info:
3623
+ body["info"] = self.info
3624
+ return body
3625
+
3626
+ @classmethod
3627
+ def from_dict(cls, d: Dict[str, Any]) -> LoggedModel:
3628
+ """Deserializes the LoggedModel from a dictionary."""
3629
+ return cls(data=_from_dict(d, "data", LoggedModelData), info=_from_dict(d, "info", LoggedModelInfo))
3630
+
3631
+
3632
+ @dataclass
3633
+ class LoggedModelData:
3634
+ """A LoggedModelData message includes logged model params and linked metrics."""
3635
+
3636
+ metrics: Optional[List[Metric]] = None
3637
+ """Performance metrics linked to the model."""
3638
+
3639
+ params: Optional[List[LoggedModelParameter]] = None
3640
+ """Immutable string key-value pairs of the model."""
3641
+
3642
+ def as_dict(self) -> dict:
3643
+ """Serializes the LoggedModelData into a dictionary suitable for use as a JSON request body."""
3644
+ body = {}
3645
+ if self.metrics:
3646
+ body["metrics"] = [v.as_dict() for v in self.metrics]
3647
+ if self.params:
3648
+ body["params"] = [v.as_dict() for v in self.params]
3649
+ return body
3650
+
3651
+ def as_shallow_dict(self) -> dict:
3652
+ """Serializes the LoggedModelData into a shallow dictionary of its immediate attributes."""
3653
+ body = {}
3654
+ if self.metrics:
3655
+ body["metrics"] = self.metrics
3656
+ if self.params:
3657
+ body["params"] = self.params
3658
+ return body
3659
+
3660
+ @classmethod
3661
+ def from_dict(cls, d: Dict[str, Any]) -> LoggedModelData:
3662
+ """Deserializes the LoggedModelData from a dictionary."""
3663
+ return cls(
3664
+ metrics=_repeated_dict(d, "metrics", Metric), params=_repeated_dict(d, "params", LoggedModelParameter)
3665
+ )
3666
+
3667
+
3668
+ @dataclass
3669
+ class LoggedModelInfo:
3670
+ """A LoggedModelInfo includes logged model attributes, tags, and registration info."""
3671
+
3672
+ artifact_uri: Optional[str] = None
3673
+ """The URI of the directory where model artifacts are stored."""
3674
+
3675
+ creation_timestamp_ms: Optional[int] = None
3676
+ """The timestamp when the model was created in milliseconds since the UNIX epoch."""
3677
+
3678
+ creator_id: Optional[int] = None
3679
+ """The ID of the user or principal that created the model."""
3680
+
3681
+ experiment_id: Optional[str] = None
3682
+ """The ID of the experiment that owns the model."""
3683
+
3684
+ last_updated_timestamp_ms: Optional[int] = None
3685
+ """The timestamp when the model was last updated in milliseconds since the UNIX epoch."""
3686
+
3687
+ model_id: Optional[str] = None
3688
+ """The unique identifier for the logged model."""
3689
+
3690
+ model_type: Optional[str] = None
3691
+ """The type of model, such as ``"Agent"``, ``"Classifier"``, ``"LLM"``."""
3692
+
3693
+ name: Optional[str] = None
3694
+ """The name of the model."""
3695
+
3696
+ source_run_id: Optional[str] = None
3697
+ """The ID of the run that created the model."""
3698
+
3699
+ status: Optional[LoggedModelStatus] = None
3700
+ """The status of whether or not the model is ready for use."""
3701
+
3702
+ status_message: Optional[str] = None
3703
+ """Details on the current model status."""
3704
+
3705
+ tags: Optional[List[LoggedModelTag]] = None
3706
+ """Mutable string key-value pairs set on the model."""
3707
+
3708
+ def as_dict(self) -> dict:
3709
+ """Serializes the LoggedModelInfo into a dictionary suitable for use as a JSON request body."""
3710
+ body = {}
3711
+ if self.artifact_uri is not None:
3712
+ body["artifact_uri"] = self.artifact_uri
3713
+ if self.creation_timestamp_ms is not None:
3714
+ body["creation_timestamp_ms"] = self.creation_timestamp_ms
3715
+ if self.creator_id is not None:
3716
+ body["creator_id"] = self.creator_id
3717
+ if self.experiment_id is not None:
3718
+ body["experiment_id"] = self.experiment_id
3719
+ if self.last_updated_timestamp_ms is not None:
3720
+ body["last_updated_timestamp_ms"] = self.last_updated_timestamp_ms
3721
+ if self.model_id is not None:
3722
+ body["model_id"] = self.model_id
3723
+ if self.model_type is not None:
3724
+ body["model_type"] = self.model_type
3725
+ if self.name is not None:
3726
+ body["name"] = self.name
3727
+ if self.source_run_id is not None:
3728
+ body["source_run_id"] = self.source_run_id
3729
+ if self.status is not None:
3730
+ body["status"] = self.status.value
3731
+ if self.status_message is not None:
3732
+ body["status_message"] = self.status_message
3733
+ if self.tags:
3734
+ body["tags"] = [v.as_dict() for v in self.tags]
3735
+ return body
3736
+
3737
+ def as_shallow_dict(self) -> dict:
3738
+ """Serializes the LoggedModelInfo into a shallow dictionary of its immediate attributes."""
3739
+ body = {}
3740
+ if self.artifact_uri is not None:
3741
+ body["artifact_uri"] = self.artifact_uri
3742
+ if self.creation_timestamp_ms is not None:
3743
+ body["creation_timestamp_ms"] = self.creation_timestamp_ms
3744
+ if self.creator_id is not None:
3745
+ body["creator_id"] = self.creator_id
3746
+ if self.experiment_id is not None:
3747
+ body["experiment_id"] = self.experiment_id
3748
+ if self.last_updated_timestamp_ms is not None:
3749
+ body["last_updated_timestamp_ms"] = self.last_updated_timestamp_ms
3750
+ if self.model_id is not None:
3751
+ body["model_id"] = self.model_id
3752
+ if self.model_type is not None:
3753
+ body["model_type"] = self.model_type
3754
+ if self.name is not None:
3755
+ body["name"] = self.name
3756
+ if self.source_run_id is not None:
3757
+ body["source_run_id"] = self.source_run_id
3758
+ if self.status is not None:
3759
+ body["status"] = self.status
3760
+ if self.status_message is not None:
3761
+ body["status_message"] = self.status_message
3762
+ if self.tags:
3763
+ body["tags"] = self.tags
3764
+ return body
3765
+
3766
+ @classmethod
3767
+ def from_dict(cls, d: Dict[str, Any]) -> LoggedModelInfo:
3768
+ """Deserializes the LoggedModelInfo from a dictionary."""
3769
+ return cls(
3770
+ artifact_uri=d.get("artifact_uri", None),
3771
+ creation_timestamp_ms=d.get("creation_timestamp_ms", None),
3772
+ creator_id=d.get("creator_id", None),
3773
+ experiment_id=d.get("experiment_id", None),
3774
+ last_updated_timestamp_ms=d.get("last_updated_timestamp_ms", None),
3775
+ model_id=d.get("model_id", None),
3776
+ model_type=d.get("model_type", None),
3777
+ name=d.get("name", None),
3778
+ source_run_id=d.get("source_run_id", None),
3779
+ status=_enum(d, "status", LoggedModelStatus),
3780
+ status_message=d.get("status_message", None),
3781
+ tags=_repeated_dict(d, "tags", LoggedModelTag),
3782
+ )
3783
+
3784
+
3785
+ @dataclass
3786
+ class LoggedModelParameter:
3787
+ """Parameter associated with a LoggedModel."""
3788
+
3789
+ key: Optional[str] = None
3790
+ """The key identifying this param."""
3791
+
3792
+ value: Optional[str] = None
3793
+ """The value of this param."""
3794
+
3795
+ def as_dict(self) -> dict:
3796
+ """Serializes the LoggedModelParameter into a dictionary suitable for use as a JSON request body."""
3797
+ body = {}
3798
+ if self.key is not None:
3799
+ body["key"] = self.key
3800
+ if self.value is not None:
3801
+ body["value"] = self.value
3802
+ return body
3803
+
3804
+ def as_shallow_dict(self) -> dict:
3805
+ """Serializes the LoggedModelParameter into a shallow dictionary of its immediate attributes."""
3806
+ body = {}
3807
+ if self.key is not None:
3808
+ body["key"] = self.key
3809
+ if self.value is not None:
3810
+ body["value"] = self.value
3811
+ return body
3812
+
3813
+ @classmethod
3814
+ def from_dict(cls, d: Dict[str, Any]) -> LoggedModelParameter:
3815
+ """Deserializes the LoggedModelParameter from a dictionary."""
3816
+ return cls(key=d.get("key", None), value=d.get("value", None))
3817
+
3818
+
3819
+ class LoggedModelStatus(Enum):
3820
+ """A LoggedModelStatus enum value represents the status of a logged model."""
3821
+
3822
+ LOGGED_MODEL_PENDING = "LOGGED_MODEL_PENDING"
3823
+ LOGGED_MODEL_READY = "LOGGED_MODEL_READY"
3824
+ LOGGED_MODEL_UPLOAD_FAILED = "LOGGED_MODEL_UPLOAD_FAILED"
3825
+
3826
+
3827
+ @dataclass
3828
+ class LoggedModelTag:
3829
+ """Tag for a LoggedModel."""
3830
+
3831
+ key: Optional[str] = None
3832
+ """The tag key."""
3833
+
3834
+ value: Optional[str] = None
3835
+ """The tag value."""
3836
+
3837
+ def as_dict(self) -> dict:
3838
+ """Serializes the LoggedModelTag into a dictionary suitable for use as a JSON request body."""
3839
+ body = {}
3840
+ if self.key is not None:
3841
+ body["key"] = self.key
3842
+ if self.value is not None:
3843
+ body["value"] = self.value
3844
+ return body
3845
+
3846
+ def as_shallow_dict(self) -> dict:
3847
+ """Serializes the LoggedModelTag into a shallow dictionary of its immediate attributes."""
3848
+ body = {}
3849
+ if self.key is not None:
3850
+ body["key"] = self.key
3851
+ if self.value is not None:
3852
+ body["value"] = self.value
3853
+ return body
3854
+
3855
+ @classmethod
3856
+ def from_dict(cls, d: Dict[str, Any]) -> LoggedModelTag:
3857
+ """Deserializes the LoggedModelTag from a dictionary."""
3858
+ return cls(key=d.get("key", None), value=d.get("value", None))
3859
+
3860
+
3861
+ @dataclass
3862
+ class Metric:
3863
+ """Metric associated with a run, represented as a key-value pair."""
3864
+
3865
+ dataset_digest: Optional[str] = None
3866
+ """The dataset digest of the dataset associated with the metric, e.g. an md5 hash of the dataset
3867
+ that uniquely identifies it within datasets of the same name."""
3868
+
3869
+ dataset_name: Optional[str] = None
3870
+ """The name of the dataset associated with the metric. E.g. “my.uc.table@2”
3871
+ “nyc-taxi-dataset”, “fantastic-elk-3”"""
3872
+
3873
+ key: Optional[str] = None
3874
+ """The key identifying the metric."""
3875
+
3876
+ model_id: Optional[str] = None
3877
+ """The ID of the logged model or registered model version associated with the metric, if
3878
+ applicable."""
3261
3879
 
3262
3880
  run_id: Optional[str] = None
3263
3881
  """The ID of the run containing the metric."""
@@ -3523,6 +4141,40 @@ class ModelInput:
3523
4141
  return cls(model_id=d.get("model_id", None))
3524
4142
 
3525
4143
 
4144
+ @dataclass
4145
+ class ModelOutput:
4146
+ """Represents a LoggedModel output of a Run."""
4147
+
4148
+ model_id: str
4149
+ """The unique identifier of the model."""
4150
+
4151
+ step: int
4152
+ """The step at which the model was produced."""
4153
+
4154
+ def as_dict(self) -> dict:
4155
+ """Serializes the ModelOutput into a dictionary suitable for use as a JSON request body."""
4156
+ body = {}
4157
+ if self.model_id is not None:
4158
+ body["model_id"] = self.model_id
4159
+ if self.step is not None:
4160
+ body["step"] = self.step
4161
+ return body
4162
+
4163
+ def as_shallow_dict(self) -> dict:
4164
+ """Serializes the ModelOutput into a shallow dictionary of its immediate attributes."""
4165
+ body = {}
4166
+ if self.model_id is not None:
4167
+ body["model_id"] = self.model_id
4168
+ if self.step is not None:
4169
+ body["step"] = self.step
4170
+ return body
4171
+
4172
+ @classmethod
4173
+ def from_dict(cls, d: Dict[str, Any]) -> ModelOutput:
4174
+ """Deserializes the ModelOutput from a dictionary."""
4175
+ return cls(model_id=d.get("model_id", None), step=d.get("step", None))
4176
+
4177
+
3526
4178
  @dataclass
3527
4179
  class ModelTag:
3528
4180
  key: Optional[str] = None
@@ -4903,49 +5555,246 @@ class RunTag:
4903
5555
  return body
4904
5556
 
4905
5557
  @classmethod
4906
- def from_dict(cls, d: Dict[str, Any]) -> RunTag:
4907
- """Deserializes the RunTag from a dictionary."""
4908
- return cls(key=d.get("key", None), value=d.get("value", None))
5558
+ def from_dict(cls, d: Dict[str, Any]) -> RunTag:
5559
+ """Deserializes the RunTag from a dictionary."""
5560
+ return cls(key=d.get("key", None), value=d.get("value", None))
5561
+
5562
+
5563
+ @dataclass
5564
+ class SearchExperiments:
5565
+ filter: Optional[str] = None
5566
+ """String representing a SQL filter condition (e.g. "name ILIKE 'my-experiment%'")"""
5567
+
5568
+ max_results: Optional[int] = None
5569
+ """Maximum number of experiments desired. Max threshold is 3000."""
5570
+
5571
+ order_by: Optional[List[str]] = None
5572
+ """List of columns for ordering search results, which can include experiment name and last updated
5573
+ timestamp with an optional "DESC" or "ASC" annotation, where "ASC" is the default. Tiebreaks are
5574
+ done by experiment id DESC."""
5575
+
5576
+ page_token: Optional[str] = None
5577
+ """Token indicating the page of experiments to fetch"""
5578
+
5579
+ view_type: Optional[ViewType] = None
5580
+ """Qualifier for type of experiments to be returned. If unspecified, return only active
5581
+ experiments."""
5582
+
5583
+ def as_dict(self) -> dict:
5584
+ """Serializes the SearchExperiments into a dictionary suitable for use as a JSON request body."""
5585
+ body = {}
5586
+ if self.filter is not None:
5587
+ body["filter"] = self.filter
5588
+ if self.max_results is not None:
5589
+ body["max_results"] = self.max_results
5590
+ if self.order_by:
5591
+ body["order_by"] = [v for v in self.order_by]
5592
+ if self.page_token is not None:
5593
+ body["page_token"] = self.page_token
5594
+ if self.view_type is not None:
5595
+ body["view_type"] = self.view_type.value
5596
+ return body
5597
+
5598
+ def as_shallow_dict(self) -> dict:
5599
+ """Serializes the SearchExperiments into a shallow dictionary of its immediate attributes."""
5600
+ body = {}
5601
+ if self.filter is not None:
5602
+ body["filter"] = self.filter
5603
+ if self.max_results is not None:
5604
+ body["max_results"] = self.max_results
5605
+ if self.order_by:
5606
+ body["order_by"] = self.order_by
5607
+ if self.page_token is not None:
5608
+ body["page_token"] = self.page_token
5609
+ if self.view_type is not None:
5610
+ body["view_type"] = self.view_type
5611
+ return body
5612
+
5613
+ @classmethod
5614
+ def from_dict(cls, d: Dict[str, Any]) -> SearchExperiments:
5615
+ """Deserializes the SearchExperiments from a dictionary."""
5616
+ return cls(
5617
+ filter=d.get("filter", None),
5618
+ max_results=d.get("max_results", None),
5619
+ order_by=d.get("order_by", None),
5620
+ page_token=d.get("page_token", None),
5621
+ view_type=_enum(d, "view_type", ViewType),
5622
+ )
5623
+
5624
+
5625
+ @dataclass
5626
+ class SearchExperimentsResponse:
5627
+ experiments: Optional[List[Experiment]] = None
5628
+ """Experiments that match the search criteria"""
5629
+
5630
+ next_page_token: Optional[str] = None
5631
+ """Token that can be used to retrieve the next page of experiments. An empty token means that no
5632
+ more experiments are available for retrieval."""
5633
+
5634
+ def as_dict(self) -> dict:
5635
+ """Serializes the SearchExperimentsResponse into a dictionary suitable for use as a JSON request body."""
5636
+ body = {}
5637
+ if self.experiments:
5638
+ body["experiments"] = [v.as_dict() for v in self.experiments]
5639
+ if self.next_page_token is not None:
5640
+ body["next_page_token"] = self.next_page_token
5641
+ return body
5642
+
5643
+ def as_shallow_dict(self) -> dict:
5644
+ """Serializes the SearchExperimentsResponse into a shallow dictionary of its immediate attributes."""
5645
+ body = {}
5646
+ if self.experiments:
5647
+ body["experiments"] = self.experiments
5648
+ if self.next_page_token is not None:
5649
+ body["next_page_token"] = self.next_page_token
5650
+ return body
5651
+
5652
+ @classmethod
5653
+ def from_dict(cls, d: Dict[str, Any]) -> SearchExperimentsResponse:
5654
+ """Deserializes the SearchExperimentsResponse from a dictionary."""
5655
+ return cls(
5656
+ experiments=_repeated_dict(d, "experiments", Experiment), next_page_token=d.get("next_page_token", None)
5657
+ )
5658
+
5659
+
5660
+ @dataclass
5661
+ class SearchLoggedModelsDataset:
5662
+ dataset_name: str
5663
+ """The name of the dataset."""
5664
+
5665
+ dataset_digest: Optional[str] = None
5666
+ """The digest of the dataset."""
5667
+
5668
+ def as_dict(self) -> dict:
5669
+ """Serializes the SearchLoggedModelsDataset into a dictionary suitable for use as a JSON request body."""
5670
+ body = {}
5671
+ if self.dataset_digest is not None:
5672
+ body["dataset_digest"] = self.dataset_digest
5673
+ if self.dataset_name is not None:
5674
+ body["dataset_name"] = self.dataset_name
5675
+ return body
5676
+
5677
+ def as_shallow_dict(self) -> dict:
5678
+ """Serializes the SearchLoggedModelsDataset into a shallow dictionary of its immediate attributes."""
5679
+ body = {}
5680
+ if self.dataset_digest is not None:
5681
+ body["dataset_digest"] = self.dataset_digest
5682
+ if self.dataset_name is not None:
5683
+ body["dataset_name"] = self.dataset_name
5684
+ return body
5685
+
5686
+ @classmethod
5687
+ def from_dict(cls, d: Dict[str, Any]) -> SearchLoggedModelsDataset:
5688
+ """Deserializes the SearchLoggedModelsDataset from a dictionary."""
5689
+ return cls(dataset_digest=d.get("dataset_digest", None), dataset_name=d.get("dataset_name", None))
5690
+
5691
+
5692
+ @dataclass
5693
+ class SearchLoggedModelsOrderBy:
5694
+ field_name: str
5695
+ """The name of the field to order by, e.g. "metrics.accuracy"."""
5696
+
5697
+ ascending: Optional[bool] = None
5698
+ """Whether the search results order is ascending or not."""
5699
+
5700
+ dataset_digest: Optional[str] = None
5701
+ """If ``field_name`` refers to a metric, this field specifies the digest of the dataset associated
5702
+ with the metric. Only metrics associated with the specified dataset name and digest will be
5703
+ considered for ordering. This field may only be set if ``dataset_name`` is also set."""
5704
+
5705
+ dataset_name: Optional[str] = None
5706
+ """If ``field_name`` refers to a metric, this field specifies the name of the dataset associated
5707
+ with the metric. Only metrics associated with the specified dataset name will be considered for
5708
+ ordering. This field may only be set if ``field_name`` refers to a metric."""
5709
+
5710
+ def as_dict(self) -> dict:
5711
+ """Serializes the SearchLoggedModelsOrderBy into a dictionary suitable for use as a JSON request body."""
5712
+ body = {}
5713
+ if self.ascending is not None:
5714
+ body["ascending"] = self.ascending
5715
+ if self.dataset_digest is not None:
5716
+ body["dataset_digest"] = self.dataset_digest
5717
+ if self.dataset_name is not None:
5718
+ body["dataset_name"] = self.dataset_name
5719
+ if self.field_name is not None:
5720
+ body["field_name"] = self.field_name
5721
+ return body
5722
+
5723
+ def as_shallow_dict(self) -> dict:
5724
+ """Serializes the SearchLoggedModelsOrderBy into a shallow dictionary of its immediate attributes."""
5725
+ body = {}
5726
+ if self.ascending is not None:
5727
+ body["ascending"] = self.ascending
5728
+ if self.dataset_digest is not None:
5729
+ body["dataset_digest"] = self.dataset_digest
5730
+ if self.dataset_name is not None:
5731
+ body["dataset_name"] = self.dataset_name
5732
+ if self.field_name is not None:
5733
+ body["field_name"] = self.field_name
5734
+ return body
5735
+
5736
+ @classmethod
5737
+ def from_dict(cls, d: Dict[str, Any]) -> SearchLoggedModelsOrderBy:
5738
+ """Deserializes the SearchLoggedModelsOrderBy from a dictionary."""
5739
+ return cls(
5740
+ ascending=d.get("ascending", None),
5741
+ dataset_digest=d.get("dataset_digest", None),
5742
+ dataset_name=d.get("dataset_name", None),
5743
+ field_name=d.get("field_name", None),
5744
+ )
4909
5745
 
4910
5746
 
4911
5747
  @dataclass
4912
- class SearchExperiments:
5748
+ class SearchLoggedModelsRequest:
5749
+ datasets: Optional[List[SearchLoggedModelsDataset]] = None
5750
+ """List of datasets on which to apply the metrics filter clauses. For example, a filter with
5751
+ `metrics.accuracy > 0.9` and dataset info with name "test_dataset" means we will return all
5752
+ logged models with accuracy > 0.9 on the test_dataset. Metric values from ANY dataset matching
5753
+ the criteria are considered. If no datasets are specified, then metrics across all datasets are
5754
+ considered in the filter."""
5755
+
5756
+ experiment_ids: Optional[List[str]] = None
5757
+ """The IDs of the experiments in which to search for logged models."""
5758
+
4913
5759
  filter: Optional[str] = None
4914
- """String representing a SQL filter condition (e.g. "name ILIKE 'my-experiment%'")"""
5760
+ """A filter expression over logged model info and data that allows returning a subset of logged
5761
+ models. The syntax is a subset of SQL that supports AND'ing together binary operations.
5762
+
5763
+ Example: ``params.alpha < 0.3 AND metrics.accuracy > 0.9``."""
4915
5764
 
4916
5765
  max_results: Optional[int] = None
4917
- """Maximum number of experiments desired. Max threshold is 3000."""
5766
+ """The maximum number of Logged Models to return. The maximum limit is 50."""
4918
5767
 
4919
- order_by: Optional[List[str]] = None
4920
- """List of columns for ordering search results, which can include experiment name and last updated
4921
- timestamp with an optional "DESC" or "ASC" annotation, where "ASC" is the default. Tiebreaks are
4922
- done by experiment id DESC."""
5768
+ order_by: Optional[List[SearchLoggedModelsOrderBy]] = None
5769
+ """The list of columns for ordering the results, with additional fields for sorting criteria."""
4923
5770
 
4924
5771
  page_token: Optional[str] = None
4925
- """Token indicating the page of experiments to fetch"""
4926
-
4927
- view_type: Optional[ViewType] = None
4928
- """Qualifier for type of experiments to be returned. If unspecified, return only active
4929
- experiments."""
5772
+ """The token indicating the page of logged models to fetch."""
4930
5773
 
4931
5774
  def as_dict(self) -> dict:
4932
- """Serializes the SearchExperiments into a dictionary suitable for use as a JSON request body."""
5775
+ """Serializes the SearchLoggedModelsRequest into a dictionary suitable for use as a JSON request body."""
4933
5776
  body = {}
5777
+ if self.datasets:
5778
+ body["datasets"] = [v.as_dict() for v in self.datasets]
5779
+ if self.experiment_ids:
5780
+ body["experiment_ids"] = [v for v in self.experiment_ids]
4934
5781
  if self.filter is not None:
4935
5782
  body["filter"] = self.filter
4936
5783
  if self.max_results is not None:
4937
5784
  body["max_results"] = self.max_results
4938
5785
  if self.order_by:
4939
- body["order_by"] = [v for v in self.order_by]
5786
+ body["order_by"] = [v.as_dict() for v in self.order_by]
4940
5787
  if self.page_token is not None:
4941
5788
  body["page_token"] = self.page_token
4942
- if self.view_type is not None:
4943
- body["view_type"] = self.view_type.value
4944
5789
  return body
4945
5790
 
4946
5791
  def as_shallow_dict(self) -> dict:
4947
- """Serializes the SearchExperiments into a shallow dictionary of its immediate attributes."""
5792
+ """Serializes the SearchLoggedModelsRequest into a shallow dictionary of its immediate attributes."""
4948
5793
  body = {}
5794
+ if self.datasets:
5795
+ body["datasets"] = self.datasets
5796
+ if self.experiment_ids:
5797
+ body["experiment_ids"] = self.experiment_ids
4949
5798
  if self.filter is not None:
4950
5799
  body["filter"] = self.filter
4951
5800
  if self.max_results is not None:
@@ -4954,55 +5803,51 @@ class SearchExperiments:
4954
5803
  body["order_by"] = self.order_by
4955
5804
  if self.page_token is not None:
4956
5805
  body["page_token"] = self.page_token
4957
- if self.view_type is not None:
4958
- body["view_type"] = self.view_type
4959
5806
  return body
4960
5807
 
4961
5808
  @classmethod
4962
- def from_dict(cls, d: Dict[str, Any]) -> SearchExperiments:
4963
- """Deserializes the SearchExperiments from a dictionary."""
5809
+ def from_dict(cls, d: Dict[str, Any]) -> SearchLoggedModelsRequest:
5810
+ """Deserializes the SearchLoggedModelsRequest from a dictionary."""
4964
5811
  return cls(
5812
+ datasets=_repeated_dict(d, "datasets", SearchLoggedModelsDataset),
5813
+ experiment_ids=d.get("experiment_ids", None),
4965
5814
  filter=d.get("filter", None),
4966
5815
  max_results=d.get("max_results", None),
4967
- order_by=d.get("order_by", None),
5816
+ order_by=_repeated_dict(d, "order_by", SearchLoggedModelsOrderBy),
4968
5817
  page_token=d.get("page_token", None),
4969
- view_type=_enum(d, "view_type", ViewType),
4970
5818
  )
4971
5819
 
4972
5820
 
4973
5821
  @dataclass
4974
- class SearchExperimentsResponse:
4975
- experiments: Optional[List[Experiment]] = None
4976
- """Experiments that match the search criteria"""
5822
+ class SearchLoggedModelsResponse:
5823
+ models: Optional[List[LoggedModel]] = None
5824
+ """Logged models that match the search criteria."""
4977
5825
 
4978
5826
  next_page_token: Optional[str] = None
4979
- """Token that can be used to retrieve the next page of experiments. An empty token means that no
4980
- more experiments are available for retrieval."""
5827
+ """The token that can be used to retrieve the next page of logged models."""
4981
5828
 
4982
5829
  def as_dict(self) -> dict:
4983
- """Serializes the SearchExperimentsResponse into a dictionary suitable for use as a JSON request body."""
5830
+ """Serializes the SearchLoggedModelsResponse into a dictionary suitable for use as a JSON request body."""
4984
5831
  body = {}
4985
- if self.experiments:
4986
- body["experiments"] = [v.as_dict() for v in self.experiments]
5832
+ if self.models:
5833
+ body["models"] = [v.as_dict() for v in self.models]
4987
5834
  if self.next_page_token is not None:
4988
5835
  body["next_page_token"] = self.next_page_token
4989
5836
  return body
4990
5837
 
4991
5838
  def as_shallow_dict(self) -> dict:
4992
- """Serializes the SearchExperimentsResponse into a shallow dictionary of its immediate attributes."""
5839
+ """Serializes the SearchLoggedModelsResponse into a shallow dictionary of its immediate attributes."""
4993
5840
  body = {}
4994
- if self.experiments:
4995
- body["experiments"] = self.experiments
5841
+ if self.models:
5842
+ body["models"] = self.models
4996
5843
  if self.next_page_token is not None:
4997
5844
  body["next_page_token"] = self.next_page_token
4998
5845
  return body
4999
5846
 
5000
5847
  @classmethod
5001
- def from_dict(cls, d: Dict[str, Any]) -> SearchExperimentsResponse:
5002
- """Deserializes the SearchExperimentsResponse from a dictionary."""
5003
- return cls(
5004
- experiments=_repeated_dict(d, "experiments", Experiment), next_page_token=d.get("next_page_token", None)
5005
- )
5848
+ def from_dict(cls, d: Dict[str, Any]) -> SearchLoggedModelsResponse:
5849
+ """Deserializes the SearchLoggedModelsResponse from a dictionary."""
5850
+ return cls(models=_repeated_dict(d, "models", LoggedModel), next_page_token=d.get("next_page_token", None))
5006
5851
 
5007
5852
 
5008
5853
  @dataclass
@@ -5244,6 +6089,56 @@ class SetExperimentTagResponse:
5244
6089
  return cls()
5245
6090
 
5246
6091
 
6092
+ @dataclass
6093
+ class SetLoggedModelTagsRequest:
6094
+ model_id: Optional[str] = None
6095
+ """The ID of the logged model to set the tags on."""
6096
+
6097
+ tags: Optional[List[LoggedModelTag]] = None
6098
+ """The tags to set on the logged model."""
6099
+
6100
+ def as_dict(self) -> dict:
6101
+ """Serializes the SetLoggedModelTagsRequest into a dictionary suitable for use as a JSON request body."""
6102
+ body = {}
6103
+ if self.model_id is not None:
6104
+ body["model_id"] = self.model_id
6105
+ if self.tags:
6106
+ body["tags"] = [v.as_dict() for v in self.tags]
6107
+ return body
6108
+
6109
+ def as_shallow_dict(self) -> dict:
6110
+ """Serializes the SetLoggedModelTagsRequest into a shallow dictionary of its immediate attributes."""
6111
+ body = {}
6112
+ if self.model_id is not None:
6113
+ body["model_id"] = self.model_id
6114
+ if self.tags:
6115
+ body["tags"] = self.tags
6116
+ return body
6117
+
6118
+ @classmethod
6119
+ def from_dict(cls, d: Dict[str, Any]) -> SetLoggedModelTagsRequest:
6120
+ """Deserializes the SetLoggedModelTagsRequest from a dictionary."""
6121
+ return cls(model_id=d.get("model_id", None), tags=_repeated_dict(d, "tags", LoggedModelTag))
6122
+
6123
+
6124
+ @dataclass
6125
+ class SetLoggedModelTagsResponse:
6126
+ def as_dict(self) -> dict:
6127
+ """Serializes the SetLoggedModelTagsResponse into a dictionary suitable for use as a JSON request body."""
6128
+ body = {}
6129
+ return body
6130
+
6131
+ def as_shallow_dict(self) -> dict:
6132
+ """Serializes the SetLoggedModelTagsResponse into a shallow dictionary of its immediate attributes."""
6133
+ body = {}
6134
+ return body
6135
+
6136
+ @classmethod
6137
+ def from_dict(cls, d: Dict[str, Any]) -> SetLoggedModelTagsResponse:
6138
+ """Deserializes the SetLoggedModelTagsResponse from a dictionary."""
6139
+ return cls()
6140
+
6141
+
5247
6142
  @dataclass
5248
6143
  class SetModelTagRequest:
5249
6144
  name: str
@@ -6208,6 +7103,54 @@ class ExperimentsAPI:
6208
7103
  res = self._api.do("POST", "/api/2.0/mlflow/experiments/create", body=body, headers=headers)
6209
7104
  return CreateExperimentResponse.from_dict(res)
6210
7105
 
7106
+ def create_logged_model(
7107
+ self,
7108
+ experiment_id: str,
7109
+ *,
7110
+ model_type: Optional[str] = None,
7111
+ name: Optional[str] = None,
7112
+ params: Optional[List[LoggedModelParameter]] = None,
7113
+ source_run_id: Optional[str] = None,
7114
+ tags: Optional[List[LoggedModelTag]] = None,
7115
+ ) -> CreateLoggedModelResponse:
7116
+ """Create a logged model.
7117
+
7118
+ :param experiment_id: str
7119
+ The ID of the experiment that owns the model.
7120
+ :param model_type: str (optional)
7121
+ The type of the model, such as ``"Agent"``, ``"Classifier"``, ``"LLM"``.
7122
+ :param name: str (optional)
7123
+ The name of the model (optional). If not specified one will be generated.
7124
+ :param params: List[:class:`LoggedModelParameter`] (optional)
7125
+ Parameters attached to the model.
7126
+ :param source_run_id: str (optional)
7127
+ The ID of the run that created the model.
7128
+ :param tags: List[:class:`LoggedModelTag`] (optional)
7129
+ Tags attached to the model.
7130
+
7131
+ :returns: :class:`CreateLoggedModelResponse`
7132
+ """
7133
+ body = {}
7134
+ if experiment_id is not None:
7135
+ body["experiment_id"] = experiment_id
7136
+ if model_type is not None:
7137
+ body["model_type"] = model_type
7138
+ if name is not None:
7139
+ body["name"] = name
7140
+ if params is not None:
7141
+ body["params"] = [v.as_dict() for v in params]
7142
+ if source_run_id is not None:
7143
+ body["source_run_id"] = source_run_id
7144
+ if tags is not None:
7145
+ body["tags"] = [v.as_dict() for v in tags]
7146
+ headers = {
7147
+ "Accept": "application/json",
7148
+ "Content-Type": "application/json",
7149
+ }
7150
+
7151
+ res = self._api.do("POST", "/api/2.0/mlflow/logged-models", body=body, headers=headers)
7152
+ return CreateLoggedModelResponse.from_dict(res)
7153
+
6211
7154
  def create_run(
6212
7155
  self,
6213
7156
  *,
@@ -6277,6 +7220,38 @@ class ExperimentsAPI:
6277
7220
 
6278
7221
  self._api.do("POST", "/api/2.0/mlflow/experiments/delete", body=body, headers=headers)
6279
7222
 
7223
+ def delete_logged_model(self, model_id: str):
7224
+ """Delete a logged model.
7225
+
7226
+ :param model_id: str
7227
+ The ID of the logged model to delete.
7228
+
7229
+
7230
+ """
7231
+
7232
+ headers = {
7233
+ "Accept": "application/json",
7234
+ }
7235
+
7236
+ self._api.do("DELETE", f"/api/2.0/mlflow/logged-models/{model_id}", headers=headers)
7237
+
7238
+ def delete_logged_model_tag(self, model_id: str, tag_key: str):
7239
+ """Delete a tag on a logged model.
7240
+
7241
+ :param model_id: str
7242
+ The ID of the logged model to delete the tag from.
7243
+ :param tag_key: str
7244
+ The tag key.
7245
+
7246
+
7247
+ """
7248
+
7249
+ headers = {
7250
+ "Accept": "application/json",
7251
+ }
7252
+
7253
+ self._api.do("DELETE", f"/api/2.0/mlflow/logged-models/{model_id}/tags/{tag_key}", headers=headers)
7254
+
6280
7255
  def delete_run(self, run_id: str):
6281
7256
  """Delete a run.
6282
7257
 
@@ -6357,6 +7332,28 @@ class ExperimentsAPI:
6357
7332
 
6358
7333
  self._api.do("POST", "/api/2.0/mlflow/runs/delete-tag", body=body, headers=headers)
6359
7334
 
7335
+ def finalize_logged_model(self, model_id: str, status: LoggedModelStatus) -> FinalizeLoggedModelResponse:
7336
+ """Finalize a logged model.
7337
+
7338
+ :param model_id: str
7339
+ The ID of the logged model to finalize.
7340
+ :param status: :class:`LoggedModelStatus`
7341
+ Whether or not the model is ready for use. ``"LOGGED_MODEL_UPLOAD_FAILED"`` indicates that something
7342
+ went wrong when logging the model weights / agent code).
7343
+
7344
+ :returns: :class:`FinalizeLoggedModelResponse`
7345
+ """
7346
+ body = {}
7347
+ if status is not None:
7348
+ body["status"] = status.value
7349
+ headers = {
7350
+ "Accept": "application/json",
7351
+ "Content-Type": "application/json",
7352
+ }
7353
+
7354
+ res = self._api.do("PATCH", f"/api/2.0/mlflow/logged-models/{model_id}", body=body, headers=headers)
7355
+ return FinalizeLoggedModelResponse.from_dict(res)
7356
+
6360
7357
  def get_by_name(self, experiment_name: str) -> GetExperimentByNameResponse:
6361
7358
  """Get an experiment by name.
6362
7359
 
@@ -6490,6 +7487,22 @@ class ExperimentsAPI:
6490
7487
  return
6491
7488
  query["page_token"] = json["next_page_token"]
6492
7489
 
7490
+ def get_logged_model(self, model_id: str) -> GetLoggedModelResponse:
7491
+ """Get a logged model.
7492
+
7493
+ :param model_id: str
7494
+ The ID of the logged model to retrieve.
7495
+
7496
+ :returns: :class:`GetLoggedModelResponse`
7497
+ """
7498
+
7499
+ headers = {
7500
+ "Accept": "application/json",
7501
+ }
7502
+
7503
+ res = self._api.do("GET", f"/api/2.0/mlflow/logged-models/{model_id}", headers=headers)
7504
+ return GetLoggedModelResponse.from_dict(res)
7505
+
6493
7506
  def get_permission_levels(self, experiment_id: str) -> GetExperimentPermissionLevelsResponse:
6494
7507
  """Get experiment permission levels.
6495
7508
 
@@ -6653,6 +7666,41 @@ class ExperimentsAPI:
6653
7666
  return
6654
7667
  query["page_token"] = json["next_page_token"]
6655
7668
 
7669
+ def list_logged_model_artifacts(
7670
+ self, model_id: str, *, artifact_directory_path: Optional[str] = None, page_token: Optional[str] = None
7671
+ ) -> ListLoggedModelArtifactsResponse:
7672
+ """List artifacts for a logged model.
7673
+
7674
+ List artifacts for a logged model. Takes an optional ``artifact_directory_path`` prefix which if
7675
+ specified, the response contains only artifacts with the specified prefix.
7676
+
7677
+ :param model_id: str
7678
+ The ID of the logged model for which to list the artifacts.
7679
+ :param artifact_directory_path: str (optional)
7680
+ Filter artifacts matching this path (a relative path from the root artifact directory).
7681
+ :param page_token: str (optional)
7682
+ Token indicating the page of artifact results to fetch. `page_token` is not supported when listing
7683
+ artifacts in UC Volumes. A maximum of 1000 artifacts will be retrieved for UC Volumes. Please call
7684
+ `/api/2.0/fs/directories{directory_path}` for listing artifacts in UC Volumes, which supports
7685
+ pagination. See [List directory contents | Files API](/api/workspace/files/listdirectorycontents).
7686
+
7687
+ :returns: :class:`ListLoggedModelArtifactsResponse`
7688
+ """
7689
+
7690
+ query = {}
7691
+ if artifact_directory_path is not None:
7692
+ query["artifact_directory_path"] = artifact_directory_path
7693
+ if page_token is not None:
7694
+ query["page_token"] = page_token
7695
+ headers = {
7696
+ "Accept": "application/json",
7697
+ }
7698
+
7699
+ res = self._api.do(
7700
+ "GET", f"/api/2.0/mlflow/logged-models/{model_id}/artifacts/directories", query=query, headers=headers
7701
+ )
7702
+ return ListLoggedModelArtifactsResponse.from_dict(res)
7703
+
6656
7704
  def log_batch(
6657
7705
  self,
6658
7706
  *,
@@ -6766,6 +7814,30 @@ class ExperimentsAPI:
6766
7814
 
6767
7815
  self._api.do("POST", "/api/2.0/mlflow/runs/log-inputs", body=body, headers=headers)
6768
7816
 
7817
+ def log_logged_model_params(self, model_id: str, *, params: Optional[List[LoggedModelParameter]] = None):
7818
+ """Log params for a logged model.
7819
+
7820
+ Logs params for a logged model. A param is a key-value pair (string key, string value). Examples
7821
+ include hyperparameters used for ML model training. A param can be logged only once for a logged
7822
+ model, and attempting to overwrite an existing param with a different value will result in an error
7823
+
7824
+ :param model_id: str
7825
+ The ID of the logged model to log params for.
7826
+ :param params: List[:class:`LoggedModelParameter`] (optional)
7827
+ Parameters to attach to the model.
7828
+
7829
+
7830
+ """
7831
+ body = {}
7832
+ if params is not None:
7833
+ body["params"] = [v.as_dict() for v in params]
7834
+ headers = {
7835
+ "Accept": "application/json",
7836
+ "Content-Type": "application/json",
7837
+ }
7838
+
7839
+ self._api.do("POST", f"/api/2.0/mlflow/logged-models/{model_id}/params", body=body, headers=headers)
7840
+
6769
7841
  def log_metric(
6770
7842
  self,
6771
7843
  key: str,
@@ -6859,6 +7931,32 @@ class ExperimentsAPI:
6859
7931
 
6860
7932
  self._api.do("POST", "/api/2.0/mlflow/runs/log-model", body=body, headers=headers)
6861
7933
 
7934
+ def log_outputs(self, run_id: str, *, models: Optional[List[ModelOutput]] = None):
7935
+ """Log outputs from a run.
7936
+
7937
+ **NOTE**: Experimental: This API may change or be removed in a future release without warning.
7938
+
7939
+ Logs outputs, such as models, from an MLflow Run.
7940
+
7941
+ :param run_id: str
7942
+ The ID of the Run from which to log outputs.
7943
+ :param models: List[:class:`ModelOutput`] (optional)
7944
+ The model outputs from the Run.
7945
+
7946
+
7947
+ """
7948
+ body = {}
7949
+ if models is not None:
7950
+ body["models"] = [v.as_dict() for v in models]
7951
+ if run_id is not None:
7952
+ body["run_id"] = run_id
7953
+ headers = {
7954
+ "Accept": "application/json",
7955
+ "Content-Type": "application/json",
7956
+ }
7957
+
7958
+ self._api.do("POST", "/api/2.0/mlflow/runs/outputs", body=body, headers=headers)
7959
+
6862
7960
  def log_param(self, key: str, value: str, *, run_id: Optional[str] = None, run_uuid: Optional[str] = None):
6863
7961
  """Log a param for a run.
6864
7962
 
@@ -7028,6 +8126,63 @@ class ExperimentsAPI:
7028
8126
  return
7029
8127
  body["page_token"] = json["next_page_token"]
7030
8128
 
8129
+ def search_logged_models(
8130
+ self,
8131
+ *,
8132
+ datasets: Optional[List[SearchLoggedModelsDataset]] = None,
8133
+ experiment_ids: Optional[List[str]] = None,
8134
+ filter: Optional[str] = None,
8135
+ max_results: Optional[int] = None,
8136
+ order_by: Optional[List[SearchLoggedModelsOrderBy]] = None,
8137
+ page_token: Optional[str] = None,
8138
+ ) -> SearchLoggedModelsResponse:
8139
+ """Search logged models.
8140
+
8141
+ Search for Logged Models that satisfy specified search criteria.
8142
+
8143
+ :param datasets: List[:class:`SearchLoggedModelsDataset`] (optional)
8144
+ List of datasets on which to apply the metrics filter clauses. For example, a filter with
8145
+ `metrics.accuracy > 0.9` and dataset info with name "test_dataset" means we will return all logged
8146
+ models with accuracy > 0.9 on the test_dataset. Metric values from ANY dataset matching the criteria
8147
+ are considered. If no datasets are specified, then metrics across all datasets are considered in the
8148
+ filter.
8149
+ :param experiment_ids: List[str] (optional)
8150
+ The IDs of the experiments in which to search for logged models.
8151
+ :param filter: str (optional)
8152
+ A filter expression over logged model info and data that allows returning a subset of logged models.
8153
+ The syntax is a subset of SQL that supports AND'ing together binary operations.
8154
+
8155
+ Example: ``params.alpha < 0.3 AND metrics.accuracy > 0.9``.
8156
+ :param max_results: int (optional)
8157
+ The maximum number of Logged Models to return. The maximum limit is 50.
8158
+ :param order_by: List[:class:`SearchLoggedModelsOrderBy`] (optional)
8159
+ The list of columns for ordering the results, with additional fields for sorting criteria.
8160
+ :param page_token: str (optional)
8161
+ The token indicating the page of logged models to fetch.
8162
+
8163
+ :returns: :class:`SearchLoggedModelsResponse`
8164
+ """
8165
+ body = {}
8166
+ if datasets is not None:
8167
+ body["datasets"] = [v.as_dict() for v in datasets]
8168
+ if experiment_ids is not None:
8169
+ body["experiment_ids"] = [v for v in experiment_ids]
8170
+ if filter is not None:
8171
+ body["filter"] = filter
8172
+ if max_results is not None:
8173
+ body["max_results"] = max_results
8174
+ if order_by is not None:
8175
+ body["order_by"] = [v.as_dict() for v in order_by]
8176
+ if page_token is not None:
8177
+ body["page_token"] = page_token
8178
+ headers = {
8179
+ "Accept": "application/json",
8180
+ "Content-Type": "application/json",
8181
+ }
8182
+
8183
+ res = self._api.do("POST", "/api/2.0/mlflow/logged-models/search", body=body, headers=headers)
8184
+ return SearchLoggedModelsResponse.from_dict(res)
8185
+
7031
8186
  def search_runs(
7032
8187
  self,
7033
8188
  *,
@@ -7127,6 +8282,26 @@ class ExperimentsAPI:
7127
8282
 
7128
8283
  self._api.do("POST", "/api/2.0/mlflow/experiments/set-experiment-tag", body=body, headers=headers)
7129
8284
 
8285
+ def set_logged_model_tags(self, model_id: str, *, tags: Optional[List[LoggedModelTag]] = None):
8286
+ """Set a tag for a logged model.
8287
+
8288
+ :param model_id: str
8289
+ The ID of the logged model to set the tags on.
8290
+ :param tags: List[:class:`LoggedModelTag`] (optional)
8291
+ The tags to set on the logged model.
8292
+
8293
+
8294
+ """
8295
+ body = {}
8296
+ if tags is not None:
8297
+ body["tags"] = [v.as_dict() for v in tags]
8298
+ headers = {
8299
+ "Accept": "application/json",
8300
+ "Content-Type": "application/json",
8301
+ }
8302
+
8303
+ self._api.do("PATCH", f"/api/2.0/mlflow/logged-models/{model_id}/tags", body=body, headers=headers)
8304
+
7130
8305
  def set_permissions(
7131
8306
  self, experiment_id: str, *, access_control_list: Optional[List[ExperimentAccessControlRequest]] = None
7132
8307
  ) -> ExperimentPermissions: