chameleon-data 0.1.1__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.
- chameleon_data-0.1.1/LICENSE +21 -0
- chameleon_data-0.1.1/PKG-INFO +117 -0
- chameleon_data-0.1.1/README.md +94 -0
- chameleon_data-0.1.1/pyproject.toml +45 -0
- chameleon_data-0.1.1/pyproject.toml.orig +37 -0
- chameleon_data-0.1.1/src/chameleon_data/__init__.py +2 -0
- chameleon_data-0.1.1/src/chameleon_data/main.py +190 -0
- chameleon_data-0.1.1/src/chameleon_data/py.typed +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hidariutiwa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chameleon-data
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Interactive CLI to mask columns of CSV/TSV/XLSX files with Faker-generated fake data
|
|
5
|
+
Keywords: cli,faker,masking,anonymize,csv,excel
|
|
6
|
+
Author: hidariutiwa
|
|
7
|
+
Author-email: hidariutiwa <hidariutiwa22@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Requires-Dist: faker>=40.43.0
|
|
15
|
+
Requires-Dist: openpyxl>=3.1.5
|
|
16
|
+
Requires-Dist: pandas>=3.1.0
|
|
17
|
+
Requires-Dist: pydantic>=2.14.1
|
|
18
|
+
Requires-Dist: questionary>=2.1.1
|
|
19
|
+
Requires-Dist: rich>=15.0.0
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Project-URL: Repository, https://github.com/hidariutiwa/chameleon-data
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# chameleon-data
|
|
25
|
+
|
|
26
|
+
CSV / TSV / XLSX ファイルの列を選んで、[Faker](https://faker.readthedocs.io/) で生成したダミーデータに置き換える対話型 CLI です。結果は元と同じ形式で保存されます。
|
|
27
|
+
|
|
28
|
+
## インストール
|
|
29
|
+
|
|
30
|
+
Python 3.11 以上が必要です。
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# CLI ツールとしてインストール (おすすめ)
|
|
34
|
+
uv tool install chameleon-data
|
|
35
|
+
|
|
36
|
+
# インストールせずに 1 回だけ実行
|
|
37
|
+
uvx --from chameleon-data chameleon -f data.csv
|
|
38
|
+
|
|
39
|
+
# 他プロジェクトの依存として追加
|
|
40
|
+
uv add chameleon-data
|
|
41
|
+
pip install chameleon-data
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
最新の開発版は GitHub から直接インストールできます。
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv tool install git+https://github.com/hidariutiwa/chameleon-data
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
GitHub 版で特定のバージョンに固定したい場合は `git+https://github.com/hidariutiwa/chameleon-data@<tag or commit>` のように指定します。
|
|
51
|
+
|
|
52
|
+
アップデート / アンインストール:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv tool upgrade chameleon-data
|
|
56
|
+
uv tool uninstall chameleon-data
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 使い方
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
chameleon -f data.csv # data_masked.csv に保存
|
|
63
|
+
chameleon -f data.xlsx -o out.xlsx # 出力先を指定
|
|
64
|
+
chameleon -f data.tsv -l en_US -s 42 # ロケールとシードを指定
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| オプション | 説明 |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `-f`, `--filepath` | 入力ファイル (必須)。`.csv` / `.tsv` / `.xlsx` |
|
|
70
|
+
| `-o`, `--output` | 出力ファイル。デフォルトは `<ファイル名>_masked.<拡張子>` |
|
|
71
|
+
| `-l`, `--language` | Faker のロケール。デフォルトは `ja_JP` |
|
|
72
|
+
| `-s`, `--seed` | 乱数シード。指定すると毎回同じ結果になります |
|
|
73
|
+
| `-v`, `--version` | バージョンを表示 |
|
|
74
|
+
|
|
75
|
+
実行すると、マスクする列をチェックボックスで選び、列ごとに置き換え方を選択します。
|
|
76
|
+
|
|
77
|
+
| 種類 | 内容 |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `masking` | すべての文字を `*` に置き換え (文字数は維持) |
|
|
80
|
+
| `full_name` / `first_name` / `last_name` | 氏名 |
|
|
81
|
+
| `full_address` | 住所 |
|
|
82
|
+
| `zipcode` | 郵便番号 |
|
|
83
|
+
| `phone_number` | 電話番号 |
|
|
84
|
+
|
|
85
|
+
同じ値は同じダミー値に置き換わるため、行同士の対応関係は保たれます。空セルは空のままです。
|
|
86
|
+
|
|
87
|
+
### サンプルデータ
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
chameleon-example # ./example/example.csv にサンプルを生成
|
|
91
|
+
chameleon -f example/example.csv
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 開発
|
|
95
|
+
|
|
96
|
+
[uv](https://docs.astral.sh/uv/) を使います。
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv sync
|
|
100
|
+
uv run chameleon -f example/example.csv
|
|
101
|
+
uv build # dist/ に wheel と sdist を作成
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### リリース
|
|
105
|
+
|
|
106
|
+
`v*` タグを push すると GitHub Actions (`.github/workflows/publish.yml`) が PyPI に公開します (Trusted Publishing)。
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv version --bump patch # pyproject.toml の version を更新 (minor / major も可)
|
|
110
|
+
git commit -am "chore: release v$(uv version --short)"
|
|
111
|
+
git tag "v$(uv version --short)"
|
|
112
|
+
git push origin main --tags
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## ライセンス
|
|
116
|
+
|
|
117
|
+
MIT
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# chameleon-data
|
|
2
|
+
|
|
3
|
+
CSV / TSV / XLSX ファイルの列を選んで、[Faker](https://faker.readthedocs.io/) で生成したダミーデータに置き換える対話型 CLI です。結果は元と同じ形式で保存されます。
|
|
4
|
+
|
|
5
|
+
## インストール
|
|
6
|
+
|
|
7
|
+
Python 3.11 以上が必要です。
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# CLI ツールとしてインストール (おすすめ)
|
|
11
|
+
uv tool install chameleon-data
|
|
12
|
+
|
|
13
|
+
# インストールせずに 1 回だけ実行
|
|
14
|
+
uvx --from chameleon-data chameleon -f data.csv
|
|
15
|
+
|
|
16
|
+
# 他プロジェクトの依存として追加
|
|
17
|
+
uv add chameleon-data
|
|
18
|
+
pip install chameleon-data
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
最新の開発版は GitHub から直接インストールできます。
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv tool install git+https://github.com/hidariutiwa/chameleon-data
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
GitHub 版で特定のバージョンに固定したい場合は `git+https://github.com/hidariutiwa/chameleon-data@<tag or commit>` のように指定します。
|
|
28
|
+
|
|
29
|
+
アップデート / アンインストール:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv tool upgrade chameleon-data
|
|
33
|
+
uv tool uninstall chameleon-data
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 使い方
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
chameleon -f data.csv # data_masked.csv に保存
|
|
40
|
+
chameleon -f data.xlsx -o out.xlsx # 出力先を指定
|
|
41
|
+
chameleon -f data.tsv -l en_US -s 42 # ロケールとシードを指定
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| オプション | 説明 |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `-f`, `--filepath` | 入力ファイル (必須)。`.csv` / `.tsv` / `.xlsx` |
|
|
47
|
+
| `-o`, `--output` | 出力ファイル。デフォルトは `<ファイル名>_masked.<拡張子>` |
|
|
48
|
+
| `-l`, `--language` | Faker のロケール。デフォルトは `ja_JP` |
|
|
49
|
+
| `-s`, `--seed` | 乱数シード。指定すると毎回同じ結果になります |
|
|
50
|
+
| `-v`, `--version` | バージョンを表示 |
|
|
51
|
+
|
|
52
|
+
実行すると、マスクする列をチェックボックスで選び、列ごとに置き換え方を選択します。
|
|
53
|
+
|
|
54
|
+
| 種類 | 内容 |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `masking` | すべての文字を `*` に置き換え (文字数は維持) |
|
|
57
|
+
| `full_name` / `first_name` / `last_name` | 氏名 |
|
|
58
|
+
| `full_address` | 住所 |
|
|
59
|
+
| `zipcode` | 郵便番号 |
|
|
60
|
+
| `phone_number` | 電話番号 |
|
|
61
|
+
|
|
62
|
+
同じ値は同じダミー値に置き換わるため、行同士の対応関係は保たれます。空セルは空のままです。
|
|
63
|
+
|
|
64
|
+
### サンプルデータ
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
chameleon-example # ./example/example.csv にサンプルを生成
|
|
68
|
+
chameleon -f example/example.csv
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 開発
|
|
72
|
+
|
|
73
|
+
[uv](https://docs.astral.sh/uv/) を使います。
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv sync
|
|
77
|
+
uv run chameleon -f example/example.csv
|
|
78
|
+
uv build # dist/ に wheel と sdist を作成
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### リリース
|
|
82
|
+
|
|
83
|
+
`v*` タグを push すると GitHub Actions (`.github/workflows/publish.yml`) が PyPI に公開します (Trusted Publishing)。
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv version --bump patch # pyproject.toml の version を更新 (minor / major も可)
|
|
87
|
+
git commit -am "chore: release v$(uv version --short)"
|
|
88
|
+
git tag "v$(uv version --short)"
|
|
89
|
+
git push origin main --tags
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## ライセンス
|
|
93
|
+
|
|
94
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "chameleon-data"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "Interactive CLI to mask columns of CSV/TSV/XLSX files with Faker-generated fake data"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
keywords = [
|
|
10
|
+
"cli",
|
|
11
|
+
"faker",
|
|
12
|
+
"masking",
|
|
13
|
+
"anonymize",
|
|
14
|
+
"csv",
|
|
15
|
+
"excel",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: Utilities",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"faker>=40.43.0",
|
|
25
|
+
"openpyxl>=3.1.5",
|
|
26
|
+
"pandas>=3.1.0",
|
|
27
|
+
"pydantic>=2.14.1",
|
|
28
|
+
"questionary>=2.1.1",
|
|
29
|
+
"rich>=15.0.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[[project.authors]]
|
|
33
|
+
name = "hidariutiwa"
|
|
34
|
+
email = "hidariutiwa22@gmail.com"
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Repository = "https://github.com/hidariutiwa/chameleon-data"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
chameleon = "chameleon_data.main:main"
|
|
41
|
+
chameleon-example = "chameleon_data.main:create_example"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["uv_build>=0.11.14,<0.12.0"]
|
|
45
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "chameleon-data"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "Interactive CLI to mask columns of CSV/TSV/XLSX files with Faker-generated fake data"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "hidariutiwa", email = "hidariutiwa22@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
keywords = ["cli", "faker", "masking", "anonymize", "csv", "excel"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Environment :: Console",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Topic :: Utilities",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"faker>=40.43.0",
|
|
21
|
+
"openpyxl>=3.1.5",
|
|
22
|
+
"pandas>=3.1.0",
|
|
23
|
+
"pydantic>=2.14.1",
|
|
24
|
+
"questionary>=2.1.1",
|
|
25
|
+
"rich>=15.0.0",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Repository = "https://github.com/hidariutiwa/chameleon-data"
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["uv_build>=0.11.14,<0.12.0"]
|
|
33
|
+
build-backend = "uv_build"
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
chameleon = "chameleon_data.main:main"
|
|
37
|
+
chameleon-example = "chameleon_data.main:create_example"
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from argparse import ArgumentParser
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from importlib.metadata import version
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import questionary
|
|
9
|
+
from faker import Faker
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ExampleData(BaseModel):
|
|
15
|
+
no: int
|
|
16
|
+
first_name: str
|
|
17
|
+
last_name: str
|
|
18
|
+
zipcode: str
|
|
19
|
+
address: str
|
|
20
|
+
phone_number: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ALLOWED_SUFFIXES = (".csv", ".tsv", ".xlsx")
|
|
24
|
+
|
|
25
|
+
console = Console()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def fake_address(fake: Faker) -> str:
|
|
29
|
+
# prefecture, chome, etc. exist only in the ja_JP provider
|
|
30
|
+
if not hasattr(fake, "prefecture"):
|
|
31
|
+
return fake.address().replace("\n", " ")
|
|
32
|
+
return f"{fake.prefecture()}{fake.city()}{fake.chome()}{fake.gou()}{fake.ban()}{fake.building_name()}{fake.building_number()}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
FAKE_GENERATORS: dict[str, Callable[[Faker], str]] = {
|
|
36
|
+
"full_name": lambda fake: f"{fake.last_name()} {fake.first_name()}",
|
|
37
|
+
"first_name": lambda fake: fake.first_name(),
|
|
38
|
+
"last_name": lambda fake: fake.last_name(),
|
|
39
|
+
"full_address": fake_address,
|
|
40
|
+
"zipcode": lambda fake: fake.zipcode(),
|
|
41
|
+
"phone_number": lambda fake: fake.phone_number(),
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
FAKE_TYPES = ["masking", *FAKE_GENERATORS]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def read_table(path: Path) -> pd.DataFrame:
|
|
48
|
+
match path.suffix:
|
|
49
|
+
case ".csv":
|
|
50
|
+
return pd.read_csv(path, dtype=str)
|
|
51
|
+
case ".tsv":
|
|
52
|
+
return pd.read_csv(path, sep="\t", dtype=str)
|
|
53
|
+
case ".xlsx":
|
|
54
|
+
return pd.read_excel(path, dtype=str)
|
|
55
|
+
raise ValueError(f"{path.suffix} is not allowed.")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def write_table(df: pd.DataFrame, path: Path) -> None:
|
|
59
|
+
match path.suffix:
|
|
60
|
+
case ".csv":
|
|
61
|
+
df.to_csv(path, index=False)
|
|
62
|
+
case ".tsv":
|
|
63
|
+
df.to_csv(path, sep="\t", index=False)
|
|
64
|
+
case ".xlsx":
|
|
65
|
+
df.to_excel(path, index=False)
|
|
66
|
+
case _:
|
|
67
|
+
raise ValueError(f"{path.suffix} is not allowed.")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def mask_column(series: pd.Series, fake_type: str, fake: Faker) -> pd.Series:
|
|
71
|
+
# same original value -> same replacement, so relations between rows are kept
|
|
72
|
+
replaced: dict[str, str] = {}
|
|
73
|
+
|
|
74
|
+
def replace(value: str) -> str:
|
|
75
|
+
if pd.isna(value):
|
|
76
|
+
return value
|
|
77
|
+
if value not in replaced:
|
|
78
|
+
if fake_type == "masking":
|
|
79
|
+
replaced[value] = "*" * len(value)
|
|
80
|
+
else:
|
|
81
|
+
replaced[value] = FAKE_GENERATORS[fake_type](fake)
|
|
82
|
+
return replaced[value]
|
|
83
|
+
|
|
84
|
+
return series.map(replace)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def exit_with_error(message: str) -> None:
|
|
88
|
+
console.print(message, style="red bold")
|
|
89
|
+
sys.exit(1)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def main() -> None:
|
|
93
|
+
parser = ArgumentParser(
|
|
94
|
+
prog="chameleon",
|
|
95
|
+
description="mask columns of csv/tsv/xlsx file with fake data.",
|
|
96
|
+
)
|
|
97
|
+
parser.add_argument(
|
|
98
|
+
"-v", "--version", action="version", version=version("chameleon-data")
|
|
99
|
+
)
|
|
100
|
+
parser.add_argument(
|
|
101
|
+
"-f",
|
|
102
|
+
"--filepath",
|
|
103
|
+
required=True,
|
|
104
|
+
help="filepath read file. allowed format: csv, tsv, xlsx",
|
|
105
|
+
)
|
|
106
|
+
parser.add_argument(
|
|
107
|
+
"-o",
|
|
108
|
+
"--output",
|
|
109
|
+
help="filepath to save masked file. default: <filename>_masked.<suffix>",
|
|
110
|
+
)
|
|
111
|
+
parser.add_argument(
|
|
112
|
+
"-l",
|
|
113
|
+
"--language",
|
|
114
|
+
default="ja_JP",
|
|
115
|
+
help="language of fake data. default: ja_JP",
|
|
116
|
+
)
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"-s",
|
|
119
|
+
"--seed",
|
|
120
|
+
type=int,
|
|
121
|
+
help="you need same data everytimes, set seed any number.",
|
|
122
|
+
)
|
|
123
|
+
args = parser.parse_args()
|
|
124
|
+
|
|
125
|
+
input_path = Path(args.filepath).resolve()
|
|
126
|
+
if args.output:
|
|
127
|
+
output_path = Path(args.output).resolve()
|
|
128
|
+
else:
|
|
129
|
+
output_path = input_path.with_stem(f"{input_path.stem}_masked")
|
|
130
|
+
|
|
131
|
+
for path in (input_path, output_path):
|
|
132
|
+
if path.suffix not in ALLOWED_SUFFIXES:
|
|
133
|
+
exit_with_error(f"{path.suffix} is not allowed.")
|
|
134
|
+
if not input_path.exists():
|
|
135
|
+
exit_with_error(f"{input_path} is not found.")
|
|
136
|
+
|
|
137
|
+
df = read_table(input_path)
|
|
138
|
+
|
|
139
|
+
headers = list(df.columns)
|
|
140
|
+
mask_columns = questionary.checkbox("select masking columns", headers).ask()
|
|
141
|
+
if mask_columns is None:
|
|
142
|
+
sys.exit(1)
|
|
143
|
+
if not mask_columns:
|
|
144
|
+
exit_with_error("no columns selected.")
|
|
145
|
+
|
|
146
|
+
fake_types = {}
|
|
147
|
+
for column in mask_columns:
|
|
148
|
+
fake_type = questionary.select(f"type of {column}", FAKE_TYPES).ask()
|
|
149
|
+
if fake_type is None:
|
|
150
|
+
sys.exit(1)
|
|
151
|
+
fake_types[column] = fake_type
|
|
152
|
+
|
|
153
|
+
fake = Faker(args.language)
|
|
154
|
+
if args.seed is not None:
|
|
155
|
+
Faker.seed(args.seed)
|
|
156
|
+
|
|
157
|
+
for column, fake_type in fake_types.items():
|
|
158
|
+
df[column] = mask_column(df[column], fake_type, fake)
|
|
159
|
+
|
|
160
|
+
write_table(df, output_path)
|
|
161
|
+
console.print(f"save masked file: {output_path}", style="cyan bold")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def create_example() -> None:
|
|
165
|
+
Faker.seed(223)
|
|
166
|
+
fake = Faker("ja_JP")
|
|
167
|
+
|
|
168
|
+
persons = [
|
|
169
|
+
ExampleData(
|
|
170
|
+
no=i + 1,
|
|
171
|
+
first_name=fake.first_name(),
|
|
172
|
+
last_name=fake.last_name(),
|
|
173
|
+
zipcode=fake.zipcode(),
|
|
174
|
+
address=fake_address(fake),
|
|
175
|
+
phone_number=fake.phone_number(),
|
|
176
|
+
)
|
|
177
|
+
for i in range(10)
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
df = pd.DataFrame([p.model_dump() for p in persons])
|
|
181
|
+
df = df.set_index("no")
|
|
182
|
+
print(df)
|
|
183
|
+
|
|
184
|
+
example_dir = Path(Path.cwd(), "example")
|
|
185
|
+
Path.mkdir(example_dir, exist_ok=True)
|
|
186
|
+
example_path = Path(example_dir, "example.csv")
|
|
187
|
+
|
|
188
|
+
df.to_csv(example_path)
|
|
189
|
+
console.print(f"save example csv: {example_path}", style="cyan bold")
|
|
190
|
+
console.print(f"try it! -> chameleon -f {example_path}", style="cyan bold")
|
|
File without changes
|