Найти в Дзене
ИИнтеграция

Создал микросервис с API для генерации Word-отчетов📄(с таблицами) из JSON: делюсь хардкорным опытом

Всё началось с того, что я разрабатывал ИИ-аналитика в n8n, который бы анализировал продажи компании по Excel-таблицам. Система должна была автоматически генерировать отчеты о проделанном анализе. Но вот незадача: после анализа данных нужно было всё это красиво оформить в текстовый документ с таблицами и текстом. Через Google Doc API заполнять таблицы практически невозможно: постоянные баги и ошибки. Я начал искать готовые решения для преобразования JSON в DOCX (в который также вставлялись бы и рандомные таблицы) и столкнулся с жестокой реальностью: 99% сервисов в сети имели критические недостатки: Представьте: у вас каждый день новые метрики, разные структуры таблиц, меняющиеся форматы данных. Создавать под каждый случай шаблон - это адская работа, которая убивает всю автоматизацию. Именно поэтому я решил разработать свой микро-сервис на FastAPI, который: Примерно так (итоговый результат работы микро сервиса): Код был написан на Python с использованием: Сервер принимал JSON вида: js
Оглавление
Мое внутреннее состояние, когда работа все же была завершена))
Мое внутреннее состояние, когда работа все же была завершена))

Предыстория проекта: почему вообще пришлось это делать

Всё началось с того, что я разрабатывал ИИ-аналитика в n8n, который бы анализировал продажи компании по Excel-таблицам. Система должна была автоматически генерировать отчеты о проделанном анализе.

-2

Но вот незадача: после анализа данных нужно было всё это красиво оформить в текстовый документ с таблицами и текстом.

Через Google Doc API заполнять таблицы практически невозможно: постоянные баги и ошибки. Я начал искать готовые решения для преобразования JSON в DOCX (в который также вставлялись бы и рандомные таблицы) и столкнулся с жестокой реальностью:

99% сервисов в сети имели критические недостатки:

  • Платные - неподъемные тарифы для небольшого проекта
  • Работают только через шаблоны - нужно заранее создавать шаблоны таблицы с переменными типа {{variable}} и только потом их передавать через http запрос
  • Нет гибкости - невозможно работать с динамическими, случайными таблицами.
  • Сложная автоматизация - для внутренней канцелярии компании, где каждый отчет уникален, шаблонный подход просто не работает
Представьте: у вас каждый день новые метрики, разные структуры таблиц, меняющиеся форматы данных. Создавать под каждый случай шаблон - это адская работа, которая убивает всю автоматизацию.

Именно поэтому я решил разработать свой микро-сервис на FastAPI, который:

  • Принимает любой JSON с данными
  • Динамически создает таблицы (может создавать неограниченное количество таблиц в одном документе за раз)
  • Чередует текст и таблицы в произвольном порядке
  • Возвращает готовый DOCX файл

Примерно так (итоговый результат работы микро сервиса):

-3

Начало разработки и обманчивые успехи

Код был написан на Python с использованием:

  • FastAPI
  • python-docx для работы с Word документами
  • uvicorn как ASGI-сервер

Сервер принимал JSON вида:

json

[
{"text": "Заголовочный текст"},
{"title": "Таблица фактов", "data": [{"metric": "value"}]},
{"text": "Пояснительный текст"},
{"title": "Топ товаров", "data": [{"product": "Name", "sales": 1000}]}
]

И возвращал готовый DOCX файл.

На тестовом стенде (Replit) всё работало идеально! Запросы из n8n обрабатывались, файлы генерировались. Казалось бы - победа!

Перенос на VPS: начало адской саги

Я развернул код на своем VPS, используя Docker. Запустил контейнер, проверил - сервер работает. Но когда я отправил ИДЕНТИЧНЫЙ запрос из n8n, который прекрасно работал на Replit, на моем VPS я получил:

"422 - Input should be a valid dictionary"

Диагностика проблемы

Первая теория: SSL сертификат

Так как на Replit был HTTPS, а на VPS изначально был HTTP, я предположил проблему с SSL.

Как решал: купил домен, привязал его к микро сервису, получил SSL.

bash

# Настройка nginx
sudo nano /etc/nginx/sites-available/json-docx.ru

server {
listen 80;
server_name json-docx.ru;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
server_name json-docx.ru;

location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

# Активация конфига и SSL
sudo ln -s /etc/nginx/sites-available/json-docx.ru /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d json-docx.ru

Результат: SSL заработал, но ошибка 422 осталась.

Вторая теория: права доступа

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

bash

# В контейнере
mkdir -p output
chmod 777 output

Результат: Папка создана, но ошибка осталась.

Третья теория: разные версии FastAPI

-4

Сравнил версии пакетов - оказалось, что на VPS в контейнере вообще не было установленных пакетов FastAPI!

bash

# Проверка версий на VPS
pip show fastapi pydantic uvicorn
# WARNING: Package(s) not found: fastapi, pydantic, uvicorn

Вот оно! Проблема была в том, что контейнер многократно пересобирался, но Docker использовал кэш, и зависимости не устанавливались заново.

Решение: пересборка контейнера с зависимостями

bash

# Остановка и удаление старого контейнера
docker stop json_docx_api
docker rm json_docx_api

# Пересборка с очисткой кэша
docker build --no-cache -t json-docx .

# Запуск нового контейнера
docker run -d -p 5000:5000 --name json_docx_api json-docx

# Проверка логов
docker logs json_docx_api

После этого всё заработало! 🎉

Выводы и уроки на будущее

1. Всегда проверяйте зависимости в production-окружении

bash

# Всегда проверяйте, что пакеты установлены
docker exec -it container_name pip list

# Или добавляйте логирование версий при старте
import fastapi
print(f"FastAPI version: {fastapi.__version__}")

2. Docker кэш - друг и враг

Используйте "--no-cache" при пересборке, если есть подозрения на устаревшие зависимости:

bash

docker build --no-cache -t your_image .

3. Всегда мониторьте логи

Добавляйте подробное логирование в код:

python

import logging
logging.basicConfig(level=logging.INFO)

@app.post("/generate-docx")
async def generate_docx(data: Any = Body(...)):
logging.info(f"Received: {type(data)} - {data}")

4. Проверяйте права доступа к файловой системе

Убедитесь, что приложение имеет права на запись в нужные директории.

5. Тестируйте полный цикл

Не доверяйте тому, что "на тестовом стенде работает". Всегда тестируйте полный цикл в production-окружении.

Итог

Проблема, которая съела 2 дня жизни, оказалась банальной - отсутствие пакетов в Docker-контейнере из-за кэширования при сборке. Но путь к этому осознанию прошел через:

  • Настройку nginx и SSL
  • Регистрацию домена и настройку DNS
  • Анализ логов и ошибок
  • Понимание работы Docker кэша

Но все было не зря: теперь у меня работает микро-сервис, который автоматически генерирует текстовые документы с таблицами без заранее заготовленных шаблонов.

P.S.

Если у Вас есть вопросы по n8n, автоматизациям, разработке простых приложений с помощью ИИ и их деплою, пишите в ТГ. Буду рад помочь! https://t.me/evgen1992_1992