Skip to content

Commit be4f22d

Browse files
authored
fix: pydantic 1.10.15 compatibility (#530)
1 parent ed36978 commit be4f22d

91 files changed

Lines changed: 3737 additions & 1602 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

langfuse/api/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
Score,
5959
ScoreBody,
6060
ScoreEvent,
61+
ScoreSource,
6162
Scores,
6263
SdkLogBody,
6364
SdkLogEvent,
@@ -95,6 +96,7 @@
9596
trace,
9697
utils,
9798
)
99+
from .version import __version__
98100

99101
__all__ = [
100102
"AccessDeniedError",
@@ -154,6 +156,7 @@
154156
"Score",
155157
"ScoreBody",
156158
"ScoreEvent",
159+
"ScoreSource",
157160
"Scores",
158161
"SdkLogBody",
159162
"SdkLogEvent",
@@ -176,6 +179,7 @@
176179
"UpdateSpanEvent",
177180
"Usage",
178181
"UsageByModel",
182+
"__version__",
179183
"commons",
180184
"dataset_items",
181185
"dataset_run_items",

langfuse/api/client.py

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,39 @@
2323

2424

2525
class FernLangfuse:
26+
"""Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propogate to these functions.
27+
28+
Parameters:
29+
- base_url: str. The base url to use for requests from the client.
30+
31+
- x_langfuse_sdk_name: typing.Optional[str].
32+
33+
- x_langfuse_sdk_version: typing.Optional[str].
34+
35+
- x_langfuse_public_key: typing.Optional[str].
36+
37+
- username: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
38+
39+
- password: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
40+
41+
- timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds, unless a custom httpx client is used, in which case a default is not set.
42+
43+
- follow_redirects: typing.Optional[bool]. Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
44+
45+
- httpx_client: typing.Optional[httpx.Client]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
46+
---
47+
from finto.client import FernLangfuse
48+
49+
client = FernLangfuse(
50+
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
51+
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
52+
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
53+
username="YOUR_USERNAME",
54+
password="YOUR_PASSWORD",
55+
base_url="https://yourhost.com/path/to/api",
56+
)
57+
"""
58+
2659
def __init__(
2760
self,
2861
*,
@@ -32,19 +65,28 @@ def __init__(
3265
x_langfuse_public_key: typing.Optional[str] = None,
3366
username: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
3467
password: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
35-
timeout: typing.Optional[float] = 60,
68+
timeout: typing.Optional[float] = None,
69+
follow_redirects: typing.Optional[bool] = None,
3670
httpx_client: typing.Optional[httpx.Client] = None,
3771
):
72+
_defaulted_timeout = (
73+
timeout if timeout is not None else 60 if httpx_client is None else None
74+
)
3875
self._client_wrapper = SyncClientWrapper(
3976
base_url=base_url,
4077
x_langfuse_sdk_name=x_langfuse_sdk_name,
4178
x_langfuse_sdk_version=x_langfuse_sdk_version,
4279
x_langfuse_public_key=x_langfuse_public_key,
4380
username=username,
4481
password=password,
45-
httpx_client=httpx.Client(timeout=timeout)
46-
if httpx_client is None
47-
else httpx_client,
82+
httpx_client=httpx_client
83+
if httpx_client is not None
84+
else httpx.Client(
85+
timeout=_defaulted_timeout, follow_redirects=follow_redirects
86+
)
87+
if follow_redirects is not None
88+
else httpx.Client(timeout=_defaulted_timeout),
89+
timeout=_defaulted_timeout,
4890
)
4991
self.dataset_items = DatasetItemsClient(client_wrapper=self._client_wrapper)
5092
self.dataset_run_items = DatasetRunItemsClient(
@@ -63,6 +105,39 @@ def __init__(
63105

64106

65107
class AsyncFernLangfuse:
108+
"""Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propogate to these functions.
109+
110+
Parameters:
111+
- base_url: str. The base url to use for requests from the client.
112+
113+
- x_langfuse_sdk_name: typing.Optional[str].
114+
115+
- x_langfuse_sdk_version: typing.Optional[str].
116+
117+
- x_langfuse_public_key: typing.Optional[str].
118+
119+
- username: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
120+
121+
- password: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
122+
123+
- timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds, unless a custom httpx client is used, in which case a default is not set.
124+
125+
- follow_redirects: typing.Optional[bool]. Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
126+
127+
- httpx_client: typing.Optional[httpx.AsyncClient]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
128+
---
129+
from finto.client import AsyncFernLangfuse
130+
131+
client = AsyncFernLangfuse(
132+
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
133+
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
134+
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
135+
username="YOUR_USERNAME",
136+
password="YOUR_PASSWORD",
137+
base_url="https://yourhost.com/path/to/api",
138+
)
139+
"""
140+
66141
def __init__(
67142
self,
68143
*,
@@ -72,19 +147,28 @@ def __init__(
72147
x_langfuse_public_key: typing.Optional[str] = None,
73148
username: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
74149
password: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
75-
timeout: typing.Optional[float] = 60,
150+
timeout: typing.Optional[float] = None,
151+
follow_redirects: typing.Optional[bool] = None,
76152
httpx_client: typing.Optional[httpx.AsyncClient] = None,
77153
):
154+
_defaulted_timeout = (
155+
timeout if timeout is not None else 60 if httpx_client is None else None
156+
)
78157
self._client_wrapper = AsyncClientWrapper(
79158
base_url=base_url,
80159
x_langfuse_sdk_name=x_langfuse_sdk_name,
81160
x_langfuse_sdk_version=x_langfuse_sdk_version,
82161
x_langfuse_public_key=x_langfuse_public_key,
83162
username=username,
84163
password=password,
85-
httpx_client=httpx.AsyncClient(timeout=timeout)
86-
if httpx_client is None
87-
else httpx_client,
164+
httpx_client=httpx_client
165+
if httpx_client is not None
166+
else httpx.AsyncClient(
167+
timeout=_defaulted_timeout, follow_redirects=follow_redirects
168+
)
169+
if follow_redirects is not None
170+
else httpx.AsyncClient(timeout=_defaulted_timeout),
171+
timeout=_defaulted_timeout,
88172
)
89173
self.dataset_items = AsyncDatasetItemsClient(
90174
client_wrapper=self._client_wrapper

langfuse/api/core/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,25 @@
33
from .api_error import ApiError
44
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
55
from .datetime_utils import serialize_datetime
6+
from .file import File, convert_file_dict_to_httpx_tuples
7+
from .http_client import AsyncHttpClient, HttpClient
68
from .jsonable_encoder import jsonable_encoder
9+
from .pydantic_utilities import pydantic_v1
710
from .remove_none_from_dict import remove_none_from_dict
11+
from .request_options import RequestOptions
812

913
__all__ = [
1014
"ApiError",
1115
"AsyncClientWrapper",
16+
"AsyncHttpClient",
1217
"BaseClientWrapper",
18+
"File",
19+
"HttpClient",
20+
"RequestOptions",
1321
"SyncClientWrapper",
22+
"convert_file_dict_to_httpx_tuples",
1423
"jsonable_encoder",
24+
"pydantic_v1",
1525
"remove_none_from_dict",
1626
"serialize_datetime",
1727
]

langfuse/api/core/api_error.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ class ApiError(Exception):
77
status_code: typing.Optional[int]
88
body: typing.Any
99

10-
def __init__(
11-
self, *, status_code: typing.Optional[int] = None, body: typing.Any = None
12-
):
10+
def __init__(self, *, status_code: typing.Optional[int] = None, body: typing.Any = None):
1311
self.status_code = status_code
1412
self.body = body
1513

langfuse/api/core/client_wrapper.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import httpx
66

7+
from .http_client import AsyncHttpClient, HttpClient
8+
79

810
class BaseClientWrapper:
911
def __init__(
@@ -15,13 +17,15 @@ def __init__(
1517
username: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
1618
password: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
1719
base_url: str,
20+
timeout: typing.Optional[float] = None
1821
):
1922
self._x_langfuse_sdk_name = x_langfuse_sdk_name
2023
self._x_langfuse_sdk_version = x_langfuse_sdk_version
2124
self._x_langfuse_public_key = x_langfuse_public_key
2225
self._username = username
2326
self._password = password
2427
self._base_url = base_url
28+
self._timeout = timeout
2529

2630
def get_headers(self) -> typing.Dict[str, str]:
2731
headers: typing.Dict[str, str] = {"X-Fern-Language": "Python"}
@@ -52,6 +56,9 @@ def _get_password(self) -> typing.Optional[str]:
5256
def get_base_url(self) -> str:
5357
return self._base_url
5458

59+
def get_timeout(self) -> typing.Optional[float]:
60+
return self._timeout
61+
5562

5663
class SyncClientWrapper(BaseClientWrapper):
5764
def __init__(
@@ -63,7 +70,8 @@ def __init__(
6370
username: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
6471
password: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
6572
base_url: str,
66-
httpx_client: httpx.Client,
73+
timeout: typing.Optional[float] = None,
74+
httpx_client: httpx.Client
6775
):
6876
super().__init__(
6977
x_langfuse_sdk_name=x_langfuse_sdk_name,
@@ -72,8 +80,9 @@ def __init__(
7280
username=username,
7381
password=password,
7482
base_url=base_url,
83+
timeout=timeout,
7584
)
76-
self.httpx_client = httpx_client
85+
self.httpx_client = HttpClient(httpx_client=httpx_client)
7786

7887

7988
class AsyncClientWrapper(BaseClientWrapper):
@@ -86,7 +95,8 @@ def __init__(
8695
username: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
8796
password: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
8897
base_url: str,
89-
httpx_client: httpx.AsyncClient,
98+
timeout: typing.Optional[float] = None,
99+
httpx_client: httpx.AsyncClient
90100
):
91101
super().__init__(
92102
x_langfuse_sdk_name=x_langfuse_sdk_name,
@@ -95,5 +105,6 @@ def __init__(
95105
username=username,
96106
password=password,
97107
base_url=base_url,
108+
timeout=timeout,
98109
)
99-
self.httpx_client = httpx_client
110+
self.httpx_client = AsyncHttpClient(httpx_client=httpx_client)

langfuse/api/core/datetime_utils.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ def serialize_datetime(v: dt.datetime) -> str:
1212
"""
1313

1414
def _serialize_zoned_datetime(v: dt.datetime) -> str:
15-
if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(
16-
None
17-
):
15+
if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(None):
1816
# UTC is a special case where we use "Z" at the end instead of "+00:00"
1917
return v.isoformat().replace("+00:00", "Z")
2018
else:

langfuse/api/core/file.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
import typing
4+
5+
# File typing inspired by the flexibility of types within the httpx library
6+
# https://github.com/encode/httpx/blob/master/httpx/_types.py
7+
FileContent = typing.Union[typing.IO[bytes], bytes, str]
8+
File = typing.Union[
9+
# file (or bytes)
10+
FileContent,
11+
# (filename, file (or bytes))
12+
typing.Tuple[typing.Optional[str], FileContent],
13+
# (filename, file (or bytes), content_type)
14+
typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str]],
15+
# (filename, file (or bytes), content_type, headers)
16+
typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str], typing.Mapping[str, str]],
17+
]
18+
19+
20+
def convert_file_dict_to_httpx_tuples(
21+
d: typing.Dict[str, typing.Union[File, typing.List[File]]]
22+
) -> typing.List[typing.Tuple[str, File]]:
23+
"""The format we use is a list of tuples, where the first element is the
24+
name of the file and the second is the file object. Typically HTTPX wants
25+
a dict, but to be able to send lists of files, you have to use the list
26+
approach (which also works for non-lists)
27+
https://github.com/encode/httpx/pull/1032
28+
"""
29+
httpx_tuples = []
30+
for key, file_like in d.items():
31+
if isinstance(file_like, list):
32+
for file_like_item in file_like:
33+
httpx_tuples.append((key, file_like_item))
34+
else:
35+
httpx_tuples.append((key, file_like))
36+
return httpx_tuples

0 commit comments

Comments
 (0)