Песочница для запуска python-скриптов в ORBISMap v2.0

Для реализации возможности запуска пользовательских скриптов в рамках ORBISMap - был разработан модуль ORBISMap py-sandbox. Который позволяет в изолированной среде выполнять python-скрипты. Для удобства разработки скриптов была разработана библиотека omlibs, упрощающая разработку скриптов. Для корректной обработки скрипты должны:

Пример структуры скрипта:

from omlibs.v1 import (
    pg,
    GLog,
    OMSApi,
    Checks,
    Variables,
)

def func1(v1):
    # выполнение пользовательских скриптов
    pass

def func2(v1, v2):
    # выполнение пользовательских скриптов
    pass

def main():
    """Точка входа.
        Выполнение скрипта интерпретируется в вызов данной функции
    """
    try:
        res1 = func1()
        return func2(res1, 100500)
    except Exception as e:
        GLog.exception(e)
        return -1

Обновление ORBISMap вручную

Основные шаги:

Обновление docker-compose.yml

Необходимо добавить новый сервис песочницы, а так же "внешний" memcached:

  py_sandbox:
    image: "registry.orbismap.com/python-sandbox:1.0.1"
    restart: always
    user: untrusted
    volumes:
      - ${PWD}/extern/scripts:/oms_scripts:ro
    networks:
      - orbismap
    env_file: orbismap.env

  memcached:
    image: "memcached:alpine"
    restart: always
    networks:
      - orbismap

В сервис oms2 добавить точку монтирования /etc/cron.d:

oms2:
    image: "registry.orbismap.com/orbis/oms-mono:ВЕРСИЯ"
    restart: always
    volumes:
      - ${PWD}/extern:/oms/extern
      - ${PWD}/extern:/tilecache/extern
      - orbismap-cron-d:/etc/cron.d

Добавить том orbismap-cron-d:

volumes:
  orbismap-pg-data:
  orbismap-mg-data:
  orbismap-mg-config:
  orbismap-cron-d:

Обновление ORBISMap

Обновление проводится штатно до требуемой версии.

Обновление orbismap.service

После обновления ORBISMap необходимо обновить внешний сервис ORBISMap. Для этого:

Библиотека omlibs

Представляет собой пакет модулей Python. Основные компоненты:

pg

Библиотека, инкапсулирующая низкоуровневую работу с БД, и предоставляющая класс работы с БД. Данный класс представляет высокоуровневые функции работы с БД:

select - Основная функция для осуществления выборок данных из БД. Основные параметры функции:

Пример использования:

from omlibs.v1 import (
    pg,
    Checks
)
# Предполагается, что значение фильтра по orbis_id, а также коды карты и слоя уже известны и получены 
# Проверка полученных данных
map_code = "map"
layer_code = "azs"
oid_filter = 5
kwargs = {
    'args': {
        'map': Checks.check_str(map_code, "код карты"),
        'layer': Checks.check_str(layer_code, "код слоя"),
        'filter_limit': Checks.check_int(oid_filter, "фильтр по orbis_id"),
    },
    'seq': True,
    'ddl': ['map', 'layer'],
    'msg': 'Ошибка выборки данных из "%s"."%s"' % (map_code, layer_code)
}
res = pg().select('''
    SELECT *
    FROM %(*map)s.%(*layer)s
    WHERE orbis_id < %(filter_limit)s;
''', **kwargs)
for i in res:
    # Обработка данных выбранной строки
    pass

execute - Основная функция выполнения всех запросов, кроме select. Основные параметры функции:

Пример использования:

from omlibs.v1 import (
    pg,
    Checks
)
# Предполагается, что значение фильтра по orbis_id, а также коды карты и слоя уже известны и получены 
# Проверка полученных данных
map_code = "map"
layer_code = "azs"
oid = 5
kwargs = {
    'args': {
        'map': Checks.check_str(map_code, "код карты"),
        'layer': Checks.check_str(layer_code, "код слоя"),
        'orbis_id': Checks.check_int(oid, "orbis_id"),
        'label': 'АЗС новая'
    },
    'ddl': ['map', 'layer'],
    'msg': 'Ошибка изменения данных в "%s"."%s"' % (map_code, layer_code)
}

pg().execute('''
    UPDATE %(*map)s.%(*layer)s
    SET label = %(label)s
    WHERE orbis_id = %(orbis_id)s;
''', **kwargs)

OMSAPI

Библиотека, инкапсулирующая работу с ORBISMap REST API, и предоставляющая класс работы с REST API OMSApi. Данный класс представляет высокоуровневые функции работы с сущностями ORBISMap. В настоящий момент реализованы следующие функции:

get_token - Получить токен авторизации пользователя для работы с ORBISMap REST API. Параметры функции:

Пример использования:

from omlibs.v1 import (
    OMSApi,
    GLog,
)

login = "user"

GLog.debug('Получение токена авторизации пользователя')
oms_api = OMSApi()
token = oms_api.get_token(login)
# Использование ORBISMap REST API с полученным токенм

get_layer - Получить модель слоя. Параметры функции:

Пример использования:

from omlibs.v1 import (
    OMSApi,
    GLog,
)

map_code = "map"
layer_code = "azs"

GLog.debug('Выполнение REST API выборки данных')
oms_api = OMSApi()
layer = oms_api.get_layer(map_code, layer_code)
# Выполнение операций с полученной моделью слоя

get_layer_objects - Получить список объектов слоя. Параметры функции:

Пример использования:

from omlibs.v1 import (
    OMSApi,
    GLog,
)

map_code = "map"
layer_code = "azs"
fields_codes = "name,description"

GLog.debug('Выполнение REST API выборки данных')
oms_api = OMSApi()
objects = oms_api.get_layer_objects(map_code, layer_code, fields_codes)
# Выполнение операций с полученными объектами слоя

get_layer_object - Получить информацию по объекту слоя. Параметры функции:

Пример использования:

from omlibs.v1 import (
    OMSApi,
    GLog,
)

map_code = "map"
layer_code = "azs"
object_id = 1

GLog.debug('Выполнение REST API выборки данных')
oms_api = OMSApi()
object_data = oms_api.get_layer_object(map_code, layer_code, object_id)
# Выполнение операций с полученным объектом слоя

edit_layer_object - Изменить объект слоя. Параметры функции:

Пример использования:

from omlibs.v1 import (
    OMSApi,
    GLog,
)

map_code = "map"
layer_code = "azs"
object_id = 1

GLog.debug('Выполнение REST API выборки данных')
oms_api = OMSApi()
object_data = oms_api.get_layer_object(map_code, layer_code, object_id)
# Выполнение операций с полученным объектом слоя
object_data["fields"]["name"] += " (new)"
GLog.debug('Выполнение REST API сохранения данных')
oms_api.edit_layer_object(map_code, layer_code, object_data["id"], object_data)

import_layer - Выполнить импорт данных в слой. Параметры функции:

В настоящий момент поддерживается импорт в слой, через передачу файл в теле POST-запроса, таким образом есть ограничение на размер файла для импорта.

Пример использования:

import requests

from omlibs.v1 import (
    OMSApi,
    GLog,
)

map_code = "map"
layer_code = "azs"

GLog.debug('Скачивание файлов со сторонних ресурсов')
url = 'https://oms-tests.orbismap.com/static/media/_py_scripts_test/azs.csv'
r = requests.get(url)
# важно сохранять файлы можно только в темповую директорию
file_path = "/tmp/azs123.csv"
with open(file_path, "wb") as code:
    code.write(r.content)

GLog.debug('Выполнение REST API изменения данных (импорт)')
res = oms_api.import_layer(map_code, layer_code, file_path)
GLog.debug(res)

Variables

Библиотека, инкапсулирующая работу с переменными окружения работы скриптов ORBISMap, и предоставляющая класс работы с переменными Variables. Данный класс представляет высокоуровневые функции работы с переменными окружения и предоставляем следующие функции:

get_var - gолучить значение конкретной переменной по имени. Параметры функции

vars - cвойство-словарь переменных окружения скрипта

Пример использования:

from omlibs.v1 import (
    Variables,
    GLog,
)

variables = Variables()

# Получаем текущие значения переменных
cur_vars = variables.vars
for item in cur_vars.items():
    # Проводится анализ имеющихся переменных
    pass

# Модифицируем текущие значения переменных
cur_vars = dict()
cur_vars['str1'] = 'String Value 1'
cur_vars['int1'] = 100500
cur_vars['float1'] = 100.5
cur_vars['bool1'] = True
cur_vars['list1'] = ['str', 100500, 100.5, False]
cur_vars['dict1'] = {
    'k1': 'v1',
    'k2': 100,
    'k3': 1.5,
    'k4': True,
    'k5': ['s', 1, 0.5, False],
    'k6': {'kk1': 'vv1'},
}
# Сохраняем новые значения переменных
variables.vars = cur_vars

GLog

Библиотека, инкапсулирующая работу с логированием процесса выполнения скриптов в ORBISMap, и предоставляющая класс работы с логами GLog. Данный класс представляет высокоуровневые функции работы с сущностями ORBISMap. В настоящий момент реализованы следующие функции:

Пример использования:

from omlibs.v1 import (
    GLog,
)

GLog.info('Информации')
GLog.debug('Отладка')
GLog.warning('Предупреждение')
GLog.error('Ошибка')
# Для логирования исключений лучше использовать GLog.exception
try:
    1/0
except Exception as e:
    GLog.exception(e)

Checks

Библиотека, инкапсулирующая базовые проверки переменных, и предоставляющая класс работы с проверками Checks. Данный класс представляет следующие функции проверок:

check_str - Функция проверок строк. Проверяет, что переданный параметр является валидной строкой, в случае несоответствия возбуждает исключение. Параметры функции:

check_int - Функция проверок целых чисел. Проверяет, что переданный параметр является валидным целым числом, в случае несоответствия возбуждает исключение. Параметры функции:

check_float - Функция проверок вещественных чисел. Проверяет, что переданный параметр является валидным вещественным числом, в случае несоответствия возбуждает исключение. Параметры функции:

check_bool - Функция проверки булевых переменных. Осуществляет приведение переданного параметра к булевому типу. Параметры функции: