error-translator-cli-v2 1.1.5__tar.gz → 2.0.0__tar.gz

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 (18) hide show
  1. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/PKG-INFO +7 -1
  2. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/README.md +6 -0
  3. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/pyproject.toml +1 -1
  4. error_translator_cli_v2-2.0.0/src/error_translator/cli.py +265 -0
  5. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/core.py +1 -1
  6. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/PKG-INFO +7 -1
  7. error_translator_cli_v2-1.1.5/src/error_translator/cli.py +0 -207
  8. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/LICENSE +0 -0
  9. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/setup.cfg +0 -0
  10. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/__init__.py +0 -0
  11. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/auto.py +0 -0
  12. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator/rules.json +0 -0
  13. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/SOURCES.txt +0 -0
  14. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/dependency_links.txt +0 -0
  15. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/entry_points.txt +0 -0
  16. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/requires.txt +0 -0
  17. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/src/error_translator_cli_v2.egg-info/top_level.txt +0 -0
  18. {error_translator_cli_v2-1.1.5 → error_translator_cli_v2-2.0.0}/tests/test_core.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.1.5
3
+ Version: 2.0.0
4
4
  Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
5
5
  Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
6
6
  License: MIT License
@@ -90,6 +90,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
90
90
  ## Key Features
91
91
 
92
92
  * **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
93
+ * **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
93
94
  * **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
94
95
  * **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
95
96
  * **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
@@ -137,6 +138,11 @@ explain-error --json "NameError: name 'x' is not defined"
137
138
  # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
138
139
  ```
139
140
 
141
+ Show an about screen with project metadata and quick usage examples:
142
+ ```bash
143
+ explain-error --about
144
+ ```
145
+
140
146
  The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
141
147
 
142
148
  ### 2. Automatic Import Hook
@@ -25,6 +25,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
25
25
  ## Key Features
26
26
 
27
27
  * **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
28
+ * **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
28
29
  * **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
29
30
  * **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
30
31
  * **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
@@ -72,6 +73,11 @@ explain-error --json "NameError: name 'x' is not defined"
72
73
  # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
73
74
  ```
74
75
 
76
+ Show an about screen with project metadata and quick usage examples:
77
+ ```bash
78
+ explain-error --about
79
+ ```
80
+
75
81
  The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
76
82
 
77
83
  ### 2. Automatic Import Hook
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "error-translator-cli-v2"
7
- version = "1.1.5"
7
+ version = "2.0.0"
8
8
  description = "Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,265 @@
1
+ import json
2
+ import sys
3
+ import argparse
4
+ from .core import translate_error
5
+ from importlib.metadata import version, PackageNotFoundError
6
+
7
+ # Import Rich UI Components
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.syntax import Syntax
11
+ from rich.text import Text
12
+ from rich.table import Table
13
+ from rich import box
14
+
15
+ try:
16
+ VERSION = version("error-translator-cli-v2")
17
+ except PackageNotFoundError:
18
+ VERSION = "unknown (not installed via pip)"
19
+
20
+ # Initialize the global rich console
21
+ console = Console()
22
+
23
+
24
+ def _print_title_banner():
25
+ banner = Text()
26
+ banner.append("Error Translator CLI\n", style="bold bright_magenta")
27
+ banner.append("Translate Python tracebacks into clear, actionable guidance.", style="cyan")
28
+ console.print(
29
+ Panel(
30
+ banner,
31
+ border_style="magenta",
32
+ padding=(1, 2),
33
+ expand=False,
34
+ )
35
+ )
36
+
37
+ def print_about():
38
+ """Prints a polished about view using rich components."""
39
+ _print_title_banner()
40
+
41
+ meta = Table.grid(padding=(0, 1))
42
+ meta.add_column(style="bold white", justify="right")
43
+ meta.add_column(style="green")
44
+ meta.add_row("Version", VERSION)
45
+ meta.add_row("Author", "Gourabananda Datta")
46
+ meta.add_row("Repository", "https://github.com/gourabanandad/error-translator-cli-v2")
47
+ console.print(Panel(meta, title="[bold cyan]Project[/]", border_style="cyan", expand=False))
48
+
49
+ features = Text()
50
+ features.append("• Offline and fast translation\n", style="white")
51
+ features.append("• Human-readable explanations\n", style="white")
52
+ features.append("• Actionable fix suggestions\n", style="white")
53
+ features.append("• Optional AST-level insight", style="white")
54
+ console.print(Panel(features, title="[bold green]Features[/]", border_style="green", expand=False))
55
+
56
+ examples = Text()
57
+ examples.append("explain-error run your_script.py\n", style="bold cyan")
58
+ examples.append("explain-error \"TypeError: ...\"\n", style="bold cyan")
59
+ examples.append("cat error.log | explain-error", style="bold cyan")
60
+ console.print(Panel(examples, title="[bold yellow]Quick Start[/]", border_style="yellow", expand=False))
61
+
62
+
63
+ def print_result(result: dict):
64
+ """Print translated output in a polished, professional layout."""
65
+ console.print()
66
+
67
+ if result.get("error") and not result.get("matched_error"):
68
+ message = result.get("message", "An unexpected error occurred.")
69
+ console.print(
70
+ Panel(
71
+ f"[bold red]{message}[/]",
72
+ title="[bold red]Error[/]",
73
+ border_style="red",
74
+ box=box.ROUNDED,
75
+ expand=False,
76
+ )
77
+ )
78
+ return
79
+
80
+ error_title = result.get("matched_error", "Unknown Error")
81
+ console.print(
82
+ Panel(
83
+ f"[bold white]{error_title}[/]",
84
+ title="[bold red]Detected Error[/]",
85
+ border_style="red",
86
+ box=box.ROUNDED,
87
+ expand=False,
88
+ )
89
+ )
90
+
91
+ file_name = result.get("file")
92
+ line_no = result.get("line", "?")
93
+ if file_name and file_name != "Unknown File":
94
+ console.print(
95
+ Panel(
96
+ f"[yellow]File:[/] {file_name}\n[yellow]Line:[/] {line_no}",
97
+ title="[bold yellow]Location[/]",
98
+ border_style="yellow",
99
+ box=box.ROUNDED,
100
+ expand=False,
101
+ )
102
+ )
103
+
104
+ if result.get("code"):
105
+ try:
106
+ start_line = int(line_no)
107
+ except (TypeError, ValueError):
108
+ start_line = 1
109
+
110
+ syntax = Syntax(
111
+ result["code"],
112
+ "python",
113
+ theme="monokai",
114
+ line_numbers=True,
115
+ start_line=start_line,
116
+ word_wrap=True,
117
+ )
118
+ console.print(Panel(syntax, title="[bold blue]Code Context[/]", border_style="blue", box=box.ROUNDED))
119
+
120
+ explanation = result.get("explanation", "No explanation available.")
121
+ console.print(
122
+ Panel(
123
+ f"[white]{explanation}[/]",
124
+ title="[bold cyan]Explanation[/]",
125
+ title_align="left",
126
+ border_style="cyan",
127
+ box=box.ROUNDED,
128
+ expand=False,
129
+ )
130
+ )
131
+
132
+ fix = result.get("fix", "No suggested fix available.")
133
+ console.print(
134
+ Panel(
135
+ f"[bold green]{fix}[/]",
136
+ title="[bold green]Suggested Fix[/]",
137
+ title_align="left",
138
+ border_style="green",
139
+ box=box.ROUNDED,
140
+ expand=False,
141
+ )
142
+ )
143
+
144
+ if result.get("ast_insight"):
145
+ console.print(
146
+ Panel(
147
+ f"[white]{result['ast_insight']}[/]",
148
+ title="[bold magenta]AST Insight[/]",
149
+ title_align="left",
150
+ border_style="magenta",
151
+ box=box.ROUNDED,
152
+ expand=False,
153
+ )
154
+ )
155
+
156
+
157
+ def print_result_json(result: dict):
158
+ """Prints the translated error as a single-line JSON object on stdout."""
159
+ print(json.dumps(result, ensure_ascii=False))
160
+
161
+
162
+ def run_script(script_name: str, *, as_json: bool = False):
163
+ """Run a Python script and translate traceback output if it fails."""
164
+ import subprocess
165
+ try:
166
+ result = subprocess.run(
167
+ [sys.executable, script_name],
168
+ capture_output=True,
169
+ text=True
170
+ )
171
+
172
+ if result.returncode == 0:
173
+ print(result.stdout, end="")
174
+ else:
175
+ if result.stdout:
176
+ print(result.stdout, end="")
177
+
178
+ translation = translate_error(result.stderr)
179
+ if as_json:
180
+ print_result_json(translation)
181
+ else:
182
+ print_result(translation)
183
+
184
+ except FileNotFoundError:
185
+ if as_json:
186
+ print(json.dumps({
187
+ "error": "script_not_found",
188
+ "message": f"Could not find script '{script_name}'",
189
+ }))
190
+ else:
191
+ console.print(
192
+ Panel(
193
+ f"[bold red]Could not find script '{script_name}'[/]",
194
+ title="[bold red]Execution Error[/]",
195
+ border_style="red",
196
+ box=box.ROUNDED,
197
+ expand=False,
198
+ )
199
+ )
200
+ except Exception as exc:
201
+ if as_json:
202
+ print(json.dumps({
203
+ "error": "runtime_failure",
204
+ "message": str(exc),
205
+ }))
206
+ else:
207
+ console.print(
208
+ Panel(
209
+ f"[bold red]{exc}[/]",
210
+ title="[bold red]Runtime Error[/]",
211
+ border_style="red",
212
+ box=box.ROUNDED,
213
+ expand=False,
214
+ )
215
+ )
216
+
217
+ def main():
218
+ parser = argparse.ArgumentParser(
219
+ prog="explain-error",
220
+ description="Error Translator — Turn cryptic Python tracebacks into clear, actionable advice.",
221
+ epilog="""
222
+ Examples:
223
+ explain-error run my_script.py
224
+ explain-error "NameError: name 'usr_count' is not defined"
225
+ cat error.log | explain-error
226
+ """,
227
+ formatter_class=argparse.RawDescriptionHelpFormatter
228
+ )
229
+
230
+ parser.add_argument("-a", "--about", action="store_true", help="Display information about the tool.")
231
+ parser.add_argument("-v", "--version", action="store_true", help="Show the current version of the tool.")
232
+ parser.add_argument("--json", action="store_true", dest="as_json", help="Output the translated error as a JSON object.")
233
+ parser.add_argument("args", nargs="*", help="Positional arguments.")
234
+
235
+ parsed_args = parser.parse_args()
236
+
237
+ if parsed_args.about:
238
+ print_about()
239
+ sys.exit(0)
240
+
241
+ if parsed_args.version:
242
+ console.print(f"Error Translator CLI Version: [bold green]{VERSION}[/]")
243
+ sys.exit(0)
244
+
245
+ emit = print_result_json if parsed_args.as_json else print_result
246
+
247
+ if not sys.stdin.isatty():
248
+ error_input = sys.stdin.read()
249
+ if error_input.strip():
250
+ emit(translate_error(error_input))
251
+ return
252
+
253
+ if not parsed_args.args:
254
+ parser.print_help()
255
+ sys.exit(1)
256
+
257
+ if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
258
+ script_name = parsed_args.args[1]
259
+ run_script(script_name, as_json=parsed_args.as_json)
260
+ else:
261
+ error_input = " ".join(parsed_args.args)
262
+ emit(translate_error(error_input))
263
+
264
+ if __name__ == "__main__":
265
+ main()
@@ -90,7 +90,7 @@ def translate_error(traceback_text: str) -> dict:
90
90
  insight = None
91
91
 
92
92
  if handler_function and file_name != "Unknown File":
93
- insight = handler_function(file_name, extracted_values)
93
+ insight = handler_function(file_name, line_number, extracted_values)
94
94
 
95
95
  return {
96
96
  "explanation": rule["explanation"].format(*extracted_values),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.1.5
3
+ Version: 2.0.0
4
4
  Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
5
5
  Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
6
6
  License: MIT License
@@ -90,6 +90,7 @@ If this project saves you debugging time, please consider starring it on GitHub:
90
90
  ## Key Features
91
91
 
92
92
  * **CLI-First Architecture**: Seamlessly process scripts, direct error strings, or piped logs via the `explain-error` command.
93
+ * **Professional Rich Terminal UI**: Clean panels, syntax-highlighted code context, structured sections, and improved readability for day-to-day debugging.
93
94
  * **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
94
95
  * **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
95
96
  * **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
@@ -137,6 +138,11 @@ explain-error --json "NameError: name 'x' is not defined"
137
138
  # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
138
139
  ```
139
140
 
141
+ Show an about screen with project metadata and quick usage examples:
142
+ ```bash
143
+ explain-error --about
144
+ ```
145
+
140
146
  The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
141
147
 
142
148
  ### 2. Automatic Import Hook
@@ -1,207 +0,0 @@
1
- import json
2
- import sys
3
- import argparse
4
- from .core import translate_error
5
- from importlib.metadata import version, PackageNotFoundError
6
-
7
- try:
8
- VERSION = version("error-translator-cli-v2")
9
- except PackageNotFoundError:
10
- VERSION = "unknown (not installed via pip)" # Fallback version if package metadata is not found
11
-
12
- # ANSI Color Codes
13
- class Colors:
14
- RED = '\033[91m'
15
- GREEN = '\033[92m'
16
- YELLOW = '\033[93m'
17
- CYAN = '\033[96m'
18
- BOLD = '\033[1m'
19
- RESET = '\033[0m'
20
- MAGENTA = '\033[95m'
21
-
22
-
23
- def print_about():
24
- """Prints the about message for the tool."""
25
- about_text = f"""
26
- ERROR TRANSLATOR CLI
27
- =====================
28
- A lightning-fast, offline tool that translates raw Python tracebacks
29
- into human-readable explanations with actionable fixes.
30
-
31
- Authors: Gourabananda Datta
32
- Repository: https://github.com/gourabanandad/error-translator-cli-v2
33
- Usage:
34
- 1. Run a script and translate its errors:
35
- explain-error run your_script.py
36
- 2. Translate an error message directly:
37
- explain-error "TypeError: unsupported operand type(s) for +: 'int' and 'str'"
38
- 3. Pipe an error log:
39
- cat error.log | explain-error
40
- 4. Get help:
41
- explain-error --help
42
- 5. About:
43
- explain-error --about
44
- """
45
- print(f"\033[96m{about_text}\033[0m")
46
-
47
-
48
- def print_result(result: dict):
49
- """Prints the translated error to the terminal with colors."""
50
- print(f"\n{Colors.RED}{Colors.BOLD} Error Detected:{Colors.RESET}")
51
- print(f"{result.get('matched_error', 'N/A')}")
52
-
53
- if "file" in result:
54
- print(f"{Colors.YELLOW} Location: {result['file']} (Line {result['line']}){Colors.RESET}\n")
55
- if result.get("code"):
56
- print(f"{Colors.RESET} |")
57
- print(f"{Colors.RESET} | {Colors.RED}{result['code']}{Colors.RESET}")
58
- print(f"{Colors.RESET} |\n")
59
- else:
60
- print("\n")
61
-
62
- else:
63
- print()
64
-
65
- print(f"{Colors.CYAN}{Colors.BOLD} Explanation:{Colors.RESET}")
66
- print(f"{result['explanation']}\n")
67
-
68
- print(f"{Colors.GREEN}{Colors.BOLD} Suggested Fix:{Colors.RESET}")
69
- print(f"{result['fix']}\n")
70
-
71
- if result.get("ast_insight"):
72
- print(f"{Colors.MAGENTA}{Colors.BOLD} AST Insight:{Colors.RESET}")
73
- print(f"{result['ast_insight']}\n")
74
-
75
-
76
- def print_result_json(result: dict):
77
- """Prints the translated error as a single-line JSON object on stdout.
78
-
79
- Useful for scripting and automation: pipe the output to `jq`, parse it
80
- in another language, or store it as structured logs.
81
- """
82
- print(json.dumps(result, ensure_ascii=False))
83
-
84
-
85
- def run_script(script_name: str, *, as_json: bool = False):
86
- """Runs a python script in the background and catches its errors."""
87
- import subprocess
88
- try:
89
- # Run the script using the current Python environment
90
- result = subprocess.run(
91
- [sys.executable, script_name],
92
- capture_output=True,
93
- text=True
94
- )
95
-
96
- # If the script ran perfectly (Return Code 0), print standard output
97
- if result.returncode == 0:
98
- print(result.stdout, end="")
99
-
100
- # If the script crashed, print whatever succeeded, THEN translate the error
101
- else:
102
- if result.stdout:
103
- print(result.stdout, end="")
104
-
105
- translation = translate_error(result.stderr)
106
- if as_json:
107
- print_result_json(translation)
108
- else:
109
- print_result(translation)
110
-
111
- except FileNotFoundError:
112
- if as_json:
113
- print(json.dumps({
114
- "error": "script_not_found",
115
- "message": f"Could not find script '{script_name}'",
116
- }))
117
- else:
118
- print(f"{Colors.RED}Error: Could not find script '{script_name}'{Colors.RESET}")
119
-
120
- # Entry point of the program
121
- def main():
122
- parser = argparse.ArgumentParser(
123
- prog="explain-error",
124
- description="Error Translator — Turn cryptic Python tracebacks into clear, actionable advice.",
125
- epilog="""
126
- Examples:
127
- # Run a Python script and translate any unhandled errors
128
- explain-error run my_script.py
129
-
130
- # Translate a raw error string directly
131
- explain-error "NameError: name 'usr_count' is not defined"
132
-
133
- # Pipe a traceback from a log file or another command
134
- cat error.log | explain-error
135
-
136
- For more information, visit: https://github.com/gourabanandad/error-translator
137
- """,
138
- formatter_class=argparse.RawDescriptionHelpFormatter
139
- )
140
-
141
- parser.add_argument(
142
- "-a",
143
- "--about",
144
- action="store_true",
145
- help="Display information about the tool."
146
- )
147
-
148
- parser.add_argument(
149
- "-v",
150
- "--version",
151
- action="store_true",
152
- help="Show the current version of the tool."
153
- )
154
-
155
- parser.add_argument(
156
- "--json",
157
- action="store_true",
158
- dest="as_json",
159
- help="Output the translated error as a single JSON object on stdout (useful for scripting)."
160
- )
161
-
162
- parser.add_argument(
163
- "args",
164
- nargs="*",
165
- help=(
166
- "Positional arguments. Use 'run <script.py>' to execute a Python file, "
167
- "or provide an error string to translate. If no arguments are given and "
168
- "stdin is not piped, this help message is displayed."
169
- )
170
- )
171
-
172
- parsed_args = parser.parse_args()
173
-
174
- if parsed_args.about:
175
- print_about()
176
- sys.exit(0)
177
-
178
- if parsed_args.version:
179
- print(f"Error Translator CLI Version: {Colors.GREEN}{VERSION}{Colors.RESET}")
180
- sys.exit(0)
181
-
182
- emit = print_result_json if parsed_args.as_json else print_result
183
-
184
- # 1. Handle Piped Input (e.g., cat error.log | explain-error)
185
- if not sys.stdin.isatty():
186
- error_input = sys.stdin.read()
187
- if error_input.strip():
188
- emit(translate_error(error_input))
189
- return
190
-
191
- # 2. Print help if no arguments and no piped input
192
- if not parsed_args.args:
193
- parser.print_help()
194
- sys.exit(1)
195
-
196
- # 3. Check if the user used the "run" command
197
- if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
198
- script_name = parsed_args.args[1]
199
- run_script(script_name, as_json=parsed_args.as_json)
200
-
201
- # 4. Fallback: Treat the input as a raw error string
202
- else:
203
- error_input = " ".join(parsed_args.args)
204
- emit(translate_error(error_input))
205
-
206
- if __name__ == "__main__":
207
- main()