Solucionado (ver solução)
Solucionado
(ver solução)
10
respostas

Run Script

Boa noite, eu estou precisando rodar em python outros scripts, em perl, R, e qualquer outro, estou precisando ter algum tipo de feedback quando rodo esses scritps, por exemplo: arquivo x criado, coluna não encontrada, script executado com sucesso, qual seria a melhor abordagem de realizar esse processo de feedback? Usar prints no console? Escrever esses feedbacks em 1 txt e depois ler o mesmo ?

Também tenho duvidas se é possivel fazer isso em tempo real, antes do script terminar sua execução completa.

obs: estou usando o Popen do python para rodar o script

10 respostas

Olá Thiago, boa noite! Você pode usar prints no console ou escrever um código para salvar em um arquivo como você disse.

O python possui um módulo chamado logging para isso. Ele possui um método específico para mostrar cada tipo de mensagem.

import logging

logging.debug('mensagem de debug')
logging.info('mensagem de informação')
logging.warning('mensagem de alerta')
logging.error('mensagem de erro')
logging.critical('mensagem crítica')

Por padrão, ele não mostra as mensagens de debug e info. Se você quiser mostrar a de debug, por exemplo, faça:

logging.basicConfig(level=logging.DEBUG)
logging.debug('mensagem de debug')

e ela aparecerá no console.

O legal é que você pode configurá-lo para salvar as mensagens em um arquivo. Se o arquivo não existir, ele cria. Basta fazer:

import logging

logging.basicConfig(filename='arquivo.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('isto será salvo em um arquivo')

Espero ter ajudado e bons estudos!

Boa noite Thais, mas como faço isso se vou dentro do python rodar um script em Perl, ou R, ou outra linguagem e no python saber se esse script correu bem, este caso do logging, não será útil certo ?

A minha dúvida foi clara ?

Olá Thiago, agora entendi melhor sua pergunta. Imagino que você tenha algo parecido com o código abaixo para ler um script em Perl:

from subprocess import Popen,

meu_script = Popen(['perl', 'script.pl'], stdout=PIPE, stderr=STDOUT)

Você pode criar um função log_subprocess() que mostra as saídas de seu script:

from subprocess import Popen, PIPE, STDOUT
import logging

logging.basicConfig(level=logging.INFO)

def log_subprocess(pipe):
    for line in pipe.readlines():
        logging.info('msg de log do script: %r', line)

meu_script = Popen(['perl', 'script.pl'], stdout=PIPE, stderr=STDOUT)

log_subprocess(meu_script.stdout)

No caso, a função vai mostrar todas as saídas do script, não diferenciando se são mensagens de log ou não, mas você pode acrescentar um tratamento para que isso aconteça (e dependendo de cada script). Caso queira salvar em um arquivo, você pode usar o próprio módulo logging do python que usamos para mostrar a mensagem e que eu comentei na outra resposta.

Espero ter ajudado e bons estudos!

Mas no caso o só é possível ver o logging depois do Popen terminar correto ?

Neste caso sim, não sei se é possível e desconheço como fazer isso enquanto roda o script. Qual o motivo de fazer isso em tempo de execução de um script?

O motivo foi que pediram pra fazer se possível, já pesquisei e não encontrei nada, ai vim buscar com os magos da alura né ;D.

Se não funciona tá tudo bem, eu verifico após o termino de cada script.

Mas o motivo principal do feedback é que vou fazer uma requisição ajax, para um webserver feito por mim em Django com o DRF, dai o que vou enviar pro server são várias instruções e preciso manter um feedback constante para o usuário que o script ocorreu tudo bem ou não

solução!

Entendi. Então, Thiago, eu dei uma pesquisada aqui e acredito que dessa maneira funcione. Ao invés de chamar pipe.readlines(), podemos usar apenas readline que vai bloquear o processo até a linha ser escrita:

from subprocess import Popen, PIPE, STDOUT, call
import logging

logging.basicConfig(level=logging.INFO)

with open('arquivo.log', 'w') as arquivo:
    process = Popen(['perl', 'script.pl'], stdout=PIPE, stderr=STDOUT)
    for line in iter(process.stdout.readline, b''):
        logging.info('msg de log script: %r', line)
        arquivo.write(str(line))

Ah, e adaptei para ele escrever em um arquivo de log chamado arquivo.log.

Só pra enttender, o for, só vai ser executado apos o script terminar, certo ? dai eu posso ver o 'arquivo.log' né ?

Eu n deveria ter um 'process.waitt()' ?

Boa Thiago, é isso mesmo!

Ok, obrigado por tudo!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software