flatbread 0.1.2__tar.gz → 0.1.3__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.
- {flatbread-0.1.2 → flatbread-0.1.3}/PKG-INFO +1 -1
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/config/config.defaults.json +10 -1
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/constants.py +16 -3
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/display.py +46 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/tablespec.py +43 -5
- {flatbread-0.1.2 → flatbread-0.1.3}/pyproject.toml +1 -1
- {flatbread-0.1.2 → flatbread-0.1.3}/.gitignore +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/environment.yml +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/__init__.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/dataframe.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/index.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/series.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/agg/aggregation.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/agg/totals.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/chaining.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/config.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/percentages.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/config.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/template.jinja.html +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/template.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/testing/dataframe.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/tooling.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/license.md +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/readme.md +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/__init__.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/__init__.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/test_percentages.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/test_totals.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/test_axes.py +0 -0
- {flatbread-0.1.2 → flatbread-0.1.3}/tests/test_levels.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
from flatbread import DEFAULTS
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
USER_PRESETS = DEFAULTS.get("format_presets", {})
|
|
6
|
+
USER_PRESETS_BY_DTYPE = {
|
|
7
|
+
dtype: set()
|
|
8
|
+
for dtype in ["float", "int", "datetime", "str", "category"]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
for preset_name, preset_config in USER_PRESETS.items():
|
|
12
|
+
preset_dtypes = preset_config.get("dtypes", ["float", "int"]) # Default to numeric
|
|
13
|
+
for dtype in preset_dtypes:
|
|
14
|
+
if dtype in USER_PRESETS_BY_DTYPE:
|
|
15
|
+
USER_PRESETS_BY_DTYPE[dtype].add(preset_name)
|
|
16
|
+
|
|
17
|
+
|
|
5
18
|
SMART_FORMATS = {
|
|
6
19
|
'percentages': {
|
|
7
20
|
'labels': [DEFAULTS['percentages']['label_pct']],
|
|
@@ -43,7 +56,7 @@ NUMBER_PRESETS = {"default", "currency", "percentage", "compact", "diffs"}
|
|
|
43
56
|
DATE_PRESETS = {"default", "date", "datetime"}
|
|
44
57
|
|
|
45
58
|
DTYPE_TO_PRESETS = {
|
|
46
|
-
"float": NUMBER_PRESETS,
|
|
47
|
-
"int": NUMBER_PRESETS,
|
|
48
|
-
"datetime": DATE_PRESETS
|
|
59
|
+
"float": NUMBER_PRESETS.union(USER_PRESETS_BY_DTYPE["float"]),
|
|
60
|
+
"int": NUMBER_PRESETS.union(USER_PRESETS_BY_DTYPE["int"]),
|
|
61
|
+
"datetime": DATE_PRESETS.union(USER_PRESETS_BY_DTYPE["datetime"]),
|
|
49
62
|
}
|
|
@@ -147,6 +147,52 @@ class PitaDisplayMixin:
|
|
|
147
147
|
self._table_spec_builder.set_formats(formats)
|
|
148
148
|
return self
|
|
149
149
|
|
|
150
|
+
def list_format_presets(self, dtype: str = None) -> dict[str, dict]:
|
|
151
|
+
"""List available format presets, optionally filtered by data type
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
dtype : str, optional
|
|
156
|
+
Filter presets by data type compatibility. Options: 'float', 'int',
|
|
157
|
+
'datetime', 'str', 'category'.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
dict
|
|
162
|
+
Dictionary of preset names and their configurations
|
|
163
|
+
"""
|
|
164
|
+
from flatbread.render.constants import USER_PRESETS, DTYPE_TO_PRESETS
|
|
165
|
+
|
|
166
|
+
# Define built-in presets with their configurations
|
|
167
|
+
built_in = {
|
|
168
|
+
"default": {"notation": "standard"},
|
|
169
|
+
"currency": {"style": "currency", "currency": "USD"},
|
|
170
|
+
"percentage": {"style": "percent"},
|
|
171
|
+
"compact": {"notation": "compact"},
|
|
172
|
+
"date": {"dateStyle": "short"},
|
|
173
|
+
"datetime": {"dateStyle": "short", "timeStyle": "short"}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# Extract user preset options
|
|
177
|
+
user_options = {
|
|
178
|
+
name: config.get("options", {})
|
|
179
|
+
for name, config in USER_PRESETS.items()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# Combine built-in and user presets
|
|
183
|
+
all_presets = {**built_in, **user_options}
|
|
184
|
+
|
|
185
|
+
# Filter by dtype if specified
|
|
186
|
+
if dtype:
|
|
187
|
+
if dtype not in DTYPE_TO_PRESETS:
|
|
188
|
+
valid_dtypes = ", ".join(sorted(DTYPE_TO_PRESETS.keys()))
|
|
189
|
+
raise ValueError(f"Invalid dtype '{dtype}'. Valid options are: {valid_dtypes}")
|
|
190
|
+
|
|
191
|
+
valid_presets = DTYPE_TO_PRESETS.get(dtype, set())
|
|
192
|
+
return {k: v for k, v in all_presets.items() if k in valid_presets}
|
|
193
|
+
|
|
194
|
+
return all_presets
|
|
195
|
+
|
|
150
196
|
def _repr_html_(self) -> str:
|
|
151
197
|
"""Generate HTML representation for Jupyter display"""
|
|
152
198
|
spec = self._table_spec_builder.get_spec_as_json()
|
|
@@ -94,17 +94,51 @@ class TableSpecBuilder:
|
|
|
94
94
|
return format_type['options']
|
|
95
95
|
return None
|
|
96
96
|
|
|
97
|
-
def set_format(self, column: str, format_spec:
|
|
97
|
+
def set_format(self, column: str, format_spec: str | dict[str, Any]) -> None:
|
|
98
|
+
"""Set format options for a column
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
column : str
|
|
103
|
+
Column to format
|
|
104
|
+
format_spec : str | dict
|
|
105
|
+
Either a preset name (e.g. 'currency') or format options dict
|
|
106
|
+
"""
|
|
107
|
+
from flatbread.render.constants import USER_PRESETS, DTYPE_TO_PRESETS, DEFAULT_DTYPES
|
|
108
|
+
|
|
98
109
|
if isinstance(format_spec, str):
|
|
110
|
+
# Check if it's a user-defined preset
|
|
111
|
+
if format_spec in USER_PRESETS:
|
|
112
|
+
pandas_dtype = str(self._data[column].dtype)
|
|
113
|
+
simple_dtype = DEFAULT_DTYPES.get(pandas_dtype, 'str')
|
|
114
|
+
|
|
115
|
+
# Get allowed dtypes for this preset
|
|
116
|
+
preset_config = USER_PRESETS[format_spec]
|
|
117
|
+
allowed_dtypes = preset_config.get("dtypes", ["float", "int"])
|
|
118
|
+
|
|
119
|
+
if simple_dtype in allowed_dtypes:
|
|
120
|
+
self._format_options[column] = preset_config.get("options", {})
|
|
121
|
+
return
|
|
122
|
+
else:
|
|
123
|
+
raise ValueError(
|
|
124
|
+
f"Preset '{format_spec}' is not compatible with column '{column}' "
|
|
125
|
+
f"of dtype {pandas_dtype} (mapped to {simple_dtype}). "
|
|
126
|
+
f"This preset supports: {', '.join(allowed_dtypes)}"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Handle built-in presets
|
|
99
130
|
pandas_dtype = str(self._data[column].dtype)
|
|
100
131
|
simple_dtype = DEFAULT_DTYPES.get(pandas_dtype, 'str')
|
|
101
132
|
valid_presets = DTYPE_TO_PRESETS.get(simple_dtype, set())
|
|
133
|
+
|
|
102
134
|
if format_spec not in valid_presets:
|
|
103
135
|
valid = ", ".join(sorted(valid_presets))
|
|
104
136
|
raise ValueError(
|
|
105
137
|
f"Invalid preset '{format_spec}' for dtype {pandas_dtype} "
|
|
106
138
|
f"(mapped to {simple_dtype}). Valid presets are: {valid}"
|
|
107
139
|
)
|
|
140
|
+
|
|
141
|
+
# If we reached here, either format_spec is a dict or a valid built-in preset
|
|
108
142
|
self._format_options[column] = format_spec
|
|
109
143
|
|
|
110
144
|
def set_formats(self, formats: FormatSpec) -> None:
|
|
@@ -112,11 +146,15 @@ class TableSpecBuilder:
|
|
|
112
146
|
|
|
113
147
|
Parameters
|
|
114
148
|
----------
|
|
115
|
-
formats : dict, list or callable
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
149
|
+
formats : str, dict, list or callable
|
|
150
|
+
- If string: apply the same format preset to all columns
|
|
151
|
+
- If dict: mapping column names to format specs
|
|
152
|
+
- If list: format specs in same order as columns
|
|
153
|
+
- If callable: function that takes DataFrame and returns a dict
|
|
119
154
|
"""
|
|
155
|
+
if isinstance(formats, str):
|
|
156
|
+
formats = {column: formats for column in self._data.columns}
|
|
157
|
+
|
|
120
158
|
if callable(formats):
|
|
121
159
|
formats = formats(self._data)
|
|
122
160
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|