- Python 97.1%
- Dockerfile 1.5%
- Shell 1.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .streamlit | ||
| examples | ||
| pii_sanitizer | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| app.py | ||
| compose.yml | ||
| Dockerfile | ||
| README.md | ||
| requirements-dev.txt | ||
| requirements.txt | ||
DashkaGPT / PII Sanitizer
Локальное обезличивание русскоязычных текстов перед ручной отправкой в ChatGPT или другой внешний AI-сервис.
Приложение не отправляет исходные тексты, найденные персональные данные, mapping или любые другие данные во внешние API. Вся обработка выполняется на вашем компьютере (или внутри изолированного Docker-контейнера в LAN).
Назначение
- Найти потенциальные персональные данные в
.txt/.md/.pdf/.docxили во вставленном тексте. - Пройти этап ручной review (исключить false positive / добавить пропуски).
- Заменить подтверждённые сущности на placeholder'ы.
- Скачать clean-текст и
mapping.json. - При необходимости восстановить исходный текст по mapping.
Требования (локальная разработка)
- macOS / Linux
- Python 3.11+
- Доступ в интернет только для установки зависимостей из PyPI. После установки приложение работает офлайн.
Установка (Mac / без Docker)
cd /path/to/DashkaGPT
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
Запуск (Mac)
source .venv/bin/activate
streamlit run app.py
Откройте локальный URL (обычно http://localhost:8501).
Тесты
source .venv/bin/activate
pytest -q
Безопасность
- Обработка только локальная; HTTP-запросы наружу приложением не выполняются.
- Telemetry Streamlit отключена (
browser.gatherUsageStats = false). - Содержимое документов не логируется в server logs.
- Загруженные файлы читаются в память и не сохраняются приложением на диск.
- Mapping содержит исходные персональные данные. Не загружайте этот файл во внешние AI-сервисы.
- Модели Natasha входят в Docker image (preload на этапе build) — runtime без сети для анализа документов.
Что ищется (MVP)
| Тип | Источник |
|---|---|
| ФИО (PERSON) | Natasha NER + entity resolution |
| Email / телефоны / ИНН / СНИЛС / паспорт / карты / счета / БИК / IP | regex (+ checksum где применимо) |
| OTHER | только вручную на этапе review |
Структура
DashkaGPT/
├── app.py
├── requirements.txt
├── requirements-dev.txt
├── Dockerfile
├── compose.yml
├── .streamlit/config.toml
├── pii_sanitizer/
├── examples/
├── scripts/deploy.sh
└── tests/
Deploy to Beelink
Целевая директория на сервере: /opt/pii-sanitizer.
Проект живёт как отдельный Compose project pii-sanitizer.
Порт публикуется только на LAN-IP Beelink (не на всех интерфейсах):
ports:
- "${BEELINK_LAN_IP}:8501:8501"
Внутри контейнера Streamlit слушает 0.0.0.0:8501.
Перед docker compose up на сервере создайте /opt/pii-sanitizer/.env:
cp .env.example .env
# укажите реальный LAN-IP Beelink, например:
# BEELINK_LAN_IP=192.168.1.50
На Mac (перед выкладкой)
source .venv/bin/activate
pytest -q
Передача кода на сервер
Подставьте свои значения вместо <BEELINK_USER> и <BEELINK_IP>:
rsync -av --delete \
--exclude '.git' \
--exclude '.venv' \
--exclude '__pycache__' \
--exclude '.pytest_cache' \
--exclude '.mypy_cache' \
--exclude '.DS_Store' \
--exclude '*.log' \
--exclude '.env' \
./ <BEELINK_USER>@<BEELINK_IP>:/opt/pii-sanitizer/
Или:
BEELINK_USER=<BEELINK_USER> BEELINK_IP=<BEELINK_IP> ./scripts/deploy.sh
# сразу build+up:
BEELINK_USER=<BEELINK_USER> BEELINK_IP=<BEELINK_IP> ./scripts/deploy.sh --up
На сервере
cd /opt/pii-sanitizer
cp -n .env.example .env
# отредактируйте BEELINK_LAN_IP=<LAN-IP Beelink>
nano .env
docker compose build
docker compose up -d
Проверка
docker compose ps
docker compose logs --tail=50
curl -s http://127.0.0.1:8501/_stcore/health
UI в LAN:
http://<BEELINK_LAN_IP>:8501
Обновление
# с Mac: rsync (как выше), затем на сервере:
cd /opt/pii-sanitizer
docker compose build
docker compose up -d
Остановка только этого проекта
cd /opt/pii-sanitizer
docker compose down
Ресурсы
В compose.yml по умолчанию:
- CPU limit:
2.0 - RAM limit:
3G
При необходимости измените cpus / mem_limit (и блок deploy.resources) под нагрузку Beelink.
Docker security (кратко)
- non-root user UID
10001 read_only: true+tmpfsна/tmpи/home/appuser/.streamlitcap_drop: ALL,no-new-privileges:true- нет volume для uploads/mapping — данные только в RAM/session
Smoke test после deploy
Используйте examples/smoke_deploy.txt (вымышленные данные):
- UI открывается.
- «Найти ПДн» находит PERSON / PHONE / EMAIL / …
- В review можно исключить сущность и добавить
OTHER(14825). - «Сформировать» → скачать clean + mapping.
- Вкладка «Восстановить» возвращает исходный текст.
Mapping (v2)
{
"[[PERSON_0001]]": {
"type": "PERSON",
"canonical": "иванов иван иванович",
"occurrences": [
"Иванов Иван Иванович",
"Иванова Ивана Ивановича"
]
}
}
Форматы загрузки
| Формат | Извлечение | Результат обезличивания |
|---|---|---|
.txt, .md |
как есть (UTF-8 / CP1251) | тот же тип файла |
.pdf |
текстовый слой (pypdf), без OCR |
.txt |
.docx |
параграфы и таблицы (python-docx) |
.txt |
Файлы читаются только в память и не сохраняются на диск.
Ограничения первой версии
- PDF: нужны страницы с текстовым слоем; сканы без OCR не поддерживаются; пароли — только «пустой» decrypt.
- DOCX: старый
.docне поддерживается; колонтитулы/текстовые поля Word могут не попасть в извлечение. - Нет HTML/CSV/XLSX.
- Нет HTTPS/nginx/домена (только LAN
:8501). - Ручной ввод на review — только точное совпадение строки.
- Regex могут давать false positive / пропускать нестандартные форматы.
- Контейнер не хранит историю документов между рестартами (это намеренно).