Примеры Python скриптов

Примеры построены на основе демо-данных. Для полноценной работы необходимо сначала установить демо данные, а также библиотеку requests и pandas (sudo apt install python3-pip && pip3 install requests && pip3 install pandas).

  1. Следующий пример получает токен авторизации, затем отправляет запрос данных в ViQube, а после этого передаёт полученные данные на виджет. Этот код можно использовать, например, для гистограммы:

    import requests
     
    host = 'http://bitest.example.com'  # Адрес сервера ViQube
    login = 'admin'  # Логин администратора
    password = '***'  # Пароль
     
    # Запрос токена авторизации
    token_url = f'{host}/idsrv/connect/token' #URL для POST-запроса
    token_data = {'grant_type': 'password', 'scope': 'openid profile email roles viqubeadmin_api viqube_api',
                  'response_type': 'id_token token', 'username': login, 'password': password} #Данные для POST-запроса
    token_headers = {'authorization': 'Basic dmlxdWJlYWRtaW5fcm9fY2xpZW50OjcmZEo1UldwVVMkLUVVQE1reHU=',
                     'content-type': 'application/x-www-form-urlencoded'} #Заголовки для POST-запроса
     
    token_response = requests.post(url=token_url, headers=token_headers, data=token_data).json() #POST-Запрос на получение токена
     
    bearer_token = 'Bearer ' + token_response['access_token'] #Значение токена авторизации для дальнейших запросов в ViQube
     
    # Запрос данных в ViQube
    query_url = f'{host}/viqube/metadata/query'#URL для POST-запроса
    query_headers = {'authorization': bearer_token, 'X-API-VERSION': '3.4',   #Чтобы узнать X-API-VERSION перейдите по адресу http://ip/viqube/version
                     'content-type': 'application/json; charset=utf-8'} #Заголовки для POST-запроса
    #JSON для получения данных из ViQube
    query_json = {
        "database": "ViQube",
        "groups": [
            {
                "mgid": "Fakticheskie_prodazhi__rubli",  #Группа показателей "Фактические продажи - рубли"
                "attributes": [
                    {
                        "dimroleid": "Gorod_dostavki",   #Атрибут "Город доставки" в строках
                        "attrid": "__attr_Goroda",
                        "axis": "ROW"
                    },
                    {
                        "dimroleid": "Gorod_prodazhi",   #Атрибут "Город продажи" в столбцах
                        "attrid": "__attr_Goroda",
                        "axis": "COLUMN"
                    }
                ],
                "measures": [
                    {
                        "mid": "Price"					 #Показатель "Стоимость продажи"	
                    }
                ],
                "filters": [
                    [
                        {
                            "attrid": "Category",        #С фильтром по измерению "Продукты" на категорию "Консервы"
                            "dimid": "Produkti",
                            "type": "INCLUDE",
                            "values": [
                                "Консервы"
                            ]
                        }
                    ]
                ]
            }
        ]
    }
     
    query_response = requests.post(url=query_url, headers=query_headers, json=query_json).json() #POST-запрос в ViQube
     
    #Передача данных на виджет
    #-Гистограмма-
    my_chart = DataFrame()
    my_chart.cols = query_response['columns']
    my_chart.rows = query_response['rows']
    my_chart.values = [list(x) for x in zip(*query_response['values'])] #Значения, полученные от ViQube необходимо транспонировать
    
    
  2. Следующий пример отличается от предыдущего тем, что после получения данных из ViQube строится объект Pandas, затем производится фильтрация в Pandas и после этого данные передаются на виджет. Этот код можно использовать, например, для сводной таблицы:

    import requests
    import pandas
     
    host = 'http://bitest.example.com'  # Адрес сервера ViQube
    login = 'admin'  # Логин администратора
    password = '***'  # Пароль
     
    # Запрос токена авторизации
    token_url = f'{host}/idsrv/connect/token' #URL для POST-запроса
    token_data = {'grant_type': 'password', 'scope': 'openid profile email roles viqubeadmin_api viqube_api',
                  'response_type': 'id_token token', 'username': login, 'password': password} #Данные для POST-запроса
    token_headers = {'authorization': 'Basic dmlxdWJlYWRtaW5fcm9fY2xpZW50OjcmZEo1UldwVVMkLUVVQE1reHU=',
                     'content-type': 'application/x-www-form-urlencoded'} #Заголовки для POST-запроса
     
    token_response = requests.post(url=token_url, headers=token_headers, data=token_data).json() #POST-Запрос на получение токена
     
    bearer_token = 'Bearer ' + token_response['access_token'] #Значение токена авторизации для дальнейших запросов в ViQube
     
    # Запрос данных в ViQube
    query_url = f'{host}/viqube/metadata/query'#URL для POST-запроса
    query_headers = {'authorization': bearer_token, 'X-API-VERSION': '3.4',   #Чтобы узнать X-API-VERSION перейдите по адресу http://ip/viqube/version
                     'content-type': 'application/json; charset=utf-8'} #Заголовки для POST-запроса
    #JSON для получения данных из ViQube
    query_json = {
        "database": "ViQube",
        "groups": [
            {
                "mgid": "Fakticheskie_prodazhi__rubli",      #Группа показателей "Фактические продажи - рубли"
                "attributes": [
                    {
                        "dimroleid": "Gorod_dostavki",       #Атрибут "Город доставки" в строках
                        "attrid": "__attr_Goroda",
                        "axis": "ROW"
                    },
                    {
                        "dimroleid": "Gorod_prodazhi",       #Атрибут "Город продажи" в столбцах
                        "attrid": "__attr_Goroda",
                        "axis": "COLUMN"
                    }
                ],
                "measures": [
                    { 
                        "mid": "Price"                       #Показатель "Стоимость продажи"
                    }
                ],
                "filters": [
                    [
                        {
                            "attrid": "Category",             #С фильтром по измерению "Продукты" на категорию "Консервы"
                            "dimid": "Produkti",
                            "type": "INCLUDE",
                            "values": [
                                "Консервы"
                            ]
                        }
                    ]
                ]
            }
        ]
    }
     
    query_response = requests.post(url=query_url, headers=query_headers, json=query_json).json() #POST-запрос в ViQube
     
    rows = list(map(lambda i: i[0], query_response['rows'])) #Для формирования индексов DataFrame в Pandas требуется массив, а данные от викуб возвращаются как массив массивов
    columns = list(map(lambda i: i[0], query_response['columns'])) #Для формирования заголовков DataFrame в Pandas требуется массив, а данные от викуб возвращаются как массив массивов
    values = query_response['values']
     
    pandas_table = pandas.DataFrame(values, index=rows, columns=columns) #Создание Pandas DataFrame
    pandas_table = pandas_table[pandas_table.Иркутск > 700000] #Фильтр на данные: стоимость реализации товаров в Иркутск > 700000р.
     
    columns = [[x] for x in list(pandas_table)] #Для передачи колонок на виджет требуется массив массивов, а в Pandas это массив
    rows = [[x] for x in list(pandas_table.index)] #Для передачи строк на виджет требуется массив массивов, а в Pandas это массив
    values = pandas_table.T.to_numpy().tolist() #Для передачи значений на виджет требуется массив массивов, а в Pandas иной формат
     
    #Передача данных на виджет
    #-Сводная таблица-
    my_chart = DataFrame()
    my_chart.cols = columns
    my_chart.rows = rows
    my_chart.values = values
    
  3. Пример влияния OLAP-фильтра на запрос данных в ViQube. Для выполнения данного кода на дашборде помимо виджета "Гистограмма" необходим виджет фильтр с названием "Фильтр 1", значениями которого являются годы (например, через привязку в Viqube к измерению "Календарь" без группы показателей), фильтр может быть как обычным, так и множественным. Добавьте этот код к виджету "Гистограмма" и в "Фильтре 1" выберите год "2016"

    import requests
     
    host = 'http://bitest.example.com'  # Адрес сервера ViQube
     
    bearer_token = 'Bearer ' + ACCESS_TOKEN # ACCESS_TOKEN - специальная переменная, содержащая текущий токен авторизации
     
    filter_name = 'Фильтр 1' # Название фильтра
     
    #-Гистограмма-
    my_chart = DataFrame()
     
    for olap_filter in olap_filters: # Цикл перебирает все фильтры на дэшборде
        if olap_filter.title == filter_name: # Выбирает фильтр с заданным именем
            selected_values = olap_filter.selected # Отбирает выбранные значения фильтра
            break
     
    filter_values = list(map(lambda i: i[0], selected_values)) # Преобразование массива массивов в массив для передачи в запрос
     
    # Отправка запроса на ViQube
     
    query_url = f'{host}/viqube/metadata/query'  # URL для POST-запроса
    query_headers = {'authorization': bearer_token, 'X-API-VERSION': '3.4',   #Чтобы узнать X-API-VERSION перейдите по адресу http://ip/viqube/version
                     'content-type': 'application/json; charset=utf-8'}  # Заголовки для POST-запроса
    query_json = {    # JSON
        "database": "ViQube",
        "groups": [
            {
                "mgid": "Fakticheskie_prodazhi__rubli",      #Группа показателей "Фактические продажи - рубли"
                "attributes": [
                    {
                        "dimroleid": "Data_pay",             #Атрибут "Дата продажи" в строках
                        "attrid": "YEAR",
                        "axis": "ROW"
                    },
                    {
                        "dimroleid": "Gorod_prodazhi",       #Атрибут "Город продажи" в столбцах
                        "attrid": "__attr_Goroda",
                        "axis": "COLUMN"
                    }
                ],
                "measures": [
                    {
                        "mid": "Pribil"                      #Показатель "Стоимость продажи"
                    }
                ],
                "filters": [
                    [
                        {
                            "dimroleid": "Data_pay",
                            "attrid": "YEAR",
                            "type": "INCLUDE",
                            "values": filter_values # Передача массива с выбранными в фильтре значениями
                        }
                    ]
                ]
            }
        ]
    }
     
    query_response = requests.post(url=query_url, headers=query_headers, json=query_json).json()  # POST-запрос в ViQube
     
    my_chart.cols = query_response['columns']
    my_chart.rows = query_response['rows']
    my_chart.values = [list(x) for x in zip(*query_response['values'])] #Значения, полученные от ViQube необходимо транспонировать
    
    
  4. Следующий пример отличается от предыдущего тем, что в ViQube запрашиваются все данные, без фильтра по годам, а сама фильтрация данных осуществляется на уровне Python-кода (добавлять на виджет "Гистограмма"):

    import requests
      
    host = 'http://bitest.example.com'  # Адрес сервера ViQube
      
    bearer_token = 'Bearer ' + ACCESS_TOKEN # ACCESS_TOKEN - специальная переменная, содержащая текущий токен авторизации
      
    filter_name = 'Фильтр 1' # Название фильтра
     
    #-Гистограмма-
    my_chart = DataFrame()
      
    for olap_filter in olap_filters: # Цикл перебирает все фильтры на дэшборде
        if olap_filter.title == filter_name: # Выбирает фильтр с заданным именем
            selected_values = olap_filter.selected # Отбирает выбранные значения фильтра
            break
             
    filter_values = list(map(lambda i: i[0], olap_filter.selected)) # Преобразование массива массивов в массив для передачи в запрос
      
    # Отправка запроса на ViQube
      
    query_url = f'{host}/viqube/metadata/query'  # URL для POST-запроса
    query_headers = {'authorization': bearer_token, 'X-API-VERSION': '3.4',  #Чтобы узнать X-API-VERSION перейдите по адресу http://ip/viqube/version
                     'content-type': 'application/json; charset=utf-8'}  # Заголовки для POST-запроса
    query_json = {    # JSON
        "database": "ViQube",
        "groups": [
            {
                "mgid": "Fakticheskie_prodazhi__rubli",       #Группа показателей "Фактические продажи - рубли"
                "attributes": [
                    {
                        "dimroleid": "Data_pay",              #Атрибут "Дата продажи" в строках
                        "attrid": "YEAR",
                        "axis": "ROW"
                    },
                    {
                        "dimroleid": "Gorod_prodazhi",        #Атрибут "Город продажи" в столбцах
                        "attrid": "__attr_Goroda",
                        "axis": "COLUMN"
                    }
                ],
                "measures": [
                    {
                        "mid": "Pribil"                       #Показатель "Стоимость продажи"
                    }
                ]
            }
        ]
    }
      
    query_response = requests.post(url=query_url, headers=query_headers, json=query_json).json()  # POST-запрос в ViQube
     
    cols_from_request = query_response['columns']
    rows_from_request = query_response['rows']
    values_from_request = query_response['values']
     
    cols = []
    rows = []
    values = []
     
    for value in filter_values: # Перебор выбранных значений фильтра
        for i in range(len(rows_from_request)): # Отбор строк со значениями из фильтра
            if rows_from_request[i][0] == value: # Здесь проверяется [0]й элемент, т.к. в ответе на запрос год стоит на 0й позиции, если бы города были тое в строках, проверялся бы [1]й элемент
                rows.append(rows_from_request[i])
                values.append(values_from_request[i])
    cols = cols_from_request
     
    values = [list(x) for x in zip(*values)] #Значения, полученные от ViQube необходимо транспонировать
     
    my_chart.cols = cols
    my_chart.rows = rows
    my_chart.values = values
    
    
  5. Следующий пример с помощью простой модели добавляет в данные прогноз на основе полученных из ViQube данных, лучше всего на основе этого кода построить виджет график. Требуется установка библиотеки scikit-learn: pip3 install scikit-learn

    import requests
    from sklearn.linear_model import LinearRegression
      
    host = 'http://bitest.example.com'  # Адрес сервера ViQube
      
    bearer_token = 'Bearer ' + ACCESS_TOKEN # ACCESS_TOKEN - специальная переменная, содержащая текущий токен авторизации
     
    # Отправка запроса на ViQube
      
    query_url = f'{host}/viqube/metadata/query'#URL для POST-запроса
    query_headers = {'authorization': bearer_token, 'X-API-VERSION': '3.4',    #Чтобы узнать X-API-VERSION перейдите по адресу http://ip/viqube/version
                     'content-type': 'application/json; charset=utf-8'} #Заголовки для POST-запроса
    #JSON для получения данных из ViQube
    query_json = {    # JSON
        "database": "ViQube",
        "groups": [
            {
                "mgid": "Fakticheskie_prodazhi__rubli",      #Группа показателей "Фактические продажи - рубли"
                "attributes": [
                    {
                        "dimroleid": "Data_pay",             #Атрибут "Дата продажи" в строках
                        "attrid": "YEAR",
                        "axis": "ROW"
                    }
                ],
                "measures": [
                    {
                        "mid": "Pribil"                      #Показатель "Стоимость продажи"
                    }
                ]
            }
        ]
    }
     
    query_response = requests.post(url=query_url, headers=query_headers, json=query_json).json() #POST-запрос в ViQube
     
    rows = query_response['rows']
    cols_done = [['Факт'], ['Прогноз']]
    values = query_response['values']
     
    predict_years = [] # Переменная для годов прогноза
     
    for i in range(len(rows)):
        rows[i][0] = int(rows[i][0]) # Преобразование годов из строк в числа, т.к. для модели необходим тип int, а в ответе на запрос приходят строки
        predict_years.append(rows[i]) # Заполнение годов прогноза
     
    predict_years.append([int(rows[-1][0])+1])
    predict_years.append([int(rows[-1][0])+2]) # Добавление двух лет для прогноза
     
    model = LinearRegression()
    model.fit(rows, values) # Обучение модели
    predict_target = model.predict(predict_years) # Создание прогноза
     
    values.append([None])
    values.append([None]) # Корректировка значений из-за добавления двух годов
     
    values_done = []
     
    values_done.append(list(map(lambda i: i[0], values)))
     
    predict_target = list(map(lambda i: i[0], predict_target))
     
    values_done.append(predict_target) # Добавление колонки с прогнозом к значениям
     
    for i in range(len(predict_years)):
        predict_years[i][0] = str(predict_years[i][0])
     
    rows_done = predict_years
     
    #Передача данных на виджет
    #-Гистограмма-
    my_chart = DataFrame()
    my_chart.cols = cols_done
    my_chart.rows = rows_done
    my_chart.values = values_done