i'm writing a simple gui script A which is calling another script B in it. Scrip B has subprocess in it which takes some time. I would like to print something like "processing..." in one of the labels on that gui and that print should be there until subprocess from script B is finished. How i can do that?
edit:
If i should have to listen for termination of subprocess of script A from script A i would simply name that process (i.e p) and check its p.poll(). Since that subprocess is product of antorher script B, i thought if i could name that process and import that script B in script A and then check for p.poll. But i faced another problem, i couldn't import script B to A. The steps i was doing were from:
Importing variables from another file?
Every time i got message that there is no such file. Fortunately at the end i found another way around to achieve what i wanted.
I would split this task into two stages:
get subprocess PID.
check whether PID is still running.
Related
I'm developing a Python code that can run two applications and exchange information between them during their run time.
The basic scheme is something like:
start a subprocess with the 1st application
start a subprocess with the 2nd application
1st application performs some calculation, writes a file A, and waits for input
2nd application reads file A, performs some calculation, writes a file B, and waits for input
1st application reads file B, performs some calculation, writes a file C, and waits for input
...and so on until some condition is met
I know how to start one Python subprocess, and now I'm learning how to pass/receive information during run time.
I'm testing my Python code using a super-simple application that just reads a file, makes a plot, closes the plot, and returns 0.
I was able to pass an input to a subprocess using subprocess.communicate() and I could tell that the subprocess used that information (plot opens and closes), but here the problems started.
I can only send an input string once. After the first subprocess.communicate() in my code below, the subprocess hangs there. I suspect I might have to use subprocess.stdin.write() instead, since I read subprocess.communicate() will wait for the end of the file and I wish to send multiple times different inputs during the application run instead. But I also read that the use of stdin.write() and stdout.read() is discouraged. I tried this second alteranative (see #alternative in the code below), but in this case the application doesn't seem to receive the inputs, i.e. it doesn't do anything and the code ends.
Debugging is complicated because I haven't found a neat way to output what the subprocess is receiving as input and giving as output. (I tried to implement the solutions described here, but I must have done something wrong: Python: How to read stdout of subprocess in a nonblocking way, A non-blocking read on a subprocess.PIPE in Python)
Here is my working example. Any help is appreciated!
import os
import subprocess
from subprocess import PIPE
# Set application name
app_folder = 'my_folder_path'
full_name_app = os.path.join(app_folder, 'test_subprocess.exe')
# Start process
out_app = subprocess.Popen([full_name_app], stdin=PIPE, stdout=PIPE)
# Pass argument to process
N = 5
for n in range(N):
str_to_communicate = f'{{\'test_{n+1}.mat\', {{\'t\', \'y\'}}}}' # funny looking string - but this how it needs to be passed
bytes_to_communicate = str_to_communicate.encode()
output_communication = out_app.communicate(bytes_to_communicate)
# output_communication = out_app.stdin.write(bytes_to_communicate) # alternative
print(f'Communication command #{n+1} sent')
# Terminate process
out_app.terminate()
I have 2 different python scripts, the first called main.py and the second called running.py
the main.py script is the following:
#setting things up and stuff
while True:
#stuff
Here running.py should be started
#stuff
while running.py contains the following
#various imports
while True:
#stuff
My question is, how can i run running.py from main.py as a new thread knowing only the name of the running script?
I looked a bit into it and, since i need to communicate and share data between main.py and running.py, I don't think creating a subprocess is the best course of action but I haven't found a way to run a whole script in a thread only knowing the script's name.
For various (stupid) company reasons I can't change the content of running.py and i can't import it into main.py so creating a threading class inside it is not a possibility but i have free rein on main.py
Is what i'm trying to do even possible?
More than a month ago I've added this script to my startup applications. It worked just like it should, every single time.
Now, for some reason, it's not working every single time (primarily it's not working every single time in the morning, there are different variations now).
I've changed the interpreter, shortened paths - it didn't help. And when nothing happens, after (and before) typing a command to find all working python processes
ps -fA | grep python
this process is there.
I'm on Linux Mint 18.3 MATE. Thanks.
#! /usr/bin/python3
"""My Alarms."""
import schedule
import time
import webbrowser
import subprocess
def breakfast():
"""Breakfast reminder."""
subprocess.Popen(['notify-send', 'TIME TO EAT BREAKFAST'])
webbrowser.open('/path_to/carbon.ogg')
def dinner():
"""Dinner reminder."""
subprocess.Popen(['notify-send', 'TIME TO MAKE A DINNER'])
webbrowser.open('/path_to/carbon.ogg')
def shut_down():
"""Shut Down (Laptop) reminder."""
subprocess.Popen(['notify-send', 'TIME TO SHUT DOWN THE PC'])
webbrowser.open('/path_to/carbon.ogg')
schedule.every().day.at("07:35").do(breakfast)
schedule.every().day.at("17:10").do(dinner)
schedule.every().day.at("21:00").do(shut_down)
while True:
schedule.run_pending()
time.sleep(1)
Turns out, I haven't met requirements for the schedule module. Some of these modules were updated, some were missing. Now it's working like it used to be. Case closed.
Hi everyone i am trying to build a file watcher in python 3.5 using watchgod. I want to continuously watch a directory and if any file is added then i want to send a list of added files to another program which will perform a series of task. Following is my code in python :-
print("execution of main file begins !!!!")
import os
from watchgod import watch
#changes gives a set object when watch finds any kind of changes in directory
for changes in watch(r'C:\Users\Rajat.Malik\Desktop\Requests'):
fileStatus = [obj[0] for obj in list(changes) ] #converting set to list which gives file status as added, changed or modified
fileLocation = [obj[1] for obj in list(changes) ] #similarly getting list of location of files added
var2 = 0
for var1 in fileLocation:
if fileStatus[var2] == 1: #if file is added then passing all files to another code which will work on the list of files added
os.system('python split_thread_module.py '+var1) #now this code will start executing
var2 = var2 + 1
So the problem i am having is that while split_thread_module.py is executing the watcher is not watching the directory. Any file which is coming at time when split_thread_module.py is executing is not reflecting in changes. How can i watch the changes in directory and pass it to the other program on the fly even when the other program is executing. I am not a python programmer. Can anyone help me in this regard ?
Thanks in advance !!!!
Sorry for delayed, I'm the developer of watchgod. I've added a python-watchgod tag to your question which I'll watch (no pun intended) in future so I can answer such questions more quickly.
To answer your question, watchgod will not miss changes which occur in the filesystem while other code is running. They'll just be reported as changes next time watch iterates.
More generally the best approach would be to run the other code asynchronously so the main process can get back to watching the directory.
a few other hints for neater python
no need to call list(changes) in the comprehension
os.system is deprecated, better to use subprocess.run
since split_thread_module.py is also python, do you really need to run it in a separate process? Even if you do you might have more luck with python multiprocessing than starting a new process with the system's process initiation.
Overall you might try something like:
from concurrent.futures import ProcessPoolExecutor
from time import sleep
from watchgod import watch
def slow_job(status, location):
print(f'status: {status}, location: {location}, starting...')
sleep(10)
print(f'status: {status}, location: {location}, done')
with ProcessPoolExecutor() as executor:
for changes in watch('./tests'):
for status, location in changes:
executor.submit(slow_job, status, location)
I have a number of python scripts that I would like to automate using Python's Datetime and Schedule module.
They are too numerous to consider breaking apart and adding to one large file.
What is the easiest way to write a python script that will open and run these other python scripts?
I have browsed similar questions but none offered a concrete answer that I could find. Thanks for your help.
A minimally demonstrative example
In a file called "child.py", write a file to the current directory:
with open('test', 'w') as f:
f.write('hello world')
Then, in a file called "parent.py", execute the "child.py" script:
import subprocess
subprocess.call(['python', 'child.py'])
Now, from your command line, you can type (assuming both "parent.py" and "child.py" are in the current directory):
python parent.py
In the next instant, you should see a file called "test" in your current directory. Open it up. What do you see?
Well, hello world of course!
The above example makes a child of the current process (meaning it inherits the environment variables in the parent), and waits until the child process completes before returning control to the parent. If you want the child script to run in the background, then you need to use Popen:
subprocess.Popen(['python', 'child.py'])