PYTHON 1C. МИКРОСЕРВИС НА FASTAPI

Введение. Python 1c

Привет программисты 1С, с вами Низамов Илья.

В последнее время было несколько вопросов по использованию 1с и python. Сделать это можно разными способами, но самым удобным считаю разработку микросервиса. В уроке мы будем использовать FastAPI, это быстрый веб-фреймворк и вполне подойдет для наших задач.

Еще был запрос на защиту конфигурации и расширений. Я против таких защит, так как тот кому надо взломает, а порядочным покупателям принесет много проблем. Решить эту проблему можно вынеся часть логики работы в микросервис и разместить его в облаке. Либо скомпилировать защитив предварительно код на python.

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

Запишись на тренинг

НАУЧИСЬ РАЗРАБАТЫВАТЬ МИКРОСЕРВИСЫ НА PYTHON ДЛЯ 1С ЗА 5 ЧАСОВ ПОДРОБНЕЕ

Микросервис на fastapi python 1с

Устанавливаем FastAPI

pip install fastapi

Устанавливаем uvicorn – асинхронный web сервер

pip install uvicorn

Добавим main.py

Импортируем FastAPI и из библиотеки pydantic – BaseModel для автоматической валидации входящих данных

from fastapi import FastAPI 
from pydantic import BaseModel

Создаем экземпляр FastAPI

app = FastAPI()

И класс для валидации данных

class OnesData(BaseModel): 
	name: str

Создаем асинхронную функцию для обработки post запросов из 1С. 
В этой функции получаем данные и проводим их валидацию 
Выводим ключ “name” 
Возвращаем обратно содержимое ключа “name” в но уже в новом ключе “newdata”

@app.post('/', status_code=201) 
async def process_data(payload: OnesData): 
    ones_data = payload.dict() 
    print(ones_data["name"]) 
    return {'newdata': ones_data["name"]}

Итоговый скрипт main.py

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class OnesData(BaseModel):
    name: str


@app.post('/', status_code=201)
async def process_data(payload: OnesData):
    ones_data = payload.dict()
    print(ones_data["name"])
    return {'newdata': ones_data["name"]}

Запускаем сервер и тестируем 
Можно так же посмотреть с помощью сгенерированной документации 
http://127.0.0.1:8000/docs

uvicorn main:app --reload

Останавливаем сервер и создаем requirements.txt

pip freeze > requirements.txt

Упаковываем микросервис в Docker

Создаем Dockerfile

FROM python:3.11.1-buster 

ENV PYTHONUNBUFFERED=1 

WORKDIR /app 

COPY ./requirements.txt ./ 

RUN /usr/local/bin/python -m pip install --upgrade pip \ 
pip install -r requirements.txt 

COPY . .

Далее docker-compose.yml для конфигурации сервиса.

version: "3.9"

services:
  python:
    container_name: ones-micro
    build: ./
    command: uvicorn main:app --reload --host 0.0.0.0 --port 8000
    restart: always
    ports:
      - 8000:8000

Добавим .dockerignore для python и pycharm, чтобы в итоговый образ не попало лишней информации.

### JetBrains template 
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 

# User-specific stuff 
.idea/**/workspace.xml 
.idea/**/tasks.xml 
.idea/**/usage.statistics.xml 
.idea/**/dictionaries 
.idea/**/shelf 

# AWS User-specific 
.idea/**/aws.xml 

# Generated files 
.idea/**/contentModel.xml 

# Sensitive or high-churn files 
.idea/**/dataSources/ 
.idea/**/dataSources.ids 
.idea/**/dataSources.local.xml 
.idea/**/sqlDataSources.xml 
.idea/**/dynamic.xml 
.idea/**/uiDesigner.xml 
.idea/**/dbnavigator.xml 

# Gradle 
.idea/**/gradle.xml 
.idea/**/libraries 

# Gradle and Maven with auto-import 
# When using Gradle or Maven with auto-import, you should exclude module files, 
# since they will be recreated, and may cause churn. Uncomment if using 
# auto-import. 
# .idea/artifacts 
# .idea/compiler.xml 
# .idea/jarRepositories.xml 
# .idea/modules.xml 
# .idea/*.iml 
# .idea/modules 
# *.iml 
# *.ipr 

# CMake 
cmake-build-*/ 

# Mongo Explorer plugin 
.idea/**/mongoSettings.xml 

# File-based project format 
*.iws 

# IntelliJ 
out/ 

# mpeltonen/sbt-idea plugin 
.idea_modules/ 

# JIRA plugin 
atlassian-ide-plugin.xml 

# Cursive Clojure plugin 
.idea/replstate.xml 

# SonarLint plugin 
.idea/sonarlint/ 

# Crashlytics plugin (for Android Studio and IntelliJ) 
com_crashlytics_export_strings.xml 
crashlytics.properties 
crashlytics-build.properties 
fabric.properties 

# Editor-based Rest Client 
.idea/httpRequests 

# Android studio 3.1+ serialized cache file 
.idea/caches/build_file_checksums.ser 

### Python template 
# Byte-compiled / optimized / DLL files 
__pycache__/ 
*.py[cod]*$py.class 

# C extensions 
*.so 

# Distribution / packaging 
.Python 
build/ 
develop-eggs/ 
dist/ 
downloads/ 
eggs/ 
.eggs/ 
lib/ 
lib64/ 
parts/ 
sdist/ 
var/ 
wheels/ 
share/python-wheels/ 
*.egg-info/ 
.installed.cfg 
*.egg 
MANIFEST 

# PyInstaller 
# Usually these files are written by a python script from a template 
# before PyInstaller builds the exe, so as to inject date/other infos into it. 
*.manifest 
*.spec 

# Installer logs 
pip-log.txt 
pip-delete-this-directory.txt 

# Unit test / coverage reports 
htmlcov/ 
.tox/ 
.nox/ 
.coverage 
.coverage.* 
.cache 
nosetests.xml 
coverage.xml 
*.cover 
*.py,cover 
.hypothesis/ 
.pytest_cache/ 
cover/ 

# Translations 
*.mo 
*.pot 

# Django stuff: 
*.log 
local_settings.py 
db.sqlite3 
db.sqlite3-journal 

# Flask stuff: 
instance/ 
.webassets-cache 

# Scrapy stuff: 
.scrapy 

# Sphinx documentation 
docs/_build/ 

# PyBuilder 
.pybuilder/ 
target/ 

# Jupyter Notebook 
.ipynb_checkpoints 

# IPython 
profile_default/ 
ipython_config.py 

# pyenv 
# For a library or package, you might want to ignore these files since the code is 
# intended to run in multiple environments; otherwise, check them in: 
# .python-version 

# pipenv 
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 
# However, in case of collaboration, if having platform-specific dependencies or dependencies 
# having no cross-platform support, pipenv may install dependencies that don't work, or not 
# install all needed dependencies. 
#Pipfile.lock 

# poetry 
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 
# This is especially recommended for binary packages to ensure reproducibility, and is more 
# commonly ignored for libraries. 
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 
#poetry.lock 

# pdm 
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 
#pdm.lock 
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 
# in version control. 
# https://pdm.fming.dev/#use-with-ide 
.pdm.toml 

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 
__pypackages__/ 

# Celery stuff 
celerybeat-schedule 
celerybeat.pid 

# SageMath parsed files 
*.sage.py 

# Environments 
.env 
.venv 
env/ 
venv/ 
ENV/ 
env.bak/ 
venv.bak/ 

# Spyder project settings 
.spyderproject 
.spyproject 

# Rope project settings 
.ropeproject 

# mkdocs documentation 
/site 

# mypy 
.mypy_cache/ 
.dmypy.json 
dmypy.json 

# Pyre type checker 
.pyre/ 

# pytype static type analyzer 
.pytype/ 

# Cython debug symbols 
cython_debug/ 

# PyCharm 
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can 
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 
# and can be added to the global gitignore or merged into this file. For a more nuclear 
# option (not recommended) you can uncomment the following to ignore the entire idea folder. 
#.idea/ 

Собираем образ и запускаем Docker контейнер

docker-compose build 
docker-compose up -d

Запросы к python 1c

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ЗапросКСервису(Команда)
	ОтветОтСервера = ЗапросКСервисуНаСервере(ТестоваяСтрока);
КонецПроцедуры

#КонецОбласти

#Область Сериализация

&НаСервереБезКонтекста
Функция СформироватьJSON(Знач Данные)
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
		
	ЗаписатьJSON(ЗаписьJSON, Данные);
		
	Возврат ЗаписьJSON.Закрыть();		
КонецФункции

#КонецОбласти 

#Область HTTPЗапрос

&НаСервереБезКонтекста
Функция ЗапросКСервисуНаСервере(Знач name)
	Попытка
		HTTPСоединение = Новый HTTPСоединение("127.0.0.1", 8000,,,, 30);
		
		Заголовки = Новый Соответствие;
		Заголовки.Вставить("Content-Type", "application/json");
		
		HTTPЗапрос = Новый HTTPЗапрос("/", Заголовки);
		
		Данные = Новый Соответствие;
		Данные.Вставить("name", name);
		
		ДанныеJSON = СформироватьJSON(Данные);
		
		HTTPЗапрос.УстановитьТелоИзСтроки(ДанныеJSON, КодировкаТекста.UTF8);
		
		HTTPОтветОтСервера = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
		
		Возврат HTTPОтветОтСервера.ПолучитьТелоКакСтроку();
	Исключение
		ЗаписьЖурналаРегистрации("FastAPI", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
	КонецПопытки;

	Возврат Неопределено;
КонецФункции

#КонецОбласти 

Посмотрите подробное видео: Python 1с интеграция

Python 1с интеграция
Python 1с интеграция