Skip to content

Commit 6a20f1c

Browse files
committed
fix(gooddata-sdk): update type annotations for ty 0.0.27 and fix Arrow result reading
1 parent b7d2744 commit 6a20f1c

6 files changed

Lines changed: 47 additions & 9 deletions

File tree

packages/gooddata-fdw/src/gooddata_fdw/executor.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from __future__ import annotations
33

44
from collections.abc import Generator
5-
from typing import Any, NamedTuple
5+
from typing import Any, ClassVar, NamedTuple
66

77
from gooddata_sdk import GoodDataSdk
88

@@ -43,7 +43,10 @@ def execute(
4343

4444

4545
class InsightExecutor(Executor):
46-
_COLUMN_VALIDATORS = [col_val.LocalIdOptionValidator(), col_val.IdOptionValidator(mandatory=False)]
46+
_COLUMN_VALIDATORS: ClassVar[list[col_val.ColumnValidator]] = [
47+
col_val.LocalIdOptionValidator(),
48+
col_val.IdOptionValidator(mandatory=False),
49+
]
4750

4851
def __init__(self, inputs: InitData) -> None:
4952
super().__init__(inputs, self._COLUMN_VALIDATORS)

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class CatalogDataSourceBase(Base):
6262
credentials: Credentials = field(repr=False)
6363
alternative_data_source_id: str | None = None
6464

65-
@type.validator # type: ignore[attr-defined]
65+
@type.validator # type: ignore
6666
def _check_allowed_values(self, attribute: Attribute, value: str) -> None:
6767
value_in_allowed(self.__class__, attribute, value, JsonApiDataSourceInAttributes)
6868

packages/gooddata-sdk/src/gooddata_sdk/catalog/entity.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def is_part_of_api(cls, entity: dict[str, Any]) -> bool:
256256
return cls.USER_KEY in entity
257257

258258
@classmethod
259-
def from_api(cls, attributes: dict[str, Any]) -> BasicCredentials: # type: ignore[override]
259+
def from_api(cls, attributes: dict[str, Any]) -> BasicCredentials: # type: ignore
260260
# Credentials are not returned from security reasons
261261
return cls(
262262
username=attributes[cls.USER_KEY],
@@ -277,7 +277,7 @@ def is_part_of_api(cls, entity: dict[str, Any]) -> bool:
277277
return cls.USER_KEY in entity and cls.PRIVATE_KEY in entity
278278

279279
@classmethod
280-
def from_api(cls, attributes: dict[str, Any]) -> KeyPairCredentials: # type: ignore[override]
280+
def from_api(cls, attributes: dict[str, Any]) -> KeyPairCredentials: # type: ignore
281281
# Credentials are not returned for security reasons
282282
return cls(
283283
username=attributes[cls.USER_KEY],
@@ -297,7 +297,7 @@ def is_part_of_api(cls, entity: dict[str, Any]) -> bool:
297297
return cls.CLIENT_ID in entity and cls.CLIENT_SECRET in entity
298298

299299
@classmethod
300-
def from_api(cls, attributes: dict[str, Any]) -> ClientSecretCredentials: # type: ignore[override]
300+
def from_api(cls, attributes: dict[str, Any]) -> ClientSecretCredentials: # type: ignore
301301
# Credentials are not returned for security reasons
302302
return cls(
303303
client_id=attributes[cls.CLIENT_ID],

packages/gooddata-sdk/src/gooddata_sdk/compute/model/execution.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
from __future__ import annotations
33

44
import logging
5-
from typing import Any, Union
5+
from typing import TYPE_CHECKING, Any, Union
6+
7+
if TYPE_CHECKING:
8+
import pyarrow
69

710
from attrs import define, field
811
from attrs.setters import frozen as frozen_attr
@@ -11,6 +14,13 @@
1114
from gooddata_api_client.model.afm_cancel_tokens import AfmCancelTokens
1215
from gooddata_api_client.model.result_spec import ResultSpec
1316

17+
try:
18+
import pyarrow as _pyarrow
19+
from pyarrow import ipc as _ipc
20+
except ImportError:
21+
_pyarrow = None # type: ignore
22+
_ipc = None # type: ignore
23+
1424
from gooddata_sdk.client import GoodDataApiClient
1525
from gooddata_sdk.compute.model.attribute import Attribute
1626
from gooddata_sdk.compute.model.filter import Filter
@@ -372,6 +382,31 @@ def read_result(
372382
)
373383
return ExecutionResult(execution_result)
374384

385+
def read_result_arrow(self) -> pyarrow.Table:
386+
"""
387+
Reads the full execution result as a pyarrow Table.
388+
389+
The binary endpoint returns the complete result in one shot (no paging).
390+
Requires pyarrow to be installed (pip install gooddata-sdk[arrow]).
391+
"""
392+
if _ipc is None:
393+
raise ImportError(
394+
"pyarrow is required to use read_result_arrow(). Install it with: pip install gooddata-sdk[arrow]"
395+
)
396+
import io
397+
398+
response = self._actions_api.retrieve_result_binary(
399+
workspace_id=self._workspace_id,
400+
result_id=self.result_id,
401+
_preload_content=False,
402+
**({"x_gdc_cancel_token": self.cancel_token} if self.cancel_token else {}),
403+
)
404+
try:
405+
buf = io.BytesIO(response.read())
406+
finally:
407+
response.release_conn()
408+
return _ipc.open_file(buf).read_all()
409+
375410
def cancel(self) -> None:
376411
"""
377412
Cancels the execution backing this execution result.

packages/gooddata-sdk/src/gooddata_sdk/compute/model/filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from gooddata_api_client.model.inline_filter_definition_inline import InlineFilterDefinitionInline
1010

1111
if find_spec("icu") is not None:
12-
from icu import Locale, SimpleDateFormat # type: ignore[import-not-found]
12+
from icu import Locale, SimpleDateFormat # type: ignore
1313

1414
import gooddata_api_client.models as afm_models
1515
from gooddata_api_client.model_utils import OpenApiModel

packages/gooddata-sdk/src/gooddata_sdk/type_converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def to_type(self, value: str) -> Any:
2727
def to_external_type(self, value: str) -> Any:
2828
typed_value = self.to_type(value)
2929
if self._EXTERNAL_CONVERSION_FNC:
30-
return self._EXTERNAL_CONVERSION_FNC(typed_value)
30+
return self._EXTERNAL_CONVERSION_FNC(typed_value) # type: ignore
3131
else:
3232
return typed_value
3333

0 commit comments

Comments
 (0)