2Plugin status and discovery command-line interface for PyHelios.
4This module provides command-line tools for checking plugin availability,
5system compatibility, and generating configuration recommendations.
8 python -m pyhelios.plugins status
9 python -m pyhelios.plugins discover
10 python -m pyhelios.plugins info <plugin_name>
11 python -m pyhelios.plugins validate <plugin_list>
16from pathlib
import Path
19sys.path.insert(0, str(Path(__file__).parent.parent.parent))
22from pyhelios.plugins.registry
import get_plugin_registry
23from pyhelios.config.plugin_metadata
import PLUGIN_METADATA, get_all_plugin_names, get_platform_compatible_plugins
24from pyhelios.config.dependency_resolver
import PluginDependencyResolver
28 """Allow the CLI's status symbols to print on a legacy-codepage console.
30 Windows consoles default to a codepage such as cp1252, whose codec has no
31 mapping for the check and cross marks used below and raises
32 UnicodeEncodeError rather than substituting. Prefer UTF-8, and fall back to
33 replacing unencodable characters so output degrades to '?' instead of
36 for stream
in (sys.stdout, sys.stderr):
37 reconfigure = getattr(stream,
'reconfigure',
None)
38 if reconfigure
is None:
41 reconfigure(encoding=
'utf-8', errors=
'replace')
42 except (OSError, ValueError, LookupError):
44 reconfigure(errors=
'replace')
45 except (OSError, ValueError):
50 """Show comprehensive plugin status."""
55 """Discover and recommend optimal plugin configuration."""
56 print(
"PyHelios Plugin Discovery")
59 resolver = PluginDependencyResolver()
62 print(
"System Analysis:")
66 compatible_plugins = get_platform_compatible_plugins()
67 all_plugins = get_all_plugin_names()
68 platform_compatibility = len(compatible_plugins) / len(all_plugins) * 100
69 print(f
"Platform compatibility: {platform_compatibility:.1f}% ({len(compatible_plugins)}/{len(all_plugins)} plugins)")
72 gpu_available = resolver._check_cuda()
73 print(f
"GPU/CUDA support: {'✓ Available' if gpu_available else '✗ Not available'}")
76 system_deps = resolver._check_system_dependencies(compatible_plugins)
77 available_deps = sum(1
for available
in system_deps.values()
if available)
78 total_deps = len(system_deps)
80 dep_percentage = available_deps / total_deps * 100
81 print(f
"System dependencies: {dep_percentage:.1f}% available ({available_deps}/{total_deps})")
86 print(
"Recommendations:")
90 print(
"✓ GPU detected - GPU-accelerated workflows are possible")
91 print(
" Recommended for: Ray tracing, radiation modeling, high-performance simulations")
92 recommended_plugins = [
"weberpenntree",
"canopygenerator",
"solarposition",
"radiation",
"visualizer",
"energybalance"]
94 print(
"• No GPU detected - Using CPU-based workflows")
95 print(
" Recommended for: General plant modeling, visualization, basic simulations")
96 recommended_plugins = [
"weberpenntree",
"canopygenerator",
"solarposition",
"visualizer",
"energybalance"]
99 recommended_plugins = [p
for p
in recommended_plugins
if p
in compatible_plugins]
100 validation = resolver.validate_configuration(recommended_plugins)
102 print(f
"\nRecommended plugins ({len(recommended_plugins)}):")
103 for plugin
in recommended_plugins:
104 if plugin
in validation[
'platform_compatible']:
105 print(f
" ✓ {plugin}")
107 print(f
" ⚠ {plugin} (may have compatibility issues)")
110 print(f
"\nSuggested build command:")
111 plugin_list =
",".join(recommended_plugins)
112 print(f
" build_scripts/build_helios --plugins {plugin_list}")
115 if validation[
'platform_incompatible']:
116 print(f
"\n⚠ Platform compatibility issues:")
117 for plugin
in validation[
'platform_incompatible']:
118 print(f
" - {plugin}")
120 missing_system_deps = [dep
for dep, available
in system_deps.items()
if not available]
121 if missing_system_deps:
122 print(f
"\n⚠ Missing system dependencies:")
123 for dep
in missing_system_deps:
128 """Show detailed information about a specific plugin."""
129 plugin_name = args.plugin_name
131 if plugin_name
not in PLUGIN_METADATA:
132 print(f
"❌ Unknown plugin: {plugin_name}")
133 print(f
"Available plugins: {', '.join(sorted(get_all_plugin_names()))}")
136 metadata = PLUGIN_METADATA[plugin_name]
138 print(f
"Plugin Information: {plugin_name}")
139 print(
"=" * (20 + len(plugin_name)))
141 print(f
"Description: {metadata.description}")
142 print(f
"GPU Required: {'Yes' if metadata.gpu_required else 'No'}")
143 print(f
"Optional: {'Yes' if metadata.optional else 'No (core plugin)'}")
144 print(f
"Supported Platforms: {', '.join(metadata.platforms)}")
146 if metadata.system_dependencies:
147 print(f
"System Dependencies: {', '.join(metadata.system_dependencies)}")
149 if metadata.plugin_dependencies:
150 print(f
"Plugin Dependencies: {', '.join(metadata.plugin_dependencies)}")
154 print(f
"\nRuntime Status:")
155 registry = get_plugin_registry()
156 available = registry.is_plugin_available(plugin_name)
157 print(f
"Available: {'✓ Yes' if available else '✗ No'}")
160 missing = registry.get_missing_plugins(list(metadata.plugin_dependencies
or []))
162 print(f
" Missing plugin dependencies: {', '.join(missing)}")
163 print(f
" Rebuild with: build_scripts/build_helios --plugins {plugin_name}")
169 """Validate a list of plugins."""
171 plugins = args.plugins
174 plugins_input = input(
"Enter plugins (comma-separated): ").strip()
175 plugins = [p.strip()
for p
in plugins_input.split(
',')
if p.strip()]
178 print(
"❌ No plugins specified")
181 print(f
"Validating plugins: {', '.join(plugins)}")
184 resolver = PluginDependencyResolver()
185 validation = resolver.validate_configuration(plugins)
187 print(f
"Total requested: {len(plugins)}")
188 print(f
"Valid plugins: {len(validation['valid_plugins'])}")
189 print(f
"Invalid plugins: {len(validation['invalid_plugins'])}")
190 print(f
"Platform compatible: {len(validation['platform_compatible'])}")
191 print(f
"Platform incompatible: {len(validation['platform_incompatible'])}")
193 if validation[
'invalid_plugins']:
194 print(f
"\n❌ Invalid plugins:")
195 for plugin
in validation[
'invalid_plugins']:
196 print(f
" - {plugin}")
198 if validation[
'platform_incompatible']:
199 print(f
"\n⚠ Platform incompatible:")
200 for plugin
in validation[
'platform_incompatible']:
201 print(f
" - {plugin}")
203 if validation[
'system_dependencies']:
204 print(f
"\nSystem Dependencies:")
205 for dep, available
in validation[
'system_dependencies'].items():
206 status =
"✓" if available
else "✗"
207 print(f
" {status} {dep}")
209 print(f
"\nGPU required: {'Yes' if validation['gpu_required'] else 'No'}")
212 if validation[
'invalid_plugins']
or validation[
'platform_incompatible']:
213 print(f
"\n💡 Suggestions:")
214 print(f
" - Use only valid, platform-compatible plugins")
215 print(f
" - Check available plugins: python -m pyhelios.plugins status")
216 print(f
" - Use specific plugin selection: build_scripts/build_helios --plugins plugin1,plugin2")
219 print(f
"\n✅ Configuration is valid")
226 """Main entry point for plugin command-line interface."""
229 parser = argparse.ArgumentParser(
230 description=
"PyHelios plugin status and discovery tools",
231 formatter_class=argparse.RawDescriptionHelpFormatter,
234 status Show comprehensive plugin status
235 discover Analyze system and recommend optimal configuration
236 info Show detailed information about a specific plugin
237 validate Validate a list of plugins for compatibility
240 python -m pyhelios.plugins status
241 python -m pyhelios.plugins discover
242 python -m pyhelios.plugins info radiation
243 python -m pyhelios.plugins validate --plugins radiation,visualizer
247 subparsers = parser.add_subparsers(dest=
'command', help=
'Available commands')
250 status_parser = subparsers.add_parser(
'status', help=
'Show plugin status')
251 status_parser.set_defaults(func=cmd_status)
254 discover_parser = subparsers.add_parser(
'discover', help=
'Discover optimal configuration')
255 discover_parser.set_defaults(func=cmd_discover)
258 info_parser = subparsers.add_parser(
'info', help=
'Show plugin information')
259 info_parser.add_argument(
'plugin_name', help=
'Name of the plugin')
260 info_parser.set_defaults(func=cmd_info)
263 validate_parser = subparsers.add_parser(
'validate', help=
'Validate plugin configuration')
264 validate_parser.add_argument(
'--plugins', nargs=
'*', help=
'Plugin names to validate')
265 validate_parser.set_defaults(func=cmd_validate)
268 args = parser.parse_args()
275 return args.func(args)
276 except KeyboardInterrupt:
277 print(
"\nOperation cancelled by user")
279 except Exception
as e:
280 print(f
"❌ Error: {e}")
284if __name__ ==
'__main__':
cmd_discover(args)
Discover and recommend optimal plugin configuration.
_make_output_encoding_safe()
Allow the CLI's status symbols to print on a legacy-codepage console.
cmd_validate(args)
Validate a list of plugins.
main()
Main entry point for plugin command-line interface.
cmd_info(args)
Show detailed information about a specific plugin.
cmd_status(args)
Show comprehensive plugin status.
print_plugin_status()
Print current plugin status for debugging.