vellum-ai 0.8.15__py3-none-any.whl → 0.8.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/core/client_wrapper.py +3 -3
- vellum/core/http_client.py +22 -16
- vellum/core/pydantic_utilities.py +26 -3
- {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.16.dist-info}/METADATA +1 -1
- {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.16.dist-info}/RECORD +7 -7
- {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.16.dist-info}/LICENSE +0 -0
- {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.16.dist-info}/WHEEL +0 -0
vellum/core/client_wrapper.py
CHANGED
@@ -17,7 +17,7 @@ class BaseClientWrapper:
|
|
17
17
|
headers: typing.Dict[str, str] = {
|
18
18
|
"X-Fern-Language": "Python",
|
19
19
|
"X-Fern-SDK-Name": "vellum-ai",
|
20
|
-
"X-Fern-SDK-Version": "0.8.
|
20
|
+
"X-Fern-SDK-Version": "0.8.16",
|
21
21
|
}
|
22
22
|
headers["X_API_KEY"] = self.api_key
|
23
23
|
return headers
|
@@ -40,7 +40,7 @@ class SyncClientWrapper(BaseClientWrapper):
|
|
40
40
|
):
|
41
41
|
super().__init__(api_key=api_key, environment=environment, timeout=timeout)
|
42
42
|
self.httpx_client = HttpClient(
|
43
|
-
httpx_client=httpx_client, base_headers=self.get_headers
|
43
|
+
httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
|
44
44
|
)
|
45
45
|
|
46
46
|
|
@@ -55,5 +55,5 @@ class AsyncClientWrapper(BaseClientWrapper):
|
|
55
55
|
):
|
56
56
|
super().__init__(api_key=api_key, environment=environment, timeout=timeout)
|
57
57
|
self.httpx_client = AsyncHttpClient(
|
58
|
-
httpx_client=httpx_client, base_headers=self.get_headers
|
58
|
+
httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
|
59
59
|
)
|
vellum/core/http_client.py
CHANGED
@@ -152,9 +152,9 @@ class HttpClient:
|
|
152
152
|
self,
|
153
153
|
*,
|
154
154
|
httpx_client: httpx.Client,
|
155
|
-
base_timeout: typing.Optional[float],
|
156
|
-
base_headers: typing.Dict[str, str],
|
157
|
-
base_url: typing.Optional[str] = None,
|
155
|
+
base_timeout: typing.Callable[[], typing.Optional[float]],
|
156
|
+
base_headers: typing.Callable[[], typing.Dict[str, str]],
|
157
|
+
base_url: typing.Optional[typing.Callable[[], str]] = None,
|
158
158
|
):
|
159
159
|
self.base_url = base_url
|
160
160
|
self.base_timeout = base_timeout
|
@@ -162,7 +162,10 @@ class HttpClient:
|
|
162
162
|
self.httpx_client = httpx_client
|
163
163
|
|
164
164
|
def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
|
165
|
-
base_url =
|
165
|
+
base_url = maybe_base_url
|
166
|
+
if self.base_url is not None and base_url is None:
|
167
|
+
base_url = self.base_url()
|
168
|
+
|
166
169
|
if base_url is None:
|
167
170
|
raise ValueError("A base_url is required to make this request, please provide one and try again.")
|
168
171
|
return base_url
|
@@ -187,7 +190,7 @@ class HttpClient:
|
|
187
190
|
timeout = (
|
188
191
|
request_options.get("timeout_in_seconds")
|
189
192
|
if request_options is not None and request_options.get("timeout_in_seconds") is not None
|
190
|
-
else self.base_timeout
|
193
|
+
else self.base_timeout()
|
191
194
|
)
|
192
195
|
|
193
196
|
json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
|
@@ -198,7 +201,7 @@ class HttpClient:
|
|
198
201
|
headers=jsonable_encoder(
|
199
202
|
remove_none_from_dict(
|
200
203
|
{
|
201
|
-
**self.base_headers,
|
204
|
+
**self.base_headers(),
|
202
205
|
**(headers if headers is not None else {}),
|
203
206
|
**(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
|
204
207
|
}
|
@@ -271,7 +274,7 @@ class HttpClient:
|
|
271
274
|
timeout = (
|
272
275
|
request_options.get("timeout_in_seconds")
|
273
276
|
if request_options is not None and request_options.get("timeout_in_seconds") is not None
|
274
|
-
else self.base_timeout
|
277
|
+
else self.base_timeout()
|
275
278
|
)
|
276
279
|
|
277
280
|
json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
|
@@ -282,7 +285,7 @@ class HttpClient:
|
|
282
285
|
headers=jsonable_encoder(
|
283
286
|
remove_none_from_dict(
|
284
287
|
{
|
285
|
-
**self.base_headers,
|
288
|
+
**self.base_headers(),
|
286
289
|
**(headers if headers is not None else {}),
|
287
290
|
**(request_options.get("additional_headers", {}) if request_options is not None else {}),
|
288
291
|
}
|
@@ -321,9 +324,9 @@ class AsyncHttpClient:
|
|
321
324
|
self,
|
322
325
|
*,
|
323
326
|
httpx_client: httpx.AsyncClient,
|
324
|
-
base_timeout: typing.Optional[float],
|
325
|
-
base_headers: typing.Dict[str, str],
|
326
|
-
base_url: typing.Optional[str] = None,
|
327
|
+
base_timeout: typing.Callable[[], typing.Optional[float]],
|
328
|
+
base_headers: typing.Callable[[], typing.Dict[str, str]],
|
329
|
+
base_url: typing.Optional[typing.Callable[[], str]] = None,
|
327
330
|
):
|
328
331
|
self.base_url = base_url
|
329
332
|
self.base_timeout = base_timeout
|
@@ -331,7 +334,10 @@ class AsyncHttpClient:
|
|
331
334
|
self.httpx_client = httpx_client
|
332
335
|
|
333
336
|
def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
|
334
|
-
base_url =
|
337
|
+
base_url = maybe_base_url
|
338
|
+
if self.base_url is not None and base_url is None:
|
339
|
+
base_url = self.base_url()
|
340
|
+
|
335
341
|
if base_url is None:
|
336
342
|
raise ValueError("A base_url is required to make this request, please provide one and try again.")
|
337
343
|
return base_url
|
@@ -356,7 +362,7 @@ class AsyncHttpClient:
|
|
356
362
|
timeout = (
|
357
363
|
request_options.get("timeout_in_seconds")
|
358
364
|
if request_options is not None and request_options.get("timeout_in_seconds") is not None
|
359
|
-
else self.base_timeout
|
365
|
+
else self.base_timeout()
|
360
366
|
)
|
361
367
|
|
362
368
|
json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
|
@@ -368,7 +374,7 @@ class AsyncHttpClient:
|
|
368
374
|
headers=jsonable_encoder(
|
369
375
|
remove_none_from_dict(
|
370
376
|
{
|
371
|
-
**self.base_headers,
|
377
|
+
**self.base_headers(),
|
372
378
|
**(headers if headers is not None else {}),
|
373
379
|
**(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
|
374
380
|
}
|
@@ -438,7 +444,7 @@ class AsyncHttpClient:
|
|
438
444
|
timeout = (
|
439
445
|
request_options.get("timeout_in_seconds")
|
440
446
|
if request_options is not None and request_options.get("timeout_in_seconds") is not None
|
441
|
-
else self.base_timeout
|
447
|
+
else self.base_timeout()
|
442
448
|
)
|
443
449
|
|
444
450
|
json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
|
@@ -449,7 +455,7 @@ class AsyncHttpClient:
|
|
449
455
|
headers=jsonable_encoder(
|
450
456
|
remove_none_from_dict(
|
451
457
|
{
|
452
|
-
**self.base_headers,
|
458
|
+
**self.base_headers(),
|
453
459
|
**(headers if headers is not None else {}),
|
454
460
|
**(request_options.get("additional_headers", {}) if request_options is not None else {}),
|
455
461
|
}
|
@@ -152,7 +152,7 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
152
152
|
)
|
153
153
|
|
154
154
|
else:
|
155
|
-
_fields_set = self.__fields_set__
|
155
|
+
_fields_set = self.__fields_set__.copy()
|
156
156
|
|
157
157
|
fields = _get_model_fields(self.__class__)
|
158
158
|
for name, field in fields.items():
|
@@ -162,9 +162,12 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
162
162
|
# If the default values are non-null act like they've been set
|
163
163
|
# This effectively allows exclude_unset to work like exclude_none where
|
164
164
|
# the latter passes through intentionally set none values.
|
165
|
-
if default
|
165
|
+
if default is not None or ("exclude_unset" in kwargs and not kwargs["exclude_unset"]):
|
166
166
|
_fields_set.add(name)
|
167
167
|
|
168
|
+
if default is not None:
|
169
|
+
self.__fields_set__.add(name)
|
170
|
+
|
168
171
|
kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
|
169
172
|
"by_alias": True,
|
170
173
|
"exclude_unset": True,
|
@@ -177,13 +180,33 @@ class UniversalBaseModel(pydantic.BaseModel):
|
|
177
180
|
return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write")
|
178
181
|
|
179
182
|
|
183
|
+
def _union_list_of_pydantic_dicts(
|
184
|
+
source: typing.List[typing.Any], destination: typing.List[typing.Any]
|
185
|
+
) -> typing.List[typing.Any]:
|
186
|
+
converted_list: typing.List[typing.Any] = []
|
187
|
+
for i, item in enumerate(source):
|
188
|
+
destination_value = destination[i] # type: ignore
|
189
|
+
if isinstance(item, dict):
|
190
|
+
converted_list.append(deep_union_pydantic_dicts(item, destination_value))
|
191
|
+
elif isinstance(item, list):
|
192
|
+
converted_list.append(_union_list_of_pydantic_dicts(item, destination_value))
|
193
|
+
else:
|
194
|
+
converted_list.append(item)
|
195
|
+
return converted_list
|
196
|
+
|
197
|
+
|
180
198
|
def deep_union_pydantic_dicts(
|
181
199
|
source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
|
182
200
|
) -> typing.Dict[str, typing.Any]:
|
183
201
|
for key, value in source.items():
|
202
|
+
node = destination.setdefault(key, {})
|
184
203
|
if isinstance(value, dict):
|
185
|
-
node = destination.setdefault(key, {})
|
186
204
|
deep_union_pydantic_dicts(value, node)
|
205
|
+
# Note: we do not do this same processing for sets given we do not have sets of models
|
206
|
+
# and given the sets are unordered, the processing of the set and matching objects would
|
207
|
+
# be non-trivial.
|
208
|
+
elif isinstance(value, list):
|
209
|
+
destination[key] = _union_list_of_pydantic_dicts(value, node)
|
187
210
|
else:
|
188
211
|
destination[key] = value
|
189
212
|
|
@@ -2,12 +2,12 @@ vellum/__init__.py,sha256=lbUhjH2L_tzm-0Vaouz3lHOKIUoLcRKN5dgCbl64AMs,30700
|
|
2
2
|
vellum/client.py,sha256=n9AlNDHYObmRUM5hX_iiFj6eYDzjIca3cdKVGuRjUSA,106566
|
3
3
|
vellum/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
4
4
|
vellum/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
5
|
-
vellum/core/client_wrapper.py,sha256=
|
5
|
+
vellum/core/client_wrapper.py,sha256=qqJD0dazy9fuf_v6c3WLU__j8ntDe27g5C1WOVwTPUQ,1890
|
6
6
|
vellum/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
7
7
|
vellum/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
8
|
-
vellum/core/http_client.py,sha256=
|
8
|
+
vellum/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
9
9
|
vellum/core/jsonable_encoder.py,sha256=qaF1gtgH-kQZb4kJskETwcCsOPUof-NnYVdszHkb-dM,3656
|
10
|
-
vellum/core/pydantic_utilities.py,sha256=
|
10
|
+
vellum/core/pydantic_utilities.py,sha256=Pj_AIcjRR-xc28URvV4t2XssDPjLvpN6HAcsY3MVLRM,11973
|
11
11
|
vellum/core/query_encoder.py,sha256=ekulqNd0j8TgD7ox-Qbz7liqX8-KP9blvT9DsRCenYM,2144
|
12
12
|
vellum/core/remove_none_from_dict.py,sha256=EU9SGgYidWq7SexuJbNs4-PZ-5Bl3Vppd864mS6vQZw,342
|
13
13
|
vellum/core/request_options.py,sha256=5cCGt5AEGgtP5xifDl4oVQUmSjlIA8FmRItAlJawM18,1417
|
@@ -493,7 +493,7 @@ vellum/types/workflow_result_event_output_data_search_results.py,sha256=U34IK7Zv
|
|
493
493
|
vellum/types/workflow_result_event_output_data_string.py,sha256=tM3kgh6tEhD0dFEb_7UU0-UspeN4pUdINCcCrD64W74,1228
|
494
494
|
vellum/types/workflow_stream_event.py,sha256=Wn3Yzuy9MqWAeo8tEaXDTKDEbJoA8DdYdMVq8EKuhu8,361
|
495
495
|
vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
|
496
|
-
vellum_ai-0.8.
|
497
|
-
vellum_ai-0.8.
|
498
|
-
vellum_ai-0.8.
|
499
|
-
vellum_ai-0.8.
|
496
|
+
vellum_ai-0.8.16.dist-info/LICENSE,sha256=CcaljEIoOBaU-wItPH4PmM_mDCGpyuUY0Er1BGu5Ti8,1073
|
497
|
+
vellum_ai-0.8.16.dist-info/METADATA,sha256=wvj5V6u5anFSM3xlxTueyzFc3bRX7va4B953YO3JHdM,4395
|
498
|
+
vellum_ai-0.8.16.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
499
|
+
vellum_ai-0.8.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|