gooddata-pandas 1.12.1.dev3__tar.gz → 1.18.2.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gooddata-pandas-1.12.1.dev3/gooddata_pandas.egg-info → gooddata_pandas-1.18.2.dev1}/PKG-INFO +3 -3
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/data_access.py +17 -11
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/dataframe.py +36 -21
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/good_pandas.py +3 -2
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/result_convertor.py +64 -21
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/utils.py +16 -10
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1/gooddata_pandas.egg-info}/PKG-INFO +3 -3
- gooddata_pandas-1.18.2.dev1/gooddata_pandas.egg-info/requires.txt +2 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/setup.py +3 -3
- gooddata-pandas-1.12.1.dev3/gooddata_pandas.egg-info/requires.txt +0 -2
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/LICENSE.txt +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/MANIFEST.in +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/README.md +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/__init__.py +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/_version.py +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/py.typed +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/series.py +1 -1
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas.egg-info/SOURCES.txt +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas.egg-info/dependency_links.txt +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas.egg-info/top_level.txt +0 -0
- {gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/setup.cfg +0 -0
{gooddata-pandas-1.12.1.dev3/gooddata_pandas.egg-info → gooddata_pandas-1.18.2.dev1}/PKG-INFO
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gooddata-pandas
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18.2.dev1
|
|
4
4
|
Summary: GoodData Cloud to pandas
|
|
5
5
|
Author: GoodData
|
|
6
6
|
Author-email: support@gooddata.com
|
|
7
7
|
License: MIT
|
|
8
|
-
Project-URL: Documentation, https://gooddata-pandas.readthedocs.io/en/v1.
|
|
8
|
+
Project-URL: Documentation, https://gooddata-pandas.readthedocs.io/en/v1.18.2.dev1
|
|
9
9
|
Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
|
|
10
10
|
Keywords: gooddata,pandas,series,data,frame,data_frame,analytics,headless,business,intelligence,headless-bi,cloud,native,semantic,layer,sql,metrics
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
|
|
|
22
22
|
Requires-Python: >=3.8.0
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: gooddata-sdk~=1.
|
|
25
|
+
Requires-Dist: gooddata-sdk~=1.18.2.dev1
|
|
26
26
|
Requires-Dist: pandas<2.0.0,>=1.0.0
|
|
27
27
|
|
|
28
28
|
# GoodData Pandas
|
|
@@ -3,15 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
from typing import Any, Optional, Union
|
|
5
5
|
|
|
6
|
-
from gooddata_pandas.utils import (
|
|
7
|
-
ColumnsDef,
|
|
8
|
-
IndexDef,
|
|
9
|
-
LabelItemDef,
|
|
10
|
-
_str_to_obj_id,
|
|
11
|
-
_to_attribute,
|
|
12
|
-
_to_item,
|
|
13
|
-
_typed_attribute_value,
|
|
14
|
-
)
|
|
15
6
|
from gooddata_sdk import (
|
|
16
7
|
Attribute,
|
|
17
8
|
AttributeFilter,
|
|
@@ -23,6 +14,17 @@ from gooddata_sdk import (
|
|
|
23
14
|
Metric,
|
|
24
15
|
MetricValueFilter,
|
|
25
16
|
ObjId,
|
|
17
|
+
TableDimension,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from gooddata_pandas.utils import (
|
|
21
|
+
ColumnsDef,
|
|
22
|
+
IndexDef,
|
|
23
|
+
LabelItemDef,
|
|
24
|
+
_str_to_obj_id,
|
|
25
|
+
_to_attribute,
|
|
26
|
+
_to_item,
|
|
27
|
+
_typed_attribute_value,
|
|
26
28
|
)
|
|
27
29
|
|
|
28
30
|
|
|
@@ -229,8 +231,12 @@ class ExecutionDefinitionBuilder:
|
|
|
229
231
|
and dimensions.
|
|
230
232
|
"""
|
|
231
233
|
dimensions = [
|
|
232
|
-
|
|
233
|
-
|
|
234
|
+
TableDimension(
|
|
235
|
+
item_ids=["measureGroup"] if self._metrics else None,
|
|
236
|
+
),
|
|
237
|
+
TableDimension(
|
|
238
|
+
item_ids=[a.local_id for a in self._attributes] if self._attributes else None,
|
|
239
|
+
),
|
|
234
240
|
]
|
|
235
241
|
|
|
236
242
|
filters = self._update_filter_ids(filter_by)
|
|
@@ -2,10 +2,20 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from typing import Optional, Tuple, Union
|
|
5
|
+
from warnings import warn
|
|
5
6
|
|
|
6
7
|
import pandas
|
|
7
|
-
|
|
8
8
|
from gooddata_api_client import models
|
|
9
|
+
from gooddata_sdk import (
|
|
10
|
+
Attribute,
|
|
11
|
+
BareExecutionResponse,
|
|
12
|
+
ExecutionDefinition,
|
|
13
|
+
Filter,
|
|
14
|
+
GoodDataSdk,
|
|
15
|
+
ResultCacheMetadata,
|
|
16
|
+
ResultSizeDimensions,
|
|
17
|
+
)
|
|
18
|
+
|
|
9
19
|
from gooddata_pandas.data_access import compute_and_extract
|
|
10
20
|
from gooddata_pandas.result_convertor import (
|
|
11
21
|
_DEFAULT_PAGE_SIZE,
|
|
@@ -15,21 +25,12 @@ from gooddata_pandas.result_convertor import (
|
|
|
15
25
|
)
|
|
16
26
|
from gooddata_pandas.utils import (
|
|
17
27
|
ColumnsDef,
|
|
18
|
-
|
|
28
|
+
DefaultVisualizationColumnNaming,
|
|
19
29
|
IndexDef,
|
|
20
30
|
LabelItemDef,
|
|
21
31
|
_to_item,
|
|
22
32
|
make_pandas_index,
|
|
23
33
|
)
|
|
24
|
-
from gooddata_sdk import (
|
|
25
|
-
Attribute,
|
|
26
|
-
BareExecutionResponse,
|
|
27
|
-
ExecutionDefinition,
|
|
28
|
-
Filter,
|
|
29
|
-
GoodDataSdk,
|
|
30
|
-
ResultCacheMetadata,
|
|
31
|
-
ResultSizeDimensions,
|
|
32
|
-
)
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
class DataFrameFactory:
|
|
@@ -43,7 +44,7 @@ class DataFrameFactory:
|
|
|
43
44
|
-> pandas.DataFrame:
|
|
44
45
|
- for_items(self, items: ColumnsDef, filter_by: Optional[Union[Filter, list[Filter]]] = None,
|
|
45
46
|
auto_index: bool = True) -> pandas.DataFrame:
|
|
46
|
-
-
|
|
47
|
+
- for_visualization(self, visualization_id: str, auto_index: bool = True)
|
|
47
48
|
-> pandas.DataFrame:
|
|
48
49
|
- result_cache_metadata_for_exec_result_id(self, result_id: str)
|
|
49
50
|
-> ResultCacheMetadata:
|
|
@@ -159,28 +160,39 @@ class DataFrameFactory:
|
|
|
159
160
|
filter_by=filter_by,
|
|
160
161
|
)
|
|
161
162
|
|
|
162
|
-
def
|
|
163
|
+
def for_visualization(self, visualization_id: str, auto_index: bool = True) -> pandas.DataFrame:
|
|
163
164
|
"""
|
|
164
|
-
Creates a data frame with columns based on the content of the
|
|
165
|
+
Creates a data frame with columns based on the content of the visualization with the provided identifier.
|
|
165
166
|
|
|
166
167
|
Args:
|
|
167
|
-
|
|
168
|
+
visualization_id (str): Visualization identifier.
|
|
168
169
|
auto_index (bool): Default True. Enables creation of DataFrame with index depending on the contents
|
|
169
|
-
of the
|
|
170
|
+
of the visualization.
|
|
170
171
|
|
|
171
172
|
Returns:
|
|
172
173
|
pandas.DataFrame: A DataFrame instance.
|
|
173
174
|
"""
|
|
174
|
-
naming =
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
naming = DefaultVisualizationColumnNaming()
|
|
176
|
+
visualization = self._sdk.visualizations.get_visualization(
|
|
177
|
+
workspace_id=self._workspace_id, visualization_id=visualization_id
|
|
178
|
+
)
|
|
179
|
+
filter_by = [f.as_computable() for f in visualization.filters]
|
|
177
180
|
columns: ColumnsDef = {
|
|
178
|
-
**{naming.col_name_for_attribute(a): a.as_computable() for a in
|
|
179
|
-
**{naming.col_name_for_metric(m): m.as_computable() for m in
|
|
181
|
+
**{naming.col_name_for_attribute(a): a.as_computable() for a in visualization.attributes},
|
|
182
|
+
**{naming.col_name_for_metric(m): m.as_computable() for m in visualization.metrics},
|
|
180
183
|
}
|
|
181
184
|
|
|
182
185
|
return self.for_items(columns, filter_by=filter_by, auto_index=auto_index)
|
|
183
186
|
|
|
187
|
+
def for_insight(self, insight_id: str, auto_index: bool = True) -> pandas.DataFrame:
|
|
188
|
+
warn(
|
|
189
|
+
"This method is deprecated and it will be removed in v1.20.0 release. "
|
|
190
|
+
"Please use 'for_visualization' method instead.",
|
|
191
|
+
DeprecationWarning,
|
|
192
|
+
stacklevel=2,
|
|
193
|
+
)
|
|
194
|
+
return self.for_visualization(insight_id, auto_index)
|
|
195
|
+
|
|
184
196
|
def result_cache_metadata_for_exec_result_id(self, result_id: str) -> ResultCacheMetadata:
|
|
185
197
|
"""
|
|
186
198
|
Retrieves result cache metadata for given :result_id:
|
|
@@ -257,6 +269,7 @@ class DataFrameFactory:
|
|
|
257
269
|
result_size_dimensions_limits: ResultSizeDimensions = (),
|
|
258
270
|
result_size_bytes_limit: Optional[int] = None,
|
|
259
271
|
use_local_ids_in_headers: bool = False,
|
|
272
|
+
use_primary_labels_in_attributes: bool = False,
|
|
260
273
|
page_size: int = _DEFAULT_PAGE_SIZE,
|
|
261
274
|
) -> Tuple[pandas.DataFrame, DataFrameMetadata]:
|
|
262
275
|
"""
|
|
@@ -286,6 +299,7 @@ class DataFrameFactory:
|
|
|
286
299
|
result_size_dimensions_limits (ResultSizeDimensions): A tuple containing maximum size of result dimensions.
|
|
287
300
|
result_size_bytes_limit (Optional[int]): Maximum size of result in bytes.
|
|
288
301
|
use_local_ids_in_headers (bool): Use local identifier in headers.
|
|
302
|
+
use_primary_labels_in_attributes (bool): Use primary labels in attributes.
|
|
289
303
|
page_size (int): Number of records per page.
|
|
290
304
|
|
|
291
305
|
Returns:
|
|
@@ -310,5 +324,6 @@ class DataFrameFactory:
|
|
|
310
324
|
result_size_dimensions_limits=result_size_dimensions_limits,
|
|
311
325
|
result_size_bytes_limit=result_size_bytes_limit,
|
|
312
326
|
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
327
|
+
use_primary_labels_in_attributes=use_primary_labels_in_attributes,
|
|
313
328
|
page_size=page_size,
|
|
314
329
|
)
|
|
@@ -4,11 +4,12 @@ from __future__ import annotations
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
|
+
from gooddata_sdk import GoodDataSdk
|
|
8
|
+
from gooddata_sdk.utils import PROFILES_FILE_PATH, good_pandas_profile_content
|
|
9
|
+
|
|
7
10
|
from gooddata_pandas import __version__
|
|
8
11
|
from gooddata_pandas.dataframe import DataFrameFactory
|
|
9
12
|
from gooddata_pandas.series import SeriesFactory
|
|
10
|
-
from gooddata_sdk import GoodDataSdk
|
|
11
|
-
from gooddata_sdk.utils import PROFILES_FILE_PATH, good_pandas_profile_content
|
|
12
13
|
|
|
13
14
|
USER_AGENT = f"gooddata-pandas/{__version__}"
|
|
14
15
|
"""Extra segment of the User-Agent header that will be appended to standard gooddata-sdk user agent."""
|
{gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas/result_convertor.py
RENAMED
|
@@ -3,7 +3,6 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Union, cast
|
|
|
3
3
|
|
|
4
4
|
import pandas
|
|
5
5
|
from attrs import define, field, frozen
|
|
6
|
-
|
|
7
6
|
from gooddata_sdk import BareExecutionResponse, ExecutionResult, ResultCacheMetadata, ResultSizeDimensions
|
|
8
7
|
|
|
9
8
|
_DEFAULT_PAGE_SIZE = 100
|
|
@@ -201,12 +200,16 @@ class DataFrameMetadata:
|
|
|
201
200
|
|
|
202
201
|
row_totals_indexes: List[List[int]]
|
|
203
202
|
execution_response: BareExecutionResponse
|
|
203
|
+
primary_labels_from_index: Dict[int, Dict[str, str]]
|
|
204
|
+
primary_labels_from_columns: Dict[int, Dict[str, str]]
|
|
204
205
|
|
|
205
206
|
@classmethod
|
|
206
207
|
def from_data(
|
|
207
208
|
cls,
|
|
208
209
|
headers: Tuple[_DataHeaders, Optional[_DataHeaders]],
|
|
209
210
|
execution_response: BareExecutionResponse,
|
|
211
|
+
primary_labels_from_index: Dict[int, Dict[str, str]],
|
|
212
|
+
primary_labels_from_columns: Dict[int, Dict[str, str]],
|
|
210
213
|
) -> "DataFrameMetadata":
|
|
211
214
|
"""This method constructs a DataFrameMetadata object from data headers and an execution response.
|
|
212
215
|
|
|
@@ -220,6 +223,8 @@ class DataFrameMetadata:
|
|
|
220
223
|
return cls(
|
|
221
224
|
row_totals_indexes=row_totals_indexes,
|
|
222
225
|
execution_response=execution_response,
|
|
226
|
+
primary_labels_from_index=primary_labels_from_index,
|
|
227
|
+
primary_labels_from_columns=primary_labels_from_columns,
|
|
223
228
|
)
|
|
224
229
|
|
|
225
230
|
|
|
@@ -305,8 +310,10 @@ def _read_complete_execution_result(
|
|
|
305
310
|
def _create_header_mapper(
|
|
306
311
|
response: BareExecutionResponse,
|
|
307
312
|
dim: int,
|
|
313
|
+
primary_attribute_labels_mapping: Dict[int, Dict[str, str]],
|
|
308
314
|
label_overrides: Optional[LabelOverrides] = None,
|
|
309
315
|
use_local_ids_in_headers: bool = False,
|
|
316
|
+
use_primary_labels_in_attributes: bool = False,
|
|
310
317
|
) -> Callable[[Any, Optional[int]], Optional[str]]:
|
|
311
318
|
"""
|
|
312
319
|
Prepares a header mapper function which translates header structures into appropriate labels used
|
|
@@ -315,9 +322,12 @@ def _create_header_mapper(
|
|
|
315
322
|
Args:
|
|
316
323
|
response (BareExecutionResponse): Response structure to gather dimension header details.
|
|
317
324
|
dim (int): Dimension id.
|
|
325
|
+
primary_attribute_labels_mapping (Dict[int, Dict[str, str]]): Dict to be filled by mapping of primary labels to
|
|
326
|
+
custom labels per level identified by integer.
|
|
318
327
|
label_overrides (Optional[LabelOverrides]): Label overrides. Defaults to None.
|
|
319
328
|
use_local_ids_in_headers (bool): Use local identifiers of header attributes and metrics. Optional.
|
|
320
329
|
Defaults to False.
|
|
330
|
+
use_primary_labels_in_attributes (bool): Use primary labels in attributes. Optional. Defaults to False.
|
|
321
331
|
|
|
322
332
|
Returns:
|
|
323
333
|
Callable[[Any, Optional[int]], Optional[str]]: Mapper function.
|
|
@@ -335,7 +345,17 @@ def _create_header_mapper(
|
|
|
335
345
|
pass
|
|
336
346
|
elif "attributeHeader" in header:
|
|
337
347
|
if "labelValue" in header["attributeHeader"]:
|
|
338
|
-
|
|
348
|
+
label_value = header["attributeHeader"]["labelValue"]
|
|
349
|
+
primary_label_value = header["attributeHeader"]["primaryLabelValue"]
|
|
350
|
+
if use_primary_labels_in_attributes:
|
|
351
|
+
label = primary_label_value
|
|
352
|
+
else:
|
|
353
|
+
label = label_value
|
|
354
|
+
if header_idx is not None:
|
|
355
|
+
if header_idx in primary_attribute_labels_mapping:
|
|
356
|
+
primary_attribute_labels_mapping[header_idx][primary_label_value] = label_value
|
|
357
|
+
else:
|
|
358
|
+
primary_attribute_labels_mapping[header_idx] = {primary_label_value: label_value}
|
|
339
359
|
# explicitly handle '(empty value)' if it's None otherwise it's not recognizable in final MultiIndex
|
|
340
360
|
# backend represents ^^^ by "" (datasource value is "") or None (datasource value is NULL) therefore
|
|
341
361
|
# if both representation are used it's necessary to set label to unique header label (space) to avoid
|
|
@@ -377,7 +397,8 @@ def _headers_to_index(
|
|
|
377
397
|
response: BareExecutionResponse,
|
|
378
398
|
label_overrides: LabelOverrides,
|
|
379
399
|
use_local_ids_in_headers: bool = False,
|
|
380
|
-
|
|
400
|
+
use_primary_labels_in_attributes: bool = False,
|
|
401
|
+
) -> Tuple[Optional[pandas.Index], Dict[int, Dict[str, str]]]:
|
|
381
402
|
"""Converts headers to a pandas MultiIndex.
|
|
382
403
|
|
|
383
404
|
This function converts the headers present in the response to a pandas MultiIndex (can be used in pandas dataframes)
|
|
@@ -389,18 +410,26 @@ def _headers_to_index(
|
|
|
389
410
|
response (BareExecutionResponse): The execution response object with all data.
|
|
390
411
|
label_overrides (LabelOverrides): A dictionary containing label overrides for the headers.
|
|
391
412
|
use_local_ids_in_headers (bool, optional): If True, uses local Ids in headers, otherwise not. Defaults to False.
|
|
413
|
+
use_primary_labels_in_attributes (bool, optional): If True, uses primary labels in attributes, otherwise not.
|
|
414
|
+
Defaults to False.
|
|
392
415
|
|
|
393
416
|
Returns:
|
|
394
|
-
Optional[pandas.Index]: A pandas MultiIndex object created from the headers
|
|
417
|
+
Tuple[Optional[pandas.Index], Dict[int, Dict[str, str]]: A pandas MultiIndex object created from the headers
|
|
418
|
+
with primary attribute labels mapping as Dict, or None with empty Dict if the headers are empty.
|
|
395
419
|
"""
|
|
420
|
+
# dict of primary labels and it's custom labels for attributes per level as key
|
|
421
|
+
primary_attribute_labels_mapping: Dict[int, Dict[str, str]] = {}
|
|
422
|
+
|
|
396
423
|
if len(response.dimensions) <= dim_idx or not len(response.dimensions[dim_idx]["headers"]):
|
|
397
|
-
return None
|
|
424
|
+
return None, primary_attribute_labels_mapping
|
|
398
425
|
|
|
399
426
|
mapper = _create_header_mapper(
|
|
400
427
|
response=response,
|
|
401
428
|
dim=dim_idx,
|
|
402
429
|
label_overrides=label_overrides,
|
|
403
430
|
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
431
|
+
use_primary_labels_in_attributes=use_primary_labels_in_attributes,
|
|
432
|
+
primary_attribute_labels_mapping=primary_attribute_labels_mapping,
|
|
404
433
|
)
|
|
405
434
|
|
|
406
435
|
return pandas.MultiIndex.from_arrays(
|
|
@@ -409,7 +438,7 @@ def _headers_to_index(
|
|
|
409
438
|
for header_idx, header_group in enumerate(cast(_DataHeaders, headers[dim_idx]))
|
|
410
439
|
],
|
|
411
440
|
names=[mapper(dim_header, None) for dim_header in (response.dimensions[dim_idx]["headers"])],
|
|
412
|
-
)
|
|
441
|
+
), primary_attribute_labels_mapping
|
|
413
442
|
|
|
414
443
|
|
|
415
444
|
def _merge_grand_totals_into_data(extract: _DataWithHeaders) -> Union[_DataArray, List[_DataArray]]:
|
|
@@ -468,6 +497,7 @@ def convert_execution_response_to_dataframe(
|
|
|
468
497
|
result_size_dimensions_limits: ResultSizeDimensions,
|
|
469
498
|
result_size_bytes_limit: Optional[int] = None,
|
|
470
499
|
use_local_ids_in_headers: bool = False,
|
|
500
|
+
use_primary_labels_in_attributes: bool = False,
|
|
471
501
|
page_size: int = _DEFAULT_PAGE_SIZE,
|
|
472
502
|
) -> Tuple[pandas.DataFrame, DataFrameMetadata]:
|
|
473
503
|
"""
|
|
@@ -481,6 +511,8 @@ def convert_execution_response_to_dataframe(
|
|
|
481
511
|
result_size_dimensions_limits (ResultSizeDimensions): Dimension limits for the dataframe.
|
|
482
512
|
result_size_bytes_limit (Optional[int], default=None): Size limit in bytes for the dataframe.
|
|
483
513
|
use_local_ids_in_headers (bool, default=False): Use local ids in headers if True, else use default settings.
|
|
514
|
+
use_primary_labels_in_attributes (bool, default=False): Use primary labels in attributes if True, else use
|
|
515
|
+
default settings.
|
|
484
516
|
page_size (int, default=_DEFAULT_PAGE_SIZE): Size of the page.
|
|
485
517
|
|
|
486
518
|
Returns:
|
|
@@ -496,22 +528,33 @@ def convert_execution_response_to_dataframe(
|
|
|
496
528
|
full_data = _merge_grand_totals_into_data(extract)
|
|
497
529
|
full_headers = _merge_grand_total_headers_into_headers(extract)
|
|
498
530
|
|
|
531
|
+
index, primary_labels_from_index = _headers_to_index(
|
|
532
|
+
dim_idx=0,
|
|
533
|
+
headers=full_headers,
|
|
534
|
+
response=execution_response,
|
|
535
|
+
label_overrides=label_overrides,
|
|
536
|
+
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
537
|
+
use_primary_labels_in_attributes=use_primary_labels_in_attributes,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
columns, primary_labels_from_columns = _headers_to_index(
|
|
541
|
+
dim_idx=1,
|
|
542
|
+
headers=full_headers,
|
|
543
|
+
response=execution_response,
|
|
544
|
+
label_overrides=label_overrides,
|
|
545
|
+
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
546
|
+
use_primary_labels_in_attributes=use_primary_labels_in_attributes,
|
|
547
|
+
)
|
|
548
|
+
|
|
499
549
|
df = pandas.DataFrame(
|
|
500
550
|
data=full_data,
|
|
501
|
-
index=
|
|
502
|
-
|
|
503
|
-
headers=full_headers,
|
|
504
|
-
response=execution_response,
|
|
505
|
-
label_overrides=label_overrides,
|
|
506
|
-
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
507
|
-
),
|
|
508
|
-
columns=_headers_to_index(
|
|
509
|
-
dim_idx=1,
|
|
510
|
-
headers=full_headers,
|
|
511
|
-
response=execution_response,
|
|
512
|
-
label_overrides=label_overrides,
|
|
513
|
-
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
514
|
-
),
|
|
551
|
+
index=index,
|
|
552
|
+
columns=columns,
|
|
515
553
|
)
|
|
516
554
|
|
|
517
|
-
return df, DataFrameMetadata.from_data(
|
|
555
|
+
return df, DataFrameMetadata.from_data(
|
|
556
|
+
headers=full_headers,
|
|
557
|
+
execution_response=execution_response,
|
|
558
|
+
primary_labels_from_index=primary_labels_from_index,
|
|
559
|
+
primary_labels_from_columns=primary_labels_from_columns,
|
|
560
|
+
)
|
|
@@ -6,17 +6,23 @@ import uuid
|
|
|
6
6
|
from typing import Any, Dict, Optional, Union
|
|
7
7
|
|
|
8
8
|
import pandas
|
|
9
|
-
from
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
from gooddata_sdk import (
|
|
10
|
+
Attribute,
|
|
11
|
+
CatalogAttribute,
|
|
12
|
+
Metric,
|
|
13
|
+
ObjId,
|
|
14
|
+
SimpleMetric,
|
|
15
|
+
VisualizationAttribute,
|
|
16
|
+
VisualizationMetric,
|
|
17
|
+
)
|
|
12
18
|
from gooddata_sdk.type_converter import AttributeConverterStore, DateConverter, DatetimeConverter, IntegerConverter
|
|
19
|
+
from pandas import Index, MultiIndex
|
|
13
20
|
|
|
14
21
|
LabelItemDef = Union[Attribute, ObjId, str]
|
|
15
22
|
DataItemDef = Union[Attribute, Metric, ObjId, str]
|
|
16
23
|
IndexDef = Union[LabelItemDef, Dict[str, LabelItemDef]]
|
|
17
24
|
ColumnsDef = Dict[str, DataItemDef]
|
|
18
25
|
|
|
19
|
-
|
|
20
26
|
# register external pandas types to converters
|
|
21
27
|
IntegerConverter.set_external_fnc(lambda self, value: pandas.to_numeric(value))
|
|
22
28
|
DateConverter.set_external_fnc(lambda self, value: pandas.to_datetime(value))
|
|
@@ -162,10 +168,10 @@ def make_pandas_index(index: dict) -> Optional[Union[Index, MultiIndex]]:
|
|
|
162
168
|
return _idx
|
|
163
169
|
|
|
164
170
|
|
|
165
|
-
class
|
|
171
|
+
class DefaultVisualizationColumnNaming:
|
|
166
172
|
def __init__(self) -> None:
|
|
167
173
|
"""
|
|
168
|
-
Initialize a
|
|
174
|
+
Initialize a DefaultVisualizationColumnNaming instance with an empty dictionary for unique names.
|
|
169
175
|
"""
|
|
170
176
|
self._uniques: dict[str, int] = dict()
|
|
171
177
|
|
|
@@ -206,24 +212,24 @@ class DefaultInsightColumnNaming:
|
|
|
206
212
|
self._uniques[unique_candidate] = 1
|
|
207
213
|
return unique_candidate
|
|
208
214
|
|
|
209
|
-
def col_name_for_attribute(self, attr:
|
|
215
|
+
def col_name_for_attribute(self, attr: VisualizationAttribute) -> str:
|
|
210
216
|
"""
|
|
211
217
|
Generate a unique column name for the given attribute.
|
|
212
218
|
|
|
213
219
|
Args:
|
|
214
|
-
attr (
|
|
220
|
+
attr (VisualizationAttribute): The attribute.
|
|
215
221
|
|
|
216
222
|
Returns:
|
|
217
223
|
str: The unique column name.
|
|
218
224
|
"""
|
|
219
225
|
return self._ensure_unique(attr.label_id)
|
|
220
226
|
|
|
221
|
-
def col_name_for_metric(self, measure:
|
|
227
|
+
def col_name_for_metric(self, measure: VisualizationMetric) -> str:
|
|
222
228
|
"""
|
|
223
229
|
Generate a unique column name for the given metric.
|
|
224
230
|
|
|
225
231
|
Args:
|
|
226
|
-
measure (
|
|
232
|
+
measure (VisualizationMetric): The metric.
|
|
227
233
|
|
|
228
234
|
Returns:
|
|
229
235
|
str: The unique column name.
|
{gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1/gooddata_pandas.egg-info}/PKG-INFO
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gooddata-pandas
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18.2.dev1
|
|
4
4
|
Summary: GoodData Cloud to pandas
|
|
5
5
|
Author: GoodData
|
|
6
6
|
Author-email: support@gooddata.com
|
|
7
7
|
License: MIT
|
|
8
|
-
Project-URL: Documentation, https://gooddata-pandas.readthedocs.io/en/v1.
|
|
8
|
+
Project-URL: Documentation, https://gooddata-pandas.readthedocs.io/en/v1.18.2.dev1
|
|
9
9
|
Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
|
|
10
10
|
Keywords: gooddata,pandas,series,data,frame,data_frame,analytics,headless,business,intelligence,headless-bi,cloud,native,semantic,layer,sql,metrics
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
|
|
|
22
22
|
Requires-Python: >=3.8.0
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: gooddata-sdk~=1.
|
|
25
|
+
Requires-Dist: gooddata-sdk~=1.18.2.dev1
|
|
26
26
|
Requires-Dist: pandas<2.0.0,>=1.0.0
|
|
27
27
|
|
|
28
28
|
# GoodData Pandas
|
|
@@ -7,7 +7,7 @@ this_directory = Path(__file__).parent
|
|
|
7
7
|
long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
8
8
|
|
|
9
9
|
REQUIRES = [
|
|
10
|
-
"gooddata-sdk~=1.
|
|
10
|
+
"gooddata-sdk~=1.18.2.dev1",
|
|
11
11
|
"pandas>=1.0.0,<2.0.0",
|
|
12
12
|
]
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ setup(
|
|
|
16
16
|
description="GoodData Cloud to pandas",
|
|
17
17
|
long_description=long_description,
|
|
18
18
|
long_description_content_type="text/markdown",
|
|
19
|
-
version="1.
|
|
19
|
+
version="1.18.2.dev1",
|
|
20
20
|
author="GoodData",
|
|
21
21
|
author_email="support@gooddata.com",
|
|
22
22
|
license="MIT",
|
|
@@ -26,7 +26,7 @@ setup(
|
|
|
26
26
|
packages=find_packages(exclude=["tests*"]),
|
|
27
27
|
python_requires=">=3.8.0",
|
|
28
28
|
project_urls={
|
|
29
|
-
"Documentation": "https://gooddata-pandas.readthedocs.io/en/v1.
|
|
29
|
+
"Documentation": "https://gooddata-pandas.readthedocs.io/en/v1.18.2.dev1",
|
|
30
30
|
"Source": "https://github.com/gooddata/gooddata-python-sdk",
|
|
31
31
|
},
|
|
32
32
|
classifiers=[
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -4,10 +4,10 @@ from __future__ import annotations
|
|
|
4
4
|
from typing import Optional, Union
|
|
5
5
|
|
|
6
6
|
import pandas
|
|
7
|
+
from gooddata_sdk import Attribute, Filter, GoodDataSdk, ObjId, SimpleMetric
|
|
7
8
|
|
|
8
9
|
from gooddata_pandas.data_access import compute_and_extract
|
|
9
10
|
from gooddata_pandas.utils import IndexDef, LabelItemDef, make_pandas_index
|
|
10
|
-
from gooddata_sdk import Attribute, Filter, GoodDataSdk, ObjId, SimpleMetric
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class SeriesFactory:
|
{gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-pandas-1.12.1.dev3 → gooddata_pandas-1.18.2.dev1}/gooddata_pandas.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|