gooddata-pandas 1.14.1.dev1__py3-none-any.whl → 1.21.1.dev3__py3-none-any.whl
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.
Potentially problematic release.
This version of gooddata-pandas might be problematic. Click here for more details.
- gooddata_pandas/data_access.py +17 -11
- gooddata_pandas/dataframe.py +26 -21
- gooddata_pandas/good_pandas.py +3 -2
- gooddata_pandas/result_convertor.py +64 -21
- gooddata_pandas/series.py +1 -1
- gooddata_pandas/utils.py +16 -10
- {gooddata_pandas-1.14.1.dev1.dist-info → gooddata_pandas-1.21.1.dev3.dist-info}/METADATA +5 -4
- gooddata_pandas-1.21.1.dev3.dist-info/RECORD +14 -0
- {gooddata_pandas-1.14.1.dev1.dist-info → gooddata_pandas-1.21.1.dev3.dist-info}/WHEEL +1 -1
- gooddata_pandas-1.14.1.dev1.dist-info/RECORD +0 -14
- {gooddata_pandas-1.14.1.dev1.dist-info → gooddata_pandas-1.21.1.dev3.dist-info}/LICENSE.txt +0 -0
- {gooddata_pandas-1.14.1.dev1.dist-info → gooddata_pandas-1.21.1.dev3.dist-info}/top_level.txt +0 -0
gooddata_pandas/data_access.py
CHANGED
|
@@ -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)
|
gooddata_pandas/dataframe.py
CHANGED
|
@@ -4,8 +4,17 @@ from __future__ import annotations
|
|
|
4
4
|
from typing import Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import pandas
|
|
7
|
-
|
|
8
7
|
from gooddata_api_client import models
|
|
8
|
+
from gooddata_sdk import (
|
|
9
|
+
Attribute,
|
|
10
|
+
BareExecutionResponse,
|
|
11
|
+
ExecutionDefinition,
|
|
12
|
+
Filter,
|
|
13
|
+
GoodDataSdk,
|
|
14
|
+
ResultCacheMetadata,
|
|
15
|
+
ResultSizeDimensions,
|
|
16
|
+
)
|
|
17
|
+
|
|
9
18
|
from gooddata_pandas.data_access import compute_and_extract
|
|
10
19
|
from gooddata_pandas.result_convertor import (
|
|
11
20
|
_DEFAULT_PAGE_SIZE,
|
|
@@ -15,21 +24,12 @@ from gooddata_pandas.result_convertor import (
|
|
|
15
24
|
)
|
|
16
25
|
from gooddata_pandas.utils import (
|
|
17
26
|
ColumnsDef,
|
|
18
|
-
|
|
27
|
+
DefaultVisualizationColumnNaming,
|
|
19
28
|
IndexDef,
|
|
20
29
|
LabelItemDef,
|
|
21
30
|
_to_item,
|
|
22
31
|
make_pandas_index,
|
|
23
32
|
)
|
|
24
|
-
from gooddata_sdk import (
|
|
25
|
-
Attribute,
|
|
26
|
-
BareExecutionResponse,
|
|
27
|
-
ExecutionDefinition,
|
|
28
|
-
Filter,
|
|
29
|
-
GoodDataSdk,
|
|
30
|
-
ResultCacheMetadata,
|
|
31
|
-
ResultSizeDimensions,
|
|
32
|
-
)
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class DataFrameFactory:
|
|
@@ -43,7 +43,7 @@ class DataFrameFactory:
|
|
|
43
43
|
-> pandas.DataFrame:
|
|
44
44
|
- for_items(self, items: ColumnsDef, filter_by: Optional[Union[Filter, list[Filter]]] = None,
|
|
45
45
|
auto_index: bool = True) -> pandas.DataFrame:
|
|
46
|
-
-
|
|
46
|
+
- for_visualization(self, visualization_id: str, auto_index: bool = True)
|
|
47
47
|
-> pandas.DataFrame:
|
|
48
48
|
- result_cache_metadata_for_exec_result_id(self, result_id: str)
|
|
49
49
|
-> ResultCacheMetadata:
|
|
@@ -159,24 +159,26 @@ class DataFrameFactory:
|
|
|
159
159
|
filter_by=filter_by,
|
|
160
160
|
)
|
|
161
161
|
|
|
162
|
-
def
|
|
162
|
+
def for_visualization(self, visualization_id: str, auto_index: bool = True) -> pandas.DataFrame:
|
|
163
163
|
"""
|
|
164
|
-
Creates a data frame with columns based on the content of the
|
|
164
|
+
Creates a data frame with columns based on the content of the visualization with the provided identifier.
|
|
165
165
|
|
|
166
166
|
Args:
|
|
167
|
-
|
|
167
|
+
visualization_id (str): Visualization identifier.
|
|
168
168
|
auto_index (bool): Default True. Enables creation of DataFrame with index depending on the contents
|
|
169
|
-
of the
|
|
169
|
+
of the visualization.
|
|
170
170
|
|
|
171
171
|
Returns:
|
|
172
172
|
pandas.DataFrame: A DataFrame instance.
|
|
173
173
|
"""
|
|
174
|
-
naming =
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
naming = DefaultVisualizationColumnNaming()
|
|
175
|
+
visualization = self._sdk.visualizations.get_visualization(
|
|
176
|
+
workspace_id=self._workspace_id, visualization_id=visualization_id
|
|
177
|
+
)
|
|
178
|
+
filter_by = [f.as_computable() for f in visualization.filters]
|
|
177
179
|
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
|
|
180
|
+
**{naming.col_name_for_attribute(a): a.as_computable() for a in visualization.attributes},
|
|
181
|
+
**{naming.col_name_for_metric(m): m.as_computable() for m in visualization.metrics},
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
return self.for_items(columns, filter_by=filter_by, auto_index=auto_index)
|
|
@@ -257,6 +259,7 @@ class DataFrameFactory:
|
|
|
257
259
|
result_size_dimensions_limits: ResultSizeDimensions = (),
|
|
258
260
|
result_size_bytes_limit: Optional[int] = None,
|
|
259
261
|
use_local_ids_in_headers: bool = False,
|
|
262
|
+
use_primary_labels_in_attributes: bool = False,
|
|
260
263
|
page_size: int = _DEFAULT_PAGE_SIZE,
|
|
261
264
|
) -> Tuple[pandas.DataFrame, DataFrameMetadata]:
|
|
262
265
|
"""
|
|
@@ -286,6 +289,7 @@ class DataFrameFactory:
|
|
|
286
289
|
result_size_dimensions_limits (ResultSizeDimensions): A tuple containing maximum size of result dimensions.
|
|
287
290
|
result_size_bytes_limit (Optional[int]): Maximum size of result in bytes.
|
|
288
291
|
use_local_ids_in_headers (bool): Use local identifier in headers.
|
|
292
|
+
use_primary_labels_in_attributes (bool): Use primary labels in attributes.
|
|
289
293
|
page_size (int): Number of records per page.
|
|
290
294
|
|
|
291
295
|
Returns:
|
|
@@ -310,5 +314,6 @@ class DataFrameFactory:
|
|
|
310
314
|
result_size_dimensions_limits=result_size_dimensions_limits,
|
|
311
315
|
result_size_bytes_limit=result_size_bytes_limit,
|
|
312
316
|
use_local_ids_in_headers=use_local_ids_in_headers,
|
|
317
|
+
use_primary_labels_in_attributes=use_primary_labels_in_attributes,
|
|
313
318
|
page_size=page_size,
|
|
314
319
|
)
|
gooddata_pandas/good_pandas.py
CHANGED
|
@@ -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."""
|
|
@@ -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
|
+
)
|
gooddata_pandas/series.py
CHANGED
|
@@ -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/utils.py
CHANGED
|
@@ -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.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gooddata-pandas
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.21.1.dev3
|
|
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.21.1.dev3
|
|
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
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
19
|
Classifier: Topic :: Database
|
|
19
20
|
Classifier: Topic :: Scientific/Engineering
|
|
20
21
|
Classifier: Topic :: Software Development
|
|
@@ -22,8 +23,8 @@ Classifier: Typing :: Typed
|
|
|
22
23
|
Requires-Python: >=3.8.0
|
|
23
24
|
Description-Content-Type: text/markdown
|
|
24
25
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: gooddata-sdk ~=1.
|
|
26
|
-
Requires-Dist: pandas <
|
|
26
|
+
Requires-Dist: gooddata-sdk ~=1.21.1.dev3
|
|
27
|
+
Requires-Dist: pandas <3.0.0,>=2.0.0
|
|
27
28
|
|
|
28
29
|
# GoodData Pandas
|
|
29
30
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
gooddata_pandas/__init__.py,sha256=Ta3qIIDq7kBRUsYSV3aC69AQBFvFvhtWDQucgP-l88w,297
|
|
2
|
+
gooddata_pandas/_version.py,sha256=YxaAwfP9Yw10sit_vyhVfHJQBAzUUwtm5p0BItfBFx8,225
|
|
3
|
+
gooddata_pandas/data_access.py,sha256=X8NKYtwWKFEfXvgrUbybuQmg1cub5pAhFtDCFMyzffY,18748
|
|
4
|
+
gooddata_pandas/dataframe.py,sha256=YwjkuO6PzqSfQTaB1Bsn2VuQHvxyiYL75xIW2iI7t3M,13007
|
|
5
|
+
gooddata_pandas/good_pandas.py,sha256=ePEm2Lmeiftz5td0BLC71q7my5Aj8aABn3xV0myRmqI,3444
|
|
6
|
+
gooddata_pandas/py.typed,sha256=u_MS29sadlaIqGRPYFjWml5u0gQnoQfvbsf9pu3TZJU,94
|
|
7
|
+
gooddata_pandas/result_convertor.py,sha256=6k9-Z6Jgtej2yPcR2iftKd2c6e8OwSEDkiil2o-zjP0,25892
|
|
8
|
+
gooddata_pandas/series.py,sha256=wTvJR_I0FUteyxo4RwHzP20eU7rei0dP8ZdqfrLbf5c,5759
|
|
9
|
+
gooddata_pandas/utils.py,sha256=PpkB6oWacRxYY9S-RbEZm9Jdblo4bgAzrmHzV9MlMPQ,7223
|
|
10
|
+
gooddata_pandas-1.21.1.dev3.dist-info/LICENSE.txt,sha256=CTs8U6T7MmKBKFFiQYARwgCfWgUzdosq01DI298WFiY,77209
|
|
11
|
+
gooddata_pandas-1.21.1.dev3.dist-info/METADATA,sha256=4DGa5M7y0bwLfmBeSKLoRUVuyOWvSflmtfhjHfU2RHM,2893
|
|
12
|
+
gooddata_pandas-1.21.1.dev3.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
13
|
+
gooddata_pandas-1.21.1.dev3.dist-info/top_level.txt,sha256=B7K_WFxlxplJbEbv5Mf0YhX74dbOpTPgDX-W6I7CssI,16
|
|
14
|
+
gooddata_pandas-1.21.1.dev3.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
gooddata_pandas/__init__.py,sha256=Ta3qIIDq7kBRUsYSV3aC69AQBFvFvhtWDQucgP-l88w,297
|
|
2
|
-
gooddata_pandas/_version.py,sha256=YxaAwfP9Yw10sit_vyhVfHJQBAzUUwtm5p0BItfBFx8,225
|
|
3
|
-
gooddata_pandas/data_access.py,sha256=8o7N2lC_tUU-3ht2RZm0osB4bYA-YQq8sCQauDaJSs4,18625
|
|
4
|
-
gooddata_pandas/dataframe.py,sha256=bpCpTBpne_qmgLQ44EJxJ8IUC-Kw0UzLaVNt89ugvO0,12655
|
|
5
|
-
gooddata_pandas/good_pandas.py,sha256=9E8sSGppJaxW-eMCdY2rR_7k5hdlAPQqv4djfkvllcg,3443
|
|
6
|
-
gooddata_pandas/py.typed,sha256=u_MS29sadlaIqGRPYFjWml5u0gQnoQfvbsf9pu3TZJU,94
|
|
7
|
-
gooddata_pandas/result_convertor.py,sha256=3DZfsJqKswz2GlctaKZVpbjUd5OHOPxlRlYHp0P_Hok,23249
|
|
8
|
-
gooddata_pandas/series.py,sha256=UmfYvX0RhuRsItXPDm-kFo5CBT73qkro_WtYEITgg1g,5759
|
|
9
|
-
gooddata_pandas/utils.py,sha256=RtOnyjHkzsOo8kpAvw_puEkI7EkqdHmOwPD3kV26RS0,7144
|
|
10
|
-
gooddata_pandas-1.14.1.dev1.dist-info/LICENSE.txt,sha256=CTs8U6T7MmKBKFFiQYARwgCfWgUzdosq01DI298WFiY,77209
|
|
11
|
-
gooddata_pandas-1.14.1.dev1.dist-info/METADATA,sha256=JbtmEvUUe6Mi24Oc7wIfq3wMFeKbNyaxcvxSFsB9akU,2842
|
|
12
|
-
gooddata_pandas-1.14.1.dev1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
13
|
-
gooddata_pandas-1.14.1.dev1.dist-info/top_level.txt,sha256=B7K_WFxlxplJbEbv5Mf0YhX74dbOpTPgDX-W6I7CssI,16
|
|
14
|
-
gooddata_pandas-1.14.1.dev1.dist-info/RECORD,,
|
|
File without changes
|
{gooddata_pandas-1.14.1.dev1.dist-info → gooddata_pandas-1.21.1.dev3.dist-info}/top_level.txt
RENAMED
|
File without changes
|