pmflow 1.2.0__tar.gz → 1.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pmflow
3
- Version: 1.2.0
3
+ Version: 1.2.3
4
4
  Summary: Manages processes
5
5
  Author-email: "Md. Mahmudul Hasan Riyad" <mhriyad98@gmail.com>
6
6
  License: MIT License
@@ -46,6 +46,7 @@ Provides-Extra: dev
46
46
  pip install pmflow
47
47
  ```
48
48
  ## Commands
49
+ ### <^> Main commands
49
50
  create: Creates a new process
50
51
 
51
52
  Required arguments:
@@ -56,26 +57,46 @@ Optional arguments:
56
57
  - --group or -g : str (default: process_id)
57
58
  - --relation or -r : "parent" | "child" (default: "parent")
58
59
  - --verbose or -v: (default: false)
60
+
61
+ Note: A child process must have a group name and the group must have a parent process.
62
+
63
+ Example:
59
64
  ```
60
- pm create "<your command>"
65
+ pm create "<command>"
61
66
  or
62
- pm create "<your command>" --name "<your process name>"
67
+ pm create "<command>" -n "<process name>" -g "<group name>" -r "child"
63
68
  ```
64
69
  ls: List all managed processes
65
70
 
66
71
  Optional arguments:
67
- - --json or -j (default: false)
72
+ - --json or -j: bool (default: false)
73
+ - --group or -g: str (default: None)
74
+ - --running or -r: bool (default: false)
75
+ Example:
68
76
  ```
69
77
  pm ls
70
78
  pm ls -j
79
+ pm ls -g <group_name>
80
+ pm ls -j -g <group_name>
81
+ pm ls -r
71
82
  ```
72
- Kill process, kills the process and also removes it from the json file.
83
+ kill: Kill process, kills the process and also removes it from the json file.
84
+
85
+ Optional arguments:
86
+ - pid (no flag needed): int (default: 0) kills one process if it's a child process. Otherwise, kills the terminates
87
+ - --group or -g: str (default: None) kills one group if exist
88
+ - --child or -c: bool (default: False) kills all child process in a group
89
+ - --all or -a : bool (default: false) kills all the process
90
+
91
+ Note: Other than -c only one options can be used at a time. -c flag must be used with -g
73
92
 
93
+ Example:
74
94
  ```
75
95
  pm kill <PID>
76
- pm kill-all
96
+ pm -g <group_name>
97
+ pm -a
77
98
  ```
78
-
99
+ ### <^> Additional commands
79
100
  Recreate all process managed by the tool:
80
101
  ```
81
102
  pm recreate
@@ -86,5 +107,5 @@ pm pause <PID>
86
107
  ```
87
108
  respawn all paused process
88
109
  ```
89
- pm respawn-all
110
+ pm respawn
90
111
  ```
pmflow-1.2.3/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # PMFlow
2
+ <p style="font-size:15px;">This is a simple process managing tool</p>
3
+
4
+ <p style="font-size:15px;">This tools keeps the information of the processes it manages in a json file created at it's installation location</p>
5
+
6
+ ## Installation
7
+ ```
8
+ pip install pmflow
9
+ ```
10
+ ## Commands
11
+ ### <^> Main commands
12
+ create: Creates a new process
13
+
14
+ Required arguments:
15
+ - command: str (default: None)
16
+
17
+ Optional arguments:
18
+ - --name or -n : str (default: None)
19
+ - --group or -g : str (default: process_id)
20
+ - --relation or -r : "parent" | "child" (default: "parent")
21
+ - --verbose or -v: (default: false)
22
+
23
+ Note: A child process must have a group name and the group must have a parent process.
24
+
25
+ Example:
26
+ ```
27
+ pm create "<command>"
28
+ or
29
+ pm create "<command>" -n "<process name>" -g "<group name>" -r "child"
30
+ ```
31
+ ls: List all managed processes
32
+
33
+ Optional arguments:
34
+ - --json or -j: bool (default: false)
35
+ - --group or -g: str (default: None)
36
+ - --running or -r: bool (default: false)
37
+ Example:
38
+ ```
39
+ pm ls
40
+ pm ls -j
41
+ pm ls -g <group_name>
42
+ pm ls -j -g <group_name>
43
+ pm ls -r
44
+ ```
45
+ kill: Kill process, kills the process and also removes it from the json file.
46
+
47
+ Optional arguments:
48
+ - pid (no flag needed): int (default: 0) kills one process if it's a child process. Otherwise, kills the terminates
49
+ - --group or -g: str (default: None) kills one group if exist
50
+ - --child or -c: bool (default: False) kills all child process in a group
51
+ - --all or -a : bool (default: false) kills all the process
52
+
53
+ Note: Other than -c only one options can be used at a time. -c flag must be used with -g
54
+
55
+ Example:
56
+ ```
57
+ pm kill <PID>
58
+ pm -g <group_name>
59
+ pm -a
60
+ ```
61
+ ### <^> Additional commands
62
+ Recreate all process managed by the tool:
63
+ ```
64
+ pm recreate
65
+ ```
66
+ Pause a process
67
+ ```
68
+ pm pause <PID>
69
+ ```
70
+ respawn all paused process
71
+ ```
72
+ pm respawn
73
+ ```
@@ -13,12 +13,7 @@ from pm.settings import state
13
13
  from typing import Optional
14
14
  from enum import Enum
15
15
  from typing_extensions import Annotated
16
-
17
-
18
- class Relation(str, Enum):
19
- PARENT = 'parent'
20
- CHILD = 'child'
21
-
16
+ from pm.schema import Relation
22
17
 
23
18
  def create(command: Annotated[str, typer.Argument()],
24
19
  name: Annotated[Optional[str], typer.Option("--name","-n")] = None,
@@ -27,15 +22,29 @@ def create(command: Annotated[str, typer.Argument()],
27
22
  verbose: Annotated [bool, typer.Option("--verbose", "-v")] = False) -> int:
28
23
 
29
24
  """Create a new subprocess and optionally assign a name."""
25
+
26
+ if relation == Relation.CHILD:
27
+ if not group:
28
+ typer.echo(f"Error 800: Please specify an existing group of a parent process")
29
+ raise typer.Exit(code=1)
30
+ elif group not in state.get_parents_groupname():
31
+ typer.echo(f"Error 801: No parent group with this name exist. "
32
+ f"Please specify an existing group of a parent process")
33
+ raise typer.Exit(code=1)
34
+
30
35
  proc = subprocess.Popen(command, shell=True)
31
36
  pid = proc.pid
32
37
 
33
- if not group:
34
- group = str(pid)
38
+ if relation == Relation.PARENT:
39
+ if not group:
40
+ group = str(pid)
41
+ elif state.is_group_exist(group):
42
+ typer.echo(f"Error 802: A group can have only one parent process.")
35
43
 
36
44
  data = {
37
45
  "command": command,
38
46
  "name": name,
47
+ "status": "running",
39
48
  "group": group,
40
49
  "relation": relation,
41
50
  }
@@ -0,0 +1,127 @@
1
+ """
2
+ This module is related to stopping a process's from running or deleting it altogether
3
+ The commands it manages are
4
+ - pause
5
+ - kill
6
+ """
7
+
8
+ import typer
9
+ import psutil
10
+ import signal
11
+ from typing import Optional
12
+ from typing_extensions import Annotated
13
+ from pm.settings import state
14
+
15
+
16
+ def pause(pid: int):
17
+ """Pause a subprocess and all its children by PID."""
18
+ pid_str = str(pid)
19
+ if pid_str in state.processes:
20
+ try:
21
+ process = psutil.Process(int(pid))
22
+ all_processes = [process] + process.children(recursive=True)
23
+ for proc in all_processes:
24
+ proc.send_signal(signal.SIGSTOP)
25
+ typer.echo(f"Process {pid} and its child processes have been paused.")
26
+ except psutil.NoSuchProcess:
27
+ typer.echo("Process not found.")
28
+ else:
29
+ typer.echo("Process not managed by this tool.")
30
+
31
+
32
+ def kill(pid: Annotated[Optional[int], typer.Argument()] = 0,
33
+ group: Annotated[Optional[str], typer.Option("--group", "-g")] = None,
34
+ child: Annotated[Optional[bool], typer.Option("--child", "-c")] = False,
35
+ all: Annotated[Optional[bool], typer.Option("--all", "-a")] = False,):
36
+ """
37
+ Kill a subprocess by PID, group name.
38
+
39
+ params:
40
+ pid: int -> kill a process by it's pid.
41
+ group: str -> kill a process by it's group name.'
42
+ child: bool -> kill all child process of a group. This can only be used with --group or -g.
43
+ all: bool -> kill all existing process.
44
+
45
+ """
46
+
47
+ # validating arguments so that only one argument is given otherwise throw error
48
+ args_given = sum([pid != 0, group is not None, all is not False])
49
+
50
+ if args_given == 0:
51
+ typer.echo("Error 1100: You must specify exactly one of: PID, group, or --all.", err=True)
52
+ raise typer.Exit(code=1)
53
+
54
+ if args_given > 1:
55
+ typer.echo("Error 1200: You can only specify one of: PID, group, or --all.", err=True)
56
+ raise typer.Exit(code=1)
57
+
58
+ # Delete process with the flag given
59
+ # For pid
60
+ if pid:
61
+ pid_str = str(pid)
62
+
63
+ if pid_str in state.get_processes().keys():
64
+ if state.get_processes()[pid_str]["relation"] == "parent":
65
+ typer.echo(f"Process {pid} is a parent process. Killing it with all it's children...")
66
+ process_group = state.get_a_group(state.get_processes()[pid_str]["group"])
67
+ if process_group:
68
+ kill_group_process(process_group)
69
+ for pid in process_group.keys():
70
+ state.remove_process(pid)
71
+ else:
72
+ try:
73
+ process = psutil.Process(int(pid))
74
+ for child in process.children(recursive=True):
75
+ child.terminate()
76
+ process.terminate()
77
+ state.remove_process(pid_str)
78
+ typer.echo(f"Process {pid} killed.")
79
+ except psutil.NoSuchProcess:
80
+ state.remove_process(pid_str)
81
+ typer.echo("Process not found. Removed from the state file.")
82
+ else:
83
+ typer.echo("Process not managed by this tool.")
84
+
85
+ # For group flag --group or -g
86
+ if group:
87
+ process_group = state.get_a_group(group)
88
+
89
+ if child:
90
+ process_group = {pid: data for pid, data in process_group.items() if data["relation"] == "child"}
91
+
92
+ if process_group:
93
+ kill_group_process(process_group)
94
+ for pid in process_group.keys():
95
+ state.remove_process(pid)
96
+
97
+ # For all flag --all or -a
98
+ if all:
99
+ for pid in state.processes.keys():
100
+ try:
101
+ process = psutil.Process(int(pid))
102
+ for child in process.children(recursive=True):
103
+ child.terminate()
104
+ process.terminate()
105
+ typer.echo(f"Process {pid} terminated.")
106
+ except psutil.NoSuchProcess:
107
+ typer.echo(f"Process {pid} not found.")
108
+ except Exception as e:
109
+ typer.echo(f"Error terminating process {pid}: {str(e)}")
110
+
111
+ state.remove_all_processes()
112
+ typer.echo("All processes have been terminated and removed from the state.")
113
+
114
+
115
+ def kill_group_process(processes: dict):
116
+
117
+ for pid in processes.keys():
118
+ try:
119
+ process = psutil.Process(int(pid))
120
+ for child in process.children(recursive=True):
121
+ child.terminate()
122
+ process.terminate()
123
+ typer.echo(f"Process {pid} terminated.")
124
+ except psutil.NoSuchProcess:
125
+ typer.echo(f"Process {pid} not found. Removed from state.")
126
+ except Exception as e:
127
+ typer.echo(f"Error terminating process {pid}: {str(e)}")
@@ -0,0 +1,67 @@
1
+ """
2
+ This module manages handles output presentation of the process's.
3
+ The command it manages are
4
+ - ls
5
+ """
6
+
7
+ import typer
8
+ import psutil
9
+ import json
10
+ from rich.console import Console
11
+ from rich.table import Table
12
+ from pm.settings import state
13
+ from typing_extensions import Annotated
14
+
15
+
16
+ def ls(json_output: Annotated[bool, typer.Option("--json", "-j")] = False,
17
+ group_name: Annotated[str, typer.Option("--group", "-g")] = None,
18
+ running: Annotated[bool, typer.Option("--running", "-r")] = False) -> None:
19
+ """List all managed subprocesses."""
20
+
21
+ # Update status of each process
22
+ for pid, properties in state.get_processes().items():
23
+ try:
24
+ process = psutil.Process(int(pid))
25
+ if process.status() == psutil.STATUS_STOPPED:
26
+ status = 'paused'
27
+ else:
28
+ status = 'running'
29
+ except psutil.NoSuchProcess:
30
+ status = "doesn't exist"
31
+
32
+ state.update_process(pid, "status", status)
33
+
34
+ # Console output block
35
+ if group_name:
36
+ process_dict = state.get_a_group(group_name)
37
+ if not process_dict:
38
+ typer.echo(f"Error 1000: No process group with group name {group_name} exist")
39
+ raise typer.Exit(code=1)
40
+ else:
41
+ process_dict = state.get_processes()
42
+
43
+ if running:
44
+ process_dict ={pid: data for pid, data in process_dict.items() if data["status"] == "running"}
45
+
46
+
47
+ if json_output:
48
+ json_output = json.dumps(process_dict)
49
+ typer.echo(json_output)
50
+
51
+ else:
52
+ table = Table()
53
+ table.add_column("PID", justify="center", style="#00ffee")
54
+ table.add_column("Name", justify="center", style="#f7d59e")
55
+ table.add_column("Status", justify="center", style="#e2fa2a")
56
+ table.add_column("Group", justify="center", style="#00ffee")
57
+ table.add_column("Relation", justify="center", style="#f700ff")
58
+ table.add_column("Command", justify="center", style="#00ff26")
59
+
60
+
61
+ for pid, properties in process_dict.items():
62
+
63
+ table.add_row(pid, properties["name"], properties["status"], properties["group"],
64
+ properties["relation"],properties["command"])
65
+
66
+ console = Console()
67
+ console.print(table)
@@ -2,7 +2,7 @@
2
2
  import typer
3
3
 
4
4
  from pm.commands.create import create, recreate, respawn
5
- from pm.commands.kill import pause, kill, kill_all
5
+ from pm.commands.kill import pause, kill
6
6
  from pm.commands.ls import ls
7
7
 
8
8
  app = typer.Typer()
@@ -20,7 +20,6 @@ app.command()(respawn)
20
20
  # Commands related to deletion of a process
21
21
  app.command()(pause)
22
22
  app.command()(kill)
23
- app.command()(kill_all)
24
23
 
25
24
 
26
25
  # Commands related to process presentation
@@ -0,0 +1,6 @@
1
+ from enum import Enum
2
+
3
+
4
+ class Relation(str, Enum):
5
+ PARENT = 'parent'
6
+ CHILD = 'child'
@@ -1,9 +1,11 @@
1
1
  import json
2
2
  import os
3
3
  import sys
4
+ from typing import List, Dict
4
5
 
5
6
  import typer
6
7
 
8
+ from pm.schema import Relation
7
9
 
8
10
  class StateManager:
9
11
  def __init__(self, STATE_FILE):
@@ -25,9 +27,6 @@ class StateManager:
25
27
  with open(self.STATE_FILE, "w") as file:
26
28
  json.dump(self.processes, file)
27
29
 
28
- def get_processes(self):
29
- return self.processes
30
-
31
30
  def add_process(self, pid, data):
32
31
  self.processes[str(pid)] = data
33
32
  self.save()
@@ -48,6 +47,21 @@ class StateManager:
48
47
  self.processes = bulk_data
49
48
  self.save()
50
49
 
50
+ def get_processes(self):
51
+ return self.processes
52
+
53
+ def get_parents_groupname(self) -> List[Relation]:
54
+ parent_groups = [process_meta_data["group"] for process_meta_data in self.processes.values()
55
+ if process_meta_data["relation"] == Relation.PARENT]
56
+ return parent_groups
57
+
58
+ def get_a_group(self, group_name: str) -> Dict:
59
+ group_process = {pid: data for pid, data in self.processes.items() if data["group"] == group_name}
60
+ return group_process
61
+
62
+ def is_group_exist(self, group_name: str) -> bool:
63
+ return group_name in self.get_parents_groupname()
64
+
51
65
 
52
66
 
53
67
  def load_state(path):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pmflow
3
- Version: 1.2.0
3
+ Version: 1.2.3
4
4
  Summary: Manages processes
5
5
  Author-email: "Md. Mahmudul Hasan Riyad" <mhriyad98@gmail.com>
6
6
  License: MIT License
@@ -46,6 +46,7 @@ Provides-Extra: dev
46
46
  pip install pmflow
47
47
  ```
48
48
  ## Commands
49
+ ### <^> Main commands
49
50
  create: Creates a new process
50
51
 
51
52
  Required arguments:
@@ -56,26 +57,46 @@ Optional arguments:
56
57
  - --group or -g : str (default: process_id)
57
58
  - --relation or -r : "parent" | "child" (default: "parent")
58
59
  - --verbose or -v: (default: false)
60
+
61
+ Note: A child process must have a group name and the group must have a parent process.
62
+
63
+ Example:
59
64
  ```
60
- pm create "<your command>"
65
+ pm create "<command>"
61
66
  or
62
- pm create "<your command>" --name "<your process name>"
67
+ pm create "<command>" -n "<process name>" -g "<group name>" -r "child"
63
68
  ```
64
69
  ls: List all managed processes
65
70
 
66
71
  Optional arguments:
67
- - --json or -j (default: false)
72
+ - --json or -j: bool (default: false)
73
+ - --group or -g: str (default: None)
74
+ - --running or -r: bool (default: false)
75
+ Example:
68
76
  ```
69
77
  pm ls
70
78
  pm ls -j
79
+ pm ls -g <group_name>
80
+ pm ls -j -g <group_name>
81
+ pm ls -r
71
82
  ```
72
- Kill process, kills the process and also removes it from the json file.
83
+ kill: Kill process, kills the process and also removes it from the json file.
84
+
85
+ Optional arguments:
86
+ - pid (no flag needed): int (default: 0) kills one process if it's a child process. Otherwise, kills the terminates
87
+ - --group or -g: str (default: None) kills one group if exist
88
+ - --child or -c: bool (default: False) kills all child process in a group
89
+ - --all or -a : bool (default: false) kills all the process
90
+
91
+ Note: Other than -c only one options can be used at a time. -c flag must be used with -g
73
92
 
93
+ Example:
74
94
  ```
75
95
  pm kill <PID>
76
- pm kill-all
96
+ pm -g <group_name>
97
+ pm -a
77
98
  ```
78
-
99
+ ### <^> Additional commands
79
100
  Recreate all process managed by the tool:
80
101
  ```
81
102
  pm recreate
@@ -86,5 +107,5 @@ pm pause <PID>
86
107
  ```
87
108
  respawn all paused process
88
109
  ```
89
- pm respawn-all
110
+ pm respawn
90
111
  ```
@@ -4,6 +4,7 @@ README.md
4
4
  pyproject.toml
5
5
  pm/__init__.py
6
6
  pm/main.py
7
+ pm/schema.py
7
8
  pm/settings.py
8
9
  pm/utils.py
9
10
  pm/commands/__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pmflow"
7
- version = "1.2.0"
7
+ version = "1.2.3"
8
8
  description = "Manages processes"
9
9
  readme = "README.md"
10
10
  authors =[{name = "Md. Mahmudul Hasan Riyad", email = "mhriyad98@gmail.com"}]
pmflow-1.2.0/README.md DELETED
@@ -1,52 +0,0 @@
1
- # PMFlow
2
- <p style="font-size:15px;">This is a simple process managing tool</p>
3
-
4
- <p style="font-size:15px;">This tools keeps the information of the processes it manages in a json file created at it's installation location</p>
5
-
6
- ## Installation
7
- ```
8
- pip install pmflow
9
- ```
10
- ## Commands
11
- create: Creates a new process
12
-
13
- Required arguments:
14
- - command: str (default: None)
15
-
16
- Optional arguments:
17
- - --name or -n : str (default: None)
18
- - --group or -g : str (default: process_id)
19
- - --relation or -r : "parent" | "child" (default: "parent")
20
- - --verbose or -v: (default: false)
21
- ```
22
- pm create "<your command>"
23
- or
24
- pm create "<your command>" --name "<your process name>"
25
- ```
26
- ls: List all managed processes
27
-
28
- Optional arguments:
29
- - --json or -j (default: false)
30
- ```
31
- pm ls
32
- pm ls -j
33
- ```
34
- Kill process, kills the process and also removes it from the json file.
35
-
36
- ```
37
- pm kill <PID>
38
- pm kill-all
39
- ```
40
-
41
- Recreate all process managed by the tool:
42
- ```
43
- pm recreate
44
- ```
45
- Pause a process
46
- ```
47
- pm pause <PID>
48
- ```
49
- respawn all paused process
50
- ```
51
- pm respawn-all
52
- ```
@@ -1,65 +0,0 @@
1
- """
2
- This module is related to stopping a process's from running or deleting it altogether
3
- The commands it manages are
4
- - pause
5
- - kill
6
- - kill-all
7
- """
8
-
9
- import typer
10
- import psutil
11
- import signal
12
- from pm.settings import state
13
-
14
-
15
- def pause(pid: int):
16
- """Pause a subprocess and all its children by PID."""
17
- pid_str = str(pid)
18
- if pid_str in state.processes:
19
- try:
20
- process = psutil.Process(int(pid))
21
- all_processes = [process] + process.children(recursive=True)
22
- for proc in all_processes:
23
- proc.send_signal(signal.SIGSTOP)
24
- typer.echo(f"Process {pid} and its child processes have been paused.")
25
- except psutil.NoSuchProcess:
26
- typer.echo("Process not found.")
27
- else:
28
- typer.echo("Process not managed by this tool.")
29
-
30
-
31
- def kill(pid: int):
32
- """Kill a subprocess by PID."""
33
- pid_str = str(pid)
34
- if pid_str in state.processes:
35
- try:
36
- process = psutil.Process(int(pid))
37
- for child in process.children(recursive=True):
38
- child.terminate()
39
- process.terminate()
40
- state.remove_process(pid_str)
41
- typer.echo(f"Process {pid} killed.")
42
- except psutil.NoSuchProcess:
43
- state.remove_process(pid_str)
44
- typer.echo("Process not found. Removed from the state file.")
45
- else:
46
- typer.echo("Process not managed by this tool.")
47
-
48
-
49
- def kill_all():
50
- """Kill all managed processes and clear the state."""
51
-
52
- for pid in state.processes.keys():
53
- try:
54
- process = psutil.Process(int(pid))
55
- for child in process.children(recursive=True):
56
- child.terminate()
57
- process.terminate()
58
- typer.echo(f"Process {pid} terminated.")
59
- except psutil.NoSuchProcess:
60
- typer.echo(f"Process {pid} not found.")
61
- except Exception as e:
62
- typer.echo(f"Error terminating process {pid}: {str(e)}")
63
-
64
- state.remove_all_processes()
65
- typer.echo("All processes have been terminated and removed from the state.")
@@ -1,47 +0,0 @@
1
- """
2
- This module manages handles output presentation of the process's.
3
- The command it manages are
4
- - ls
5
- """
6
-
7
- import typer
8
- import psutil
9
- import json
10
- from rich.console import Console
11
- from rich.table import Table
12
- from pm.settings import state
13
- from typing_extensions import Annotated
14
-
15
-
16
- def ls(json_output: Annotated[bool, typer.Option("--json", "-j")] = False) -> None:
17
- """List all managed subprocesses."""
18
-
19
- if json_output:
20
- json_output = json.dumps(state.get_processes())
21
- typer.echo(json_output)
22
-
23
- else:
24
- table = Table()
25
- table.add_column("PID", justify="center", style="#00ffee")
26
- table.add_column("Name", justify="center", style="#f7d59e")
27
- table.add_column("Status", justify="center", style="#e2fa2a")
28
- table.add_column("Group", justify="center", style="#00ffee")
29
- table.add_column("Relation", justify="center", style="#f700ff")
30
- table.add_column("Command", justify="center", style="#00ff26")
31
-
32
-
33
- for pid, properties in state.get_processes().items():
34
- try:
35
- process = psutil.Process(int(pid))
36
- if process.status() == psutil.STATUS_STOPPED:
37
- status = 'paused'
38
- else:
39
- status = 'running'
40
- except psutil.NoSuchProcess:
41
- status = "doesn't exist"
42
-
43
- table.add_row(pid, properties["name"], status, properties["group"],
44
- properties["relation"],properties["command"])
45
-
46
- console = Console()
47
- console.print(table)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes