ZahirJS commited on
Commit
d1aacb9
·
verified ·
1 Parent(s): 3cbeab5

Update process_flow_generator.py

Browse files
Files changed (1) hide show
  1. process_flow_generator.py +226 -48
process_flow_generator.py CHANGED
@@ -1,3 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import graphviz
2
  import json
3
  from tempfile import NamedTemporaryFile
@@ -94,84 +281,76 @@ def generate_process_flow_diagram(json_input: str, output_format: str) -> str:
94
  raise ValueError("Missing required fields: 'start_node', 'nodes', or 'connections'")
95
 
96
  node_shapes = {
97
- "process": "box", # Rectangle for processes
98
- "decision": "diamond", # Diamond for decisions
99
- "start": "oval", # Oval for start
100
- "end": "oval", # Oval for end
101
- "io": "parallelogram", # Input/Output
102
- "document": "note", # Document symbol
103
- "default": "box" # Fallback
 
 
 
 
 
 
 
 
 
 
104
  }
105
 
106
  dot = graphviz.Digraph(
107
  name='ProcessFlowDiagram',
108
  format='png',
109
  graph_attr={
110
- 'rankdir': 'TB', # Top-to-Bottom flow is common for flowcharts
111
- 'splines': 'ortho', # Straight lines with 90-degree bends
112
- 'bgcolor': 'white', # White background
113
- 'pad': '0.5', # Padding around the graph
114
- 'nodesep': '0.6', # Spacing between nodes on same rank
115
- 'ranksep': '0.8' # Spacing between ranks
116
  }
117
  )
118
 
119
- base_color = '#19191a'
120
-
121
- fill_color_for_nodes = base_color
122
- font_color_for_nodes = 'white' if base_color == '#19191a' or base_color.lower() in ['#000000', '#19191a'] else 'black'
123
-
124
  all_defined_nodes = {node['id']: node for node in data['nodes']}
125
 
126
  start_node_id = data['start_node']
127
  dot.node(
128
  start_node_id,
129
- start_node_id, # Label is typically the ID itself for start/end
130
  shape=node_shapes['start'],
131
  style='filled,rounded',
132
- fillcolor='#2196F3', # A distinct blue for Start
133
- fontcolor='white',
134
  fontsize='14'
135
  )
136
 
137
  for node_id, node_info in all_defined_nodes.items():
138
- if node_id == start_node_id: # Skip if it's the start node, already added
139
  continue
140
 
141
  node_type = node_info.get("type", "default")
142
  shape = node_shapes.get(node_type, "box")
143
-
144
  node_label = node_info['label']
145
 
146
- # Use distinct color for end node if it exists
147
- if node_type == 'end':
148
- dot.node(
149
- node_id,
150
- node_label,
151
- shape=shape,
152
- style='filled,rounded',
153
- fillcolor='#F44336', # A distinct red for End
154
- fontcolor='white',
155
- fontsize='14'
156
- )
157
- else: # Regular process, decision, etc. nodes use the selected base color
158
- dot.node(
159
- node_id,
160
- node_label,
161
- shape=shape,
162
- style='filled,rounded',
163
- fillcolor=fill_color_for_nodes,
164
- fontcolor=font_color_for_nodes,
165
- fontsize='14'
166
- )
167
-
168
- # Add connections (edges)
169
  for connection in data['connections']:
170
  dot.edge(
171
  connection['from'],
172
  connection['to'],
173
  label=connection.get('label', ''),
174
- color='#4a4a4a', # Dark gray for lines
175
  fontcolor='#4a4a4a',
176
  fontsize='10'
177
  )
@@ -184,4 +363,3 @@ def generate_process_flow_diagram(json_input: str, output_format: str) -> str:
184
  return "Error: Invalid JSON format"
185
  except Exception as e:
186
  return f"Error: {str(e)}"
187
-
 
1
+ # import graphviz
2
+ # import json
3
+ # from tempfile import NamedTemporaryFile
4
+ # import os
5
+
6
+ # def generate_process_flow_diagram(json_input: str, output_format: str) -> str:
7
+ # """
8
+ # Generates a Process Flow Diagram (Flowchart) from JSON input.
9
+
10
+ # Args:
11
+ # json_input (str): A JSON string describing the process flow structure.
12
+ # It must follow the Expected JSON Format Example below.
13
+
14
+ # Expected JSON Format Example:
15
+ # {
16
+ # "start_node": "Start Inference Request",
17
+ # "nodes": [
18
+ # {
19
+ # "id": "user_input",
20
+ # "label": "Receive User Input (Data)",
21
+ # "type": "io"
22
+ # },
23
+ # {
24
+ # "id": "preprocess_data",
25
+ # "label": "Preprocess Data",
26
+ # "type": "process"
27
+ # },
28
+ # {
29
+ # "id": "validate_data",
30
+ # "label": "Validate Data Format/Type",
31
+ # "type": "decision"
32
+ # },
33
+ # {
34
+ # "id": "data_valid_yes",
35
+ # "label": "Data Valid?",
36
+ # "type": "decision"
37
+ # },
38
+ # {
39
+ # "id": "load_model",
40
+ # "label": "Load AI Model (if not cached)",
41
+ # "type": "process"
42
+ # },
43
+ # {
44
+ # "id": "run_inference",
45
+ # "label": "Run AI Model Inference",
46
+ # "type": "process"
47
+ # },
48
+ # {
49
+ # "id": "postprocess_output",
50
+ # "label": "Postprocess Model Output",
51
+ # "type": "process"
52
+ # },
53
+ # {
54
+ # "id": "send_response",
55
+ # "label": "Send Response to User",
56
+ # "type": "io"
57
+ # },
58
+ # {
59
+ # "id": "log_error",
60
+ # "label": "Log Error & Notify User",
61
+ # "type": "process"
62
+ # },
63
+ # {
64
+ # "id": "end_inference_process",
65
+ # "label": "End Inference Process",
66
+ # "type": "end"
67
+ # }
68
+ # ],
69
+ # "connections": [
70
+ # {"from": "start_node", "to": "user_input", "label": "Request"},
71
+ # {"from": "user_input", "to": "preprocess_data", "label": "Data Received"},
72
+ # {"from": "preprocess_data", "to": "validate_data", "label": "Cleaned"},
73
+ # {"from": "validate_data", "to": "data_valid_yes", "label": "Check"},
74
+ # {"from": "data_valid_yes", "to": "load_model", "label": "Yes"},
75
+ # {"from": "data_valid_yes", "to": "log_error", "label": "No"},
76
+ # {"from": "load_model", "to": "run_inference", "label": "Model Ready"},
77
+ # {"from": "run_inference", "to": "postprocess_output", "label": "Output Generated"},
78
+ # {"from": "postprocess_output", "to": "send_response", "label": "Ready"},
79
+ # {"from": "send_response", "to": "end_inference_process", "label": "Response Sent"},
80
+ # {"from": "log_error", "to": "end_inference_process", "label": "Error Handled"}
81
+ # ]
82
+ # }
83
+
84
+ # Returns:
85
+ # str: The filepath to the generated PNG image file.
86
+ # """
87
+ # try:
88
+ # if not json_input.strip():
89
+ # return "Error: Empty input"
90
+
91
+ # data = json.loads(json_input)
92
+
93
+ # if 'start_node' not in data or 'nodes' not in data or 'connections' not in data:
94
+ # raise ValueError("Missing required fields: 'start_node', 'nodes', or 'connections'")
95
+
96
+ # node_shapes = {
97
+ # "process": "box", # Rectangle for processes
98
+ # "decision": "diamond", # Diamond for decisions
99
+ # "start": "oval", # Oval for start
100
+ # "end": "oval", # Oval for end
101
+ # "io": "parallelogram", # Input/Output
102
+ # "document": "note", # Document symbol
103
+ # "default": "box" # Fallback
104
+ # }
105
+
106
+ # dot = graphviz.Digraph(
107
+ # name='ProcessFlowDiagram',
108
+ # format='png',
109
+ # graph_attr={
110
+ # 'rankdir': 'TB', # Top-to-Bottom flow is common for flowcharts
111
+ # 'splines': 'ortho', # Straight lines with 90-degree bends
112
+ # 'bgcolor': 'white', # White background
113
+ # 'pad': '0.5', # Padding around the graph
114
+ # 'nodesep': '0.6', # Spacing between nodes on same rank
115
+ # 'ranksep': '0.8' # Spacing between ranks
116
+ # }
117
+ # )
118
+
119
+ # base_color = '#19191a'
120
+
121
+ # fill_color_for_nodes = base_color
122
+ # font_color_for_nodes = 'white' if base_color == '#19191a' or base_color.lower() in ['#000000', '#19191a'] else 'black'
123
+
124
+ # all_defined_nodes = {node['id']: node for node in data['nodes']}
125
+
126
+ # start_node_id = data['start_node']
127
+ # dot.node(
128
+ # start_node_id,
129
+ # start_node_id, # Label is typically the ID itself for start/end
130
+ # shape=node_shapes['start'],
131
+ # style='filled,rounded',
132
+ # fillcolor='#2196F3', # A distinct blue for Start
133
+ # fontcolor='white',
134
+ # fontsize='14'
135
+ # )
136
+
137
+ # for node_id, node_info in all_defined_nodes.items():
138
+ # if node_id == start_node_id: # Skip if it's the start node, already added
139
+ # continue
140
+
141
+ # node_type = node_info.get("type", "default")
142
+ # shape = node_shapes.get(node_type, "box")
143
+
144
+ # node_label = node_info['label']
145
+
146
+ # # Use distinct color for end node if it exists
147
+ # if node_type == 'end':
148
+ # dot.node(
149
+ # node_id,
150
+ # node_label,
151
+ # shape=shape,
152
+ # style='filled,rounded',
153
+ # fillcolor='#F44336', # A distinct red for End
154
+ # fontcolor='white',
155
+ # fontsize='14'
156
+ # )
157
+ # else: # Regular process, decision, etc. nodes use the selected base color
158
+ # dot.node(
159
+ # node_id,
160
+ # node_label,
161
+ # shape=shape,
162
+ # style='filled,rounded',
163
+ # fillcolor=fill_color_for_nodes,
164
+ # fontcolor=font_color_for_nodes,
165
+ # fontsize='14'
166
+ # )
167
+
168
+ # # Add connections (edges)
169
+ # for connection in data['connections']:
170
+ # dot.edge(
171
+ # connection['from'],
172
+ # connection['to'],
173
+ # label=connection.get('label', ''),
174
+ # color='#4a4a4a', # Dark gray for lines
175
+ # fontcolor='#4a4a4a',
176
+ # fontsize='10'
177
+ # )
178
+
179
+ # with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
180
+ # dot.render(tmp.name, format=output_format, cleanup=True)
181
+ # return f"{tmp.name}.{output_format}"
182
+
183
+ # except json.JSONDecodeError:
184
+ # return "Error: Invalid JSON format"
185
+ # except Exception as e:
186
+ # return f"Error: {str(e)}"
187
+
188
  import graphviz
189
  import json
190
  from tempfile import NamedTemporaryFile
 
281
  raise ValueError("Missing required fields: 'start_node', 'nodes', or 'connections'")
282
 
283
  node_shapes = {
284
+ "process": "box",
285
+ "decision": "diamond",
286
+ "start": "oval",
287
+ "end": "oval",
288
+ "io": "parallelogram",
289
+ "document": "note",
290
+ "default": "box"
291
+ }
292
+
293
+ node_colors = {
294
+ "process": "#BEBEBE",
295
+ "decision": "#B8D4F1",
296
+ "start": "#A8E6CF",
297
+ "end": "#FFB3BA",
298
+ "io": "#D4A5FF",
299
+ "document": "#F0F8FF",
300
+ "default": "#BEBEBE"
301
  }
302
 
303
  dot = graphviz.Digraph(
304
  name='ProcessFlowDiagram',
305
  format='png',
306
  graph_attr={
307
+ 'rankdir': 'TB',
308
+ 'splines': 'ortho',
309
+ 'bgcolor': 'white',
310
+ 'pad': '0.5',
311
+ 'nodesep': '0.6',
312
+ 'ranksep': '0.8'
313
  }
314
  )
315
 
 
 
 
 
 
316
  all_defined_nodes = {node['id']: node for node in data['nodes']}
317
 
318
  start_node_id = data['start_node']
319
  dot.node(
320
  start_node_id,
321
+ start_node_id,
322
  shape=node_shapes['start'],
323
  style='filled,rounded',
324
+ fillcolor=node_colors['start'],
325
+ fontcolor='black',
326
  fontsize='14'
327
  )
328
 
329
  for node_id, node_info in all_defined_nodes.items():
330
+ if node_id == start_node_id:
331
  continue
332
 
333
  node_type = node_info.get("type", "default")
334
  shape = node_shapes.get(node_type, "box")
335
+ color = node_colors.get(node_type, node_colors["default"])
336
  node_label = node_info['label']
337
 
338
+ dot.node(
339
+ node_id,
340
+ node_label,
341
+ shape=shape,
342
+ style='filled,rounded',
343
+ fillcolor=color,
344
+ fontcolor='black',
345
+ fontsize='14'
346
+ )
347
+
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  for connection in data['connections']:
349
  dot.edge(
350
  connection['from'],
351
  connection['to'],
352
  label=connection.get('label', ''),
353
+ color='#4a4a4a',
354
  fontcolor='#4a4a4a',
355
  fontsize='10'
356
  )
 
363
  return "Error: Invalid JSON format"
364
  except Exception as e:
365
  return f"Error: {str(e)}"