From 9825aa619dcb6deb209ce571121127baaf0ad07d Mon Sep 17 00:00:00 2001 From: aittalam <4476645+aittalam@users.noreply.github.com> Date: Sat, 17 Oct 2026 12:24:09 +0000 Subject: [PATCH] feat: regenerate SDK client core from Otari OpenAPI spec --- src/otari/_client/__init__.py | 2 + src/otari/_client/models/__init__.py | 1 + src/otari/_client/models/tool_charge_line.py | 113 ++++++++++++++++++ .../usage_entry_pricing_breakdown_inner.py | 43 ++++--- 4 files changed, 145 insertions(+), 14 deletions(-) create mode 100644 src/otari/_client/models/tool_charge_line.py diff --git a/src/otari/_client/__init__.py b/src/otari/_client/__init__.py index 440127d2..a9e93fea 100644 --- a/src/otari/_client/__init__.py +++ b/src/otari/_client/__init__.py @@ -682,6 +682,7 @@ "TextResourceContents", "TokenChargeLine", "ToolCallsInner", + "ToolChargeLine", "ToolChoice", "ToolChoice1", "ToolMeter", @@ -1439,6 +1440,7 @@ from otari._client.models.text_resource_contents import TextResourceContents as TextResourceContents from otari._client.models.token_charge_line import TokenChargeLine as TokenChargeLine from otari._client.models.tool_calls_inner import ToolCallsInner as ToolCallsInner +from otari._client.models.tool_charge_line import ToolChargeLine as ToolChargeLine from otari._client.models.tool_choice import ToolChoice as ToolChoice from otari._client.models.tool_choice1 import ToolChoice1 as ToolChoice1 from otari._client.models.tool_meter import ToolMeter as ToolMeter diff --git a/src/otari/_client/models/__init__.py b/src/otari/_client/models/__init__.py index 4ae9ab97..7684848a 100644 --- a/src/otari/_client/models/__init__.py +++ b/src/otari/_client/models/__init__.py @@ -606,6 +606,7 @@ from otari._client.models.text_resource_contents import TextResourceContents from otari._client.models.token_charge_line import TokenChargeLine from otari._client.models.tool_calls_inner import ToolCallsInner +from otari._client.models.tool_charge_line import ToolChargeLine from otari._client.models.tool_choice import ToolChoice from otari._client.models.tool_choice1 import ToolChoice1 from otari._client.models.tool_meter import ToolMeter diff --git a/src/otari/_client/models/tool_charge_line.py b/src/otari/_client/models/tool_charge_line.py new file mode 100644 index 00000000..09763791 --- /dev/null +++ b/src/otari/_client/models/tool_charge_line.py @@ -0,0 +1,113 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Union +from otari._client.models.units1 import Units1 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ToolChargeLine(BaseModel): + """ + A gateway-run tool's charge line, one per tool and label. A subclass with ``label`` required, rather than a defaulted field on :class:`UnitChargeLine`, so the per-request, rerank and image lines, and a stored tool line without a label, serialize back without a ``\"label\": null`` they never had. + """ # noqa: E501 + cost: Union[StrictFloat, StrictInt] = Field(description="USD charged for this line.") + label: StrictStr = Field(description="What served the calls: ':' for a search or fetch instance, 'builtin:builtin_fetch' for the built-in fetcher, 'org:' for an organization's own key, or 'otari:' for any other gateway-run tool.") + meter: StrictStr = Field(description="What was metered, e.g. 'request' or 'web_search_calls'.") + unit_rate: Union[StrictFloat, StrictInt] = Field(description="USD per call.") + units: Units1 + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cost", "label", "meter", "unit_rate", "units"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ToolChargeLine from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of units + if self.units: + _dict['units'] = self.units.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ToolChargeLine from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cost": obj.get("cost"), + "label": obj.get("label"), + "meter": obj.get("meter"), + "unit_rate": obj.get("unit_rate"), + "units": Units1.from_dict(obj["units"]) if obj.get("units") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/usage_entry_pricing_breakdown_inner.py b/src/otari/_client/models/usage_entry_pricing_breakdown_inner.py index 9a34445d..b6334c7c 100644 --- a/src/otari/_client/models/usage_entry_pricing_breakdown_inner.py +++ b/src/otari/_client/models/usage_entry_pricing_breakdown_inner.py @@ -20,29 +20,32 @@ from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator from typing import Any, Dict, Optional from otari._client.models.token_charge_line import TokenChargeLine +from otari._client.models.tool_charge_line import ToolChargeLine from otari._client.models.unit_charge_line import UnitChargeLine from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict from typing_extensions import Literal, Self from pydantic import Field -USAGEENTRYPRICINGBREAKDOWNINNER_ANY_OF_SCHEMAS = ["Dict[str, object]", "TokenChargeLine", "UnitChargeLine"] +USAGEENTRYPRICINGBREAKDOWNINNER_ANY_OF_SCHEMAS = ["Dict[str, object]", "TokenChargeLine", "ToolChargeLine", "UnitChargeLine"] class UsageEntryPricingBreakdownInner(BaseModel): """ UsageEntryPricingBreakdownInner """ + # data type: ToolChargeLine + anyof_schema_1_validator: Optional[ToolChargeLine] = None # data type: TokenChargeLine - anyof_schema_1_validator: Optional[TokenChargeLine] = None + anyof_schema_2_validator: Optional[TokenChargeLine] = None # data type: UnitChargeLine - anyof_schema_2_validator: Optional[UnitChargeLine] = None + anyof_schema_3_validator: Optional[UnitChargeLine] = None # data type: Dict[str, object] - anyof_schema_3_validator: Optional[Dict[str, Any]] = Field(default=None, description="Tags for cost attribution, recorded on the request's usage rows and filterable in the usage API: up to 16 string pairs, keys up to 64 characters and values up to 512. A null value is ignored. LiteLLM's nested `spend_logs_metadata` object is also read, and wins over a flat key of the same name; it is never forwarded to the provider.") + anyof_schema_4_validator: Optional[Dict[str, Any]] = Field(default=None, description="Tags for cost attribution, recorded on the request's usage rows and filterable in the usage API: up to 16 string pairs, keys up to 64 characters and values up to 512. A null value is ignored. LiteLLM's nested `spend_logs_metadata` object is also read, and wins over a flat key of the same name; it is never forwarded to the provider.") if TYPE_CHECKING: - actual_instance: Optional[Union[Dict[str, object], TokenChargeLine, UnitChargeLine]] = None + actual_instance: Optional[Union[Dict[str, object], TokenChargeLine, ToolChargeLine, UnitChargeLine]] = None else: actual_instance: Any = None - any_of_schemas: Set[str] = { "Dict[str, object]", "TokenChargeLine", "UnitChargeLine" } + any_of_schemas: Set[str] = { "Dict[str, object]", "TokenChargeLine", "ToolChargeLine", "UnitChargeLine" } model_config = { "validate_assignment": True, @@ -63,6 +66,12 @@ def __init__(self, *args, **kwargs) -> None: def actual_instance_must_validate_anyof(cls, v): instance = UsageEntryPricingBreakdownInner.model_construct() error_messages = [] + # validate data type: ToolChargeLine + if not isinstance(v, ToolChargeLine): + error_messages.append(f"Error! Input type `{type(v)}` is not `ToolChargeLine`") + else: + return v + # validate data type: TokenChargeLine if not isinstance(v, TokenChargeLine): error_messages.append(f"Error! Input type `{type(v)}` is not `TokenChargeLine`") @@ -77,13 +86,13 @@ def actual_instance_must_validate_anyof(cls, v): # validate data type: Dict[str, object] try: - instance.anyof_schema_3_validator = v + instance.anyof_schema_4_validator = v return v except (ValidationError, ValueError) as e: error_messages.append(str(e)) if error_messages: # no match - raise ValueError("No match found when setting the actual_instance in UsageEntryPricingBreakdownInner with anyOf schemas: Dict[str, object], TokenChargeLine, UnitChargeLine. Details: " + ", ".join(error_messages)) + raise ValueError("No match found when setting the actual_instance in UsageEntryPricingBreakdownInner with anyOf schemas: Dict[str, object], TokenChargeLine, ToolChargeLine, UnitChargeLine. Details: " + ", ".join(error_messages)) else: return v @@ -96,13 +105,19 @@ def from_json(cls, json_str: str) -> Self: """Returns the object represented by the json string""" instance = cls.model_construct() error_messages = [] - # anyof_schema_1_validator: Optional[TokenChargeLine] = None + # anyof_schema_1_validator: Optional[ToolChargeLine] = None + try: + instance.actual_instance = ToolChargeLine.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[TokenChargeLine] = None try: instance.actual_instance = TokenChargeLine.from_json(json_str) return instance except (ValidationError, ValueError) as e: error_messages.append(str(e)) - # anyof_schema_2_validator: Optional[UnitChargeLine] = None + # anyof_schema_3_validator: Optional[UnitChargeLine] = None try: instance.actual_instance = UnitChargeLine.from_json(json_str) return instance @@ -111,16 +126,16 @@ def from_json(cls, json_str: str) -> Self: # deserialize data into Dict[str, object] try: # validation - instance.anyof_schema_3_validator = json.loads(json_str) + instance.anyof_schema_4_validator = json.loads(json_str) # assign value to actual_instance - instance.actual_instance = instance.anyof_schema_3_validator + instance.actual_instance = instance.anyof_schema_4_validator return instance except (ValidationError, ValueError) as e: error_messages.append(str(e)) if error_messages: # no match - raise ValueError("No match found when deserializing the JSON string into UsageEntryPricingBreakdownInner with anyOf schemas: Dict[str, object], TokenChargeLine, UnitChargeLine. Details: " + ", ".join(error_messages)) + raise ValueError("No match found when deserializing the JSON string into UsageEntryPricingBreakdownInner with anyOf schemas: Dict[str, object], TokenChargeLine, ToolChargeLine, UnitChargeLine. Details: " + ", ".join(error_messages)) else: return instance @@ -134,7 +149,7 @@ def to_json(self) -> str: else: return json.dumps(self.actual_instance) - def to_dict(self) -> Optional[Union[Dict[str, Any], Dict[str, object], TokenChargeLine, UnitChargeLine]]: + def to_dict(self) -> Optional[Union[Dict[str, Any], Dict[str, object], TokenChargeLine, ToolChargeLine, UnitChargeLine]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None