Skip to content

Commit c824488

Browse files
authored
Merge pull request #23 from netinvent/v1.5.0
V1.5.0
2 parents 3a094ec + 50dfc8b commit c824488

File tree

4 files changed

+280
-59
lines changed

4 files changed

+280
-59
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# v1.5.0 - command and conquer them all, nod if you're happy
2+
3+
- New silent parameter disabling all logger calls except of logging.DEBUG levels
4+
- New on_exit parameter that takes a callback function as argument
5+
- valid_exit_codes now accept boolean True which means "all" exit codes
6+
- New priority parameter
7+
- New io_priority parameter
8+
- Fix output capture failure should be an error log instead of debug
9+
- Fix no longer show debug logging for stdout or stderr when empty
10+
111
# v1.4.1 - command and conquer them all, don't nod
212

313
- Fix endoding always was set to os default unless explicitly disabled by setting `encoding=False`

README.md

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ while solving various problems a developer may face among:
1616
- Allow stdout/stderr stream output to be redirected to callback functions / output queues / files so you get to handle output in your application while commands are running
1717
- Callback to optional stop check so we can stop execution from outside command_runner
1818
- Callback with optional process information so we get to control the process from outside command_runner
19+
- Callback once we're finished to easen thread usage
20+
- Optional process priority and io_priority settings
1921
- System agnostic functionality, the developer shouldn't carry the burden of Windows & Linux differences
2022
- Optional Windows UAC elevation module compatible with CPython, PyInstaller & Nuitka
2123
- Optional Linux sudo elevation compatible with CPython, PyInstaller & Nuitka
@@ -144,15 +146,26 @@ Be aware that under MS Windows, no direct process tree is available.
144146
We fixed this by walking processes during runtime. The drawback is that orphaned processes cannot be identified this way.
145147

146148

147-
#### Disabling logs
149+
#### Disabling logs / silencing
148150

149-
Whenever you want another loglevel for command_runner, you might do with the following statement in your code
151+
`command_runner` has it's own logging system, which will log all sorts of error logs.
152+
If you need to disable it's logging, just run with argument silent.
153+
Be aware that logging.DEBUG log levels won't be silenced, by design.
154+
155+
Example:
156+
```python
157+
from command_runner import command_runner
158+
159+
exit_code, output = command_runner('ping 127.0.0.1', silent=True)
160+
```
161+
162+
If you also need to disable logging.DEBUG level, you can run the following code which will required logging.CRITICAL only messages which `command_runner` never does:
150163

151164
```python
152165
import logging
153166
import command_runner
154167

155-
logging.getLogger('command_runner').setLevel(logging.ERROR)
168+
logging.getLogger('command_runner').setLevel(logging.CRITICAL)
156169
```
157170

158171
#### Capture method
@@ -323,7 +336,7 @@ def callback_function(string):
323336
exit_code, output = command_runner('ping 127.0.0.1', stdout=callback_function, method='poller')
324337
```
325338

326-
#### Stop_on
339+
#### stop_on
327340

328341
In some situations, you want a command to be aborted on some external triggers.
329342
That's where `stop_on` argument comes in handy.
@@ -376,6 +389,32 @@ print('stdout', stdout)
376389
print('stderr', stderr)
377390
```
378391

392+
#### On-exit Callback
393+
394+
`command_runner` allows to execute a callback function once it has finished it's execution.
395+
This might help building threaded programs where a callback is needed to disable GUI elements for example.
396+
397+
Example:
398+
```python
399+
from command_runner import command_runner
400+
401+
def do_something():
402+
print("We're done running")
403+
404+
exit_code, output = command_runner('ping 127.0.0.1', on_exit=do_something)
405+
```
406+
407+
### Process and IO priority
408+
`command_runner` can set it's subprocess priority to 'low', 'medium' or 'high', which translate to 15, 0, -15 niceness on Linux and BELOW_NORMAL_PRIORITY_CLASS and HIGH_PRIORITY_CLASS in Windows.
409+
410+
The same applies to IO bound priority.
411+
412+
Example:
413+
```python
414+
from command_runner import command_runner
415+
416+
exit_code, output = command_runner('some_intensive_process', priority='low', io_priority='high')
417+
```
379418

380419
#### Other arguments
381420

@@ -389,34 +428,24 @@ It also uses the following standard arguments:
389428
- encoding (str/bool): Which text encoding the command produces, defaults to cp437 under Windows and utf-8 under Linux
390429
- stdout (str/queue.Queue/function/False/None): Optional path to filename where to dump stdout, or queue where to write stdout, or callback function which is called when stdout has output
391430
- stderr (str/queue.Queue/function/False/None): Optional path to filename where to dump stderr, or queue where to write stderr, or callback function which is called when stderr has output
392-
- split_streams (bool): Split stdout and stderr into two separate results
393431
- windows_no_window (bool): Shall a command create a console window (MS Windows only), defaults to False
394432
- live_output (bool): Print output to stdout while executing command, defaults to False
395433
- method (str): Accepts 'poller' or 'monitor' stdout capture and timeout monitoring methods
396434
- check interval (float): Defaults to 0.05 seconds, which is the time between stream readings and timeout checks
397435
- stop_on (function): Optional function that when returns True stops command_runner execution
436+
- on_exit (function): Optional function that gets executed when command_runner has finished (callback function)
398437
- process_callback (function): Optional function that will take command_runner spawned process as argument, in order to deal with process info outside of command_runner
438+
- split_streams (bool): Split stdout and stderr into two separate results
439+
- silent (bool): Allows to disable command_runner's internal logs, except for logging.DEBUG levels which for obvious reasons should never be silenced
440+
- priority (str): Allows to set CPU bound process priority (takes 'low', 'normal' or 'high' parameter)
441+
- io_priority (str): Allows to set IO priority for process (takes 'low', 'normal' or 'high' parameter)
399442
- close_fds (bool): Like Popen, defaults to True on Linux and False on Windows
400443
- universal_newlines (bool): Like Popen, defaults to False
401444
- creation_flags (int): Like Popen, defaults to 0
402445
- bufsize (int): Like Popen, defaults to 16384. Line buffering (bufsize=1) is deprecated since Python 3.7
403446

404447
**Note that ALL other subprocess.Popen arguments are supported, since they are directly passed to subprocess.**
405448

406-
### logging
407-
408-
Even muted, `command_runner` will still log errors.
409-
If you want to completely mute `command_runner`, you will have to set it's logger instance to `logger.CRITICAL` level, since this level is never called.
410-
411-
Example of entirely muted `command_runner` execution:
412-
```
413-
rom command_runner import command_runner
414-
import logging
415-
416-
logging.getLogger("command_runner").setLevel(logging.CRITICAL)
417-
418-
err_code, stdout, stderr = command_runner("ping 127.0.0.1", timeout=1, method='monitor', live_output=False, stdout=False, stderr=False, split_streams=True)
419-
```
420449

421450
## UAC Elevation / sudo elevation
422451

0 commit comments

Comments
 (0)