Contract-oriented data control layer
Project description
AcidEngine — Data Control Layer
Контрактно-ориентированная платформа управления качеством данных. Описывайте правила данных декларативно, и AcidEngine гарантирует их соблюдение на всех этапах: от загрузки CSV до генерации production-пайплайнов.
Проблема
Правила данных (уникальность ID, формат email, диапазон возраста) дублируются между сервисами, размазываются по коду и со временем превращаются в хаос.
Типичный ETL-скрипт постепенно обрастает десятками проверок:
seen_ids = set()
for row in data:
if not row["id"]:
continue
if row["id"] in seen_ids:
continue
if "@" not in row["email"]:
continue
# ...
Через несколько месяцев становится трудно понять:
- Какие правила реально действуют
- Где находятся бизнес-ограничения
- Какие проверки уже реализованы
- Какие данные считаются валидными
Before / After (реальный CSV-кейс)
Задача
Загрузить users.csv с полями:
id— уникальный, > 0email— валидный emailage— диапазон 0–120phone— формат+7XXXXXXXXXX- если email заканчивается на
@company.com, возраст должен быть >= 18
Before (чистый Python)
import csv
import re
seen_ids = set()
clean = []
with open("users.csv") as f:
for row in csv.DictReader(f):
# id
try:
id_val = int(row["id"])
if id_val < 1:
continue
if id_val in seen_ids:
continue
seen_ids.add(id_val)
except Exception:
continue
# email
if "@" not in row["email"] or "." not in row["email"]:
continue
# age
try:
age = int(row["age"])
if age < 0 or age > 120:
continue
except Exception:
continue
# phone
if not re.match(r"^\+7\d{10}$", row.get("phone", "")):
continue
# business rule
if row["email"].endswith("@company.com") and age < 18:
continue
clean.append(row)
After (AcidEngine)
from acid_engine import Contract, Field
contract = Contract(
schema={
"id": Field(type=int, min=1),
"email": Field.Email(),
"age": Field(type=int, min=0, max=120),
"phone": Field(
type=str,
regex=r"^\+7\d{10}$"
)
},
unique=["id"]
)
contract.add_rule(
"age >= 18 if email.endswith('@company.com')"
)
result = contract.validate("users.csv")
result.explain()
Результат
| Метрика | Обычный Python | AcidEngine |
|---|---|---|
| Строк кода | 30+ | ~6 |
| Проверки типов | Вручную | Автоматически |
| Проверки уникальности | Вручную | Автоматически |
| Бизнес-правила | В коде цикла | В контракте |
| Отчёт об ошибках | Вручную | Встроен |
| Читаемость | Средняя | Высокая |
Контракт становится единственной точкой правды для правил данных.
Ключевые возможности
| Возможность | Описание |
|---|---|
| Field Contracts | Типы, диапазоны, regex, choices, встроенные пресеты |
| Cross-Field Rules | Правила между полями (start_date <= end_date) |
| Business Rules | Декларативные ограничения (age >= 18 if ...) |
| QualityGate | strict / recovery / audit / quarantine |
| Automatic Rollback | Откат при превышении порога ошибок |
| Explain Engine | Статистика, топ ошибок, примеры записей |
| YAML Support | Contract.from_yaml() и Contract.to_yaml() |
| Pipeline Generator | Генерация Python-пайплайнов из контракта |
| Pandas Integration | Поддержка DataFrame |
| CSV Loader | Загрузка и валидация CSV |
| Smart Contract Generator | Автоматическое построение контракта по данным |
| Global Scope | Структурирование ETL-пайплайнов |
| Quality Reports | Markdown-отчёты по результатам проверки |
YAML Contracts
Контракты можно описывать как конфигурацию:
schema:
id:
type: int
min: 1
email:
type: email
age:
type: int
min: 0
max: 120
unique:
- id
rules:
- age >= 18 if email.endswith('@company.com')
Загрузка:
contract = Contract.from_yaml(
"users.contract.yaml"
)
Quick Start
Установка:
pip install acid-engine
Пример:
from acid_engine import Contract
from acid_engine import Field
contract = Contract(
schema={
"email": Field.Email(),
"age": Field(
type=int,
min=0,
max=120
)
}
)
result = contract.validate(data)
result.explain()
Пример отчёта
Всего проверено: 1000
Ошибок: 37
Успешно: 963
Процент ошибок: 3.7%
Топ нарушений:
Email invalid .............. 21
Age out of range ........... 10
Duplicate ID ............... 6
Архитектурная философия
AcidEngine строится вокруг простой идеи:
Контракт описывает поведение данных и тем самым определяет их структуру.
Контракт является primary source of truth.
Код становится реализацией контракта, а не местом хранения бизнес-логики.
Это позволяет:
- убрать дублирование проверок
- сделать правила данных явными
- повысить читаемость ETL-кода
- упростить сопровождение проектов
- стандартизировать обработку данных
Roadmap
v1.0
- Field Contracts
- Contract Engine
- Container Validation
- Cross-Field Rules
- Safe Rule Engine
- QualityGate
- Explain Engine
- YAML Support
- Pandas Integration
- CSV Loader
- Smart Contract Generator
- Pipeline Generator
v1.1
- AI Guard
- Contract Registry
- Audit Trail
- Polars Adapter
v2.0
- Kafka Integration
- Spark Integration
- Contract Marketplace
- Rust Performance Core
Status
✅ Core v1.0 completed
✅ Ready for pilot projects
🔄 Active development
License
Apache License 2.0
Copyright © 2025 Alexey Rodkin
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acid_engine-0.1.0.tar.gz.
File metadata
- Download URL: acid_engine-0.1.0.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da8d8f6fd249c9c326b40d366254ef50040635e343f4fb8ffd384bb3cf07d40f
|
|
| MD5 |
2dd39527ad19cd064156f5e12d0f2a8f
|
|
| BLAKE2b-256 |
9bb938f8574d0b392544d4935c8bcfd39e712778d630e3195e9ed9ed5f358723
|
File details
Details for the file acid_engine-0.1.0-py3-none-any.whl.
File metadata
- Download URL: acid_engine-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b63968f6f9338505f276170e10c59517fe78fad44aaf2e1003fd1daab43d7d1
|
|
| MD5 |
590dd8102d3b5a932fcf5034581b96c7
|
|
| BLAKE2b-256 |
e22a8f5c7e4604a59f33e390712fd4136f9dd0cb4f40371d604eab556a599694
|