Подпроцесс Django в режиме реального времени / небуферизованный отчет о stdout из пакетных скриптов - PullRequest
1 голос
/ 19 ноября 2010

По сути, история состоит в том, что я создал отбор сценариев Python для клиента для обработки импорта и экспорта пакетных заданий между базой данных их операций и базой данных сайта ecomms.это отлично работаетэти сценарии пишут в stdout, чтобы обновить пользователя в статусе пакетного сценария.

Я пытаюсь создать основу для этих сценариев, которые будут запускаться через представление django, и разместить stdout на веб-странице дляпоказать пользователю ход выполнения этих пакетных процессов.

план был - вызвать пакетный скрипт как подпроцесс и затем сохранить stdout и stderr в файл.- вернуть перенаправление на страницу отображения, которая будет перезагружаться каждые 2 секунды, и построчно отображать содержимое файла, в который записывается стандартный вывод.

однако проблема в том, что файл stdout / stderr нена самом деле выполняется запись до тех пор, пока весь пакетный скрипт не завершит работу или не произойдет ошибка.

Я пробовал несколько вещей, но, похоже, ни одна из них не работает.

Вот код текущего представления.

def long_running(app, filename):
    """where app is ['command', 'arg1', 'arg2'] and filename is the file used for output"""
    # where to write the result (something like /tmp/some-unique-id)
    fullname = temppath+filename
    f = file(fullname, "a+")
    # launch the script which outputs something slowly
    subprocess.Popen(app, stdout=f, stderr=f)# .communicate()
    # once the script is done, close the output
    f.close()

def attributeexport(request):
    filename = "%d_attribute" %(int(time.time())) #set the filename to be the current time stamp plus an identifier
    app = ['python','/home/windsor/django/applications/attribute_exports.py']
    #break thread for processing.
    threading.Thread(target=long_running, args=(app,filename)).start()
    return HttpResponseRedirect('/scripts/dynamic/'+filename+'/')
    pass

def dynamic(request, viewfile):
    fileobj = open(temppath+viewfile, 'r')
    results = []
    for line in fileobj:
        results.append(line)
        if '~END' in line:
            #if the process has completed
            return render_to_response('scripts/static.html', {'displaylist':results, 'filename':viewfile})
    return render_to_response('scripts/dynamic.html', {'displaylist':results, 'filename':viewfile})
pass

1 Ответ

1 голос
/ 23 ноября 2010

Помогает, если вы используете следующее:

['python','-u','path/to/python/script.py']
...