Skip to main content

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 — уникальный, > 0
  • email — валидный email
  • age — диапазон 0–120
  • phone — формат +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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

acid_engine-0.1.0.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

acid_engine-0.1.0-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

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

Hashes for acid_engine-0.1.0.tar.gz
Algorithm Hash digest
SHA256 da8d8f6fd249c9c326b40d366254ef50040635e343f4fb8ffd384bb3cf07d40f
MD5 2dd39527ad19cd064156f5e12d0f2a8f
BLAKE2b-256 9bb938f8574d0b392544d4935c8bcfd39e712778d630e3195e9ed9ed5f358723

See more details on using hashes here.

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

Hashes for acid_engine-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9b63968f6f9338505f276170e10c59517fe78fad44aaf2e1003fd1daab43d7d1
MD5 590dd8102d3b5a932fcf5034581b96c7
BLAKE2b-256 e22a8f5c7e4604a59f33e390712fd4136f9dd0cb4f40371d604eab556a599694

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page