Skip to content

Commit d2dafdb

Browse files
authored
Replaced hardcoded print() with logging (#754)
Replaced hardcoded runtime print() calls in aiida-workgraph with logging/process reporting so embedding apps can control output without stdout pollution.
1 parent e5df967 commit d2dafdb

File tree

7 files changed

+33
-19
lines changed

7 files changed

+33
-19
lines changed

src/aiida_workgraph/engine/awaitable_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def on_awaitable_finished(self, awaitable: Awaitable) -> None:
131131
try:
132132
self.process.resume()
133133
except Exception as e:
134-
print(e)
134+
self.logger.exception('Failed to resume process after awaitable completion: %s', e)
135135

136136
def to_context(self, **kwargs: Awaitable | ProcessNode) -> None:
137137
"""Add a dictionary of awaitables to the context.

src/aiida_workgraph/engine/task_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def should_run_task(self, task: 'Task') -> bool:
134134
# skip if the max number of awaitables is reached
135135
if task.task_type.upper() in process_task_types:
136136
if len(self.process._awaitables) >= self.process.wg.max_number_jobs:
137-
print(MAX_NUMBER_AWAITABLES_MSG.format(self.process.wg.max_number_jobs, name))
137+
self.process.report(MAX_NUMBER_AWAITABLES_MSG.format(self.process.wg.max_number_jobs, name))
138138
return False
139139
# skip if the task is already executed or if the task is in a skippped state
140140
if name in self.ctx._executed_tasks or self.state_manager.get_task_runtime_info(name, 'state') in ['SKIPPED']:

src/aiida_workgraph/executors/builtins.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import logging
12
from typing import Any
23
from aiida import orm
34

5+
LOGGER = logging.getLogger(__name__)
6+
47

58
def UnavailableExecutor(*args, **kwargs):
69
raise RuntimeError('This executor was defined dynamically and is not available from the database snapshot.')
@@ -53,5 +56,5 @@ def load_code(pk: int = None, uuid: str = None, label: str = None) -> orm.Code:
5356
pk = label.value if isinstance(label, orm.Str) else label
5457
else:
5558
pk = pk.value if isinstance(pk, orm.Int) else pk
56-
print(f'Loading code with pk: {pk}')
59+
LOGGER.info('Loading code with pk: %s', pk)
5760
return orm.load_code(pk)

src/aiida_workgraph/tasks/monitors.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import datetime
22
import typing as t
3+
import logging
34

45
from aiida_workgraph import task
56

7+
LOGGER = logging.getLogger(__name__)
8+
69

710
@task.monitor
811
def monitor_file(filepath: str):
@@ -49,8 +52,8 @@ def monitor_task(task_name: str, workgraph_pk: int = None, workgraph_name: str =
4952
)
5053
if builder.count() == 0:
5154
return False
52-
print('Found workgraph')
55+
LOGGER.debug('Found workgraph')
5356
node = builder.first()[0]
5457
state = node.task_states.get(task_name, '')
55-
print(f'Task state: {state}')
58+
LOGGER.debug('Task state: %s', state)
5659
return state in ['FINISHED', 'FAILED', 'SKIPPED']

src/aiida_workgraph/utils/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import logging
34
from typing import Any, Dict, Optional, Union, Callable, List
45
from aiida.engine.processes import Process
56
from aiida import orm
@@ -18,6 +19,8 @@
1819
from aiida_workgraph.orm.utils import deserialize_safe
1920
from copy import deepcopy
2021

22+
LOGGER = logging.getLogger(__name__)
23+
2124

2225
def inspect_aiida_component_type(executor: Callable) -> str:
2326
task_type = None
@@ -261,9 +264,7 @@ def load_workgraph_data(node: Union[int, orm.Node]) -> Optional[Dict[str, Any]]:
261264
try:
262265
task_inputs = deserialize_safe(node.task_inputs or '')
263266
except (yaml.constructor.ConstructorError, yaml.YAMLError):
264-
print(
265-
'Info: could not deserialize inputs.The workgraph is still loaded and you can inspect tasks and outputs. '
266-
)
267+
LOGGER.info('Could not deserialize inputs. The workgraph is still loaded and tasks/outputs remain inspectable.')
267268
task_inputs = {}
268269

269270
for name, data in task_inputs.items():

src/aiida_workgraph/utils/control.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
from __future__ import annotations
22

3+
import logging
4+
35
from aiida.manage import get_manager
46
from aiida import orm
57
from aiida.engine.processes import control
68

9+
LOGGER = logging.getLogger(__name__)
10+
711

812
def create_task_action(
913
pk: int,
@@ -35,7 +39,7 @@ def pause_tasks(pk: int, tasks: list[str], timeout: int = 5):
3539
node = orm.load_node(pk)
3640
if node.is_finished:
3741
message = 'WorkGraph is finished. Cannot pause tasks.'
38-
print(message)
42+
LOGGER.warning(message)
3943
return False, message
4044
elif node.process_state.value.upper() in [
4145
'CREATED',
@@ -54,15 +58,15 @@ def pause_tasks(pk: int, tasks: list[str], timeout: int = 5):
5458
timeout=timeout,
5559
)
5660
except Exception as e:
57-
print(f'Pause task {name} failed: {e}')
61+
LOGGER.exception('Pause task %s failed: %s', name, e)
5862
return True, ''
5963

6064

6165
def play_tasks(pk: int, tasks: list, timeout: int = 5):
6266
node = orm.load_node(pk)
6367
if node.is_finished:
6468
message = 'WorkGraph is finished. Cannot kill tasks.'
65-
print(message)
69+
LOGGER.warning(message)
6670
return False, message
6771
elif node.process_state.value.upper() in [
6872
'CREATED',
@@ -86,15 +90,15 @@ def play_tasks(pk: int, tasks: list, timeout: int = 5):
8690
timeout=timeout,
8791
)
8892
except Exception as e:
89-
print(f'Play task {name} failed: {e}')
93+
LOGGER.exception('Play task %s failed: %s', name, e)
9094
return True, ''
9195

9296

9397
def kill_tasks(pk: int, tasks: list, timeout: int = 5):
9498
node = orm.load_node(pk)
9599
if node.is_finished:
96100
message = 'WorkGraph is finished. Cannot kill tasks.'
97-
print(message)
101+
LOGGER.warning(message)
98102
return False, message
99103
elif node.process_state.value.upper() in [
100104
'CREATED',
@@ -114,7 +118,7 @@ def kill_tasks(pk: int, tasks: list, timeout: int = 5):
114118
'PAUSED',
115119
]:
116120
if process is None:
117-
print(f'Task {name} is not a AiiDA process.')
121+
LOGGER.warning('Task %s is not an AiiDA process.', name)
118122
create_task_action(pk, tasks, action='kill')
119123
else:
120124
try:
@@ -124,7 +128,7 @@ def kill_tasks(pk: int, tasks: list, timeout: int = 5):
124128
timeout=timeout,
125129
)
126130
except Exception as e:
127-
print(f'Kill task {name} failed: {e}')
131+
LOGGER.exception('Kill task %s failed: %s', name, e)
128132
return True, ''
129133

130134

@@ -136,7 +140,7 @@ def reset_tasks(pk: int, tasks: list) -> None:
136140
node = orm.load_node(pk)
137141
if node.is_finished:
138142
message = 'WorkGraph is finished. Cannot kill tasks.'
139-
print(message)
143+
LOGGER.warning(message)
140144
return False, message
141145
elif node.process_state.value.upper() in [
142146
'CREATED',

src/aiida_workgraph/workgraph.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import logging
34
import node_graph
45
import aiida
56
from aiida_workgraph.task import Task
@@ -12,6 +13,8 @@
1213
from aiida_workgraph.socket_spec import SocketSpecAPI
1314
from node_graph.error_handler import ErrorHandlerSpec
1415

16+
LOGGER = logging.getLogger(__name__)
17+
1518

1619
class WorkGraph(node_graph.Graph):
1720
"""Build flexible workflows with AiiDA.
@@ -207,7 +210,7 @@ def save(self, metadata: Optional[Dict[str, Any]] = None) -> None:
207210
self.process = process_inited.node
208211
self.process_inited = process_inited
209212
process_inited.close()
210-
print(f'WorkGraph process created, PK: {self.process.pk}')
213+
LOGGER.info('WorkGraph process created, PK: %s', self.process.pk)
211214
else:
212215
self.save_to_base(inputs)
213216
self.update()
@@ -290,7 +293,7 @@ def wait(self, timeout: int = 600, tasks: dict = None, interval: int = 5) -> Non
290293
finished = self.state in terminating_states
291294

292295
if finished:
293-
print(f'Process {self.process.pk} finished with state: {self.state}')
296+
LOGGER.info('Process %s finished with state: %s', self.process.pk, self.state)
294297
return
295298

296299
time.sleep(interval)
@@ -470,7 +473,7 @@ def kill_tasks(self, tasks: List[str]) -> None:
470473
def reset_tasks(self, tasks: List[str]) -> None:
471474
from aiida_workgraph.utils.control import reset_tasks
472475

473-
print(f'Reset tasks: {tasks}')
476+
LOGGER.info('Reset tasks: %s', tasks)
474477

475478
if self.process is None:
476479
for name in tasks:

0 commit comments

Comments
 (0)