Развертывание Docker с Flask + Tesseract и взаимодействие с 1С: Документооборот на примере версии 1.4
В данной инструкции рассмотрим процесс развертывания приложения на Python с использованием фреймворка Flask и Tesseract OCR в контейнере Docker. Узнаем, как использовать Tesseract в связке с Flask и осуществлять обращения к Tesseract для обработки изображений. Рассмотрим пример обращения к приложению Docker из 1С.
Разворачивание приложения
Установка Docker
Прежде всего, убедитесь, что у вас установлен Docker. Вы можете скачать и установить его с официального сайта Docker). После установки проверьте, что Docker работает, выполнив команду:
docker --version
Создание проекта Flask
Клонируйте репозиторий:
git clone https://gitverse.ru/dgmcomru/imagemagick.git
Перейдите в каталог:
cd imagemagick
Убедитесь, что структура каталогов выглядит так:
ls
Результат:
<DIR> doc
<DIR> src
docker-compose.yaml
Dockerfile
README.md
РаспознаваниеPDF.epf
В каталоге src располагаются модули Python: main.py, skew.py
Построение Docker-образа
Теперь мы можем построить наш Docker-образ. Выполните следующую команду:
docker-compose build prod
Запуск Docker-контейнера
После успешной сборки образа выполните команду для создания и запуска контейнера:
docker-compose up prod
Проверка доступности приложения, запущенного в Docker-контейнере
Теперь вы можете открыть браузер и перейти по адресу http://localhost:5000
, где вы увидите сообщение "OCR system enable". Приложение доступно, можем двигаться дальше.
Проверка извлечения текста
Теперь вы можете отправлять изображения на обработку в Tesseract через ваше Flask-приложение, используя POST-запрос на /upload
с файлом изображения. Например, вы можете использовать curl
:
curl -X POST http://localhost:5000/upload -F "image=@path_to_image_file.png"
Если всё настроено правильно, вы получите текст, распознанный Tesseract, в ответе.
Использование Docker-приложения в прикладном решении 1С: Документооборот
Протестировано в версии 1С:Документооборота 1.4.11.2.
Обращение к приложению Docker из 1С, передача файла в метод http://localhost:5000/upload для распознавания
Рассмотрим основные - важные процедуры реализующие обращения к приложению Docker для детального понимания реализации
&НаСервереБезКонтекста
Функция РаспознатьНаВнешнемРесурсе(ВерсияСсылка)
СодержимоеФайла = ПолучитьСодержимоеФайла(ВерсияСсылка, Ложь);
РезультатСервера = "";
Если ТипЗнч(СодержимоеФайла) = Тип("ДвоичныеДанные") Тогда
HTTPСерверРаспознавания = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("АвтоматическоеРаспознаваниеИзображений", "HTTPСерверРаспознавания",,,"Администратор");
Соединение = Новый HTTPСоединение(HTTPСерверРаспознавания);
ЗапросСервера = Новый HTTPЗапрос("/upload");
ЗапросСервера.УстановитьТелоИзДвоичныхДанных(СодержимоеФайла);
ОтветСервера = Соединение.ВызватьHTTPМетод("POST", ЗапросСервера);
РезультатСервера = ОтветСервера.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
КонецЕсли;
Возврат РезультатСервера;
КонецФункции
Вызов процедуры распознавания на сервере
&НаСервереБезКонтекста
Процедура РаспознаваниеИзображений() Экспорт
ПроверитьДоступностьВнешнегоРесурса();
Если НЕ РаспознаваниеВключено() Тогда
ЗаписьЖурналаРегистрацииСервер(НСтр("ru = 'Распознавание отключено, включите или остановите регламентное задание.'"),);
Возврат;
КонецЕсли;
УникальныйИдентификатор = Новый УникальныйИдентификатор;
РазмерПорции = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("АвтоматическоеРаспознаваниеИзображений", "КоличествоФайловВПорции",,,"Администратор");
Попытка
РазмерПорцииТекущий = ?(РазмерПорции = Неопределено, 10, РазмерПорции);
МассивВерсий = ПолучитьМассивВерсийДляРаспознавания(РазмерПорцииТекущий);
Если МассивВерсий.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для Индекс = 0 По МассивВерсий.Количество() - 1 Цикл
//Проверим, если ВЫКлючили прервем цикл
Если НЕ РаспознаваниеВключено() Тогда
Прервать;
КонецЕсли;
ВерсияСсылка = МассивВерсий[Индекс];
Попытка
СтруктураВозврата = РаботаСФайламиВызовСервера.ПолучитьДанныеФайлаИНавигационнуюСсылкуВерсииДляРаспознавания(ВерсияСсылка, УникальныйИдентификатор);
ДанныеФайла = СтруктураВозврата.ДанныеФайла;
АдресФайла = СтруктураВозврата.НавигационнаяСсылкаВерсии;
РасширениеФайлаРезультата = СтруктураВозврата.РасширениеФайлаРезультата;
Если ДанныеФайла.СтатусРаспознаванияТекста <> "НужноРаспознать" Тогда
Если ЭтоАдресВременногоХранилища(АдресФайла) Тогда
УдалитьИзВременногоХранилища(АдресФайла);
КонецЕсли;
Продолжить; // другой клиент уже обработал файл
КонецЕсли;
РаспознанныйТекст = "";
СтрокаВозврата = "Успешно";
РаспознанныйТекст = РаспознатьНаВнешнемРесурсе(ВерсияСсылка);
Если Не ЗначениеЗаполнено(РаспознанныйТекст) Тогда
СтрокаВозврата = "Ошибка";
ЗаписьЖурналаРегистрацииСервер(нСтр("ru='Результат распознавания пустой'", "ru"), ВерсияСсылка);
КонецЕсли;
ЗаписатьРезультатРаспознавания(ВерсияСсылка, СтрокаВозврата, Ложь, РаспознанныйТекст);
Исключение
ИмяСРасширениемФайла = ФайловыеФункцииКлиентСервер.ПолучитьИмяСРасширением(ДанныеФайла.ПолноеНаименованиеВерсии, ДанныеФайла.Расширение);
ОписаниеОшибкиИнфо = ОписаниеОшибки();
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Во время распознавания изображения из файла ""%1"" произошла неизвестная ошибка.'"),
ИмяСРасширениемФайла);
ТекстСообщения = ТекстСообщения + Строка(ОписаниеОшибкиИнфо);
ЗанестиИнформациюОбОшибкеРаспознавания(ВерсияСсылка, ТекстСообщения);
КонецПопытки;
КонецЦикла;
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Распознавание изображений завершено. Обработано файлов: %1'"),
МассивВерсий.Количество());
ЗаписьЖурналаРегистрацииСервер(ТекстСообщения,);
Исключение
ОписаниеОшибкиИнфо = ОписаниеОшибки();
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Во время распознавания изображения из файла ""%1"" произошла неизвестная ошибка.'"), ИмяСРасширениемФайла);
ТекстСообщения = ТекстСообщения + Строка(ОписаниеОшибкиИнфо);
ЗаписьЖурналаРегистрацииСервер(ТекстСообщения,);
КонецПопытки;
КонецПроцедуры
Вызов процедуры распознавания с клиента
&НаКлиенте
Процедура РаспознатьВсе(Команда)
РаспознаваниеВключено = Истина;
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("АвтоматическоеРаспознаваниеИзображений", "РаспознаваниеВключено", РаспознаваниеВключено,,"Администратор");
КоличествоНераспознанныхФайловДоНачалаОперации = ПолучитьКоличествоНераспознанныхВерсий();
РаспознаваниеИзображений();
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru='Завершено распознавание всех нераспознанных файлов. Обработано файлов: %1.'"), КоличествоНераспознанныхФайловДоНачалаОперации);
ПоказатьПредупреждение(, ТекстСообщения);
КонецПроцедуры
Первый запуск обработки РаспознаваниеPDF.epf
Запустите обработку и нажмите кнопку Настройка
. Определите адрес ресурса localhost:5000
или внешний servername:5000
. Определите количество документов - pdf файлов в одном цикле.
Кнопка Старт
разрешает отправку файлов для извлечения текста.
Кнопка Стоп
запрещает отправку файлов для извлечения текста.
Кнопка Распознать все
отправляет определенное количество документов для извлечения текста и записи результата в Справочник ВерсииФайлов
Пробуйте :)
Буду рад, если вы оцените этот проект и решите присоединиться к его развитию.