Keep track of which files are created by a certain process - python

I'm using a Python (3.3) script to run a command that will render a whole bunch of image files for an animation film.
While it's rendering, it creates an empty image file every time it starts a new frame of the animation, and when it's done rendering that frame, it saves the image over that empty file and moves onto the next frame.
The python script starts this rendering process by running another script using:
proc = subprocess.Popen(cmd, shell=True)
Is it at all possible to check which files were created during this process?
The reason being, someone may wish to stop the render before it finishes, but when they do so there will be an empty image file left over. I'd like to have the script delete the empty images when the big red Stop Render button is pushed, but I cannot simply delete all empty images because there may be other computers rendering - the empty images are there to prevent multiple computers rendering the same frame (they skip that frame if the image file for it exists).
If it helps, all the computers use Windows 7, and the animation program that does the rendering is Maya (2014).
If there's no easy way, I'd be happy to use any kind of ugly hack to get the job done :)

If you are doing this in Maya, you can use mayapy interpeter that comes with Maya (rather than mayaBatch or maya -r). Inside of standalone you can run any script(s) you need to setup the render, execute it, and post-process the results. At a minimum, that will let you handle one frame at a time and use python to submit the images one at a time.
A basic setup would be:
Create a python script that does what you need to do and works correctly inside the maya python interpeter. The script will be run as if it were in the maya listener, so you can import maya.cmds and use maya features as needed.
If the script needs command line arguments, use sys.argv to retrieve them. When you run the script, any arguments you pass in will be available in sys.argv.
Your script can get access to all of Maya's functionality by importing maya.standalone and calling it's initialize method (more details here)
From the command line, run the mayapy.exe that lives in the bin folder of your maya install. The -s flag allows you to specify a script to run, so you'll pass in the python script as an argument, followed by any other arguments you need: something like "path/to/mayapy.exe" -s "path/to/yourscript.py" arg1 arg2 arg3.
You won't be able to catch a user cancelling via control-c but you could request cancellation from outside using a TCP connection to the maya command port, or even just by prompting for user input after each frame
For a fancier operation you can run an rpc server inside your Maya using something like ZeroMQ or RpyC. You could also make your own with a WSGI server listening to the http port.
You can also look in to 3d party render management systems. There are some open-source ones here

Related

Python3 - Issues with "subprocess.call()" function

my software uses the subprocess.call([sys.executable, SCRIPT_NAME] instruction in order to open others kind of scripts specified by the user using a GUI (Tkinter). I have two issue with this instruction:
the "command line" scripts start and close themeselves quicly and it means that the user can't interact with them. it's a weird behaviour because in all of them there is an input instruction, so they should wait an input by the user before to close themeselves. how can I solve this issue?
the "GUI" scripts instead, start without any kind of issue, but their "life", let me say, put in stuck the main script (it uses Tkinter). in this case I can interact with the second script but not with the main one. how can I call my other scripts with the subprocess.call() function whithout put in stuck the main one? from my point of view this issue happens because the second script is a part of the same process of the main one and in this case Tkinter has to wait. if we open the others scripts using different processes for all of them the main script would be free to live its life independently of the others. but how can I do it?

run python script when you are on other applications

I would like to run my python script while I'm working on other things. For example, I want to run the python script while I'm watching a movie. But I don't want to exit full screen and go to the interactive shell and then go back.
I tried to create a batch file and run from the command line. But it's still not as neat and straight-forward as single-button functionality.
If I want to check the time while I'm watching a movie on hulu website.
python script:
import datetime
datetime.datetime.now()
I wonder if I can set a hotkey so that while I'm on other applications, I can just press the key and then python script will run itself in the background.
Try using keyboard module (allows us to assign custom shortcut keys):
import pyttsx3
import datetime
import keyboard
def time():
engine = pyttsx3.init()
hours = int(datetime.datetime.now().time().hour)%12
if not hours:
hours = 12
engine.say("the time is " + str(hours) + " " + str(datetime.datetime.now().time().minute))
engine.runAndWait()
def keyPress():
keyboard.add_hotkey('+', lambda: time())
keyboard.wait()
keyPress()
WHAT THIS PROGRAM DOES:-
This program a first creates a custom shortcut (assigns it to keyboard key +(change this to whatever hotkey combination you want)). Upon pressing this key, a function called time() gets called, which makes use of windows TTS, to tell your the current time (via voice functionality like siri, alisa etc).
HOW DOES THIS WORK:-
I made use of external libraries keyboard(necessary) and pyttsx3(optional), where the module keyboard allows us to define our custom hotkeys and create a event handler for keyboard events, and pyttsx3 makes use of windows Text to Speech feature to read some text via speech (aka voice). I made use of voice functionality, to not interrupt your flow while your are watching something online.
HOW TO SET IT UP:-
Copy the code, and save it as a .pyw file (notice the w in the
end). The difference between a regular .py an a .pyw file is
that, .py invokes console (~commandline) equivalent tool for
execution and executes in foreground, on the other hand a .pyw
file runs in the background at all times (i.e the console won't show
up). So it won't require you to manually open the console at all
times for executing the script as the script will be running in the
background at all time.
Copy this file (example.pyw) in the startup folder of your OS (any
file in this folder will automatically execute once the operating
system has started). What this will do is when your OS, will boot
your example.pyw file will automatically start executing in the
background, so you won't have to manually launch it at every system
startup. And since it is in the background it won't interfere with
your work. (if you're on windows OS, you can access your startup folder by typing shell:common startup on your run and pressing enter) (adding files to this folder requires root privileges)
HOW TO USE IT:-
While using your system press + (for my case), and your OS will tell you what the current time is. (though it requires your OS to have correct time)
PROS:-
Upon using this for long time I can tell you I never encountered a
single application in which the custom defined hotkey won't work.
Slim to None time required after keypress, for command execution.
A lot resistant to spam of hotkey's. e.x. You may press the
hotkey 100 times but the calls won't be made unless the previous
command has completed execution.
CONS:-
Calling the script for the first time after Bootup, may cause a
little latency in command execution (but only for once, i.e
subsequent calls would be really fast)
P.S:-
It is optional to use pyttsx3, I used it as it makes checking time a lot more easier then reading text or something (at least for me).
Secondly, this process could be made more efficient if you want.
RECOMMENDATIONS:-
Alternatively, If you are familiar with AHK (AutoHotKey) then, doing what i just told on a .ahk script would be a piece of cake, and it's scripts are even faster than my Python one. (Honestly I would definitely Recommend you to use AutoHotKey as it is a really robust language, when it comes to make efficient Operating System scripts)

Pass variable from Python as input to external program with subprocess

Currently, I have a Python application which opens (via subprocess) an executable, waits for the user to input certain values on the GUI and perform a calculation, and then, upon closing this executable, reads in the output file back into my Python application for further processing.
I would like, however, to pass variables directly from my application and input these into the entry blocks on the external GUI.
Is this possible?
For anyone that may be interested, the PyAutoGUI module provides the functionality I was interested in: https://pyautogui.readthedocs.org/en/latest/

is it possible to launch a window that does not stop the mainloop in python

OS = windows 7
I have a python program (works) that is listening to activity on the usb bus. I want to perform a lot of tests that require a particular user input at a particular time. I would like to pop up a window that says, "press button xxx". The key point is that the mainloop needs to continue running because it's looking for events. I don't care about the window or if it remains or not and I don't need to capture any information from the window. I just want a message to the user to press the correct button at the correct time. Any type of signaling would work; it doesn't have to be a gui window. It doesn't have to look pretty. Appreciate any suggestions or links to something like this. thx
It sounds like the operation of the Python script you're running does not depend upon the user input you request. To run another process without interrupting the Python script execution you can use:
import subprocess
subprocess.Popen([exe,arg1,arg2,arg3])
where
exe = executable/script to run from your OS command line
arg1= first argument to pass to exe
arg2= second argument to pass to exe
etc... (as many arguments as your OS supports in a list)
This separate exe process could request input from the user.

Executing a python script in a subprocess - with graphics

I've seen a lot of stuff about running code in subprocesses or threads, and using the multiprocessing and threading modules it's been really easy. However, doing this in a GUI adds an extra layer of complication.
From what I understand, the GUI classes don't like it if you try and manipulate them from multiple threads (or processes). The workaround is to send the data from whatever thread you created it in to the thread responsible for the graphics and then render it there.
Unfortunately, for the scenario I have in mind this is not an option: The gui I've created allows users to write their own plotting code which is then executed. This means I have no control over how they plot exactly, nor do I want to have it. (Update: these plots are displayed in separate windows and don't need to be embedded anywhere in the main GUI. What I want is for them to exist separated from the main GUI, without sharing any of the underlying stack of graphics libraries.)
So what I'm wondering now is
Is there some clean(ish) way of executing a string of python code in a whole new interpreter instance with its own ties to the windowing system?
In response to the comments:
The current application is set up as follows: A simple python script loads a wxPython gui (a wx.App). Using this gui users can set up a simulation, part of which involves creating a script in plain python that runs the simulation and post-processes the results (which usually involves making plots and displaying them). At the moment I'm doing this by simply calling exec() on the script code. This works fine, but the gui freezes while the simulation is running. I've experimented with running the embedded script in a subprocess, which also works fine, right up until you try to display the created graphs (usually using matplotlib's show()). At this point some library deep down in the stack of wxPython, wx, gtk etc starts complaining because you cannot manipulate it from multiple threads.
The set-up I would like to have is roughly the same, but instead of the embedded script sharing a GUI with the main application, I would like it to show graphics in an environment of its own.
And just to clarify:
This is not a question about "how do I do multithreading/multiprocessing" or even "how do I do multithreading/multiprocessing within a single wxpython gui". The question is how I can start a script from a gui that loads an entirely new gui. How do I get the window manager to see this script as an entirely separate application?
The easiest way would be to generate it in a temporary folder somewhere and then make a non-blocking call to the python interpreter, but this makes communication more difficult and it'd be quite hard to know when I could delete the temp files again. I was hoping there was a cleaner, dynamical way of doing this.
Can you simply use subprocess to run 'python.exe' and pipe the script in?
Alternatively, the multiprocessing package should suffice if you want to move some (pickle-able) data over to the new process in which you run the script. Just create a function/callable that runs the script, and create a Process object with the callable as target. That way, you should be able to pass some data over, without having GUI issues.
Capturing text with either is easy, subprocess allows that and no more. With multiprocess, you can pass python objects back and forth more easily.
On Windows, you can create window with a parent window from another process, and draw to that.
See the hWndParent argument to CreateWindowEx.
If wxWindows supports getting/setting that explicitly, then you should be good to go.
Depending on your platform, something similar might be possible in any windows system.
So, just giving your users the ability to find the handle of your apps window should give them the option to plot away at views embedded in your app, while running in their own processes.
I don't no much about wx, I work with jython(python implemented in java and you can use java) and swing. Swing has its own worker thread, and if you do gui updates you wrap your code into a runnable and invoke it with swing.invokelater.
You could see if wx has something like that, if you however are only allowed to manipulate the gui from the thread in which you created it try something similar. create a proxy object for your gui, which forwards all your calls to your thread which forwards them to the gui.
But proxying like this gets messy. how about you let them define classes, with an 'updateGui' function, that they should hand back to you over a queue and that you will execute in your gui thread.
In wxPython land when you use threads, you have to use its thread-safe methods to communicate with the GUI: wx.CallAfter, wx.CallLater or wx.PostEvent. In your case, I would run any long running code in a separate thread/process and when it's done its processing, send the result to the GUI. The GUI can instantiate a new frame and use matplotlib or PyPlot to show the plot, depending on which way you want to go. I've heard you can draw the plot using FloatCanvas too.
Anyway, if you instantiate the new frame correctly, then you can instantiate N frames and show them and be fine. See the wxPython wiki for a few examples of using Threads with wx: http://wiki.wxpython.org/LongRunningTasks

Categories

Resources