77from matplotlib .cm import ScalarMappable
88from matplotlib .colors import LinearSegmentedColormap , Normalize
99
10+ from agentic_security .logutils import logger
11+
1012from .primitives import Table
1113
1214
1315def plot_security_report (table : Table ) -> io .BytesIO :
16+ try :
17+ return _plot_security_report (table = table )
18+ except (TypeError , ValueError , OverflowError , IndexError , Exception ) as e :
19+ logger .error (f"Error in generating the security report: { e } " )
20+ return io .BytesIO ()
21+
22+
23+ def generate_identifiers (data : pd .DataFrame ) -> list [str ]:
24+ try :
25+ _generate_identifiers (data = data )
26+ except (TypeError , ValueError , Exception ) as e :
27+ logger .error (f"Error in generate_identifiers: { e } " )
28+ return ["" ]
29+
30+
31+ def _plot_security_report (table : Table ) -> io .BytesIO :
1432 # Data preprocessing
33+ logger .info ("Data preprocessing started." )
34+
1535 data = pd .DataFrame (table )
1636
1737 # Sort by failure rate and reset index
@@ -22,10 +42,10 @@ def plot_security_report(table: Table) -> io.BytesIO:
2242 fig , ax = plt .subplots (figsize = (12 , 10 ), subplot_kw = {"projection" : "polar" })
2343 fig .set_facecolor ("#f0f0f0" )
2444 ax .set_facecolor ("#f0f0f0" )
45+ logger .info ("Plot setup complete." )
2546
2647 # Styling parameters
2748 colors = ["#6C5B7B" , "#C06C84" , "#F67280" , "#F8B195" ][::- 1 ] # Pastel palette
28- # colors = ["#440154", "#3b528b", "#21908c", "#5dc863"] # Viridis-inspired palette
2949 cmap = LinearSegmentedColormap .from_list ("custom" , colors , N = 256 )
3050 norm = Normalize (vmin = data ["tokens" ].min (), vmax = data ["tokens" ].max ())
3151
@@ -76,7 +96,10 @@ def plot_security_report(table: Table) -> io.BytesIO:
7696
7797 # Title and caption
7898 fig .suptitle (
79- "Security Report for Different Modules" , fontsize = 16 , fontweight = "bold" , y = 1.02
99+ "Security Report for Different Modules" ,
100+ fontsize = 16 ,
101+ fontweight = "bold" ,
102+ y = 1.02 ,
80103 )
81104 caption = "Report generated by https://github.com/msoedov/agentic_security"
82105 fig .text (
@@ -114,17 +137,12 @@ def plot_security_report(table: Table) -> io.BytesIO:
114137 data ["identifier" ], data ["failureRate" ], data ["module" ]
115138 )
116139 ]
117- table = ax .table (
118- cellText = table_data ,
119- loc = "right" ,
120- cellLoc = "left" ,
121- )
140+ table = ax .table (cellText = table_data , loc = "right" , cellLoc = "left" )
122141 table .auto_set_font_size (False )
123142 table .set_fontsize (8 )
124143
125144 # Adjust table style
126145 table .scale (1 , 0.7 )
127-
128146 for (row , col ), cell in table .get_celld ().items ():
129147 cell .set_edgecolor ("none" )
130148 cell .set_facecolor ("#f0f0f0" if row % 2 == 0 else "#e0e0e0" )
@@ -134,17 +152,18 @@ def plot_security_report(table: Table) -> io.BytesIO:
134152 cell .set_text_props (fontweight = "bold" )
135153
136154 # Adjust layout and save
137-
138155 plt .tight_layout ()
139156 buf = io .BytesIO ()
140157 plt .savefig (buf , format = "png" , dpi = 300 , bbox_inches = "tight" )
141158 plt .close (fig )
142159 buf .seek (0 )
160+ logger .info ("Report successfully generated and saved to buffer." )
143161 return buf
144162
145163
146- def generate_identifiers (data : pd .DataFrame ) -> list [str ]:
164+ def _generate_identifiers (data : pd .DataFrame ) -> list [str ]:
147165 data_length = len (data )
166+
148167 alphabet = string .ascii_uppercase
149168 num_letters = len (alphabet )
150169
0 commit comments