Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/gooddata-sdk/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ test = [
]

[tool.ty.analysis]
allowed-unresolved-imports = ["gooddata_api_client.**"]
allowed-unresolved-imports = ["gooddata_api_client.**", "pyarrow.**"]

[tool.hatch.build.targets.wheel]
packages = ["src/gooddata_sdk"]
Expand Down
1 change: 1 addition & 0 deletions packages/gooddata-sdk/src/gooddata_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
ExecutionDefinition,
ExecutionResponse,
ExecutionResult,
ExecutionResultLimitBreak,
ResultCacheMetadata,
ResultSizeBytesLimitExceeded,
ResultSizeDimensions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
import pyarrow as _pyarrow
from pyarrow import ipc as _ipc
except ImportError:
_pyarrow = None # type: ignore
_ipc = None # type: ignore
_pyarrow = None
_ipc = None

from gooddata_sdk.client import GoodDataApiClient
from gooddata_sdk.compute.model.attribute import Attribute
Expand All @@ -30,6 +30,29 @@
logger = logging.getLogger(__name__)


@define
class ExecutionResultLimitBreak:
"""Describes a limit that was broken, resulting in partial data being returned."""

limit: int
"""The configured threshold value."""

limit_type: str
"""Type of the limit that was broken, e.g. 'rowCount'."""

value: int | None = None
"""The actual value that triggered the limit; None when it cannot be determined exactly."""

@classmethod
def from_api(cls, data: dict[str, Any]) -> ExecutionResultLimitBreak:
raw_value = data.get("value")
return cls(
limit=int(data["limit"]),
limit_type=str(data["limitType"]),
value=int(raw_value) if raw_value is not None else None,
)


@define
class TotalDimension:
idx: int
Expand Down Expand Up @@ -271,6 +294,18 @@ def paging_offset(self) -> list[int]:
def metadata(self) -> models.ExecutionResultMetadata:
return self._metadata

@property
def limit_breaks(self) -> list[ExecutionResultLimitBreak]:
"""Returns limits that were broken during result computation.

When no limits were broken (result is complete), returns an empty list.
The ``limitBreaks`` field is absent from the API response in that case.
"""
raw = self._metadata.get("limitBreaks")
if not raw:
return []
return [ExecutionResultLimitBreak.from_api(item) for item in raw]

def is_complete(self, dim: int = 0) -> bool:
return self.paging_offset[dim] + self.paging_count[dim] >= self.paging_total[dim]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def __init__(
self._from_shift = from_shift
self._to_shift = to_shift
self._bounded_filter = bounded_filter
self._empty_value_handling = empty_value_handling
self._empty_value_handling: EmptyValueHandling | None = empty_value_handling

@property
def dataset(self) -> ObjId:
Expand Down Expand Up @@ -435,7 +435,7 @@ def __init__(

self._dataset = dataset
self._granularity = granularity
self._empty_value_handling = empty_value_handling
self._empty_value_handling: EmptyValueHandling | None = empty_value_handling

@property
def dataset(self) -> ObjId:
Expand Down Expand Up @@ -490,7 +490,7 @@ def __init__(
self._dataset = dataset
self._from_date = from_date
self._to_date = to_date
self._empty_value_handling = empty_value_handling
self._empty_value_handling: EmptyValueHandling | None = empty_value_handling

@property
def dataset(self) -> ObjId:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
interactions:
- request:
body:
execution:
attributes: []
filters: []
measures:
- definition:
measure:
computeRatio: false
filters: []
item:
identifier:
id: order_amount
type: metric
localIdentifier: m1
resultSpec:
dimensions:
- itemIdentifiers:
- measureGroup
localIdentifier: dim_0
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
Content-Type:
- application/json
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
method: POST
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute
response:
body:
string:
executionResponse:
dimensions:
- headers:
- measureGroupHeaders:
- format: $#,##0
localIdentifier: m1
name: Order Amount
localIdentifier: dim_0
links:
executionResult: EXECUTION_NORMALIZED_1
headers:
Content-Type:
- application/json
DATE:
- PLACEHOLDER
Expires:
- '0'
Pragma:
- no-cache
X-Content-Type-Options:
- nosniff
X-GDC-CANCEL-TOKEN:
- PLACEHOLDER
X-GDC-TRACE-ID:
- PLACEHOLDER
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
method: GET
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/EXECUTION_NORMALIZED_1?offset=0&limit=1
response:
body:
string:
detail: An error has occurred while calculating the result
reason: Cannot reach the URL
resultId: d7b1e3aaa86bd0f1a31337e6d88c5449e3326183
status: 400
title: Bad Request
traceId: NORMALIZED_TRACE_ID_000000000000
headers:
Content-Type:
- application/problem+json
DATE:
- PLACEHOLDER
Expires:
- '0'
Pragma:
- no-cache
X-Content-Type-Options:
- nosniff
X-GDC-TRACE-ID:
- PLACEHOLDER
status:
code: 400
message: Bad Request
- request:
body:
execution:
attributes: []
filters: []
measures:
- definition:
measure:
computeRatio: false
filters: []
item:
identifier:
id: order_amount
type: metric
localIdentifier: m1
resultSpec:
dimensions:
- itemIdentifiers:
- measureGroup
localIdentifier: dim_0
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
Content-Type:
- application/json
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
method: POST
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute
response:
body:
string:
executionResponse:
dimensions:
- headers:
- measureGroupHeaders:
- format: $#,##0
localIdentifier: m1
name: Order Amount
localIdentifier: dim_0
links:
executionResult: EXECUTION_NORMALIZED_1
headers:
Content-Type:
- application/json
DATE:
- PLACEHOLDER
Expires:
- '0'
Pragma:
- no-cache
X-Content-Type-Options:
- nosniff
X-GDC-CANCEL-TOKEN:
- PLACEHOLDER
X-GDC-TRACE-ID:
- PLACEHOLDER
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- br, gzip, deflate
X-GDC-VALIDATE-RELATIONS:
- 'true'
X-Requested-With:
- XMLHttpRequest
method: GET
uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/EXECUTION_NORMALIZED_1?offset=0&limit=1
response:
body:
string:
detail: An error has occurred while calculating the result
reason: Cannot reach the URL
resultId: 67da26dd311be7504d1af3a312ea1d382cfdf313
status: 400
title: Bad Request
traceId: NORMALIZED_TRACE_ID_000000000000
headers:
Content-Type:
- application/problem+json
DATE:
- PLACEHOLDER
Expires:
- '0'
Pragma:
- no-cache
X-Content-Type-Options:
- nosniff
X-GDC-TRACE-ID:
- PLACEHOLDER
status:
code: 400
message: Bad Request
version: 1
Loading
Loading