Skip to content

Commit 8bd61dc

Browse files
authored
fix(api): list models parsing errors (#964)
1 parent a6ef70f commit 8bd61dc

File tree

6 files changed

+269
-93
lines changed

6 files changed

+269
-93
lines changed

langfuse/api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Finto Python Library
22

3-
[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-SDK%20generated%20by%20Fern-brightgreen)](https://github.com/fern-api/fern)
3+
[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=Finto%2FPython)
44
[![pypi](https://img.shields.io/pypi/v/finto)](https://pypi.python.org/pypi/finto)
55

66
The Finto Python library provides convenient access to the Finto API from Python.

langfuse/api/reference.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,15 +1061,15 @@ client.metrics.daily(
10611061
<dl>
10621062
<dd>
10631063

1064-
**from_timestamp:** `typing.Optional[dt.datetime]` — Optional filter to only include traces on or after a certain datetime (ISO 8601)
1064+
**from_timestamp:** `typing.Optional[dt.datetime]` — Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
10651065

10661066
</dd>
10671067
</dl>
10681068

10691069
<dl>
10701070
<dd>
10711071

1072-
**to_timestamp:** `typing.Optional[dt.datetime]` — Optional filter to only include traces before a certain datetime (ISO 8601)
1072+
**to_timestamp:** `typing.Optional[dt.datetime]` — Optional filter to only include traces and observations before a certain datetime (ISO 8601)
10731073

10741074
</dd>
10751075
</dl>
@@ -1134,8 +1134,8 @@ client.models.create(
11341134
request=CreateModelRequest(
11351135
model_name="string",
11361136
match_pattern="string",
1137-
start_date=datetime.date.fromisoformat(
1138-
"2023-01-15",
1137+
start_date=datetime.datetime.fromisoformat(
1138+
"2024-01-15 09:30:00+00:00",
11391139
),
11401140
unit=ModelUsageUnit.CHARACTERS,
11411141
input_price=1.1,

langfuse/api/resources/commons/types/model.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ class Model(pydantic_v1.BaseModel):
2424
Regex pattern which matches this model definition to generation.model. Useful in case of fine-tuned models. If you want to exact match, use `(?i)^modelname$`
2525
"""
2626

27-
start_date: typing.Optional[dt.date] = pydantic_v1.Field(alias="startDate", default=None)
27+
start_date: typing.Optional[dt.datetime] = pydantic_v1.Field(
28+
alias="startDate", default=None
29+
)
2830
"""
2931
Apply only to generations which are newer than this ISO date.
3032
"""
@@ -34,43 +36,66 @@ class Model(pydantic_v1.BaseModel):
3436
Unit used by this model.
3537
"""
3638

37-
input_price: typing.Optional[float] = pydantic_v1.Field(alias="inputPrice", default=None)
39+
input_price: typing.Optional[float] = pydantic_v1.Field(
40+
alias="inputPrice", default=None
41+
)
3842
"""
3943
Price (USD) per input unit
4044
"""
4145

42-
output_price: typing.Optional[float] = pydantic_v1.Field(alias="outputPrice", default=None)
46+
output_price: typing.Optional[float] = pydantic_v1.Field(
47+
alias="outputPrice", default=None
48+
)
4349
"""
4450
Price (USD) per output unit
4551
"""
4652

47-
total_price: typing.Optional[float] = pydantic_v1.Field(alias="totalPrice", default=None)
53+
total_price: typing.Optional[float] = pydantic_v1.Field(
54+
alias="totalPrice", default=None
55+
)
4856
"""
4957
Price (USD) per total unit. Cannot be set if input or output price is set.
5058
"""
5159

52-
tokenizer_id: typing.Optional[str] = pydantic_v1.Field(alias="tokenizerId", default=None)
60+
tokenizer_id: typing.Optional[str] = pydantic_v1.Field(
61+
alias="tokenizerId", default=None
62+
)
5363
"""
5464
Optional. Tokenizer to be applied to observations which match to this model. See docs for more details.
5565
"""
5666

57-
tokenizer_config: typing.Optional[typing.Any] = pydantic_v1.Field(alias="tokenizerConfig", default=None)
67+
tokenizer_config: typing.Optional[typing.Any] = pydantic_v1.Field(
68+
alias="tokenizerConfig", default=None
69+
)
5870
"""
5971
Optional. Configuration for the selected tokenizer. Needs to be JSON. See docs for more details.
6072
"""
6173

6274
is_langfuse_managed: bool = pydantic_v1.Field(alias="isLangfuseManaged")
6375

6476
def json(self, **kwargs: typing.Any) -> str:
65-
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
77+
kwargs_with_defaults: typing.Any = {
78+
"by_alias": True,
79+
"exclude_unset": True,
80+
**kwargs,
81+
}
6682
return super().json(**kwargs_with_defaults)
6783

6884
def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
69-
kwargs_with_defaults_exclude_unset: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
70-
kwargs_with_defaults_exclude_none: typing.Any = {"by_alias": True, "exclude_none": True, **kwargs}
85+
kwargs_with_defaults_exclude_unset: typing.Any = {
86+
"by_alias": True,
87+
"exclude_unset": True,
88+
**kwargs,
89+
}
90+
kwargs_with_defaults_exclude_none: typing.Any = {
91+
"by_alias": True,
92+
"exclude_none": True,
93+
**kwargs,
94+
}
7195

7296
return deep_union_pydantic_dicts(
73-
super().dict(**kwargs_with_defaults_exclude_unset), super().dict(**kwargs_with_defaults_exclude_none)
97+
super().dict(**kwargs_with_defaults_exclude_unset),
98+
super().dict(**kwargs_with_defaults_exclude_none),
7499
)
75100

76101
class Config:

langfuse/api/resources/metrics/client.py

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def daily(
3131
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
3232
from_timestamp: typing.Optional[dt.datetime] = None,
3333
to_timestamp: typing.Optional[dt.datetime] = None,
34-
request_options: typing.Optional[RequestOptions] = None
34+
request_options: typing.Optional[RequestOptions] = None,
3535
) -> DailyMetrics:
3636
"""
3737
Get daily metrics of the Langfuse project
@@ -54,10 +54,10 @@ def daily(
5454
Optional filter for metrics where traces include all of these tags
5555
5656
from_timestamp : typing.Optional[dt.datetime]
57-
Optional filter to only include traces on or after a certain datetime (ISO 8601)
57+
Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
5858
5959
to_timestamp : typing.Optional[dt.datetime]
60-
Optional filter to only include traces before a certain datetime (ISO 8601)
60+
Optional filter to only include traces and observations before a certain datetime (ISO 8601)
6161
6262
request_options : typing.Optional[RequestOptions]
6363
Request-specific configuration.
@@ -103,8 +103,12 @@ def daily(
103103
"traceName": trace_name,
104104
"userId": user_id,
105105
"tags": tags,
106-
"fromTimestamp": serialize_datetime(from_timestamp) if from_timestamp is not None else None,
107-
"toTimestamp": serialize_datetime(to_timestamp) if to_timestamp is not None else None,
106+
"fromTimestamp": serialize_datetime(from_timestamp)
107+
if from_timestamp is not None
108+
else None,
109+
"toTimestamp": serialize_datetime(to_timestamp)
110+
if to_timestamp is not None
111+
else None,
108112
},
109113
request_options=request_options,
110114
)
@@ -114,13 +118,21 @@ def daily(
114118
if _response.status_code == 400:
115119
raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
116120
if _response.status_code == 401:
117-
raise UnauthorizedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
121+
raise UnauthorizedError(
122+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
123+
) # type: ignore
118124
if _response.status_code == 403:
119-
raise AccessDeniedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
125+
raise AccessDeniedError(
126+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
127+
) # type: ignore
120128
if _response.status_code == 405:
121-
raise MethodNotAllowedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
129+
raise MethodNotAllowedError(
130+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
131+
) # type: ignore
122132
if _response.status_code == 404:
123-
raise NotFoundError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
133+
raise NotFoundError(
134+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
135+
) # type: ignore
124136
_response_json = _response.json()
125137
except JSONDecodeError:
126138
raise ApiError(status_code=_response.status_code, body=_response.text)
@@ -141,7 +153,7 @@ async def daily(
141153
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
142154
from_timestamp: typing.Optional[dt.datetime] = None,
143155
to_timestamp: typing.Optional[dt.datetime] = None,
144-
request_options: typing.Optional[RequestOptions] = None
156+
request_options: typing.Optional[RequestOptions] = None,
145157
) -> DailyMetrics:
146158
"""
147159
Get daily metrics of the Langfuse project
@@ -164,10 +176,10 @@ async def daily(
164176
Optional filter for metrics where traces include all of these tags
165177
166178
from_timestamp : typing.Optional[dt.datetime]
167-
Optional filter to only include traces on or after a certain datetime (ISO 8601)
179+
Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
168180
169181
to_timestamp : typing.Optional[dt.datetime]
170-
Optional filter to only include traces before a certain datetime (ISO 8601)
182+
Optional filter to only include traces and observations before a certain datetime (ISO 8601)
171183
172184
request_options : typing.Optional[RequestOptions]
173185
Request-specific configuration.
@@ -220,8 +232,12 @@ async def main() -> None:
220232
"traceName": trace_name,
221233
"userId": user_id,
222234
"tags": tags,
223-
"fromTimestamp": serialize_datetime(from_timestamp) if from_timestamp is not None else None,
224-
"toTimestamp": serialize_datetime(to_timestamp) if to_timestamp is not None else None,
235+
"fromTimestamp": serialize_datetime(from_timestamp)
236+
if from_timestamp is not None
237+
else None,
238+
"toTimestamp": serialize_datetime(to_timestamp)
239+
if to_timestamp is not None
240+
else None,
225241
},
226242
request_options=request_options,
227243
)
@@ -231,13 +247,21 @@ async def main() -> None:
231247
if _response.status_code == 400:
232248
raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
233249
if _response.status_code == 401:
234-
raise UnauthorizedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
250+
raise UnauthorizedError(
251+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
252+
) # type: ignore
235253
if _response.status_code == 403:
236-
raise AccessDeniedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
254+
raise AccessDeniedError(
255+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
256+
) # type: ignore
237257
if _response.status_code == 405:
238-
raise MethodNotAllowedError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
258+
raise MethodNotAllowedError(
259+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
260+
) # type: ignore
239261
if _response.status_code == 404:
240-
raise NotFoundError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
262+
raise NotFoundError(
263+
pydantic_v1.parse_obj_as(typing.Any, _response.json())
264+
) # type: ignore
241265
_response_json = _response.json()
242266
except JSONDecodeError:
243267
raise ApiError(status_code=_response.status_code, body=_response.text)

0 commit comments

Comments
 (0)