diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b4e9013..6db19b9 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.16.0"
+ ".": "0.17.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index d1c4212..f5eb7d0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/premai%2Fpremai-25d63a01824adb74eba6e672fea1205184b5ed7105af5be98dc0b8e45bc65fad.yml
-openapi_spec_hash: b0c6d81a06eb23d7f31d3074afad7b2d
-config_hash: 4c4b619097d71f725c588da6ada0a0f5
+configured_endpoints: 17
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/premai%2Fpremai-d71329d1d7714d540c1a90fdb5178337061b3a73cb691a24b8869c25d4f0abcb.yml
+openapi_spec_hash: 9530f7daf03545cd24167b1adcb03f50
+config_hash: a84721ef021ce1dbb70854ae5ff9d7c5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a5b82a..5721867 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.17.0 (2025-11-12)
+
+Full Changelog: [v0.16.0...v0.17.0](https://github.com/premAI-io/prem-py-sdk/compare/v0.16.0...v0.17.0)
+
+### Features
+
+* **api:** api update ([739a8d7](https://github.com/premAI-io/prem-py-sdk/commit/739a8d7fa6b045c6e9c30fd7510245772344d50a))
+
## 0.16.0 (2025-11-12)
Full Changelog: [v0.15.4...v0.16.0](https://github.com/premAI-io/prem-py-sdk/compare/v0.15.4...v0.16.0)
diff --git a/api.md b/api.md
index 5d18db1..dcb0ef5 100644
--- a/api.md
+++ b/api.md
@@ -69,13 +69,12 @@ Methods:
Types:
```python
-from premai.types import SnapshotCreateResponse, SnapshotCreateFromFilesResponse
+from premai.types import SnapshotCreateResponse
```
Methods:
- client.snapshots.create(\*\*params) -> SnapshotCreateResponse
-- client.snapshots.create_from_files(\*\*params) -> SnapshotCreateFromFilesResponse
# Recommendations
diff --git a/pyproject.toml b/pyproject.toml
index 3ad3bb0..bedcaa5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "premai"
-version = "0.16.0"
+version = "0.17.0"
description = "The official Python library for the PremAI API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/premai/_version.py b/src/premai/_version.py
index a48e9b0..1c4bb0e 100644
--- a/src/premai/_version.py
+++ b/src/premai/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "premai"
-__version__ = "0.16.0" # x-release-please-version
+__version__ = "0.17.0" # x-release-please-version
diff --git a/src/premai/resources/snapshots.py b/src/premai/resources/snapshots.py
index 030b4d5..cf05152 100644
--- a/src/premai/resources/snapshots.py
+++ b/src/premai/resources/snapshots.py
@@ -2,13 +2,11 @@
from __future__ import annotations
-from typing import Mapping, cast
-
import httpx
-from ..types import snapshot_create_params, snapshot_create_from_files_params
-from .._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given
-from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
+from ..types import snapshot_create_params
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -19,7 +17,6 @@
)
from .._base_client import make_request_options
from ..types.snapshot_create_response import SnapshotCreateResponse
-from ..types.snapshot_create_from_files_response import SnapshotCreateFromFilesResponse
__all__ = ["SnapshotsResource", "AsyncSnapshotsResource"]
@@ -88,65 +85,6 @@ def create(
cast_to=SnapshotCreateResponse,
)
- def create_from_files(
- self,
- *,
- label: str,
- project_id: str,
- training_file: FileTypes,
- validation_file: FileTypes,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SnapshotCreateFromFilesResponse:
- """
- Create snapshot from separate training and validation files
-
- Args:
- label: Snapshot name shown in the dashboard once the snapshot is created.
-
- project_id: Project ID that will own the generated snapshot. Must match an existing project.
-
- training_file: Required JSONL training file. Upload line-delimited messages that will form the
- training split.
-
- validation_file: Required JSONL validation file. Upload line-delimited messages reserved for
- validation.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- body = deepcopy_minimal(
- {
- "label": label,
- "project_id": project_id,
- "training_file": training_file,
- "validation_file": validation_file,
- }
- )
- files = extract_files(cast(Mapping[str, object], body), paths=[["training_file"], ["validation_file"]])
- # It should be noted that the actual Content-Type header that will be
- # sent to the server will contain a `boundary` parameter, e.g.
- # multipart/form-data; boundary=---abc--
- extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
- return self._post(
- "/api/v1/public/snapshots/create-from-files",
- body=maybe_transform(body, snapshot_create_from_files_params.SnapshotCreateFromFilesParams),
- files=files,
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=SnapshotCreateFromFilesResponse,
- )
-
class AsyncSnapshotsResource(AsyncAPIResource):
@cached_property
@@ -212,65 +150,6 @@ async def create(
cast_to=SnapshotCreateResponse,
)
- async def create_from_files(
- self,
- *,
- label: str,
- project_id: str,
- training_file: FileTypes,
- validation_file: FileTypes,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SnapshotCreateFromFilesResponse:
- """
- Create snapshot from separate training and validation files
-
- Args:
- label: Snapshot name shown in the dashboard once the snapshot is created.
-
- project_id: Project ID that will own the generated snapshot. Must match an existing project.
-
- training_file: Required JSONL training file. Upload line-delimited messages that will form the
- training split.
-
- validation_file: Required JSONL validation file. Upload line-delimited messages reserved for
- validation.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- body = deepcopy_minimal(
- {
- "label": label,
- "project_id": project_id,
- "training_file": training_file,
- "validation_file": validation_file,
- }
- )
- files = extract_files(cast(Mapping[str, object], body), paths=[["training_file"], ["validation_file"]])
- # It should be noted that the actual Content-Type header that will be
- # sent to the server will contain a `boundary` parameter, e.g.
- # multipart/form-data; boundary=---abc--
- extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
- return await self._post(
- "/api/v1/public/snapshots/create-from-files",
- body=await async_maybe_transform(body, snapshot_create_from_files_params.SnapshotCreateFromFilesParams),
- files=files,
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=SnapshotCreateFromFilesResponse,
- )
-
class SnapshotsResourceWithRawResponse:
def __init__(self, snapshots: SnapshotsResource) -> None:
@@ -279,9 +158,6 @@ def __init__(self, snapshots: SnapshotsResource) -> None:
self.create = to_raw_response_wrapper(
snapshots.create,
)
- self.create_from_files = to_raw_response_wrapper(
- snapshots.create_from_files,
- )
class AsyncSnapshotsResourceWithRawResponse:
@@ -291,9 +167,6 @@ def __init__(self, snapshots: AsyncSnapshotsResource) -> None:
self.create = async_to_raw_response_wrapper(
snapshots.create,
)
- self.create_from_files = async_to_raw_response_wrapper(
- snapshots.create_from_files,
- )
class SnapshotsResourceWithStreamingResponse:
@@ -303,9 +176,6 @@ def __init__(self, snapshots: SnapshotsResource) -> None:
self.create = to_streamed_response_wrapper(
snapshots.create,
)
- self.create_from_files = to_streamed_response_wrapper(
- snapshots.create_from_files,
- )
class AsyncSnapshotsResourceWithStreamingResponse:
@@ -315,6 +185,3 @@ def __init__(self, snapshots: AsyncSnapshotsResource) -> None:
self.create = async_to_streamed_response_wrapper(
snapshots.create,
)
- self.create_from_files = async_to_streamed_response_wrapper(
- snapshots.create_from_files,
- )
diff --git a/src/premai/types/__init__.py b/src/premai/types/__init__.py
index 2bdab36..d1a8049 100644
--- a/src/premai/types/__init__.py
+++ b/src/premai/types/__init__.py
@@ -29,6 +29,4 @@
from .dataset_create_from_jsonl_params import DatasetCreateFromJSONLParams as DatasetCreateFromJSONLParams
from .recommendation_generate_response import RecommendationGenerateResponse as RecommendationGenerateResponse
from .dataset_create_synthetic_response import DatasetCreateSyntheticResponse as DatasetCreateSyntheticResponse
-from .snapshot_create_from_files_params import SnapshotCreateFromFilesParams as SnapshotCreateFromFilesParams
from .dataset_create_from_jsonl_response import DatasetCreateFromJSONLResponse as DatasetCreateFromJSONLResponse
-from .snapshot_create_from_files_response import SnapshotCreateFromFilesResponse as SnapshotCreateFromFilesResponse
diff --git a/src/premai/types/recommendation_get_response.py b/src/premai/types/recommendation_get_response.py
index cb8bb07..8448142 100644
--- a/src/premai/types/recommendation_get_response.py
+++ b/src/premai/types/recommendation_get_response.py
@@ -3,47 +3,64 @@
from typing import List, Optional
from typing_extensions import Literal
-from pydantic import Field as FieldInfo
-
from .._models import BaseModel
__all__ = [
"RecommendationGetResponse",
+ "RecommendedExperiment",
"RecommendedModel",
"RecommendedModelFullHyperparameters",
"RecommendedModelLoraHyperparameters",
]
+class RecommendedExperiment(BaseModel):
+ base_model_id: str
+
+ batch_size: int
+
+ learning_rate_multiplier: float
+
+ lora: bool
+
+ n_epochs: int
+
+ reason_for_recommendation: Optional[str] = None
+
+ recommended: bool
+
+
class RecommendedModelFullHyperparameters(BaseModel):
- batch_size: int = FieldInfo(alias="batchSize")
+ batch_size: int
- learning_rate_multiplier: float = FieldInfo(alias="learningRateMultiplier")
+ learning_rate_multiplier: float
- n_epochs: int = FieldInfo(alias="nEpochs")
+ n_epochs: int
class RecommendedModelLoraHyperparameters(BaseModel):
- batch_size: int = FieldInfo(alias="batchSize")
+ batch_size: int
- learning_rate_multiplier: float = FieldInfo(alias="learningRateMultiplier")
+ learning_rate_multiplier: float
- n_epochs: int = FieldInfo(alias="nEpochs")
+ n_epochs: int
class RecommendedModel(BaseModel):
- base_model_id: str = FieldInfo(alias="baseModelId")
+ base_model_id: str
- full_hyperparameters: RecommendedModelFullHyperparameters
+ full_hyperparameters: Optional[RecommendedModelFullHyperparameters] = None
- lora_hyperparameters: RecommendedModelLoraHyperparameters
+ lora_hyperparameters: Optional[RecommendedModelLoraHyperparameters] = None
- reason_for_recommendation: Optional[str] = FieldInfo(alias="reasonForRecommendation", default=None)
+ reason_for_recommendation: Optional[str] = None
recommended: bool
class RecommendationGetResponse(BaseModel):
+ recommended_experiments: Optional[List[RecommendedExperiment]] = None
+
recommended_models: Optional[List[RecommendedModel]] = None
snapshot_id: str
diff --git a/src/premai/types/snapshot_create_from_files_params.py b/src/premai/types/snapshot_create_from_files_params.py
deleted file mode 100644
index ee25bca..0000000
--- a/src/premai/types/snapshot_create_from_files_params.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-from .._types import FileTypes
-
-__all__ = ["SnapshotCreateFromFilesParams"]
-
-
-class SnapshotCreateFromFilesParams(TypedDict, total=False):
- label: Required[str]
- """Snapshot name shown in the dashboard once the snapshot is created."""
-
- project_id: Required[str]
- """Project ID that will own the generated snapshot.
-
- Must match an existing project.
- """
-
- training_file: Required[FileTypes]
- """Required JSONL training file.
-
- Upload line-delimited messages that will form the training split.
- """
-
- validation_file: Required[FileTypes]
- """Required JSONL validation file.
-
- Upload line-delimited messages reserved for validation.
- """
diff --git a/src/premai/types/snapshot_create_from_files_response.py b/src/premai/types/snapshot_create_from_files_response.py
deleted file mode 100644
index ab17412..0000000
--- a/src/premai/types/snapshot_create_from_files_response.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .._models import BaseModel
-
-__all__ = ["SnapshotCreateFromFilesResponse"]
-
-
-class SnapshotCreateFromFilesResponse(BaseModel):
- snapshot_id: str
diff --git a/tests/api_resources/test_snapshots.py b/tests/api_resources/test_snapshots.py
index dd59479..cea7f88 100644
--- a/tests/api_resources/test_snapshots.py
+++ b/tests/api_resources/test_snapshots.py
@@ -9,10 +9,7 @@
from premai import PremAI, AsyncPremAI
from tests.utils import assert_matches_type
-from premai.types import (
- SnapshotCreateResponse,
- SnapshotCreateFromFilesResponse,
-)
+from premai.types import SnapshotCreateResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -63,49 +60,6 @@ def test_streaming_response_create(self, client: PremAI) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_method_create_from_files(self, client: PremAI) -> None:
- snapshot = client.snapshots.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- )
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_raw_response_create_from_files(self, client: PremAI) -> None:
- response = client.snapshots.with_raw_response.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- snapshot = response.parse()
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_streaming_response_create_from_files(self, client: PremAI) -> None:
- with client.snapshots.with_streaming_response.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- snapshot = response.parse()
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
class TestAsyncSnapshots:
parametrize = pytest.mark.parametrize(
@@ -154,46 +108,3 @@ async def test_streaming_response_create(self, async_client: AsyncPremAI) -> Non
assert_matches_type(SnapshotCreateResponse, snapshot, path=["response"])
assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_method_create_from_files(self, async_client: AsyncPremAI) -> None:
- snapshot = await async_client.snapshots.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- )
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_raw_response_create_from_files(self, async_client: AsyncPremAI) -> None:
- response = await async_client.snapshots.with_raw_response.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- snapshot = await response.parse()
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_streaming_response_create_from_files(self, async_client: AsyncPremAI) -> None:
- async with async_client.snapshots.with_streaming_response.create_from_files(
- label="x",
- project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- training_file=b"raw file contents",
- validation_file=b"raw file contents",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- snapshot = await response.parse()
- assert_matches_type(SnapshotCreateFromFilesResponse, snapshot, path=["response"])
-
- assert cast(Any, response.is_closed) is True