python-table-converter 0.1.1__tar.gz → 0.2.0__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.
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/PKG-INFO +4 -1
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/pyproject.toml +3 -1
- python_table_converter-0.2.0/table_converter/__init__.py +2 -0
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/table_converter/cli.py +9 -3
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/table_converter/commands/convert_tables.py +11 -1
- python_table_converter-0.2.0/table_converter/core/config.py +56 -0
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/table_converter/core/convert.py +20 -12
- python_table_converter-0.1.1/table_converter/__init__.py +0 -2
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/LICENSE +0 -0
- {python_table_converter-0.1.1 → python_table_converter-0.2.0}/README.md +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-table-converter
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A table data converter
|
|
5
|
+
Home-page: https://github.com/akivajp/python-table-converter
|
|
5
6
|
License: MIT
|
|
6
7
|
Author: Akiva Miura
|
|
7
8
|
Author-email: akiva.miura@gmail.com
|
|
@@ -15,7 +16,9 @@ Requires-Dist: icecream (>=2.1.3,<3.0.0)
|
|
|
15
16
|
Requires-Dist: logzero (>=1.7.0,<2.0.0)
|
|
16
17
|
Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
|
|
17
18
|
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
19
|
+
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
|
18
20
|
Requires-Dist: tqdm (>=4.67.0,<5.0.0)
|
|
21
|
+
Project-URL: Repository, https://github.com/akivajp/python-table-converter
|
|
19
22
|
Description-Content-Type: text/markdown
|
|
20
23
|
|
|
21
24
|
# Table Data Converter
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "python-table-converter"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "A table data converter"
|
|
5
5
|
authors = ["Akiva Miura <akiva.miura@gmail.com>"]
|
|
6
6
|
license = "MIT"
|
|
7
7
|
readme = "README.md"
|
|
8
|
+
repository = "https://github.com/akivajp/python-table-converter"
|
|
8
9
|
packages = [
|
|
9
10
|
{ include = "table_converter" },
|
|
10
11
|
]
|
|
@@ -24,6 +25,7 @@ logzero = "^1.7.0"
|
|
|
24
25
|
tqdm = "^4.67.0"
|
|
25
26
|
pandas = "^2.2.3"
|
|
26
27
|
openpyxl = "^3.1.5"
|
|
28
|
+
pyyaml = "^6.0.2"
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
[build-system]
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
|
+
import os
|
|
5
6
|
import sys
|
|
6
7
|
|
|
7
8
|
from icecream import ic
|
|
@@ -9,9 +10,14 @@ from icecream import ic
|
|
|
9
10
|
def parse_and_run(
|
|
10
11
|
parser: argparse.ArgumentParser,
|
|
11
12
|
):
|
|
12
|
-
|
|
13
|
+
if os.environ.get('DEBUG', '').lower() in ['1', 'true', 'yes', 'on']:
|
|
14
|
+
pass
|
|
15
|
+
else:
|
|
16
|
+
ic.disable()
|
|
13
17
|
ic()
|
|
14
18
|
args = parser.parse_args()
|
|
19
|
+
if args.verbose:
|
|
20
|
+
ic.enable()
|
|
15
21
|
ic(args)
|
|
16
22
|
if args.handler:
|
|
17
23
|
args.handler(args)
|
|
@@ -28,10 +34,10 @@ def command_convert_tables(
|
|
|
28
34
|
)
|
|
29
35
|
else:
|
|
30
36
|
command_parser = parser
|
|
31
|
-
from .
|
|
37
|
+
from table_converter.commands.convert_tables import setup_parser
|
|
32
38
|
setup_parser(command_parser)
|
|
33
39
|
if parser is None:
|
|
34
|
-
parse_and_run(
|
|
40
|
+
parse_and_run(command_parser)
|
|
35
41
|
|
|
36
42
|
def main():
|
|
37
43
|
parser = argparse.ArgumentParser(description='Table Data Converter')
|
|
@@ -12,6 +12,7 @@ def run(
|
|
|
12
12
|
convert(
|
|
13
13
|
input_files = args.input_files,
|
|
14
14
|
output_file = args.output_file,
|
|
15
|
+
config_path = args.config,
|
|
15
16
|
assign_constants = args.assign_constants,
|
|
16
17
|
assign_formats = args.assign_formats,
|
|
17
18
|
pickup_columns= args.pickup_columns,
|
|
@@ -23,6 +24,10 @@ def run(
|
|
|
23
24
|
def setup_parser(
|
|
24
25
|
parser: argparse.ArgumentParser,
|
|
25
26
|
):
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
'--verbose', '-v',
|
|
29
|
+
action='store_true',
|
|
30
|
+
)
|
|
26
31
|
parser.add_argument(
|
|
27
32
|
'input_files',
|
|
28
33
|
metavar='INPUT_FILE',
|
|
@@ -30,11 +35,16 @@ def setup_parser(
|
|
|
30
35
|
help='Path to the input file.'
|
|
31
36
|
)
|
|
32
37
|
parser.add_argument(
|
|
33
|
-
'-
|
|
38
|
+
'--output-file', '-o',
|
|
34
39
|
metavar='OUTPUT_FILE',
|
|
35
40
|
required=True,
|
|
36
41
|
help='Path to the output file.'
|
|
37
42
|
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
'--config', '-c',
|
|
45
|
+
type=str,
|
|
46
|
+
help='Path to the configuration file.',
|
|
47
|
+
)
|
|
38
48
|
parser.add_argument(
|
|
39
49
|
'--pickup-columns',
|
|
40
50
|
type=str,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from collections import OrderedDict
|
|
4
|
+
import dataclasses
|
|
5
|
+
from typing import Mapping
|
|
6
|
+
|
|
7
|
+
from icecream import ic
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
type FlatFieldMap = Mapping[str, str]
|
|
11
|
+
type FieldMap = Mapping[str, str|FieldMap]
|
|
12
|
+
|
|
13
|
+
@dataclasses.dataclass
|
|
14
|
+
class Config:
|
|
15
|
+
#map: OrderedDict|None = dataclasses.field(default_factory=lambda: None)
|
|
16
|
+
map: FieldMap|None = dataclasses.field(default_factory=lambda: None)
|
|
17
|
+
|
|
18
|
+
def flatten(
|
|
19
|
+
mapping: FieldMap,
|
|
20
|
+
parent_key: str = '',
|
|
21
|
+
new_mapping: FlatFieldMap | None = None,
|
|
22
|
+
) -> FlatFieldMap:
|
|
23
|
+
if new_mapping is None:
|
|
24
|
+
new_mapping = OrderedDict()
|
|
25
|
+
for key, mapped in mapping.items():
|
|
26
|
+
new_key = f'{parent_key}.{key}' if parent_key else key
|
|
27
|
+
if isinstance(mapped, Mapping):
|
|
28
|
+
flatten(mapped, new_key, new_mapping)
|
|
29
|
+
else:
|
|
30
|
+
new_mapping[new_key] = mapped
|
|
31
|
+
return new_mapping
|
|
32
|
+
|
|
33
|
+
def setup_config(
|
|
34
|
+
config_path: str | None = None,
|
|
35
|
+
):
|
|
36
|
+
if config_path:
|
|
37
|
+
if config_path.endswith('.yaml'):
|
|
38
|
+
yaml.add_constructor(
|
|
39
|
+
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
|
40
|
+
lambda loader, node: OrderedDict(loader.construct_pairs(node)),
|
|
41
|
+
)
|
|
42
|
+
with open(config_path, 'r') as f:
|
|
43
|
+
data = yaml.load(f, yaml.Loader)
|
|
44
|
+
#ic(data)
|
|
45
|
+
config = Config(
|
|
46
|
+
#**data,
|
|
47
|
+
map = flatten(data.get('map', {})),
|
|
48
|
+
)
|
|
49
|
+
else:
|
|
50
|
+
raise ValueError(
|
|
51
|
+
'Only YAML configuration files are supported.'
|
|
52
|
+
)
|
|
53
|
+
else:
|
|
54
|
+
config = Config(
|
|
55
|
+
)
|
|
56
|
+
return config
|
{python_table_converter-0.1.1 → python_table_converter-0.2.0}/table_converter/core/convert.py
RENAMED
|
@@ -5,9 +5,15 @@ import os
|
|
|
5
5
|
|
|
6
6
|
from collections import OrderedDict
|
|
7
7
|
|
|
8
|
+
# 3-rd party modules
|
|
9
|
+
|
|
10
|
+
from icecream import ic
|
|
8
11
|
import numpy as np
|
|
9
12
|
import pandas as pd
|
|
10
|
-
|
|
13
|
+
|
|
14
|
+
# local
|
|
15
|
+
|
|
16
|
+
from . config import setup_config
|
|
11
17
|
|
|
12
18
|
dict_loaders: dict[str, callable] = {}
|
|
13
19
|
def register_loader(
|
|
@@ -227,6 +233,7 @@ def assign_id(
|
|
|
227
233
|
def convert(
|
|
228
234
|
input_files: list[str],
|
|
229
235
|
output_file: str | None = None,
|
|
236
|
+
config_path: str | None = None,
|
|
230
237
|
assign_constants: str | None = None,
|
|
231
238
|
assign_formats: str | None = None,
|
|
232
239
|
pickup_columns: str | None = None,
|
|
@@ -234,16 +241,17 @@ def convert(
|
|
|
234
241
|
fields_to_assign_ids: str | None = None,
|
|
235
242
|
output_debug: bool = False,
|
|
236
243
|
):
|
|
244
|
+
ic.enable()
|
|
237
245
|
ic()
|
|
238
246
|
ic(input_files)
|
|
239
247
|
df_list = []
|
|
240
248
|
dict_constants: OrderedDict | None = None
|
|
241
|
-
dict_columns: OrderedDict | None = None
|
|
242
249
|
dict_formats: OrderedDict | None = None
|
|
243
|
-
#list_fields_to_split_by_newline = None
|
|
244
250
|
dict_split_by_newline: OrderedDict | None = None
|
|
245
251
|
dict_assign_ids= None
|
|
246
252
|
root_id_stat = create_id_stat_node()
|
|
253
|
+
config = setup_config(config_path)
|
|
254
|
+
ic(config)
|
|
247
255
|
if assign_constants:
|
|
248
256
|
dict_constants = OrderedDict()
|
|
249
257
|
fields = assign_constants.split(',')
|
|
@@ -263,14 +271,15 @@ def convert(
|
|
|
263
271
|
else:
|
|
264
272
|
raise ValueError(f'Invalid template assignment: {field}')
|
|
265
273
|
if pickup_columns:
|
|
266
|
-
|
|
274
|
+
if config.map is None:
|
|
275
|
+
config.map = OrderedDict()
|
|
267
276
|
fields = pickup_columns.split(',')
|
|
268
277
|
for field in fields:
|
|
269
278
|
if '=' in field:
|
|
270
279
|
dst, value = field.split('=')
|
|
271
|
-
|
|
280
|
+
set_field_value(config.map, dst, value)
|
|
272
281
|
else:
|
|
273
|
-
|
|
282
|
+
set_field_value(config.map, field, field)
|
|
274
283
|
if fields_to_split_by_newline:
|
|
275
284
|
#list_fields_to_split_by_newline = fields_to_split_by_newline.split(',')
|
|
276
285
|
dict_split_by_newline = OrderedDict()
|
|
@@ -295,6 +304,7 @@ def convert(
|
|
|
295
304
|
if ext not in dict_savers:
|
|
296
305
|
raise ValueError(f'Unsupported file type: {ext}')
|
|
297
306
|
saver = dict_savers[ext]
|
|
307
|
+
ic(config)
|
|
298
308
|
for input_file in input_files:
|
|
299
309
|
ic(input_file)
|
|
300
310
|
if not os.path.exists(input_file):
|
|
@@ -318,18 +328,16 @@ def convert(
|
|
|
318
328
|
set_field_value(new_row, '__debug__.__file__', input_file)
|
|
319
329
|
if dict_constants:
|
|
320
330
|
new_row = map_constants(new_row, dict_constants)
|
|
321
|
-
if
|
|
322
|
-
new_row = remap_columns(new_row,
|
|
323
|
-
#if list_fields_to_split_by_newline:
|
|
324
|
-
# new_row = apply_fields_split_by_newline(new_row, list_fields_to_split_by_newline)
|
|
331
|
+
if config.map:
|
|
332
|
+
new_row = remap_columns(new_row, config.map)
|
|
325
333
|
if dict_split_by_newline:
|
|
326
334
|
new_row = apply_fields_split_by_newline(new_row, dict_split_by_newline)
|
|
327
335
|
if dict_assign_ids:
|
|
328
336
|
new_row = assign_id(new_row, dict_assign_ids, root_id_stat)
|
|
329
337
|
if dict_formats:
|
|
330
338
|
new_row = map_formats(new_row, dict_formats)
|
|
331
|
-
if
|
|
332
|
-
new_row = remap_columns(new_row,
|
|
339
|
+
if config.map:
|
|
340
|
+
new_row = remap_columns(new_row, config.map)
|
|
333
341
|
if not output_debug:
|
|
334
342
|
new_row.pop('__debug__', None)
|
|
335
343
|
new_rows.append(new_row)
|
|
File without changes
|
|
File without changes
|