vellum-ai 0.8.15__py3-none-any.whl → 0.8.16__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|