Автоматизация, Программирование

Вызов скриптов и библиотек на других языках

Время прочтения: 3 мин.

Вряд ли начинающий кодер будет допущен до какой-то уникальной задачи, следовательно, вероятность найти готовое или похожее решение совсем ненулевая. Но здесь тебя могут подстерегать «грабли» — решение может быть на другом языке.

Получается, готовое решение любой задачи можно загуглить?

И что тогда? Учить 100500 языков?

Python позволяет осуществлять вызовы скриптов и библиотек на других языках. И для этого не обязательно их учить, главное – понимать, что подавать на вход и что ты получишь на выходе. Как раз похожий кейс возник и у нас.

И в чем заключался кейс?

При решении задачи по анализу диалогов клиентов и брокеров, для получения информации по полу и возрасту клиента, нужно было получить спектральные и частотные результаты обработки аудио файлов в конкретном виде. Усиленное гугление выдало, что результаты в данном виде могут быть получены после обработки аудио с помощью функции specan языка R. Прямого аналога данной функции в Python опознано не было, возможные варианты получения аналогичных данных с помощью Фурье навевали тоску. Дальнейший поиск выдал решение — запускаем функции R напрямую из Python. Способов такого запуска существует несколько: можно использовать специализированные библиотеки или осуществить исполнение скриптов с помощью командной строки (command line tools) + промежуточное хранение файлов на диске (filling air gap).

И как конкретно был решен вопрос?

Мы выбрали command line tools, так как для этого не требовалась установка дополнительных модулей и их настройка:

1) Заюзаем builtin модуль Python subprocess, с его помощью запускаем процесс, через который вызываем запуск скрипта на R.

import subprocess

def r_spec(command='Rscript', duration, path, temp, path2script):
        ''' command - команда запуска скрипта R
            duration - продолжительность файла в секундах
            path - путь где лежат файлы для анализа './data/voice/clips/'
            temp - путь для записи csv файла './data/tmpcsv/'
            path2script - путь до скрипта на R './R/spectr.R'
        ''' 
	cmd = [command, path2script] + [name, duration, path, temp]
        p = subprocess.Popen(cmd, 
                             stdin=subprocess.PIPE, 
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE, 
                             shell=True)

2) Запущенный скрипт на R осуществляет обработку аудио в части снятия аудиохарактеристик файла и их записи в файл «data.csv» с использованием библиотек warbleR и tuneR. Передача параметров в скрипт R осуществляется через аргументы как при вызове файла из командной строки.

library(warbleR)
library(tuneR)
# передача параметров в скрипт R через аргументы как при вызове файла из командной строки
# args[1] - имя файла для анализа - вида common_voice_ru_18849003_0_0.wav 
# args[2] - продолжительность файла в секундах
# args[3] - путь где лежат файлы для анализа /data/voice/clips
# args[4] - путь для записи csv файла - os.getcwd() + '/data/tmpcsv/'
options(echo = F)
args <- commandArgs(trailingOnly = T) 
dataframe <- data.frame(args[1], 2, 1, as.numeric(args[2]))

# обработка файлов функциями specprop и specan
b <- specprop(spec(readWave(paste0(args[3], args[1])), f = 16000, plot = F))
names(dataframe) <- c("sound.files", "selec", "start", "end")
a <- specan(X = dataframe, bp = c(0,29), wl = 512, wl.freq = NULL, threshold = 15, parallel = 1, fast = TRUE, path = args[3], pb = F, ovlp = 50, ff.method = "seewave", wn = "hanning", fsmooth = 0.1)

# формирование датафрейма из результатов и запись датафрейма в csv
dataframe_2 <- data.frame(a, b)
write.table(dataframe_2, file = paste0(args[4], "data_test.csv"), sep = ",", append = T, row.names = F, col.names = F)

На выходе в папке «./data/tmpcsv/» получаем файл csv, в котором записаны аудиохарактеристики файлов, доступный для обработки в Python.

В итоге, мы выяснили, что из Python можно легко запустить скрипт на R и организовать обмен данными с помощью инструментов командной строки. Конечно, есть более продвинутые способы, в частности, взаимодействие с языком R можно производить с помощью библиотек rpy2 и reticulate. Но это уже совсем другая история…

Аналогично с помощью похожих инструментов можно организовать взаимодействие Python с любым другим языком программирования.

Советуем почитать