Skip to content

Commit c9cf36d

Browse files
Fokkogabeiglio
authored andcommitted
REST: Delegate parsing to Pydantic (apache#1847)
# Rationale for this change Right now we deserialize the JSON into a dict, which is then passed into the Pydantic model. It is better to fully delegate this to pydantic because it is probably faster, and we can detect when models are created from json or from Python dicts. Required by apache#1770 This is also a recommendation by Pydantic itself: https://docs.pydantic.dev/latest/concepts/performance/#in-general-use-model_validate_json-not-model_validatejsonloads # Are these changes tested? Existing tests # Are there any user-facing changes? No <!-- In the case of user-facing changes, please add the changelog label. -->
1 parent 9ae90e1 commit c9cf36d

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

pyiceberg/catalog/rest.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ def _fetch_access_token(self, session: Session, credential: str) -> str:
378378
except HTTPError as exc:
379379
self._handle_non_200_response(exc, {400: OAuthError, 401: OAuthError})
380380

381-
return TokenResponse(**response.json()).access_token
381+
return TokenResponse.model_validate_json(response.text).access_token
382382

383383
def _fetch_config(self) -> None:
384384
params = {}
@@ -391,7 +391,7 @@ def _fetch_config(self) -> None:
391391
response.raise_for_status()
392392
except HTTPError as exc:
393393
self._handle_non_200_response(exc, {})
394-
config_response = ConfigResponse(**response.json())
394+
config_response = ConfigResponse.model_validate_json(response.text)
395395

396396
config = config_response.defaults
397397
config.update(self.properties)
@@ -451,14 +451,14 @@ def _handle_non_200_response(self, exc: HTTPError, error_handler: Dict[int, Type
451451
try:
452452
if exception == OAuthError:
453453
# The OAuthErrorResponse has a different format
454-
error = OAuthErrorResponse(**exc.response.json())
454+
error = OAuthErrorResponse.model_validate_json(exc.response.text)
455455
response = str(error.error)
456456
if description := error.error_description:
457457
response += f": {description}"
458458
if uri := error.error_uri:
459459
response += f" ({uri})"
460460
else:
461-
error = ErrorResponse(**exc.response.json()).error
461+
error = ErrorResponse.model_validate_json(exc.response.text).error
462462
response = f"{error.type}: {error.message}"
463463
except JSONDecodeError:
464464
# In the case we don't have a proper response
@@ -596,7 +596,7 @@ def _create_table(
596596
response.raise_for_status()
597597
except HTTPError as exc:
598598
self._handle_non_200_response(exc, {409: TableAlreadyExistsError})
599-
return TableResponse(**response.json())
599+
return TableResponse.model_validate_json(response.text)
600600

601601
@retry(**_RETRY_ARGS)
602602
def create_table(
@@ -670,7 +670,7 @@ def register_table(self, identifier: Union[str, Identifier], metadata_location:
670670
except HTTPError as exc:
671671
self._handle_non_200_response(exc, {409: TableAlreadyExistsError})
672672

673-
table_response = TableResponse(**response.json())
673+
table_response = TableResponse.model_validate_json(response.text)
674674
return self._response_to_table(self.identifier_to_tuple(identifier), table_response)
675675

676676
@retry(**_RETRY_ARGS)
@@ -682,7 +682,7 @@ def list_tables(self, namespace: Union[str, Identifier]) -> List[Identifier]:
682682
response.raise_for_status()
683683
except HTTPError as exc:
684684
self._handle_non_200_response(exc, {404: NoSuchNamespaceError})
685-
return [(*table.namespace, table.name) for table in ListTablesResponse(**response.json()).identifiers]
685+
return [(*table.namespace, table.name) for table in ListTablesResponse.model_validate_json(response.text).identifiers]
686686

687687
@retry(**_RETRY_ARGS)
688688
def load_table(self, identifier: Union[str, Identifier]) -> Table:
@@ -692,7 +692,7 @@ def load_table(self, identifier: Union[str, Identifier]) -> Table:
692692
except HTTPError as exc:
693693
self._handle_non_200_response(exc, {404: NoSuchTableError})
694694

695-
table_response = TableResponse(**response.json())
695+
table_response = TableResponse.model_validate_json(response.text)
696696
return self._response_to_table(self.identifier_to_tuple(identifier), table_response)
697697

698698
@retry(**_RETRY_ARGS)
@@ -743,7 +743,7 @@ def list_views(self, namespace: Union[str, Identifier]) -> List[Identifier]:
743743
response.raise_for_status()
744744
except HTTPError as exc:
745745
self._handle_non_200_response(exc, {404: NoSuchNamespaceError})
746-
return [(*view.namespace, view.name) for view in ListViewsResponse(**response.json()).identifiers]
746+
return [(*view.namespace, view.name) for view in ListViewsResponse.model_validate_json(response.text).identifiers]
747747

748748
@retry(**_RETRY_ARGS)
749749
def commit_table(
@@ -789,7 +789,7 @@ def commit_table(
789789
504: CommitStateUnknownException,
790790
},
791791
)
792-
return CommitTableResponse(**response.json())
792+
return CommitTableResponse.model_validate_json(response.text)
793793

794794
@retry(**_RETRY_ARGS)
795795
def create_namespace(self, namespace: Union[str, Identifier], properties: Properties = EMPTY_DICT) -> None:
@@ -826,7 +826,7 @@ def list_namespaces(self, namespace: Union[str, Identifier] = ()) -> List[Identi
826826
except HTTPError as exc:
827827
self._handle_non_200_response(exc, {})
828828

829-
return ListNamespaceResponse(**response.json()).namespaces
829+
return ListNamespaceResponse.model_validate_json(response.text).namespaces
830830

831831
@retry(**_RETRY_ARGS)
832832
def load_namespace_properties(self, namespace: Union[str, Identifier]) -> Properties:
@@ -838,7 +838,7 @@ def load_namespace_properties(self, namespace: Union[str, Identifier]) -> Proper
838838
except HTTPError as exc:
839839
self._handle_non_200_response(exc, {404: NoSuchNamespaceError})
840840

841-
return NamespaceResponse(**response.json()).properties
841+
return NamespaceResponse.model_validate_json(response.text).properties
842842

843843
@retry(**_RETRY_ARGS)
844844
def update_namespace_properties(
@@ -852,7 +852,7 @@ def update_namespace_properties(
852852
response.raise_for_status()
853853
except HTTPError as exc:
854854
self._handle_non_200_response(exc, {404: NoSuchNamespaceError})
855-
parsed_response = UpdateNamespacePropertiesResponse(**response.json())
855+
parsed_response = UpdateNamespacePropertiesResponse.model_validate_json(response.text)
856856
return PropertiesUpdateSummary(
857857
removed=parsed_response.removed,
858858
updated=parsed_response.updated,

0 commit comments

Comments
 (0)