Девопсы в 1С: микросервис распознавания штрихкодов

09.08.21

Разработка - Групповая разработка (Git, хранилище)

Распознавание штрихкода из сканированного документа в PDF.

"Мы словно живём в комнате, где на стене висит плакат. Уставимся на него и думаем, что это и есть весь мир. Комната... И плакат. На плакате что-то симпатичное: пейзаж, знаменитость. Как в том фильме про тюрьму... Как же он назывался? Комната — тюремная камера. А картинку каждый из нас видит по-своему. Она может быть прекрасной или ужасающей, но все мы к ней прикованы. Но это всё неправда: лишь ширма, скрывающая истину. Они нам врут. Мы врём самим себе. Комната — не весь мир. Мир намного больше, намного удивительнее. Плакат на стене скрывает лаз, ведущий в реальный мир. Мы ощущаем себя в безопасности в той комнате. Но иногда... Иногда нечто выползает из-за плаката. И каждый, кто становится тому свидетелем, в страхе пытается забыть о том, что видел."

- Джесси Фейден, Control


Итак, одеваем свой фурсьюит и ставим задачу:

Есть база 1С, в которой есть документы, к которым привязаны штрихкоды. Для простоты возьмём EAN13, но вообще более перспективными выглядят QR.

Штрихкоды печатаются в печатных формах, а еще есть возможность печатать их на этикетках и лепить на готовые бумажные документы.

Обе эти задачи решаются тривиально, например, с помощью специального шрифта для печати EAN13 и дополнительного реквизита.

Но теперь, после того, как эти распечатанные документы подписали, мы хотим их засунуть обратно в 1С. Для хранения файлов в БСП есть готовые средства, соответственно, они присутствуют во всех типовых конфигурациях.

Прикрепление небольшого количества файлов не вызывает затруднений - мы можем сканировать и добавлять их вручную. Однако, не будем забывать о том, что уже изобрели пакетное сканирование.

Будем считать, что пользователь кладет в сканер сразу все листы, относящиеся к одному документу. Например, это может быть счет на трёх страницах, коммерческое предложение и прайс. Условимся, что весь этот пакет будет отсканирован в один PDF-документ (для удобства дальнейшего использования).

Теперь у нас получилась папка с pdf-файлами, в которых содержатся сканы документов со штрихкодами. Нужно распознать штрихкоды и привязать их к документам. Естественно, часть про привязать находится на стороне 1С, но что с распознаванием?

Варианты примерно следующие:

  • использовать какую-то внешнюю компоненту (вероятнее всего, просто ActiveX)
  • использовать CLI утилиту (такой вариант мне нравится всё больше)
  • использовать REST API, или, по-нашему, HTTP-сервис - красиво, модно, молодежно!

Собственно, третьим вариантом и попробуем воспользоваться. А так как сейчас довольно популярен Python, и я про него практически ничего не знаю, то я попробовал решить эту задачу с его помощью.

Архитектура будет такая:

в одной локальной сети стоит три машины:

  • 1C (сервер или клиент - в данном случае не важно)
  • Веб-сервер на питоне
  • Обычная сетевая папка, пусть будет Windows

В первой версии архитектуры у сервера 1С и у Flask есть доступ к этой папке. Почему так? Потому что так легче отлаживать - можно делать это через браузер, не загружая каждый раз файл. Потом можно легко переделать на передачу самих двоичных данных файла через HTTP, благо ни у 1С, ни у Питона с этим проблем нет.

Что понадобится для реализации?

  1. Python
  2. IDE
  3. Flask
  4. pdf2image
  5. pyzbar
  6. poppler

Питон вроде бы устанавливается вместе с IDE, но можно скачать c https://www.python.org/downloads/

Очевидные варианты IDE - Microsoft Visual Studio Code, она у меня как раз есть, и PyCharm. Мне нравится IDEA, решил попробовать PyCharm.

Следующие три компонента устанавливаются с помощью пакетного менеджера:

pip install flask
pip install pyzbar
pip install pdf2image

К сожалению, так как на самом Питоне написано ничего, то для работы нужно установить некоторые компоненты. В нашем случае пришлось установить http://blog.alivate.com.au/poppler-windows/, распаковать архив и прописать путь к папке bin в переменную окружения PATH (у меня Windows).

Собственно, все эти библиотеки я нашел за 20 минут гуглежа, думаю, есть варианты и получше, но важен сам принцип.

Во фласке методы REST API прописываются с помощью так называемых роутов, выглядит похоже на 1С:

@app.route("/decode_ean13/<string:strfilename>/<int:pagenum>", methods=["GET"])

Также, как в HTTP-сервисах 1С. можно в качестве части пути объявлять обязательные параметры, но тут их можно еще и типизировать. У меня эти параметры strfilename и pagenum - хочу передавать путь к файлу и номер страницы (на самом деле она по условиям всегда первая, но на будущее), метод будет, естественно, GET (мы хотим только получать данные от этого сервиса). Тут роут может поддерживать несколько методов, также, как и в 1С.

Теперь осталось сохранить указанную страницу файла, путь к которому получили, и распознать с неё штрихкод EAN13.

За сохранение страницы как раз отвечает pdf2image, и делает это с помощью единственного вызова:

pages = convert_from_path(filename, dpi=300, first_page=pagenum, last_page=pagenum)

Здесь pages - список полученных страниц. Так как мы получаем только одну страницу, то она у нас будет pages[0].

За распознавание штрихкода отвечает pyzbar:

decode(image, symbols=[ZBarSymbol.EAN13])

Здесь я сразу ограничиваю виды штрихкодов, которые нужно распознавать - думаю, так будет работать быстрее. Кроме того, я так снижаю вероятность распознавания чужих штрихкодов - ведь, например, на документе поставщика может быть штрихкод поставщика и наш. Конечно, они оба могут быть EAN13, но какую-то часть ошибок я отсеку.

Как выяснилось, decode в качестве параметра принимает объект типа Image, и convert_from_path возвращает объект типа Image, но это разные Image :(

В общем, пока для простоты я полученную страницу сохраняю в PNG-файл, и тут же загружаю его обратно и распознаю штрихкод. В результате распознавания возвращается список со всеми штрихкодами, которые удалось распознать, и это очень полезно - помним про штрихкоды поставщика? Эти штрикоды в виде JSON я и возвращаю в ответ.

В процессе выяснилась странная особенность то ли Flask, то ли не знаю чего: нельзя передать слэш (разделитель пути) даже в виде url-кода %2F. Поэтому я его заменил на |:

Вот пример изображения:

В принципе, для случая с сетевой папкой, которая доступна для обеих машин, всё уже работает - осталось научиться сохранять картинку во временный файл, а не в папку с исходным PDF (она по идее не должна быть доступна на запись).

Для случая, когда папка недоступна, нужны доработки: 1С будет отправлять двоичные данные, а сервер на Питоне будет распознавать штрихкод из них. Для этого в pdf2image уже есть convert_from_bytes,  и еще нужно выяснить, как объект-изображение из pdf2image преобразовать в изображение pyzbar. Заглушки в коде я уже поставил ;)

Код из статьи доступен в репозитории https://github.com/AlexNecro/NBarcoder. На стороне 1С ничего не делалось - и так всё понятно.

PS. Спросите, причем тут девопс? Ну так нужно этот скрипт на питоне положить в Docker, вот и всё!

PPS. Прошу пинать, так как всё натыкано мышкой как попало, хотелось бы привести всё в нормальный вид, а опыта работы с Питоном, Гитом и Докером особо нет.

штрихкод python flask rest api http pdf ean13 распознавание

См. также

SALE! 50%

1С-программирование DevOps и автоматизация разработки Групповая разработка (Git, хранилище) DevOps для 1С Программист Стажер Платформа 1С v8.3 Платные (руб)

Использования систем контроля версий — стандарт современной разработки. На курсе научимся использованию Хранилища 1С и GIT при разработке на 1С:Предприятие 8. Разберем подходы и приемы коллективной разработки, научимся самостоятельно настраивать системы и ориентироваться в них.

4900 2450 руб.

29.06.2022    11949    100    4    

132

Групповая разработка (Git, хранилище) Программист Руководитель проекта Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда в хранилище одновременно разрабатывают несколько команд, сортировка сделанного и несделанного при формировании релиза и проведение code review по задачам превращаются в непроходимый квест. В таких случаях нужен бранчинг. Расскажем об опыте перехода на новую схему хранения кода для ИТ-департамента.

23.09.2024    2894    kraynev-navi    2    

25

Групповая разработка (Git, хранилище) Программист Бесплатно (free)

Называть Git новой технологией – уже смешно, но для многих 1С-ников это действительно «новое и неизведанное». Расскажем о плюсах и минусах двух главных систем контроля версий в мире 1С: Git и хранилища.

17.09.2024    7355    Golovanoff    69    

26

Групповая разработка (Git, хранилище) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Во многих командах незаслуженно забывают о том, что в базе меняются расширения (как от вендора, так и собственные) и внешние отчеты и обработки. Вплоть до того, что релиз происходит каждый день – меняются печатные формы, отчеты, обработки. Расскажем о том, как выгружать в Git не только изменения конфигурации рабочего контура, но и файлы внешних обработок и расширений.

05.09.2024    2216    ardn    12    

15

EDT Групповая разработка (Git, хранилище) Программист Платформа 1С v8.3 Бесплатно (free)

Заказчики любят EDT+Git за прозрачность и контроль качества. А у разработчиков есть две основные причины не любить EDT – это тормоза и глюки. Расскажем о том, что нужно учесть команде при переходе на EDT+Git.

14.08.2024    7680    lekot    34    

8

Групповая разработка (Git, хранилище) Программист Платформа 1С v8.3 Бесплатно (free)

В «долгоиграющих» проектах стандартный захват объектов 1С в хранилище может привести к длительным простоям других разработчиков. Но и создавать под каждую доработку отдельное хранилище, чтобы использовать технологию разветвленной разработки конфигураций от фирмы «1С» – избыточно. Расскажем о том, как разрабатывать в отдельной базе без ожиданий, а потом с легкостью перенести изменения в хранилище, используя основную идею технологии 1С – конфигурацию на поддержке хранилища.

05.08.2024    4320    sinichenko_alex    16    

25

Групповая разработка (Git, хранилище) Программист Руководитель проекта Стажер Бесплатно (free)

Про изменения и новинки в агрегаторе открытых проектов OpenYellow, которые появились с момента его создания: про портал, Github и Telegram

15.07.2024    3272    bayselonarrend    8    

24
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. elcoan 1045 09.08.21 21:57 Сейчас в теме
В процессе выяснилась странная особенность то ли Flask, то ли не знаю чего: нельзя передать слэш (разделитель пути) даже в виде url-кода %2F. Поэтому я его заменил на |:

Думаю, Вам поможет strict_slashes=False:
@app.route('/test', strict_slashes=False)
@app.route('/test/<path:path>')
def test(path=None):
    return str(path)
2. alexey_kurdyukov 165 10.08.21 02:44 Сейчас в теме
(1)
, strict_slashes=False

Почему-то не помогло
Прикрепленные файлы:
3. alexey_kurdyukov 165 10.08.21 05:11 Сейчас в теме
(2) Похоже потому, что не добавил path:
4. alexey_kurdyukov 165 12.08.21 02:43 Сейчас в теме
(1) C path помогло, спасибо
5. user1085902 13.08.21 10:24 Сейчас в теме
Извиняюсь, но использование докера не равно DevOps. Плюс сервис распознавания не особо удачен с точки зрения использования общей папки.
Мое видение этого процесса:
- Настроить http сервис на 1с, чтобы он умел отдавать документы по какому-то адресу.
- Через брокер и/или периодический обмен сообщать сервису распознавания что нужно распознать такой-то документ, вот тебе ссылка, ответ верни по этому адресу.
- Сервис распознавания качает себе файл, распознает, вызывает коллбэк куда отдаёт результат.

Готово, теперь это можно называть микросервисом.
6. alexey_kurdyukov 165 13.08.21 10:27 Сейчас в теме
(5) Чем плох вариант вызова этого же сервиса, только не с указанием имени файла, а с передачей сразу двоичных данных? Запросы можно выполнять в фоновых заданиях
7. user1085902 13.08.21 10:48 Сейчас в теме
(6) Соглашусь, если нужно синхронно обрабатывать данные.
Плюс обоих подходов - доступно горизонтальное масштабирование.
8. user626743_2mugik 03.09.21 09:54 Сейчас в теме
Я Zbar сишный использовал. Думаю быстрее работает. подключался через Внешнюю компоненту 1С.
Оставьте свое сообщение