Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Python SDK Changelog

## [Unreleased]

## [1.2.0] - 2026-06-04

### Added

- **Metric versions API: `client.metric_versions`**
- New `client.metric_versions.list(metric_id)`, `.create(metric_id, request)`, and `.deploy(metric_id, version_name)` methods (plus `*_async` variants) for managing a metric's immutable version history, backed by `/v1/metrics/{metric_id}/versions`. Each metric keeps a history of versions with one deployed at a time; pass `deploy_immediately=True` on create to atomically deploy the new version. Version request/response models are exported from `honeyhive.models`.

### Fixed

- **OTLP JSON exporter: serialize numeric fields as JSON strings**
- Integer span attributes (`intValue`) and uint64 timestamp fields
(`startTimeUnixNano`, `endTimeUnixNano`, `timeUnixNano`) were emitted as
raw JSON numbers. The protobuf JSON mapping spec requires these to be JSON
strings; values above 2^53 could otherwise lose precision silently through
float64 rounding. Now matches native `opentelemetry-exporter-otlp-proto-http`
behavior.
- **Decorator input capture: remove truncation of serialized list/dict values**
- List and dict span attributes are serialized to strings and
previously were truncated to 1000 characters in length. The arbitrary limit
of 1000 characters has been removed.

## [1.1.0] - 2026-05-19

### Added
Expand Down Expand Up @@ -49,7 +72,7 @@
### Removed

- **`honeyhive` Python CLI entry point removed from `pyproject.toml`**
- The shipped Python `honeyhive` console script was non-functional (dead code) and shadowed the official TypeScript CLI on `$PATH`. CLI functionality is now provided by the official [`honeyhive` TypeScript CLI](https://docs.honeyhive.ai/v2/sdk-reference/cli); removing the Python script entry point lets `honeyhive` resolve correctly when both packages are installed globally.
- The shipped Python `honeyhive` console script was non-functional (dead code) and shadowed the official TypeScript CLI on `$PATH`. CLI functionality is now provided by the official [`honeyhive` TypeScript CLI](https://docs.honeyhive.ai/v2/cli-reference/getting-started); removing the Python script entry point lets `honeyhive` resolve correctly when both packages are installed globally.

## [1.0.1] - 2026-05-05

Expand Down Expand Up @@ -82,6 +105,8 @@ The changes below are relative to `1.0.0rc22`. For the full picture of what ship
- **`DeleteMetricQuery` removed from `honeyhive.models`**
- Internal query-params type that was exported but unused — no public method accepted or returned it. The public `client.metrics.delete(id=...)` signature is unchanged.

<!-- changelog:legacy-below -->

## [1.0.0rc22] - 2026-05-01

### Added
Expand Down
633 changes: 569 additions & 64 deletions openapi/v1.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ dev = [
"pytest-asyncio>=0.21.0",
"pytest-cov>=7.0.0",
"pytest-mock>=3.10.0",
"pytest-rerunfailures>=16.3",
"pytest-xdist>=3.0.0",
"tox>=4.0.0",
"ruff>=0.4.0",
Expand Down
2 changes: 1 addition & 1 deletion src/honeyhive/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Version must be defined BEFORE imports to avoid circular import issues
# Version must be semver or semver followed by "a" (alpha), "b" (beta), or "rc"
# (release candidate) + a number
__version__ = "1.1.0"
__version__ = "1.2.0"

# Main API client
from .api import HoneyHive
Expand Down
21 changes: 21 additions & 0 deletions src/honeyhive/_generated/models/CreateMetricVersionParams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

__all__ = ["CreateMetricVersionParams"]


class CreateMetricVersionParams(BaseModel):
"""
CreateMetricVersionParams model
Path parameters for POST /v1/metrics/{metric_id}/versions
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

metric_id: str = Field(validation_alias="metric_id")
29 changes: 29 additions & 0 deletions src/honeyhive/_generated/models/CreateMetricVersionRequest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersionContentRequest import MetricVersionContentRequest

__all__ = ["CreateMetricVersionRequest"]


class CreateMetricVersionRequest(BaseModel):
"""
CreateMetricVersionRequest model
Request body for POST /v1/metrics/{metric_id}/versions
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

message: str = Field(validation_alias="message")

content: MetricVersionContentRequest = Field(validation_alias="content")

deploy_immediately: Optional[bool] = Field(
validation_alias="deploy_immediately", default=None
)
25 changes: 25 additions & 0 deletions src/honeyhive/_generated/models/CreateMetricVersionResponse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersion import MetricVersion

__all__ = ["CreateMetricVersionResponse"]


class CreateMetricVersionResponse(BaseModel):
"""
CreateMetricVersionResponse model
Response for POST /v1/metrics/{metric_id}/versions
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

success: bool = Field(validation_alias="success")

data: MetricVersion = Field(validation_alias="data")
23 changes: 23 additions & 0 deletions src/honeyhive/_generated/models/DeployMetricVersionParams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

__all__ = ["DeployMetricVersionParams"]


class DeployMetricVersionParams(BaseModel):
"""
DeployMetricVersionParams model
Path parameters for POST /v1/metrics/{metric_id}/versions/{version_name}/deploy
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

metric_id: str = Field(validation_alias="metric_id")

version_name: str = Field(validation_alias="version_name")
25 changes: 25 additions & 0 deletions src/honeyhive/_generated/models/DeployMetricVersionResponse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersion import MetricVersion

__all__ = ["DeployMetricVersionResponse"]


class DeployMetricVersionResponse(BaseModel):
"""
DeployMetricVersionResponse model
Response for POST /v1/metrics/{metric_id}/versions/{version_name}/deploy
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

success: bool = Field(validation_alias="success")

data: MetricVersion = Field(validation_alias="data")
21 changes: 21 additions & 0 deletions src/honeyhive/_generated/models/GetMetricVersionsParams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

__all__ = ["GetMetricVersionsParams"]


class GetMetricVersionsParams(BaseModel):
"""
GetMetricVersionsParams model
Path parameters for GET /v1/metrics/{metric_id}/versions
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

metric_id: str = Field(validation_alias="metric_id")
25 changes: 25 additions & 0 deletions src/honeyhive/_generated/models/GetMetricVersionsResponse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersion import MetricVersion

__all__ = ["GetMetricVersionsResponse"]


class GetMetricVersionsResponse(BaseModel):
"""
GetMetricVersionsResponse model
Response for GET /v1/metrics/{metric_id}/versions
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

success: bool = Field(validation_alias="success")

data: List[MetricVersion] = Field(validation_alias="data")
33 changes: 33 additions & 0 deletions src/honeyhive/_generated/models/MetricVersion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersionContent import MetricVersionContent

__all__ = ["MetricVersion"]


class MetricVersion(BaseModel):
"""
MetricVersion model
A versioned snapshot of a metric definition.
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

name: str = Field(validation_alias="name")

full_sha: str = Field(validation_alias="full_sha")

message: str = Field(validation_alias="message")

date: str = Field(validation_alias="date")

deployed: bool = Field(validation_alias="deployed")

content: MetricVersionContent = Field(validation_alias="content")
57 changes: 57 additions & 0 deletions src/honeyhive/_generated/models/MetricVersionContent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .MetricVersionContentFilters import MetricVersionContentFilters

__all__ = ["MetricVersionContent"]


class MetricVersionContent(BaseModel):
"""
MetricVersionContent model
Versioned snapshot of a metric definition.
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

name: str = Field(validation_alias="name")

type: str = Field(validation_alias="type")

criteria: str = Field(validation_alias="criteria")

description: Optional[str] = Field(validation_alias="description")

return_type: str = Field(validation_alias="return_type")

enabled_in_prod: bool = Field(validation_alias="enabled_in_prod")

needs_ground_truth: bool = Field(validation_alias="needs_ground_truth")

sampling_percentage: float = Field(validation_alias="sampling_percentage")

model_provider: Optional[str] = Field(
validation_alias="model_provider", default=None
)

model_name: Optional[str] = Field(validation_alias="model_name", default=None)

scale: Optional[int] = Field(validation_alias="scale", default=None)

threshold: Optional[Dict[str, Any]] = Field(
validation_alias="threshold", default=None
)

categories: Optional[List[Any]] = Field(validation_alias="categories", default=None)

child_metrics: Optional[List[Any]] = Field(
validation_alias="child_metrics", default=None
)

filters: MetricVersionContentFilters = Field(validation_alias="filters")
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

__all__ = ["MetricVersionContentCategoriesItem"]


class MetricVersionContentCategoriesItem(BaseModel):
"""
MetricVersionContentCategoriesItem model
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

category: str = Field(validation_alias="category")

score: Optional[float] = Field(validation_alias="score")
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

__all__ = ["MetricVersionContentChildMetricsItem"]


class MetricVersionContentChildMetricsItem(BaseModel):
"""
MetricVersionContentChildMetricsItem model
"""

model_config = {
"populate_by_name": True,
"validate_assignment": True,
"extra": "allow",
"protected_namespaces": (),
}

id: Optional[str] = Field(validation_alias="id", default=None)

name: str = Field(validation_alias="name")

weight: float = Field(validation_alias="weight")

scale: Optional[int] = Field(validation_alias="scale", default=None)
Loading