Skip to content

Commit 7a94582

Browse files
SK-3118: flowvault Java-parity fixes + internal HTTP pool/concurrency defaults
Parity with the Java flowvault SDK: - update(): send updateType to the API (was silently dropped). Wired the regenerated update endpoint's updateType through the controller, converting the public UpsertType enum to its wire value and omitting it when unset. - Add typed DetokenizeResponseRecordMetadata for the metadata field on both unary and bulk detokenize responses (was an untyped dict). - Rename public ColumnRedaction -> ColumnRedactions (matches Java; pre-release, no alias). Generated wire type untouched. - Type update_type as UpsertType on UpdateRequest and UpsertOptions. Internal HTTP tuning (not exposed via VaultConfig): - httpx connection pool defaults: max_connections=100, max_keepalive_connections=100, keepalive_expiry=60s (was 20 / 5s) to reduce connection churn. - Raise bulk insert/detokenize MAX_CONCURRENCY cap from 10 to 100. Tests updated accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 1fc4469 commit 7a94582

26 files changed

Lines changed: 202 additions & 32 deletions

flowvault/skyflow/generated/rest/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
TokenizeResponseObject,
3131
UniqueValue,
3232
UpdateRecordData,
33+
UpdateRecordDataUpdateType,
3334
UpdateResponse,
3435
Upsert,
3536
UpsertUpdateType,
@@ -46,6 +47,7 @@
4647
from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient
4748
from .client import AsyncSkyflowAuth, SkyflowAuth
4849
from .environment import SkyflowAuthEnvironment
50+
from .records import UpdateRequestUpdateType
4951
from .version import __version__
5052
_dynamic_imports: typing.Dict[str, str] = {
5153
"AsyncSkyflowAuth": ".client",
@@ -82,6 +84,8 @@
8284
"UnauthorizedError": ".errors",
8385
"UniqueValue": ".types",
8486
"UpdateRecordData": ".types",
87+
"UpdateRecordDataUpdateType": ".types",
88+
"UpdateRequestUpdateType": ".records",
8589
"UpdateResponse": ".types",
8690
"Upsert": ".types",
8791
"UpsertUpdateType": ".types",
@@ -148,6 +152,8 @@ def __dir__():
148152
"UnauthorizedError",
149153
"UniqueValue",
150154
"UpdateRecordData",
155+
"UpdateRecordDataUpdateType",
156+
"UpdateRequestUpdateType",
151157
"UpdateResponse",
152158
"Upsert",
153159
"UpsertUpdateType",

flowvault/skyflow/generated/rest/core/client_wrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def get_headers(self) -> typing.Dict[str, str]:
3737
"X-Fern-Runtime": f"python/{platform.python_version()}",
3838
"X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
3939
"X-Fern-SDK-Name": "skyflow.generated.rest",
40-
"X-Fern-SDK-Version": "0.0.20",
40+
"X-Fern-SDK-Version": "0.0.21",
4141
**(self.get_custom_headers() or {}),
4242
}
4343
token = self._get_token()

flowvault/skyflow/generated/rest/records/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,33 @@
22

33
# isort: skip_file
44

5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from .types import UpdateRequestUpdateType
10+
_dynamic_imports: typing.Dict[str, str] = {"UpdateRequestUpdateType": ".types"}
11+
12+
13+
def __getattr__(attr_name: str) -> typing.Any:
14+
module_name = _dynamic_imports.get(attr_name)
15+
if module_name is None:
16+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
17+
try:
18+
module = import_module(module_name, __package__)
19+
if module_name == f".{attr_name}":
20+
return module
21+
else:
22+
return getattr(module, attr_name)
23+
except ImportError as e:
24+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
25+
except AttributeError as e:
26+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
27+
28+
29+
def __dir__():
30+
lazy_attrs = list(_dynamic_imports.keys())
31+
return sorted(lazy_attrs)
32+
33+
34+
__all__ = ["UpdateRequestUpdateType"]

flowvault/skyflow/generated/rest/records/client.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from ..types.update_response import UpdateResponse
1616
from ..types.upsert import Upsert
1717
from .raw_client import AsyncRawRecordsClient, RawRecordsClient
18+
from .types.update_request_update_type import UpdateRequestUpdateType
1819

1920
# this is used as the default value for optional parameters
2021
OMIT = typing.cast(typing.Any, ...)
@@ -264,6 +265,7 @@ def update_records(
264265
vault_id: str,
265266
table_name: str,
266267
records: typing.Sequence[UpdateRecordData],
268+
update_type: typing.Optional[UpdateRequestUpdateType] = OMIT,
267269
request_options: typing.Optional[RequestOptions] = None,
268270
) -> UpdateResponse:
269271
"""
@@ -280,6 +282,9 @@ def update_records(
280282
records : typing.Sequence[UpdateRecordData]
281283
Data to update as a list of records.
282284
285+
update_type : typing.Optional[UpdateRequestUpdateType]
286+
Type of update operation to perform.
287+
283288
request_options : typing.Optional[RequestOptions]
284289
Request-specific configuration.
285290
@@ -323,7 +328,11 @@ def update_records(
323328
)
324329
"""
325330
_response = self._raw_client.update_records(
326-
vault_id=vault_id, table_name=table_name, records=records, request_options=request_options
331+
vault_id=vault_id,
332+
table_name=table_name,
333+
records=records,
334+
update_type=update_type,
335+
request_options=request_options,
327336
)
328337
return _response.data
329338

@@ -596,6 +605,7 @@ async def update_records(
596605
vault_id: str,
597606
table_name: str,
598607
records: typing.Sequence[UpdateRecordData],
608+
update_type: typing.Optional[UpdateRequestUpdateType] = OMIT,
599609
request_options: typing.Optional[RequestOptions] = None,
600610
) -> UpdateResponse:
601611
"""
@@ -612,6 +622,9 @@ async def update_records(
612622
records : typing.Sequence[UpdateRecordData]
613623
Data to update as a list of records.
614624
625+
update_type : typing.Optional[UpdateRequestUpdateType]
626+
Type of update operation to perform.
627+
615628
request_options : typing.Optional[RequestOptions]
616629
Request-specific configuration.
617630
@@ -663,6 +676,10 @@ async def main() -> None:
663676
asyncio.run(main())
664677
"""
665678
_response = await self._raw_client.update_records(
666-
vault_id=vault_id, table_name=table_name, records=records, request_options=request_options
679+
vault_id=vault_id,
680+
table_name=table_name,
681+
records=records,
682+
update_type=update_type,
683+
request_options=request_options,
667684
)
668685
return _response.data

flowvault/skyflow/generated/rest/records/raw_client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from ..types.update_record_data import UpdateRecordData
2626
from ..types.update_response import UpdateResponse
2727
from ..types.upsert import Upsert
28+
from .types.update_request_update_type import UpdateRequestUpdateType
2829
from pydantic import ValidationError
2930

3031
# this is used as the default value for optional parameters
@@ -400,6 +401,7 @@ def update_records(
400401
vault_id: str,
401402
table_name: str,
402403
records: typing.Sequence[UpdateRecordData],
404+
update_type: typing.Optional[UpdateRequestUpdateType] = OMIT,
403405
request_options: typing.Optional[RequestOptions] = None,
404406
) -> HttpResponse[UpdateResponse]:
405407
"""
@@ -416,6 +418,9 @@ def update_records(
416418
records : typing.Sequence[UpdateRecordData]
417419
Data to update as a list of records.
418420
421+
update_type : typing.Optional[UpdateRequestUpdateType]
422+
Type of update operation to perform.
423+
419424
request_options : typing.Optional[RequestOptions]
420425
Request-specific configuration.
421426
@@ -433,6 +438,7 @@ def update_records(
433438
"records": convert_and_respect_annotation_metadata(
434439
object_=records, annotation=typing.Sequence[UpdateRecordData], direction="write"
435440
),
441+
"updateType": update_type,
436442
},
437443
headers={
438444
"content-type": "application/json",
@@ -873,6 +879,7 @@ async def update_records(
873879
vault_id: str,
874880
table_name: str,
875881
records: typing.Sequence[UpdateRecordData],
882+
update_type: typing.Optional[UpdateRequestUpdateType] = OMIT,
876883
request_options: typing.Optional[RequestOptions] = None,
877884
) -> AsyncHttpResponse[UpdateResponse]:
878885
"""
@@ -889,6 +896,9 @@ async def update_records(
889896
records : typing.Sequence[UpdateRecordData]
890897
Data to update as a list of records.
891898
899+
update_type : typing.Optional[UpdateRequestUpdateType]
900+
Type of update operation to perform.
901+
892902
request_options : typing.Optional[RequestOptions]
893903
Request-specific configuration.
894904
@@ -906,6 +916,7 @@ async def update_records(
906916
"records": convert_and_respect_annotation_metadata(
907917
object_=records, annotation=typing.Sequence[UpdateRecordData], direction="write"
908918
),
919+
"updateType": update_type,
909920
},
910921
headers={
911922
"content-type": "application/json",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
# isort: skip_file
4+
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from .update_request_update_type import UpdateRequestUpdateType
10+
_dynamic_imports: typing.Dict[str, str] = {"UpdateRequestUpdateType": ".update_request_update_type"}
11+
12+
13+
def __getattr__(attr_name: str) -> typing.Any:
14+
module_name = _dynamic_imports.get(attr_name)
15+
if module_name is None:
16+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
17+
try:
18+
module = import_module(module_name, __package__)
19+
if module_name == f".{attr_name}":
20+
return module
21+
else:
22+
return getattr(module, attr_name)
23+
except ImportError as e:
24+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
25+
except AttributeError as e:
26+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
27+
28+
29+
def __dir__():
30+
lazy_attrs = list(_dynamic_imports.keys())
31+
return sorted(lazy_attrs)
32+
33+
34+
__all__ = ["UpdateRequestUpdateType"]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
import typing
4+
5+
UpdateRequestUpdateType = typing.Union[typing.Literal["UPDATE", "REPLACE"], typing.Any]

flowvault/skyflow/generated/rest/types/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from .tokenize_response_object import TokenizeResponseObject
3030
from .unique_value import UniqueValue
3131
from .update_record_data import UpdateRecordData
32+
from .update_record_data_update_type import UpdateRecordDataUpdateType
3233
from .update_response import UpdateResponse
3334
from .upsert import Upsert
3435
from .upsert_update_type import UpsertUpdateType
@@ -56,6 +57,7 @@
5657
"TokenizeResponseObject": ".tokenize_response_object",
5758
"UniqueValue": ".unique_value",
5859
"UpdateRecordData": ".update_record_data",
60+
"UpdateRecordDataUpdateType": ".update_record_data_update_type",
5961
"UpdateResponse": ".update_response",
6062
"Upsert": ".upsert",
6163
"UpsertUpdateType": ".upsert_update_type",
@@ -107,6 +109,7 @@ def __dir__():
107109
"TokenizeResponseObject",
108110
"UniqueValue",
109111
"UpdateRecordData",
112+
"UpdateRecordDataUpdateType",
110113
"UpdateResponse",
111114
"Upsert",
112115
"UpsertUpdateType",

flowvault/skyflow/generated/rest/types/update_record_data.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import typing_extensions
77
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
88
from ..core.serialization import FieldMetadata
9+
from .update_record_data_update_type import UpdateRecordDataUpdateType
910

1011

1112
class UpdateRecordData(UniversalBaseModel):
@@ -32,6 +33,15 @@ class UpdateRecordData(UniversalBaseModel):
3233
Name of the table to update data in.
3334
"""
3435

36+
update_type: typing_extensions.Annotated[
37+
typing.Optional[UpdateRecordDataUpdateType],
38+
FieldMetadata(alias="updateType"),
39+
pydantic.Field(alias="updateType", description="Type of update operation to perform."),
40+
] = None
41+
"""
42+
Type of update operation to perform.
43+
"""
44+
3545
if IS_PYDANTIC_V2:
3646
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
3747
else:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
import typing
4+
5+
UpdateRecordDataUpdateType = typing.Union[typing.Literal["UPDATE", "REPLACE"], typing.Any]

0 commit comments

Comments
 (0)