runbooks 1.1.4__py3-none-any.whl → 1.1.6__py3-none-any.whl

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.
Files changed (273) hide show
  1. runbooks/__init__.py +31 -2
  2. runbooks/__init___optimized.py +18 -4
  3. runbooks/_platform/__init__.py +1 -5
  4. runbooks/_platform/core/runbooks_wrapper.py +141 -138
  5. runbooks/aws2/accuracy_validator.py +812 -0
  6. runbooks/base.py +7 -0
  7. runbooks/cfat/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +135 -91
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +17 -12
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +99 -79
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +315 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/aws_decorators.py +2 -3
  113. runbooks/inventory/check_cloudtrail_compliance.py +2 -4
  114. runbooks/inventory/check_controltower_readiness.py +152 -151
  115. runbooks/inventory/check_landingzone_readiness.py +85 -84
  116. runbooks/inventory/cloud_foundations_integration.py +144 -149
  117. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  118. runbooks/inventory/collectors/aws_networking.py +109 -99
  119. runbooks/inventory/collectors/base.py +4 -0
  120. runbooks/inventory/core/collector.py +495 -313
  121. runbooks/inventory/core/formatter.py +11 -0
  122. runbooks/inventory/draw_org_structure.py +8 -9
  123. runbooks/inventory/drift_detection_cli.py +69 -96
  124. runbooks/inventory/ec2_vpc_utils.py +2 -2
  125. runbooks/inventory/find_cfn_drift_detection.py +5 -7
  126. runbooks/inventory/find_cfn_orphaned_stacks.py +7 -9
  127. runbooks/inventory/find_cfn_stackset_drift.py +5 -6
  128. runbooks/inventory/find_ec2_security_groups.py +48 -42
  129. runbooks/inventory/find_landingzone_versions.py +4 -6
  130. runbooks/inventory/find_vpc_flow_logs.py +7 -9
  131. runbooks/inventory/inventory_mcp_cli.py +48 -46
  132. runbooks/inventory/inventory_modules.py +103 -91
  133. runbooks/inventory/list_cfn_stacks.py +9 -10
  134. runbooks/inventory/list_cfn_stackset_operation_results.py +1 -3
  135. runbooks/inventory/list_cfn_stackset_operations.py +79 -57
  136. runbooks/inventory/list_cfn_stacksets.py +8 -10
  137. runbooks/inventory/list_config_recorders_delivery_channels.py +49 -39
  138. runbooks/inventory/list_ds_directories.py +65 -53
  139. runbooks/inventory/list_ec2_availability_zones.py +2 -4
  140. runbooks/inventory/list_ec2_ebs_volumes.py +32 -35
  141. runbooks/inventory/list_ec2_instances.py +23 -28
  142. runbooks/inventory/list_ecs_clusters_and_tasks.py +26 -34
  143. runbooks/inventory/list_elbs_load_balancers.py +22 -20
  144. runbooks/inventory/list_enis_network_interfaces.py +26 -33
  145. runbooks/inventory/list_guardduty_detectors.py +2 -4
  146. runbooks/inventory/list_iam_policies.py +2 -4
  147. runbooks/inventory/list_iam_roles.py +5 -7
  148. runbooks/inventory/list_iam_saml_providers.py +4 -6
  149. runbooks/inventory/list_lambda_functions.py +38 -38
  150. runbooks/inventory/list_org_accounts.py +6 -8
  151. runbooks/inventory/list_org_accounts_users.py +55 -44
  152. runbooks/inventory/list_rds_db_instances.py +31 -33
  153. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  154. runbooks/inventory/list_route53_hosted_zones.py +3 -5
  155. runbooks/inventory/list_servicecatalog_provisioned_products.py +37 -41
  156. runbooks/inventory/list_sns_topics.py +2 -4
  157. runbooks/inventory/list_ssm_parameters.py +4 -7
  158. runbooks/inventory/list_vpc_subnets.py +2 -4
  159. runbooks/inventory/list_vpcs.py +7 -10
  160. runbooks/inventory/mcp_inventory_validator.py +554 -468
  161. runbooks/inventory/mcp_vpc_validator.py +359 -442
  162. runbooks/inventory/organizations_discovery.py +63 -55
  163. runbooks/inventory/recover_cfn_stack_ids.py +7 -8
  164. runbooks/inventory/requirements.txt +0 -1
  165. runbooks/inventory/rich_inventory_display.py +35 -34
  166. runbooks/inventory/run_on_multi_accounts.py +3 -5
  167. runbooks/inventory/unified_validation_engine.py +281 -253
  168. runbooks/inventory/verify_ec2_security_groups.py +1 -1
  169. runbooks/inventory/vpc_analyzer.py +735 -697
  170. runbooks/inventory/vpc_architecture_validator.py +293 -348
  171. runbooks/inventory/vpc_dependency_analyzer.py +384 -380
  172. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  173. runbooks/main.py +49 -34
  174. runbooks/main_final.py +91 -60
  175. runbooks/main_minimal.py +22 -10
  176. runbooks/main_optimized.py +131 -100
  177. runbooks/main_ultra_minimal.py +7 -2
  178. runbooks/mcp/__init__.py +36 -0
  179. runbooks/mcp/integration.py +679 -0
  180. runbooks/monitoring/performance_monitor.py +9 -4
  181. runbooks/operate/dynamodb_operations.py +3 -1
  182. runbooks/operate/ec2_operations.py +145 -137
  183. runbooks/operate/iam_operations.py +146 -152
  184. runbooks/operate/networking_cost_heatmap.py +29 -8
  185. runbooks/operate/rds_operations.py +223 -254
  186. runbooks/operate/s3_operations.py +107 -118
  187. runbooks/operate/vpc_operations.py +646 -616
  188. runbooks/remediation/base.py +1 -1
  189. runbooks/remediation/commons.py +10 -7
  190. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  191. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  192. runbooks/remediation/multi_account.py +24 -21
  193. runbooks/remediation/rds_snapshot_list.py +86 -60
  194. runbooks/remediation/remediation_cli.py +92 -146
  195. runbooks/remediation/universal_account_discovery.py +83 -79
  196. runbooks/remediation/workspaces_list.py +46 -41
  197. runbooks/security/__init__.py +19 -0
  198. runbooks/security/assessment_runner.py +1150 -0
  199. runbooks/security/baseline_checker.py +812 -0
  200. runbooks/security/cloudops_automation_security_validator.py +509 -535
  201. runbooks/security/compliance_automation_engine.py +17 -17
  202. runbooks/security/config/__init__.py +2 -2
  203. runbooks/security/config/compliance_config.py +50 -50
  204. runbooks/security/config_template_generator.py +63 -76
  205. runbooks/security/enterprise_security_framework.py +1 -1
  206. runbooks/security/executive_security_dashboard.py +519 -508
  207. runbooks/security/multi_account_security_controls.py +959 -1210
  208. runbooks/security/real_time_security_monitor.py +422 -444
  209. runbooks/security/security_baseline_tester.py +1 -1
  210. runbooks/security/security_cli.py +143 -112
  211. runbooks/security/test_2way_validation.py +439 -0
  212. runbooks/security/two_way_validation_framework.py +852 -0
  213. runbooks/sre/production_monitoring_framework.py +167 -177
  214. runbooks/tdd/__init__.py +15 -0
  215. runbooks/tdd/cli.py +1071 -0
  216. runbooks/utils/__init__.py +14 -17
  217. runbooks/utils/logger.py +7 -2
  218. runbooks/utils/version_validator.py +50 -47
  219. runbooks/validation/__init__.py +6 -6
  220. runbooks/validation/cli.py +9 -3
  221. runbooks/validation/comprehensive_2way_validator.py +745 -704
  222. runbooks/validation/mcp_validator.py +906 -228
  223. runbooks/validation/terraform_citations_validator.py +104 -115
  224. runbooks/validation/terraform_drift_detector.py +461 -454
  225. runbooks/vpc/README.md +617 -0
  226. runbooks/vpc/__init__.py +8 -1
  227. runbooks/vpc/analyzer.py +577 -0
  228. runbooks/vpc/cleanup_wrapper.py +476 -413
  229. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  230. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  231. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  232. runbooks/vpc/config.py +92 -97
  233. runbooks/vpc/cost_engine.py +411 -148
  234. runbooks/vpc/cost_explorer_integration.py +553 -0
  235. runbooks/vpc/cross_account_session.py +101 -106
  236. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  237. runbooks/vpc/eni_gate_validator.py +961 -0
  238. runbooks/vpc/heatmap_engine.py +185 -160
  239. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  240. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  241. runbooks/vpc/networking_wrapper.py +15 -8
  242. runbooks/vpc/pdca_remediation_planner.py +528 -0
  243. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  244. runbooks/vpc/runbooks_adapter.py +1167 -241
  245. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  246. runbooks/vpc/test_data_loader.py +358 -0
  247. runbooks/vpc/tests/conftest.py +314 -4
  248. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  249. runbooks/vpc/tests/test_cost_engine.py +0 -2
  250. runbooks/vpc/topology_generator.py +326 -0
  251. runbooks/vpc/unified_scenarios.py +1297 -1124
  252. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  253. runbooks-1.1.6.dist-info/METADATA +327 -0
  254. runbooks-1.1.6.dist-info/RECORD +489 -0
  255. runbooks/finops/README.md +0 -414
  256. runbooks/finops/accuracy_cross_validator.py +0 -647
  257. runbooks/finops/business_cases.py +0 -950
  258. runbooks/finops/dashboard_router.py +0 -922
  259. runbooks/finops/ebs_optimizer.py +0 -973
  260. runbooks/finops/embedded_mcp_validator.py +0 -1629
  261. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  262. runbooks/finops/finops_dashboard.py +0 -584
  263. runbooks/finops/finops_scenarios.py +0 -1218
  264. runbooks/finops/legacy_migration.py +0 -730
  265. runbooks/finops/multi_dashboard.py +0 -1519
  266. runbooks/finops/single_dashboard.py +0 -1113
  267. runbooks/finops/unlimited_scenarios.py +0 -393
  268. runbooks-1.1.4.dist-info/METADATA +0 -800
  269. runbooks-1.1.4.dist-info/RECORD +0 -468
  270. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/WHEEL +0 -0
  271. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/entry_points.txt +0 -0
  272. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/licenses/LICENSE +0 -0
  273. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/top_level.txt +0 -0
@@ -81,17 +81,17 @@ class DRYPatternManager:
81
81
  return
82
82
 
83
83
  # Common import patterns
84
- cls._patterns['click'] = click
85
- cls._patterns['console'] = cls.get_console()
84
+ cls._patterns["click"] = click
85
+ cls._patterns["console"] = cls.get_console()
86
86
 
87
87
  # Error handling patterns
88
- cls._patterns['error_handlers'] = cls._create_error_handlers()
88
+ cls._patterns["error_handlers"] = cls._create_error_handlers()
89
89
 
90
90
  # Click group patterns
91
- cls._patterns['click_group'] = cls._create_click_group_pattern()
91
+ cls._patterns["click_group"] = cls._create_click_group_pattern()
92
92
 
93
93
  # Common CLI decorators reference
94
- cls._patterns['common_decorators'] = cls._get_common_decorators()
94
+ cls._patterns["common_decorators"] = cls._get_common_decorators()
95
95
 
96
96
  cls._loaded = True
97
97
 
@@ -119,9 +119,9 @@ class DRYPatternManager:
119
119
  console.print(f"[dim]{details}[/dim]")
120
120
 
121
121
  return {
122
- 'module_not_available': module_not_available_error,
123
- 'operation_failed': operation_failed_error,
124
- 'success': success_message
122
+ "module_not_available": module_not_available_error,
123
+ "operation_failed": operation_failed_error,
124
+ "success": success_message,
125
125
  }
126
126
 
127
127
  @classmethod
@@ -131,6 +131,7 @@ class DRYPatternManager:
131
131
 
132
132
  Eliminates 6 instances of identical @click.group patterns.
133
133
  """
134
+
134
135
  def create_group(name: str, help_text: str, invoke_without_command: bool = True):
135
136
  """Create standardized Click group with common options."""
136
137
 
@@ -153,15 +154,12 @@ class DRYPatternManager:
153
154
  def _get_common_decorators(cls):
154
155
  """Reference to common decorators - avoid importing in every module."""
155
156
  try:
156
- from runbooks.common.decorators import (
157
- common_aws_options,
158
- common_output_options,
159
- common_filter_options
160
- )
157
+ from runbooks.common.decorators import common_aws_options, common_output_options, common_filter_options
158
+
161
159
  return {
162
- 'aws_options': common_aws_options,
163
- 'output_options': common_output_options,
164
- 'filter_options': common_filter_options
160
+ "aws_options": common_aws_options,
161
+ "output_options": common_output_options,
162
+ "filter_options": common_filter_options,
165
163
  }
166
164
  except ImportError:
167
165
  # Graceful degradation if decorators not available
@@ -176,17 +174,17 @@ def get_console() -> Console:
176
174
 
177
175
  def get_error_handlers() -> Dict[str, Callable]:
178
176
  """Get standardized error handlers."""
179
- return DRYPatternManager.get_pattern('error_handlers')
177
+ return DRYPatternManager.get_pattern("error_handlers")
180
178
 
181
179
 
182
180
  def get_click_group_creator() -> Callable:
183
181
  """Get standardized Click group creator."""
184
- return DRYPatternManager.get_pattern('click_group')
182
+ return DRYPatternManager.get_pattern("click_group")
185
183
 
186
184
 
187
185
  def get_common_decorators() -> Dict[str, Any]:
188
186
  """Get common CLI decorators."""
189
- return DRYPatternManager.get_pattern('common_decorators')
187
+ return DRYPatternManager.get_pattern("common_decorators")
190
188
 
191
189
 
192
190
  # Pattern registry status for monitoring
@@ -198,9 +196,9 @@ def get_pattern_registry_status() -> Dict[str, Any]:
198
196
  Dictionary containing registry status, loaded patterns, and memory efficiency metrics
199
197
  """
200
198
  return {
201
- 'loaded': DRYPatternManager._loaded,
202
- 'pattern_count': len(DRYPatternManager._patterns),
203
- 'available_patterns': list(DRYPatternManager._patterns.keys()),
204
- 'console_shared': DRYPatternManager._console is not None,
205
- 'memory_efficiency': 'Single instance sharing active'
206
- }
199
+ "loaded": DRYPatternManager._loaded,
200
+ "pattern_count": len(DRYPatternManager._patterns),
201
+ "available_patterns": list(DRYPatternManager._patterns.keys()),
202
+ "console_shared": DRYPatternManager._console is not None,
203
+ "memory_efficiency": "Single instance sharing active",
204
+ }
@@ -25,14 +25,21 @@ from datetime import datetime
25
25
  import json
26
26
 
27
27
  from runbooks.common.rich_utils import (
28
- console, print_success, print_warning, print_info, print_error,
29
- create_table, create_progress_bar, STATUS_INDICATORS
28
+ console,
29
+ print_success,
30
+ print_warning,
31
+ print_info,
32
+ print_error,
33
+ create_table,
34
+ create_progress_bar,
35
+ STATUS_INDICATORS,
30
36
  )
31
37
 
32
38
 
33
39
  @dataclass
34
40
  class PerformanceMetrics:
35
41
  """Enterprise performance metrics tracking."""
42
+
36
43
  operation_name: str
37
44
  module_name: str
38
45
  start_time: float
@@ -68,21 +75,22 @@ class PerformanceMetrics:
68
75
  "api_calls": self.api_calls_count,
69
76
  "success": self.success,
70
77
  "business_value": self.business_value,
71
- "resources_processed": self.resources_processed
78
+ "resources_processed": self.resources_processed,
72
79
  }
73
80
 
74
81
 
75
82
  @dataclass
76
83
  class ModulePerformanceTargets:
77
84
  """Module-specific performance targets for enterprise operations."""
78
- finops: int = 15 # FinOps cost analysis operations
79
- inventory: int = 45 # Multi-account discovery operations
80
- operate: int = 15 # Resource operations with safety validation
81
- security: int = 45 # Comprehensive security assessments
82
- cfat: int = 60 # Cloud foundations assessments
83
- vpc: int = 30 # Network analysis with cost integration
84
- remediation: int = 15 # Automated security remediation
85
- sre: int = 30 # Site reliability engineering operations
85
+
86
+ finops: int = 15 # FinOps cost analysis operations
87
+ inventory: int = 45 # Multi-account discovery operations
88
+ operate: int = 15 # Resource operations with safety validation
89
+ security: int = 45 # Comprehensive security assessments
90
+ cfat: int = 60 # Cloud foundations assessments
91
+ vpc: int = 30 # Network analysis with cost integration
92
+ remediation: int = 15 # Automated security remediation
93
+ sre: int = 30 # Site reliability engineering operations
86
94
 
87
95
  def get_target(self, module_name: str) -> int:
88
96
  """Get performance target for module."""
@@ -107,10 +115,12 @@ def reset_api_counter():
107
115
  _api_call_counter = 0
108
116
 
109
117
 
110
- def monitor_performance(module_name: str = "runbooks",
111
- operation_name: Optional[str] = None,
112
- target_seconds: Optional[int] = None,
113
- track_memory: bool = True):
118
+ def monitor_performance(
119
+ module_name: str = "runbooks",
120
+ operation_name: Optional[str] = None,
121
+ target_seconds: Optional[int] = None,
122
+ track_memory: bool = True,
123
+ ):
114
124
  """
115
125
  Decorator for comprehensive performance monitoring.
116
126
 
@@ -128,6 +138,7 @@ def monitor_performance(module_name: str = "runbooks",
128
138
  def analyze_costs(**kwargs):
129
139
  # Your operation code here
130
140
  """
141
+
131
142
  def decorator(f: Callable) -> Callable:
132
143
  @wraps(f)
133
144
  def wrapper(*args, **kwargs):
@@ -143,7 +154,7 @@ def monitor_performance(module_name: str = "runbooks",
143
154
  module_name=module_name,
144
155
  start_time=time.time(),
145
156
  end_time=0.0,
146
- target_seconds=target
157
+ target_seconds=target,
147
158
  )
148
159
 
149
160
  # Start memory tracking if enabled
@@ -166,8 +177,8 @@ def monitor_performance(module_name: str = "runbooks",
166
177
 
167
178
  # Extract business metrics if available
168
179
  if isinstance(result, dict):
169
- metrics.business_value = result.get('annual_savings', 0.0)
170
- metrics.resources_processed = result.get('resources_count', 0)
180
+ metrics.business_value = result.get("annual_savings", 0.0)
181
+ metrics.resources_processed = result.get("resources_count", 0)
171
182
 
172
183
  # Capture performance data
173
184
  metrics.api_calls_count = _api_call_counter
@@ -205,6 +216,7 @@ def monitor_performance(module_name: str = "runbooks",
205
216
  raise
206
217
 
207
218
  return wrapper
219
+
208
220
  return decorator
209
221
 
210
222
 
@@ -221,8 +233,7 @@ def _provide_performance_feedback(metrics: PerformanceMetrics):
221
233
  if execution_time <= target:
222
234
  # Performance target met
223
235
  print_success(
224
- f"⚡ Performance: {execution_time:.1f}s "
225
- f"(target: <{target}s) - {metrics.efficiency_score:.1f}% efficient"
236
+ f"⚡ Performance: {execution_time:.1f}s (target: <{target}s) - {metrics.efficiency_score:.1f}% efficient"
226
237
  )
227
238
 
228
239
  # Celebrate exceptional performance
@@ -232,8 +243,7 @@ def _provide_performance_feedback(metrics: PerformanceMetrics):
232
243
  else:
233
244
  # Performance target exceeded
234
245
  print_warning(
235
- f"⚠️ Performance: {execution_time:.1f}s "
236
- f"(exceeded {target}s target by {execution_time - target:.1f}s)"
246
+ f"⚠️ Performance: {execution_time:.1f}s (exceeded {target}s target by {execution_time - target:.1f}s)"
237
247
  )
238
248
 
239
249
  # Provide optimization recommendations
@@ -269,16 +279,10 @@ def _provide_optimization_recommendations(metrics: PerformanceMetrics):
269
279
  module_recommendations = {
270
280
  "finops": [
271
281
  "Use more specific date ranges to reduce Cost Explorer data",
272
- "Consider account filtering for large organizations"
282
+ "Consider account filtering for large organizations",
273
283
  ],
274
- "inventory": [
275
- "Use service-specific discovery instead of full scan",
276
- "Implement parallel account processing"
277
- ],
278
- "security": [
279
- "Focus on high-priority security checks first",
280
- "Use incremental scanning for large environments"
281
- ]
284
+ "inventory": ["Use service-specific discovery instead of full scan", "Implement parallel account processing"],
285
+ "security": ["Focus on high-priority security checks first", "Use incremental scanning for large environments"],
282
286
  }
283
287
 
284
288
  if metrics.module_name in module_recommendations:
@@ -286,8 +290,7 @@ def _provide_optimization_recommendations(metrics: PerformanceMetrics):
286
290
  print_info(f" • {rec}")
287
291
 
288
292
 
289
- def benchmark_operation(module_name: str, operation_name: str,
290
- target_calls: int = 10):
293
+ def benchmark_operation(module_name: str, operation_name: str, target_calls: int = 10):
291
294
  """
292
295
  Decorator for benchmarking operation performance over multiple runs.
293
296
 
@@ -301,6 +304,7 @@ def benchmark_operation(module_name: str, operation_name: str,
301
304
  def analyze_costs(**kwargs):
302
305
  # Your operation code here
303
306
  """
307
+
304
308
  def decorator(f: Callable) -> Callable:
305
309
  @wraps(f)
306
310
  def wrapper(*args, **kwargs):
@@ -313,8 +317,7 @@ def benchmark_operation(module_name: str, operation_name: str,
313
317
 
314
318
  # Execute with monitoring
315
319
  monitored_func = monitor_performance(
316
- module_name=module_name,
317
- operation_name=f"{operation_name}_benchmark_{run+1}"
320
+ module_name=module_name, operation_name=f"{operation_name}_benchmark_{run + 1}"
318
321
  )(f)
319
322
 
320
323
  result = monitored_func(*args, **kwargs)
@@ -329,6 +332,7 @@ def benchmark_operation(module_name: str, operation_name: str,
329
332
  return result
330
333
 
331
334
  return wrapper
335
+
332
336
  return decorator
333
337
 
334
338
 
@@ -360,28 +364,30 @@ def _analyze_benchmark_results(results: List[PerformanceMetrics], operation_name
360
364
  columns=[
361
365
  {"name": "Metric", "style": "cyan"},
362
366
  {"name": "Value", "style": "green"},
363
- {"name": "Assessment", "style": "yellow"}
364
- ]
367
+ {"name": "Assessment", "style": "yellow"},
368
+ ],
365
369
  )
366
370
 
367
371
  target = results[0].target_seconds
368
372
 
369
- table.add_row("Average Time", f"{avg_time:.2f}s",
370
- " Good" if avg_time <= target else "⚠️ Needs optimization")
371
- table.add_row("Best Time", f"{min_time:.2f}s",
372
- "🏆 Excellent" if min_time <= target * 0.5 else "✅ Good")
373
- table.add_row("Worst Time", f"{max_time:.2f}s",
374
- "⚠️ Investigate" if max_time > target * 1.5 else "✅ Acceptable")
375
- table.add_row("Success Rate", f"{len(execution_times)}/{len(results)}",
376
- "✅ Perfect" if len(execution_times) == len(results) else "⚠️ Some failures")
377
- table.add_row("Consistency", f"±{(max_time - min_time):.2f}s",
378
- "✅ Consistent" if (max_time - min_time) <= target * 0.2 else "⚠️ Variable")
373
+ table.add_row("Average Time", f"{avg_time:.2f}s", "✅ Good" if avg_time <= target else "⚠️ Needs optimization")
374
+ table.add_row("Best Time", f"{min_time:.2f}s", "🏆 Excellent" if min_time <= target * 0.5 else " Good")
375
+ table.add_row("Worst Time", f"{max_time:.2f}s", "⚠️ Investigate" if max_time > target * 1.5 else "✅ Acceptable")
376
+ table.add_row(
377
+ "Success Rate",
378
+ f"{len(execution_times)}/{len(results)}",
379
+ " Perfect" if len(execution_times) == len(results) else "⚠️ Some failures",
380
+ )
381
+ table.add_row(
382
+ "Consistency",
383
+ f"±{(max_time - min_time):.2f}s",
384
+ "✅ Consistent" if (max_time - min_time) <= target * 0.2 else "⚠️ Variable",
385
+ )
379
386
 
380
387
  console.print(table)
381
388
 
382
389
 
383
- def get_performance_report(module_name: Optional[str] = None,
384
- last_n_operations: int = 10) -> Dict[str, Any]:
390
+ def get_performance_report(module_name: Optional[str] = None, last_n_operations: int = 10) -> Dict[str, Any]:
385
391
  """
386
392
  Generate performance report for operations.
387
393
 
@@ -395,8 +401,7 @@ def get_performance_report(module_name: Optional[str] = None,
395
401
  # Filter operations
396
402
  filtered_operations = _performance_history
397
403
  if module_name:
398
- filtered_operations = [op for op in filtered_operations
399
- if op.module_name == module_name]
404
+ filtered_operations = [op for op in filtered_operations if op.module_name == module_name]
400
405
 
401
406
  # Get recent operations
402
407
  recent_operations = filtered_operations[-last_n_operations:]
@@ -418,10 +423,10 @@ def get_performance_report(module_name: Optional[str] = None,
418
423
  "failed_operations": len(failed_ops),
419
424
  "success_rate_percent": (len(successful_ops) / len(recent_operations)) * 100,
420
425
  "average_execution_time": round(avg_time, 2),
421
- "average_efficiency_score": round(avg_efficiency, 1)
426
+ "average_efficiency_score": round(avg_efficiency, 1),
422
427
  },
423
428
  "operations": [op.to_dict() for op in recent_operations],
424
- "recommendations": _generate_performance_recommendations(recent_operations)
429
+ "recommendations": _generate_performance_recommendations(recent_operations),
425
430
  }
426
431
 
427
432
  return report
@@ -435,17 +440,12 @@ def _generate_performance_recommendations(operations: List[PerformanceMetrics])
435
440
  return recommendations
436
441
 
437
442
  # Analyze patterns
438
- slow_operations = [op for op in operations
439
- if op.success and op.performance_ratio > 1.5]
440
- high_memory_operations = [op for op in operations
441
- if op.memory_peak_mb > 150]
442
- high_api_operations = [op for op in operations
443
- if op.api_calls_count > 50]
443
+ slow_operations = [op for op in operations if op.success and op.performance_ratio > 1.5]
444
+ high_memory_operations = [op for op in operations if op.memory_peak_mb > 150]
445
+ high_api_operations = [op for op in operations if op.api_calls_count > 50]
444
446
 
445
447
  if slow_operations:
446
- recommendations.append(
447
- f"⚠️ {len(slow_operations)} operations exceeded target by >50% - consider optimization"
448
- )
448
+ recommendations.append(f"⚠️ {len(slow_operations)} operations exceeded target by >50% - consider optimization")
449
449
 
450
450
  if high_memory_operations:
451
451
  recommendations.append(
@@ -453,16 +453,12 @@ def _generate_performance_recommendations(operations: List[PerformanceMetrics])
453
453
  )
454
454
 
455
455
  if high_api_operations:
456
- recommendations.append(
457
- f"🔄 {len(high_api_operations)} operations made >50 API calls - consider caching"
458
- )
456
+ recommendations.append(f"🔄 {len(high_api_operations)} operations made >50 API calls - consider caching")
459
457
 
460
458
  # Success rate recommendations
461
459
  failed_ops = [op for op in operations if not op.success]
462
460
  if len(failed_ops) > len(operations) * 0.1: # >10% failure rate
463
- recommendations.append(
464
- "❌ High failure rate detected - review error handling and retry logic"
465
- )
461
+ recommendations.append("❌ High failure rate detected - review error handling and retry logic")
466
462
 
467
463
  return recommendations
468
464
 
@@ -487,7 +483,7 @@ def export_performance_data(output_path: str = "performance_report.json") -> boo
487
483
  try:
488
484
  report = get_performance_report()
489
485
 
490
- with open(output_path, 'w') as f:
486
+ with open(output_path, "w") as f:
491
487
  json.dump(report, f, indent=2)
492
488
 
493
489
  print_success(f"Performance data exported to {output_path}")
@@ -508,5 +504,5 @@ __all__ = [
508
504
  "reset_api_counter",
509
505
  "get_performance_report",
510
506
  "clear_performance_history",
511
- "export_performance_data"
512
- ]
507
+ "export_performance_data",
508
+ ]