python-template-project 0.1.0__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.
File without changes
@@ -0,0 +1,8 @@
1
+ """Entry point for python_template_project."""
2
+
3
+ import sys # pragma: no cover
4
+
5
+ from .cli.cli import main # pragma: no cover
6
+
7
+ if __name__ == "__main__": # pragma: no cover
8
+ sys.exit(main())
File without changes
@@ -0,0 +1,8 @@
1
+ """CLI entry point for project_name."""
2
+
3
+ import sys # pragma: no cover
4
+
5
+ from .cli import main # pragma: no cover
6
+
7
+ if __name__ == "__main__": # pragma: no cover
8
+ sys.exit(main())
@@ -0,0 +1,217 @@
1
+ """Auto-generated CLI interface for python_template_project project.
2
+
3
+ This file was generated from config.py parameter definitions.
4
+ Do not modify manually - regenerate using ConfigParameterManager CLI generation methods.
5
+
6
+ run cli: python -m python_template_project.cli
7
+ """
8
+
9
+ import argparse
10
+ import traceback
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+ from python_template_project.config.config import ConfigParameterManager
15
+ from python_template_project.core.base import BaseGPXProcessor
16
+ from python_template_project.core.logging import initialize_logging
17
+
18
+
19
+ def parse_arguments():
20
+ """Parse command line arguments with config file support."""
21
+ parser = argparse.ArgumentParser(
22
+ description="Process input files",
23
+ formatter_class=argparse.RawDescriptionHelpFormatter,
24
+ epilog="""
25
+ Examples:
26
+ python -m python_template_project.cli input.txt
27
+ python -m python_template_project.cli --output result.txt input.txt
28
+ python -m python_template_project.cli --config custom_config.yaml input.txt
29
+ """,
30
+ )
31
+
32
+ # Config file argument
33
+ parser.add_argument(
34
+ "--config",
35
+ default=None,
36
+ help="Path to configuration file (JSON or YAML)",
37
+ )
38
+
39
+ # Verbose/quiet options for log level override
40
+ parser.add_argument(
41
+ "-v", "--verbose", action="store_true", help="Enable verbose logging (DEBUG level)"
42
+ )
43
+ parser.add_argument(
44
+ "-q", "--quiet", action="store_true", help="Enable quiet mode (WARNING level only)"
45
+ )
46
+
47
+ # Get CLI parameters from ConfigParameterManager
48
+ config_manager = ConfigParameterManager()
49
+ cli_params = config_manager.get_cli_parameters()
50
+
51
+ # Generate arguments from CLI config parameters
52
+ for param in cli_params:
53
+ if param.required and param.cli_arg is None:
54
+ # Positional argument (like 'input')
55
+ parser.add_argument(param.name, help=param.help)
56
+ else:
57
+ # Optional argument
58
+ kwargs = {
59
+ "default": argparse.SUPPRESS, # Don't set default here, handle in config
60
+ "help": f"{param.help} (default: {param.default})",
61
+ }
62
+
63
+ # Handle different parameter types
64
+ if param.choices and not param.type_ == bool:
65
+ kwargs["choices"] = param.choices
66
+
67
+ if param.type_ == int:
68
+ kwargs["type"] = int
69
+ if param.type_ == float:
70
+ kwargs["type"] = float
71
+ elif param.type_ == bool:
72
+ kwargs["action"] = "store_true" if not param.default else "store_false"
73
+ kwargs["help"] = f"{param.help} (default: {param.default})"
74
+ elif param.type_ == str:
75
+ kwargs["type"] = str
76
+
77
+ parser.add_argument(param.cli_arg, **kwargs)
78
+
79
+ return parser.parse_args()
80
+
81
+
82
+ def create_config_overrides(args: argparse.Namespace) -> dict[str, Any]:
83
+ """Create configuration overrides from CLI arguments.
84
+
85
+ Args:
86
+ args: Parsed command line arguments
87
+
88
+ Returns:
89
+ Dictionary with CLI parameter overrides in format cli__parameter_name
90
+ """
91
+ config_manager = ConfigParameterManager()
92
+ cli_params = config_manager.get_cli_parameters()
93
+ overrides = {}
94
+
95
+ for param in cli_params:
96
+ if hasattr(args, param.name):
97
+ arg_value = getattr(args, param.name)
98
+ # Add CLI category prefix for override system
99
+ overrides[f"cli__{param.name}"] = arg_value
100
+
101
+ # Handle log level overrides from verbose/quiet flags
102
+ if hasattr(args, "verbose") and args.verbose:
103
+ overrides["app__log_level"] = "DEBUG"
104
+ elif hasattr(args, "quiet") and args.quiet:
105
+ overrides["app__log_level"] = "WARNING"
106
+
107
+ return overrides
108
+
109
+
110
+ def validate_config(config: ConfigParameterManager, logger) -> bool:
111
+ """Validate the configuration parameters.
112
+
113
+ Args:
114
+ config: Configuration manager instance
115
+ logger: Logger instance for error reporting
116
+
117
+ Returns:
118
+ True if configuration is valid, False otherwise
119
+ """
120
+ # Check required parameters
121
+ if not config.cli.input.default:
122
+ logger.error("Input is required")
123
+ return False
124
+
125
+ # Check if input file exists
126
+ input_path = Path(config.cli.input.default)
127
+ if not input_path.exists():
128
+ logger.error(f"File not found: {input_path}")
129
+ return False
130
+
131
+ logger.debug(f"Input file validation passed: {input_path}")
132
+ return True
133
+
134
+
135
+ def main():
136
+ """Main entry point for the CLI application."""
137
+ logger = None
138
+
139
+ try:
140
+ # Parse command line arguments
141
+ args = parse_arguments()
142
+
143
+ # Create configuration overrides from CLI arguments
144
+ cli_overrides = create_config_overrides(args)
145
+
146
+ # Create config object with file and CLI overrides
147
+ config = ConfigParameterManager(
148
+ config_file=args.config if hasattr(args, "config") and args.config else None,
149
+ **cli_overrides,
150
+ )
151
+
152
+ # Initialize logging system
153
+ logger_manager = initialize_logging(config)
154
+ logger = logger_manager.get_logger()
155
+
156
+ # Log startup information
157
+ logger.info("Starting python_template_project CLI")
158
+ logger.debug(f"Command line arguments: {vars(args)}")
159
+ logger_manager.log_config_summary()
160
+
161
+ # Validate configuration
162
+ if not validate_config(config, logger):
163
+ logger.error("Configuration validation failed")
164
+ return 1
165
+
166
+ logger.info(f"Processing input: {config.cli.input.default}")
167
+
168
+ # Create and run BaseGPXProcessor
169
+ project = BaseGPXProcessor(
170
+ config.cli.input.default,
171
+ config.cli.output.default,
172
+ config.cli.min_dist.default,
173
+ config.cli.extract_waypoints.default,
174
+ config.app.date_format.default,
175
+ )
176
+
177
+ logger.info("Starting conversion process")
178
+
179
+ project.compress_files()
180
+
181
+ logger.info(f"Successfully processed: {config.cli.input.default}")
182
+ if config.cli.output.default:
183
+ logger.info(f"Output written to: {config.cli.output.default}")
184
+
185
+ logger.info("CLI processing completed successfully")
186
+ return 0
187
+
188
+ except FileNotFoundError as e:
189
+ if logger:
190
+ logger.error(f"File not found: {e}")
191
+ logger.debug("Full traceback:", exc_info=True)
192
+ else:
193
+ print(f"Error: {e}")
194
+ traceback.print_exc()
195
+ return 1
196
+
197
+ except KeyboardInterrupt:
198
+ if logger:
199
+ logger.warning("Process interrupted by user")
200
+ else:
201
+ print("Process interrupted by user")
202
+ return 130 # Standard exit code for SIGINT
203
+
204
+ except Exception as e:
205
+ if logger:
206
+ logger.error(f"Unexpected error: {e}")
207
+ logger.debug("Full traceback:", exc_info=True)
208
+ else:
209
+ print(f"Unexpected error: {e}")
210
+ traceback.print_exc()
211
+ return 1
212
+
213
+
214
+ if __name__ == "__main__":
215
+ import sys
216
+
217
+ sys.exit(main())
File without changes