PYTHON 1C. МИКРОСЕРВИС НА FASTAPI
Типичная ситуация: 1С нужно отдать данные во внешнюю систему или, наоборот, принять запрос снаружи, а встроенный HTTP-сервис 1С для этого неудобен — нет валидации входящих данных «из коробки», сложно обрабатывать долгие операции асинхронно, тяжело логировать и покрывать тестами. В итоге логику обвязки либо городят прямо в конфигурации 1С, либо тратят часы на ручную проверку каждого входящего JSON.
В этой статье соберём рабочий микросервис на Python и FastAPI, который принимает POST-запросы от 1С, автоматически валидирует тело запроса через Pydantic, возвращает предсказуемый ответ и поднимается в Docker одной командой. Дополнительно разберём защиту эндпоинта токеном, обработку ошибок на стороне 1С и сравним подход с аналогичным сервисом на Node.js.
Что вы узнаете
- Как поднять минимальный сервис на FastAPI и подключить автоматическую валидацию через Pydantic v2
- Как вызвать этот сервис из 1С через
HTTPСоединениеи корректно обработать ошибку - Как защитить эндпоинт токеном, чтобы к нему не мог обратиться кто угодно из интернета
- Как упаковать микросервис в Docker и запустить его через docker-compose
- Чем FastAPI отличается от аналогичного решения на Node.js/Express
- Какие ошибки чаще всего допускают при интеграции 1С и Python
Зачем выносить логику из 1С в отдельный микросервис
Привет, на связи Илья Низамов. Периодически прилетают вопросы про интеграцию 1С и Python — и почти всегда за ними стоит одна из двух задач: либо нужно дёрнуть внешний API (LLM, платёжный шлюз, стороннюю CRM) из 1С, либо, наоборот, принять данные снаружи и что-то с ними сделать до того, как они попадут в базу.
Отдельная причина выносить логику наружу — защита кода. Часть разработчиков просит спрятать логику конфигурации или расширения от конечного пользователя. Городить обфускацию средствами 1С — плохая идея: тот, кому действительно надо, всё равно разберётся, а порядочным клиентам это только создаёт проблемы с обновлениями. Рабочий вариант — вынести чувствительную часть логики в микросервис на Python, скомпилировать его отдельно и разместить в облаке или на своём сервере. 1С в этом случае обращается к сервису по HTTP и не видит исходный код.
Быстрый старт: FastAPI + Pydantic
Ставим сам фреймворк:
pip install fastapi
И ASGI-сервер, на котором FastAPI будет работать — uvicorn:
pip install uvicorn
Создаём файл main.py. Импортируем сам FastAPI и BaseModel из pydantic — он отвечает за автоматическую валидацию входящих данных без единой строчки ручных проверок:
from fastapi import FastAPI, Header, HTTPException, status
from pydantic import BaseModel, Field
Создаём экземпляр приложения:
app = FastAPI(title="1C Integration Service")
Описываем схему данных, которые ждём от 1С. В Pydantic v2 это обычный класс-наследник BaseModel с типизированными полями — если 1С пришлёт не строку в name или вообще забудет это поле, FastAPI сам вернёт 422 с понятным описанием ошибки, до вашего кода дело не дойдёт:
class OnesData(BaseModel):
# min_length защищает от пустых строк, которые 1С иногда шлёт вместо NULL
name: str = Field(..., min_length=1, description="Значение, полученное из 1С")
Для реальной интеграции эндпоинт без авторизации — плохая идея: сервис торчит наружу, и запрос в него может отправить кто угодно. Добавляем простую проверку токена через заголовок запроса. Для продакшена токен читаем из переменной окружения, а не хардкодим в коде:
import os
API_TOKEN = os.environ.get("ONES_API_TOKEN", "dev-only-token")
def verify_token(x_api_key: str = Header(...)) -> None:
# сравнение через == тут допустимо: токен не секрет уровня платёжной подписи,
# для боевого продакшена лучше secrets.compare_digest
if x_api_key != API_TOKEN:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Неверный токен")
Теперь сам эндпоинт. Обратите внимание на model_dump() — в Pydantic v1 использовался .dict(), в актуальной v2 это устаревший алиас, правильный вызов именно model_dump():
from fastapi import Depends
@app.post("/", status_code=201, dependencies=[Depends(verify_token)])
async def process_data(payload: OnesData):
ones_data = payload.model_dump() # Pydantic v2: .dict() устарел, используем model_dump()
print(ones_data["name"])
return {"newdata": ones_data["name"]}
Отдельно стоит добавить health-check — он не завязан на токен и нужен, чтобы Docker/оркестратор мог проверять, что сервис живой, не дёргая бизнес-логику:
@app.get("/health")
async def health_check():
return {"status": "ok"}
Итоговый main.py
Собираем всё вместе — это уже полностью рабочий сервис с валидацией, авторизацией и health-check:
import os
from fastapi import Depends, FastAPI, Header, HTTPException, status
from pydantic import BaseModel, Field
app = FastAPI(title="1C Integration Service")
API_TOKEN = os.environ.get("ONES_API_TOKEN", "dev-only-token")
class OnesData(BaseModel):
name: str = Field(..., min_length=1, description="Значение, полученное из 1С")
def verify_token(x_api_key: str = Header(...)) -> None:
if x_api_key != API_TOKEN:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Неверный токен")
@app.get("/health")
async def health_check():
return {"status": "ok"}
@app.post("/", status_code=201, dependencies=[Depends(verify_token)])
async def process_data(payload: OnesData):
ones_data = payload.model_dump()
print(ones_data["name"])
return {"newdata": ones_data["name"]}
Запуск и проверка
Запускаем сервер в режиме автоперезагрузки и сразу открываем автосгенерированную документацию — в ней можно отправить тестовый запрос прямо из браузера:
uvicorn main:app --reload
Документация доступна по адресу http://127.0.0.1:8000/docs. Когда сервис готов, фиксируем зависимости:
pip freeze > requirements.txt
Упаковываем микросервис в Docker
Dockerfile — используем актуальный slim-образ Python вместо устаревшего buster:
FROM python:3.12-slim
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml для локального запуска. Токен передаём через переменную окружения, а не через код:
services:
python:
container_name: ones-micro
build: ./
environment:
ONES_API_TOKEN: ${ONES_API_TOKEN}
restart: always
ports:
- "8000:8000"
.dockerignore — чтобы в образ не попадали виртуальное окружение, кеш и локальные настройки IDE:
__pycache__/
*.pyc
.venv/
venv/
.env
.git
.idea
Dockerfile
docker-compose.yml
Собираем образ и поднимаем контейнер:
docker-compose build
docker-compose up -d
Вызов микросервиса из 1С
На стороне 1С — обычный HTTPСоединение с таймаутом и заголовком авторизации. Ниже пример с комментариями по каждому шагу:
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ЗапросКСервису(Команда)
ОтветОтСервера = ЗапросКСервисуНаСервере(ТестоваяСтрока);
КонецПроцедуры
#КонецОбласти
#Область Сериализация
&НаСервереБезКонтекста
Функция СформироватьJSON(Знач Данные)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Данные);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
#КонецОбласти
#Область HTTPЗапрос
&НаСервереБезКонтекста
Функция ЗапросКСервисуНаСервере(Знач name)
Попытка
// 30 секунд — таймаут соединения, без него зависший сервис повесит и 1С
HTTPСоединение = Новый HTTPСоединение("127.0.0.1", 8000,,,, 30);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
// токен должен совпадать с ONES_API_TOKEN на стороне сервиса,
// иначе FastAPI вернёт 401 ещё до вызова process_data
Заголовки.Вставить("X-Api-Key", "секрет-из-настроек-1с");
HTTPЗапрос = Новый HTTPЗапрос("/", Заголовки);
Данные = Новый Соответствие;
Данные.Вставить("name", name);
ДанныеJSON = СформироватьJSON(Данные);
HTTPЗапрос.УстановитьТелоИзСтроки(ДанныеJSON, КодировкаТекста.UTF8);
HTTPОтветОтСервера = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
// код ответа стоит проверять отдельно: 401 (токен), 422 (валидация)
// и 5xx (сервис упал) требуют разной реакции у вызывающего кода
Если HTTPОтветОтСервера.КодСостояния <> 201 Тогда
ЗаписьЖурналаРегистрации("FastAPI", УровеньЖурналаРегистрации.Предупреждение,,,
"Код ответа: " + HTTPОтветОтСервера.КодСостояния);
КонецЕсли;
Возврат HTTPОтветОтСервера.ПолучитьТелоКакСтроку();
Исключение
ЗаписьЖурналаРегистрации("FastAPI", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Возврат Неопределено;
КонецФункции
#КонецОбласти FastAPI vs Node.js/Express: что выбрать для интеграции с 1С
Оба стека одинаково хорошо справляются с ролью «принять HTTP-запрос от 1С и что-то с ним сделать». Разница — в деталях, которые важны именно для интеграций с 1С:
| Критерий | FastAPI (Python) | Node.js / Express |
|---|---|---|
| Валидация входящих данных | Из коробки через Pydantic — схема одновременно и валидирует, и документирует API | Нужна отдельная библиотека (Zod, Joi) и ручная привязка к роутам |
| Документация API | Автогенерация Swagger UI на /docs без дополнительной настройки | Нужен отдельный пакет (swagger-jsdoc и подобные) и описание вручную |
| Экосистема для работы с 1С | Большинство существующих скриптов обмена, парсеров выгрузок 1С и ML/LLM-библиотек — на Python | Сильнее в реалтайме (WebSocket, SSE) и там, где фронтенд и бэкенд на одном языке |
| Порог входа для разработчика 1С | Синтаксис ближе к тому, что 1С-разработчик уже видел в скриптах на Python | Нужно параллельно разбираться с npm-экосистемой и async/await в JS |
Практический вывод: если микросервис — это в первую очередь приём/валидация данных от 1С и дальнейшая передача в Python-экосистему (пандас, LLM, ML-модели), берите FastAPI. Если сервис — часть более крупного Node.js-бэкенда или нужен постоянный канал (WebSocket) с фронтендом, разумнее остаться на Node.js/Express. Подробнее про интеграцию 1С с JavaScript и Node.js — в статье «1С и JavaScript/Node.js».
Частые ошибки при интеграции 1С и Python
- Отсутствие таймаута в
HTTPСоединениена стороне 1С — зависший микросервис повесит и сеанс 1С. - Синхронный блокирующий код внутри
async def— обращение к БД или файлу без await блокирует весь event loop FastAPI, а не только один запрос. - Отсутствие авторизации на эндпоинте, который смотрит в интернет напрямую, без reverse-proxy и firewall-правил.
- Игнорирование кода ответа на стороне 1С: 401 и 422 требуют разной реакции, чем 5xx, но часто в 1С просто проверяют «тело не пустое».
- Хардкод токенов и паролей в коде микросервиса вместо переменных окружения — при коммите в git это моментально становится технической проблемой.
Похожие статьи
- 1С и Kafka: REST-сервис и интеграция через события
- ИИ-агент для 1С на Python и FastAPI: микросервис + LLM
- 1С и JavaScript/Node.js: интеграция через поле HTML и веб-сервисы
- Упаковка FastAPI-приложения в exe через PyInstaller
Полный курс по Python + 1С
Если хотите не просто повторить один пример, а системно разобраться в интеграции 1С и Python — от HTTP-сервисов 1С до защищённого прокси-сервера на Python и OAuth 2 — приходите на курс «Python + 1С: защищённый OAuth 2 сервер». Разбираем архитектуру интеграции, безопасность и типовые ошибки на реальных кейсах.
Если тема ближе к ИИ-интеграциям — LLM, RAG, MCP-серверы для 1С — на эту задачу отвечает курс «ИИ-агент для 1С: LangChain, RAG и MCP-серверы», где похожий микросервис на FastAPI используется как шлюз между 1С и языковой моделью.
