Использование декоратора @use в bonobo

#python #python-decorators #bonobo-etl

#python #python-декораторы #bonobo-etl

Вопрос:

В документации bonobo у них есть следующий пример настройки зависимости от службы:

 from bonobo.config import use
@use('orders_database')
def select_all(database):
yield from database.query('SELECT * FROM foo;')
  

Я попытался сделать что-то подобное и получил сообщение об ошибке. Вот очень упрощенная версия моего скрипта:

 import bonobo
from bonobo.config import use
from ftplib import FTP

def get_services(**options):
    ftp_1 =  FTP('ftp.gnu.org')
    ftp_1.login()
    ftp_1.cwd('gnu/emacs')
    return{
        'ftp1': ftp_1,
    }

@use('ftp1')
def listen_for_file(ftp):
    test = ftp.nlst('README.olderversions')
    if test:
        print( 'Found file')
        return True
    else:
        print('File not found in ftp')
        return False

def get_graph(**options):
    graph = bonobo.Graph()
    graph.add_chain(listen_for_file)
    return graph

if __name__ == '__main__':
    parser = bonobo.get_argument_parser()
    with bonobo.parse_args(parser) as options:
        bonobo.run(get_graph(**options), services=get_services(**options))
  

Если я попытаюсь запустить это, я получу следующую ошибку:

КРИТИЧЕСКИЙ:bonobo.execution.contexts.base:<NodeExecutionContext( listen_for_file) in=1 ошибка =1> Трассировка (последний последний вызов): Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 102, в файле call bound = self._bind(_input) «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 89, в _bind возвращаетпривязать (* self.args, *_input, ** self.kwargs) файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libinspect.py «, строка 3015, в привязке возвращает args[0]._bind(args[1:], kwargs) Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libinspect.py «, строка 2930, в _bind поднять TypeError(msg) из None TypeError: отсутствует обязательный аргумент: ‘ftp’

Приведенное выше исключение было прямой причиной следующего исключения:

Обратная трассировка (последний последний вызов): Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboexecutioncontextsnode.py» , строка 102, в файле loop self.step() «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboexecutioncontextsnode.py» , строка 129, в результатах шага = self._stack(input_bag) Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 114, в вызове) из exc bonobo.ошибки.Ошибка неисправимого типа: ввод <функция listen_for_file в 0x000002A591047F78> не привязывается к подписи узла. Аргументы: () Ввод: () Kwargs: {‘ftp1’:FTP-объект в 0x000002A5910CF708>} Подпись: (ftp)

Единственный способ запустить его — это изменить ftp на ftp1 в функции listen_for_file. Что я здесь делаю не так?

Комментарии:

1. > Единственный способ запустить его — это изменить ftp на ftp1 в функции listen_for_file. Да, это звучит разумно для меня. Потому что имя ссылки должно совпадать с тем, о чем я думаю.

2. @FonyLew, значит, он работает так, как задумано? Потому что пример, который я привел со страницы документации, имеет разные имена (‘orders_database’ в use decorator и ‘database’ в определении функции).

Ответ №1:

bonobo строго относится к именованию переменных, хотя этого не должно быть.

Для использования config.use лучше использовать точное имя службы в сигнатуре функции и сохранить его в качестве последнего параметра.

Чтобы изменить фактического поставщика услуг, который вы хотите использовать, вам необходимо изменить карту в вашей get_services функции.

 import bonobo
from bonobo.config import use
from ftplib import FTP

def get_services(**options):
    ftp_1 =  FTP(options.get('ftp_server') or 'ftp.gnu.org')
    ftp_1.login()
    ftp_1.cwd('gnu/emacs')
    return{
        'ftp': ftp_1,
    }

@use('ftp')
def listen_for_file(ftp):
    test = ftp.nlst('README.olderversions')
    if test:
        print( 'Found file')
        return True
    else:
        print('File not found in ftp')
        return False

def get_graph(**options):
    graph = bonobo.Graph()
    graph.add_chain(listen_for_file)
    return graph

if __name__ == '__main__':
    parser = bonobo.get_argument_parser()
    parser.add('--ftp_server')
    with bonobo.parse_args(parser) as options:
        bonobo.run(get_graph(**options), services=get_services(**options))
  

Комментарии:

1. Спасибо, @PyGuy, это делает то, что я хочу.