SMEV Transform (Python) v2.0
Полная реализация алгоритма трансформации "urn://smev-gov-ru/xmldsig/transform" для Python согласно официальной документации СМЭВ 3.5.0.27.
Это улучшенный порт оригинальной PHP библиотеки danbka/smev-transform на Python с полной поддержкой всех 9 шагов трансформации.
📚 Документация СМЭВ
Алгоритм адаптирован для СМЭВ версии 3.5.0.27 согласно официальной документации:
- Методические документы СМЭВ3
- Версия спецификации: 3.5.0.27
🆕 Новое в версии 2.0
КРИТИЧЕСКОЕ ОБНОВЛЕНИЕ: Добавлена полная поддержка Шага 9 - Декодирование текста, который отсутствовал в оригинальной PHP библиотеке!
Что добавлено:
✅ Шаг 9.1 - Декодирование текстовых блоков:
- Снятие экранирования символов (

,<,&и др.) - Корректная обработка CDATA секций
- Умное кодирование блоков по размеру (до 11 символов / от 12 символов)
- Условное кодирование символа
>согласно спецификации
✅ Шаг 9.2 - Декодирование атрибутов:
- Нормализация пробельных символов в атрибутах
- Снятие экранирования в значениях атрибутов
- Правильное кодирование атрибутов
Описание
При подписании XML-фрагментов ЭП в формате XMLDSig, обязательно использование трансформации urn://smev-gov-ru/xmldsig/transform.
Полный алгоритм трансформации (9 шагов)
- ✅ XML declaration и processing instructions удаляются
- ✅ Пробельные символы удаляются из текстовых узлов
- ✅ Empty element tags преобразуются в пары start-tag + end-tag
- ✅ Неиспользуемые namespace prefix удаляются
- ✅ Namespace declarations проверяются и добавляются при необходимости
- ✅ Автоматические префиксы генерируются (ns1, ns2, ...)
- ✅ Атрибуты сортируются в алфавитном порядке
- ✅ Namespace declarations размещаются перед атрибутами
- ✅ Декодирование текста (НОВОЕ!) - полная обработка текстовых блоков и атрибутов
Установка
Из PyPI (рекомендовано)
pip install smev-transform
Из исходников
git clone https://github.com/imdeniil/smev-transform
cd smev-transform
pip install -e .
С использованием uv
uv pip install smev-transform
Использование
Базовое использование
from smev_transform import Transform
transform = Transform()
result = transform.process(xml_string)
Использование отдельных компонентов
from smev_transform import TextDecoder, AttributeDecoder
# Декодирование текстовых блоков
decoded_text = TextDecoder.decode_text_block(text_with_entities)
# Декодирование атрибутов
decoded_attr = AttributeDecoder.decode_attribute_value(attr_value)
Примеры
Пример 1: Базовая трансформация
from smev_transform import Transform
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<elementOne xmlns="http://test/1" xmlns:qwe="http://test/2">
<qwe:elementTwo attB="bbb" attA="aaa"/>
</elementOne>'''
transform = Transform()
result = transform.process(xml)
print(result)
# Результат: <ns1:elementOne xmlns:ns1="http://test/1"><ns2:elementTwo xmlns:ns2="http://test/2" attA="aaa" attB="bbb"></ns2:elementTwo></ns1:elementOne>
Пример 2: Обработка текста с экранированием (Шаг 9.1)
from smev_transform import Transform
xml = '''<root>>>text&content<</root>'''
transform = Transform()
result = transform.process(xml)
print(result)
# Текст проходит декодирование согласно алгоритму СМЭВ
Пример 3: Обработка атрибутов с пробелами (Шаг 9.2)
from smev_transform import Transform
xml = '''<root attr="value with tabs and
newlines"/>'''
transform = Transform()
result = transform.process(xml)
print(result)
# Пробельные символы в атрибутах нормализуются согласно СМЭВ
Пример 4: CDATA секции
from smev_transform import Transform
xml = '''<root>
Текст до CDATA
<![CDATA[Сырой контент < & > остается нетронутым]]>
Текст после CDATA
</root>'''
transform = Transform()
result = transform.process(xml)
# CDATA секции обрабатываются корректно согласно спецификации
Тестирование
# Все тесты
python -m unittest discover tests/
# Конкретные тесты
python -m unittest tests.test_transform -v
python -m unittest tests.test_text_decoder -v
python -m unittest tests.test_attribute_decoder -v
Различия с оригинальной PHP библиотекой
| Функциональность | PHP версия | Python v2.0 |
|---|---|---|
| Шаги 1-8 (базовая трансформация) | ✅ | ✅ |
| Шаг 9.1 (декодирование текста) | ❌ ОТСУТСТВУЕТ | ✅ РЕАЛИЗОВАНО |
| Шаг 9.2 (декодирование атрибутов) | ❌ ОТСУТСТВУЕТ | ✅ РЕАЛИЗОВАНО |
| Обработка CDATA | ⚠️ Частично | ✅ Полностью |
| Соответствие официальной спецификации | ⚠️ 89% | ✅ 100% |
Требования
- Python 3.7+
- Только стандартная библиотека Python (xml.etree.ElementTree)
Структура проекта
smev_transform/
├── __init__.py # Основной модуль
├── transform.py # Главный класс Transform
├── text_decoder.py # Декодирование текстовых блоков (Шаг 9.1)
├── attribute_decoder.py # Декодирование атрибутов (Шаг 9.2)
├── xml_namespace.py # Работа с XML namespaces
├── attribute.py # Представление XML атрибутов
├── comparators.py # Сортировка атрибутов
└── exceptions.py # Исключения
tests/ # Полное покрытие тестами
├── test_transform.py
├── test_text_decoder.py # Тесты Шага 9.1
└── test_attribute_decoder.py # Тесты Шага 9.2
Совместимость и миграция
Миграция с версии 1.0:
- API полностью совместимо - никаких изменений в коде не требуется
- Результаты трансформации могут отличаться из-за добавления Шага 9
- Рекомендуется протестировать с реальными СМЭВ сообщениями
Для продакшен-использования:
- ✅ Версия 2.0 рекомендована для всех новых проектов
- ✅ Полное соответствие официальной документации СМЭВ3
- ✅ Корректная работа с реальными СМЭВ сообщениями
Публикация на PyPI
Для публикации пакета на PyPI:
# Установка инструментов сборки
uv pip install build twine
# Сборка дистрибутива
python -m build
# Публикация на PyPI
python -m twine upload dist/*
Разработка
Установка зависимостей для разработки
uv pip install -e ".[dev]"
Запуск тестов
pytest
# или
python -m pytest -v
Проверка покрытия кода тестами
pytest --cov=smev_transform --cov-report=html
Ссылки
Автор
Daniil (@imdeniil)
- Email: keemor821@gmail.com
- GitHub: https://github.com/imdeniil/
Лицензия
MIT License - см. файл LICENSE для деталей.
⚠️ ВАЖНО: Если вы используете эту библиотеку для интеграции с СМЭВ3, настоятельно рекомендуется использовать версию 2.0, так как она включает все требования официальной спецификации СМЭВ 3.5.0.27.
Поддержка
Если вы обнаружили баг или у вас есть предложения по улучшению, пожалуйста, создайте issue на GitHub.
Metadata
Release files for smev-transform 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| smev_transform-2.0.0.tar.gz | 36.5 kB | Without provenance | Details for smev_transform-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| smev_transform-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for smev_transform-2.0.0-py3-none-any.whl |
Total release size: 52.5 kB
Release files / smev_transform-2.0.0.tar.gz
| Download URL | smev_transform-2.0.0.tar.gz |
|---|---|
| Size | 36.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bfa2a8d75a0711f8c774d26591403ade0596ab65ef69e29a6e39f66806e1a385
|
|
BLAKE2b-256 checksum How to use checksums |
bfcd3b2f559b457e80c811af74afb47220d8601b05a3f5c33d59012353059f65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / smev_transform-2.0.0-py3-none-any.whl
| Download URL | smev_transform-2.0.0-py3-none-any.whl |
|---|---|
| Size | 16.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5b0002c3422cadde52de692896dad2ac1ec50e68670684b516518d358c4addca
|
|
BLAKE2b-256 checksum How to use checksums |
ef0e1a1e23e746f18f5f6356b796760bb2d5a343faea995c12eeeceaaf494b67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for smev-transform 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.