error-translator-cli-v2 1.1.4__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 (23) hide show
  1. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/PKG-INFO +42 -13
  2. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/README.md +31 -3
  3. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/pyproject.toml +31 -10
  4. error_translator_cli_v2-2.0.0/src/error_translator/cli.py +265 -0
  5. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator/core.py +50 -23
  6. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator_cli_v2.egg-info/PKG-INFO +42 -13
  7. error_translator_cli_v2-2.0.0/src/error_translator_cli_v2.egg-info/SOURCES.txt +15 -0
  8. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/tests/test_core.py +22 -0
  9. error_translator_cli_v2-1.1.4/error_translator/ast_handlers.py +0 -50
  10. error_translator_cli_v2-1.1.4/error_translator/cli.py +0 -178
  11. error_translator_cli_v2-1.1.4/error_translator/server.py +0 -47
  12. error_translator_cli_v2-1.1.4/error_translator/static/index.html +0 -78
  13. error_translator_cli_v2-1.1.4/error_translator/static/style.css +0 -93
  14. error_translator_cli_v2-1.1.4/error_translator_cli_v2.egg-info/SOURCES.txt +0 -19
  15. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/LICENSE +0 -0
  16. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0}/setup.cfg +0 -0
  17. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator/__init__.py +0 -0
  18. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator/auto.py +0 -0
  19. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator/rules.json +0 -0
  20. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator_cli_v2.egg-info/dependency_links.txt +0 -0
  21. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator_cli_v2.egg-info/entry_points.txt +0 -0
  22. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator_cli_v2.egg-info/requires.txt +0 -0
  23. {error_translator_cli_v2-1.1.4 → error_translator_cli_v2-2.0.0/src}/error_translator_cli_v2.egg-info/top_level.txt +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.1.4
4
- Summary: A CLI tool that explains Python errors in simple human language.
5
- Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
3
+ Version: 2.0.0
4
+ Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
5
+ Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
6
6
  License: MIT License
7
7
 
8
8
  Copyright (c) 2026 Gourabananda Datta
@@ -25,13 +25,14 @@ License: MIT License
25
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
26
  SOFTWARE.
27
27
 
28
- Project-URL: Homepage, https://github.com/gourabanandad/error-translator
29
- Project-URL: Source, https://github.com/gourabanandad/error-translator
30
- Project-URL: Documentation, https://github.com/gourabanandad/error-translator/tree/master/docs
31
- Project-URL: Issues, https://github.com/gourabanandad/error-translator/issues
32
- Project-URL: Changelog, https://github.com/gourabanandad/error-translator/releases
33
- Project-URL: Contributors, https://github.com/gourabanandad/error-translator/graphs/contributors
34
- Keywords: python,traceback,cli,debugging,error handling,developer tools
28
+ Project-URL: Homepage, https://github.com/gourabanandad/error-translator-cli-v2
29
+ Project-URL: Source, https://github.com/gourabanandad/error-translator-cli-v2
30
+ Project-URL: Documentation, https://gourabanandad.github.io/error-translator-cli-v2/
31
+ Project-URL: Issues, https://github.com/gourabanandad/error-translator-cli-v2/issues
32
+ Project-URL: Changelog, https://github.com/gourabanandad/error-translator-cli-v2/releases
33
+ Project-URL: Contributors, https://github.com/gourabanandad/error-translator-cli-v2/graphs/contributors
34
+ Project-URL: PyPI, https://pypi.org/project/error-translator-cli-v2/
35
+ Keywords: python,python error translator,traceback translator,python traceback analyzer,python exception explainer,error explainer,error handling,debugging,developer tools,stack-trace,cli,terminal,offline,fastapi,human-readable
35
36
  Classifier: Development Status :: 4 - Beta
36
37
  Classifier: Environment :: Console
37
38
  Classifier: Intended Audience :: Developers
@@ -75,7 +76,7 @@ Dynamic: license-file
75
76
 
76
77
  <br>
77
78
 
78
- **Error Translator** is a powerful offline engine designed to parse raw Python tracebacks and translate them into crystal-clear explanations with immediately actionable fixes. Built with local-first development workflows in mind, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
79
+ **Error Translator** is an offline Python traceback translator and exception explainer that converts raw errors into crystal-clear explanations and immediately actionable fixes. Built for local-first development workflows, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
79
80
 
80
81
  If this project saves you debugging time, please consider starring it on GitHub: https://github.com/gourabanandad/error-translator-cli-v2
81
82
 
@@ -89,9 +90,11 @@ If this project saves you debugging time, please consider starring it on GitHub:
89
90
  ## Key Features
90
91
 
91
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.
92
94
  * **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
93
95
  * **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
94
96
  * **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
97
+ * **Optional Native Acceleration**: A C extension matcher (`fast_matcher`) can accelerate rule scanning, with automatic fallback to pure Python when unavailable.
95
98
  * **Optional AST Insight Hooks**: Registered handlers can append targeted hints (`ast_insight`) for selected error types.
96
99
 
97
100
  ## Installation
@@ -129,6 +132,19 @@ Pipe system or Docker logs into the engine:
129
132
  cat error.log | explain-error
130
133
  ```
131
134
 
135
+ Emit structured JSON for scripting and automation:
136
+ ```bash
137
+ explain-error --json "NameError: name 'x' is not defined"
138
+ # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
139
+ ```
140
+
141
+ Show an about screen with project metadata and quick usage examples:
142
+ ```bash
143
+ explain-error --about
144
+ ```
145
+
146
+ The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
147
+
132
148
  ### 2. Automatic Import Hook
133
149
 
134
150
  Catch and translate unhandled exceptions globally by importing the module:
@@ -149,7 +165,7 @@ if __name__ == "__main__":
149
165
  Start the built-in HTTP server for remote translation services:
150
166
 
151
167
  ```bash
152
- uvicorn error_translator.server:app --host 127.0.0.1 --port 8000 --reload
168
+ uvicorn error_translator.api.server:app --host 127.0.0.1 --port 8000 --reload
153
169
  ```
154
170
 
155
171
  Submit a traceback payload via the exposed REST API:
@@ -163,7 +179,20 @@ curl -X POST http://127.0.0.1:8000/translate \
163
179
  Additional endpoints:
164
180
 
165
181
  - `GET /health` returns service status.
166
- - `GET /` serves the bundled web UI from `error_translator/static/index.html`.
182
+ - `GET /` serves the bundled web UI from `error_translator/api/static/index.html`.
183
+
184
+ ### 4. Optional C Extension Build
185
+
186
+ The translation engine automatically attempts to import `error_translator.fast_matcher`.
187
+ If it is not built or not available on the platform, Error Translator falls back to the pure Python regex loop with no behavior change.
188
+
189
+ Build the extension in-place from the repository root:
190
+
191
+ ```bash
192
+ python setup_ext.py build_ext --inplace
193
+ ```
194
+
195
+ This step is optional and intended for local performance optimization.
167
196
 
168
197
  ## Documentation
169
198
 
@@ -11,7 +11,7 @@
11
11
 
12
12
  <br>
13
13
 
14
- **Error Translator** is a powerful offline engine designed to parse raw Python tracebacks and translate them into crystal-clear explanations with immediately actionable fixes. Built with local-first development workflows in mind, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
14
+ **Error Translator** is an offline Python traceback translator and exception explainer that converts raw errors into crystal-clear explanations and immediately actionable fixes. Built for local-first development workflows, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
15
15
 
16
16
  If this project saves you debugging time, please consider starring it on GitHub: https://github.com/gourabanandad/error-translator-cli-v2
17
17
 
@@ -25,9 +25,11 @@ 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.
32
+ * **Optional Native Acceleration**: A C extension matcher (`fast_matcher`) can accelerate rule scanning, with automatic fallback to pure Python when unavailable.
31
33
  * **Optional AST Insight Hooks**: Registered handlers can append targeted hints (`ast_insight`) for selected error types.
32
34
 
33
35
  ## Installation
@@ -65,6 +67,19 @@ Pipe system or Docker logs into the engine:
65
67
  cat error.log | explain-error
66
68
  ```
67
69
 
70
+ Emit structured JSON for scripting and automation:
71
+ ```bash
72
+ explain-error --json "NameError: name 'x' is not defined"
73
+ # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
74
+ ```
75
+
76
+ Show an about screen with project metadata and quick usage examples:
77
+ ```bash
78
+ explain-error --about
79
+ ```
80
+
81
+ The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
82
+
68
83
  ### 2. Automatic Import Hook
69
84
 
70
85
  Catch and translate unhandled exceptions globally by importing the module:
@@ -85,7 +100,7 @@ if __name__ == "__main__":
85
100
  Start the built-in HTTP server for remote translation services:
86
101
 
87
102
  ```bash
88
- uvicorn error_translator.server:app --host 127.0.0.1 --port 8000 --reload
103
+ uvicorn error_translator.api.server:app --host 127.0.0.1 --port 8000 --reload
89
104
  ```
90
105
 
91
106
  Submit a traceback payload via the exposed REST API:
@@ -99,7 +114,20 @@ curl -X POST http://127.0.0.1:8000/translate \
99
114
  Additional endpoints:
100
115
 
101
116
  - `GET /health` returns service status.
102
- - `GET /` serves the bundled web UI from `error_translator/static/index.html`.
117
+ - `GET /` serves the bundled web UI from `error_translator/api/static/index.html`.
118
+
119
+ ### 4. Optional C Extension Build
120
+
121
+ The translation engine automatically attempts to import `error_translator.fast_matcher`.
122
+ If it is not built or not available on the platform, Error Translator falls back to the pure Python regex loop with no behavior change.
123
+
124
+ Build the extension in-place from the repository root:
125
+
126
+ ```bash
127
+ python setup_ext.py build_ext --inplace
128
+ ```
129
+
130
+ This step is optional and intended for local performance optimization.
103
131
 
104
132
  ## Documentation
105
133
 
@@ -4,15 +4,31 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "error-translator-cli-v2"
7
- version = "1.1.4"
8
- description = "A CLI tool that explains Python errors in simple human language."
7
+ version = "2.0.0"
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"
11
11
  license = { file = "LICENSE" }
12
12
  authors = [
13
- { name = "Gourabananda Datta", email = "gourabanandadatta@zohomail.com" }
13
+ { name = "Gourabananda Datta", email = "gourabanandadatta@zohomail.in" }
14
+ ]
15
+ keywords = [
16
+ "python",
17
+ "python error translator",
18
+ "traceback translator",
19
+ "python traceback analyzer",
20
+ "python exception explainer",
21
+ "error explainer",
22
+ "error handling",
23
+ "debugging",
24
+ "developer tools",
25
+ "stack-trace",
26
+ "cli",
27
+ "terminal",
28
+ "offline",
29
+ "fastapi",
30
+ "human-readable"
14
31
  ]
15
- keywords = ["python", "traceback", "cli", "debugging", "error handling", "developer tools"]
16
32
  classifiers = [
17
33
  "Development Status :: 4 - Beta",
18
34
  "Environment :: Console",
@@ -30,12 +46,13 @@ classifiers = [
30
46
  ]
31
47
 
32
48
  [project.urls]
33
- "Homepage" = "https://github.com/gourabanandad/error-translator"
34
- "Source" = "https://github.com/gourabanandad/error-translator"
35
- "Documentation" = "https://github.com/gourabanandad/error-translator/tree/master/docs"
36
- "Issues" = "https://github.com/gourabanandad/error-translator/issues"
37
- "Changelog" = "https://github.com/gourabanandad/error-translator/releases"
38
- "Contributors" = "https://github.com/gourabanandad/error-translator/graphs/contributors"
49
+ "Homepage" = "https://github.com/gourabanandad/error-translator-cli-v2"
50
+ "Source" = "https://github.com/gourabanandad/error-translator-cli-v2"
51
+ "Documentation" = "https://gourabanandad.github.io/error-translator-cli-v2/"
52
+ "Issues" = "https://github.com/gourabanandad/error-translator-cli-v2/issues"
53
+ "Changelog" = "https://github.com/gourabanandad/error-translator-cli-v2/releases"
54
+ "Contributors" = "https://github.com/gourabanandad/error-translator-cli-v2/graphs/contributors"
55
+ "PyPI" = "https://pypi.org/project/error-translator-cli-v2/"
39
56
 
40
57
  [project.scripts]
41
58
  explain-error = "error_translator.cli:main"
@@ -46,7 +63,11 @@ docs = ["mkdocs>=1.6", "mkdocs-material>=9.7", "pymdown-extensions>=10.0"]
46
63
  dev = ["pytest>=8.0", "build>=1.2", "twine>=5.0"]
47
64
 
48
65
  [tool.setuptools]
66
+ package-dir = {"" = "src"}
49
67
  packages = ["error_translator"]
50
68
 
69
+ [tool.pytest.ini_options]
70
+ pythonpath = ["src"]
71
+
51
72
  [tool.setuptools.package-data]
52
73
  error_translator = ["rules.json", "static/*.html", "static/*.css"]
@@ -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()
@@ -3,7 +3,14 @@ import os
3
3
  import re
4
4
  import linecache
5
5
  from functools import lru_cache
6
- from .ast_handlers import AST_REGISTRY
6
+ from .ast.ast_handlers import AST_REGISTRY
7
+
8
+ # Attempt to load the ultra-fast C extension, fallback to Python if unavailable
9
+ try:
10
+ from .fast_matcher import match_loop
11
+ C_EXTENSION_AVAILABLE = True
12
+ except ImportError:
13
+ C_EXTENSION_AVAILABLE = False
7
14
 
8
15
 
9
16
  @lru_cache(maxsize=1)
@@ -55,27 +62,47 @@ def translate_error(traceback_text: str) -> dict:
55
62
  except Exception:
56
63
  pass
57
64
 
58
- for pattern, rule in rules:
59
- match = pattern.search(actual_error_line)
60
- if match:
61
- extracted_values = list(match.groups())
62
- fix_text = rule["fix"].format(*extracted_values)
63
-
64
- error_type = actual_error_line.split(":")[0].strip()
65
- handler_function = AST_REGISTRY.get(error_type)
66
- insight = None
67
- if handler_function and file_name != "Unknown File":
68
- insight = handler_function(file_name, extracted_values)
69
- return {
70
- "explanation": rule["explanation"].format(*extracted_values),
71
- "fix": fix_text,
72
- "ast_insight": insight,
73
- "matched_error": actual_error_line,
74
- "file": file_name,
75
- "line": line_number,
76
- "code": code_context,
77
- }
78
-
65
+ # ==========================================
66
+ # FAST MATCHING ENGINE (C Extension + Python Fallback)
67
+ # ==========================================
68
+ match = None
69
+ rule = None
70
+
71
+ if C_EXTENSION_AVAILABLE:
72
+ # Execute the C extension (runs at C speed)
73
+ result = match_loop(actual_error_line, rules)
74
+ if result:
75
+ match, rule = result
76
+ else:
77
+ # Standard Python fallback loop
78
+ for pattern, r in rules:
79
+ m = pattern.search(actual_error_line)
80
+ if m:
81
+ match, rule = m, r
82
+ break
83
+
84
+ if match and rule:
85
+ extracted_values = list(match.groups())
86
+ fix_text = rule["fix"].format(*extracted_values)
87
+
88
+ error_type = actual_error_line.split(":")[0].strip()
89
+ handler_function = AST_REGISTRY.get(error_type)
90
+ insight = None
91
+
92
+ if handler_function and file_name != "Unknown File":
93
+ insight = handler_function(file_name, line_number, extracted_values)
94
+
95
+ return {
96
+ "explanation": rule["explanation"].format(*extracted_values),
97
+ "fix": fix_text,
98
+ "ast_insight": insight,
99
+ "matched_error": actual_error_line,
100
+ "file": file_name,
101
+ "line": line_number,
102
+ "code": code_context,
103
+ }
104
+
105
+ # Default fallback when no rules match
79
106
  return {
80
107
  "explanation": default_error["explanation"],
81
108
  "fix": default_error["fix"],
@@ -83,4 +110,4 @@ def translate_error(traceback_text: str) -> dict:
83
110
  "file": file_name,
84
111
  "line": line_number,
85
112
  "code": code_context,
86
- }
113
+ }
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: error-translator-cli-v2
3
- Version: 1.1.4
4
- Summary: A CLI tool that explains Python errors in simple human language.
5
- Author-email: Gourabananda Datta <gourabanandadatta@zohomail.com>
3
+ Version: 2.0.0
4
+ Summary: Offline Python traceback translator and error explainer CLI that converts exceptions into clear explanations and actionable fixes.
5
+ Author-email: Gourabananda Datta <gourabanandadatta@zohomail.in>
6
6
  License: MIT License
7
7
 
8
8
  Copyright (c) 2026 Gourabananda Datta
@@ -25,13 +25,14 @@ License: MIT License
25
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
26
  SOFTWARE.
27
27
 
28
- Project-URL: Homepage, https://github.com/gourabanandad/error-translator
29
- Project-URL: Source, https://github.com/gourabanandad/error-translator
30
- Project-URL: Documentation, https://github.com/gourabanandad/error-translator/tree/master/docs
31
- Project-URL: Issues, https://github.com/gourabanandad/error-translator/issues
32
- Project-URL: Changelog, https://github.com/gourabanandad/error-translator/releases
33
- Project-URL: Contributors, https://github.com/gourabanandad/error-translator/graphs/contributors
34
- Keywords: python,traceback,cli,debugging,error handling,developer tools
28
+ Project-URL: Homepage, https://github.com/gourabanandad/error-translator-cli-v2
29
+ Project-URL: Source, https://github.com/gourabanandad/error-translator-cli-v2
30
+ Project-URL: Documentation, https://gourabanandad.github.io/error-translator-cli-v2/
31
+ Project-URL: Issues, https://github.com/gourabanandad/error-translator-cli-v2/issues
32
+ Project-URL: Changelog, https://github.com/gourabanandad/error-translator-cli-v2/releases
33
+ Project-URL: Contributors, https://github.com/gourabanandad/error-translator-cli-v2/graphs/contributors
34
+ Project-URL: PyPI, https://pypi.org/project/error-translator-cli-v2/
35
+ Keywords: python,python error translator,traceback translator,python traceback analyzer,python exception explainer,error explainer,error handling,debugging,developer tools,stack-trace,cli,terminal,offline,fastapi,human-readable
35
36
  Classifier: Development Status :: 4 - Beta
36
37
  Classifier: Environment :: Console
37
38
  Classifier: Intended Audience :: Developers
@@ -75,7 +76,7 @@ Dynamic: license-file
75
76
 
76
77
  <br>
77
78
 
78
- **Error Translator** is a powerful offline engine designed to parse raw Python tracebacks and translate them into crystal-clear explanations with immediately actionable fixes. Built with local-first development workflows in mind, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
79
+ **Error Translator** is an offline Python traceback translator and exception explainer that converts raw errors into crystal-clear explanations and immediately actionable fixes. Built for local-first development workflows, it supports direct CLI usage, an automatic import hook, a programmatic Python API, and a FastAPI integration.
79
80
 
80
81
  If this project saves you debugging time, please consider starring it on GitHub: https://github.com/gourabanandad/error-translator-cli-v2
81
82
 
@@ -89,9 +90,11 @@ If this project saves you debugging time, please consider starring it on GitHub:
89
90
  ## Key Features
90
91
 
91
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.
92
94
  * **Automatic Integration Mode**: Inject the module via `import error_translator.auto` to automatically override `sys.excepthook` for graceful, translated crash reporting.
93
95
  * **Extensible API Surfaces**: Integrate natively within Python or expose the core engine over HTTP via the included FastAPI server.
94
96
  * **Deterministic Rules Engine**: High-performance, regex-based matching powered by `rules.json` guarantees offline and privacy-first translations.
97
+ * **Optional Native Acceleration**: A C extension matcher (`fast_matcher`) can accelerate rule scanning, with automatic fallback to pure Python when unavailable.
95
98
  * **Optional AST Insight Hooks**: Registered handlers can append targeted hints (`ast_insight`) for selected error types.
96
99
 
97
100
  ## Installation
@@ -129,6 +132,19 @@ Pipe system or Docker logs into the engine:
129
132
  cat error.log | explain-error
130
133
  ```
131
134
 
135
+ Emit structured JSON for scripting and automation:
136
+ ```bash
137
+ explain-error --json "NameError: name 'x' is not defined"
138
+ # {"explanation": "...", "fix": "...", "matched_error": "...", "file": "...", "line": "...", "code": "...", "ast_insight": null}
139
+ ```
140
+
141
+ Show an about screen with project metadata and quick usage examples:
142
+ ```bash
143
+ explain-error --about
144
+ ```
145
+
146
+ The `--json` flag works with every input mode (`run <script>`, raw string, piped log).
147
+
132
148
  ### 2. Automatic Import Hook
133
149
 
134
150
  Catch and translate unhandled exceptions globally by importing the module:
@@ -149,7 +165,7 @@ if __name__ == "__main__":
149
165
  Start the built-in HTTP server for remote translation services:
150
166
 
151
167
  ```bash
152
- uvicorn error_translator.server:app --host 127.0.0.1 --port 8000 --reload
168
+ uvicorn error_translator.api.server:app --host 127.0.0.1 --port 8000 --reload
153
169
  ```
154
170
 
155
171
  Submit a traceback payload via the exposed REST API:
@@ -163,7 +179,20 @@ curl -X POST http://127.0.0.1:8000/translate \
163
179
  Additional endpoints:
164
180
 
165
181
  - `GET /health` returns service status.
166
- - `GET /` serves the bundled web UI from `error_translator/static/index.html`.
182
+ - `GET /` serves the bundled web UI from `error_translator/api/static/index.html`.
183
+
184
+ ### 4. Optional C Extension Build
185
+
186
+ The translation engine automatically attempts to import `error_translator.fast_matcher`.
187
+ If it is not built or not available on the platform, Error Translator falls back to the pure Python regex loop with no behavior change.
188
+
189
+ Build the extension in-place from the repository root:
190
+
191
+ ```bash
192
+ python setup_ext.py build_ext --inplace
193
+ ```
194
+
195
+ This step is optional and intended for local performance optimization.
167
196
 
168
197
  ## Documentation
169
198
 
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/error_translator/__init__.py
5
+ src/error_translator/auto.py
6
+ src/error_translator/cli.py
7
+ src/error_translator/core.py
8
+ src/error_translator/rules.json
9
+ src/error_translator_cli_v2.egg-info/PKG-INFO
10
+ src/error_translator_cli_v2.egg-info/SOURCES.txt
11
+ src/error_translator_cli_v2.egg-info/dependency_links.txt
12
+ src/error_translator_cli_v2.egg-info/entry_points.txt
13
+ src/error_translator_cli_v2.egg-info/requires.txt
14
+ src/error_translator_cli_v2.egg-info/top_level.txt
15
+ tests/test_core.py
@@ -147,3 +147,25 @@ def test_regex_extraction_for_supported_errors(mock_traceback, expected_in_expla
147
147
  # 2. Prove the Context Engine successfully parsed the file location
148
148
  assert result["file"] == "script.py"
149
149
  assert result["line"] == "5"
150
+
151
+
152
+ def test_print_result_json_emits_valid_json(capsys):
153
+ """The --json formatter writes a single line of valid JSON containing the result keys."""
154
+ import json
155
+ from error_translator.cli import print_result_json
156
+
157
+ payload = {
158
+ "explanation": "x is undefined",
159
+ "fix": "Define x before use",
160
+ "matched_error": "NameError: name 'x' is not defined",
161
+ "file": "Unknown File",
162
+ "line": "Unknown Line",
163
+ "code": "",
164
+ "ast_insight": None,
165
+ }
166
+ print_result_json(payload)
167
+ captured = capsys.readouterr().out
168
+ # Single line, valid JSON, contains the key fields
169
+ assert captured.count("\n") == 1
170
+ parsed = json.loads(captured.strip())
171
+ assert parsed == payload
@@ -1,50 +0,0 @@
1
- import ast
2
- import difflib
3
- import os
4
-
5
- # --- 1. THE INDIVIDUAL STRATEGIES (PLUGINS) ---
6
-
7
- def handle_name_error(file_path: str, extracted_values: list) -> str:
8
- """Finds typos for missing variables."""
9
- missing_var = extracted_values[0]
10
-
11
- # ... (Imagine your previous AST parsing code is here) ...
12
- # For brevity, let's assume we found the match:
13
- closest_match = "maximum_user_connections" # Mocking the AST output
14
-
15
- if closest_match:
16
- return f"Did you mean to type '{closest_match}'?"
17
- return ""
18
-
19
- def handle_attribute_error(file_path: str, extracted_values: list) -> str:
20
- """Finds typos for missing object methods (e.g., .appendd)"""
21
- obj_type = extracted_values[0]
22
- missing_attr = extracted_values[1]
23
-
24
- # ... (AST logic to find valid methods for this object) ...
25
- closest_match = "append" # Mocking the AST output
26
-
27
- if closest_match:
28
- return f"{obj_type} objects don't have '{missing_attr}'. Did you mean '{closest_match}'?"
29
- return ""
30
-
31
- def handle_import_error(file_path: str, extracted_values: list) -> str:
32
- """ Find typos for missing imports """
33
- missing_module = extracted_values[0]
34
-
35
- # ... (Imagine your previous AST parsing code is here) ...
36
- # For brevity, let's assume we found the match:
37
- closest_match = "maximum_user_connections" # Mocking the AST output
38
-
39
- if closest_match:
40
- return f"Did you mean to type '{closest_match}'?"
41
- return ""
42
-
43
- # --- 2. THE REGISTRY (THE MAGIC ROUTER) ---
44
- # We map the string name of the error to the function that handles it.
45
- AST_REGISTRY = {
46
- "NameError": handle_name_error,
47
- "AttributeError": handle_attribute_error,
48
- "ImportError": handle_import_error,
49
- # "SyntaxError": handle_syntax_error,
50
- }
@@ -1,178 +0,0 @@
1
- import sys
2
- import argparse
3
- from .core import translate_error
4
- from importlib.metadata import version, PackageNotFoundError
5
-
6
- try:
7
- VERSION = version("error-translator-cli-v2")
8
- except PackageNotFoundError:
9
- VERSION = "unknown (not installed via pip)" # Fallback version if package metadata is not found
10
-
11
- # ANSI Color Codes
12
- class Colors:
13
- RED = '\033[91m'
14
- GREEN = '\033[92m'
15
- YELLOW = '\033[93m'
16
- CYAN = '\033[96m'
17
- BOLD = '\033[1m'
18
- RESET = '\033[0m'
19
- MAGENTA = '\033[95m'
20
-
21
-
22
- def print_about():
23
- """Prints the about message for the tool."""
24
- about_text = f"""
25
- ERROR TRANSLATOR CLI
26
- =====================
27
- A lightning-fast, offline tool that translates raw Python tracebacks
28
- into human-readable explanations with actionable fixes.
29
-
30
- Authors: Gourabananda Datta
31
- Repository: https://github.com/gourabanandad/error-translator-cli-v2
32
- Usage:
33
- 1. Run a script and translate its errors:
34
- explain-error run your_script.py
35
- 2. Translate an error message directly:
36
- explain-error "TypeError: unsupported operand type(s) for +: 'int' and 'str'"
37
- 3. Pipe an error log:
38
- cat error.log | explain-error
39
- 4. Get help:
40
- explain-error --help
41
- 5. About:
42
- explain-error --about
43
- """
44
- print(f"\033[96m{about_text}\033[0m")
45
-
46
-
47
- def print_result(result: dict):
48
- """Prints the translated error to the terminal with colors."""
49
- print(f"\n{Colors.RED}{Colors.BOLD} Error Detected:{Colors.RESET}")
50
- print(f"{result.get('matched_error', 'N/A')}")
51
-
52
- if "file" in result:
53
- print(f"{Colors.YELLOW} Location: {result['file']} (Line {result['line']}){Colors.RESET}\n")
54
- if result.get("code"):
55
- print(f"{Colors.RESET} |")
56
- print(f"{Colors.RESET} | {Colors.RED}{result['code']}{Colors.RESET}")
57
- print(f"{Colors.RESET} |\n")
58
- else:
59
- print("\n")
60
-
61
- else:
62
- print()
63
-
64
- print(f"{Colors.CYAN}{Colors.BOLD} Explanation:{Colors.RESET}")
65
- print(f"{result['explanation']}\n")
66
-
67
- print(f"{Colors.GREEN}{Colors.BOLD} Suggested Fix:{Colors.RESET}")
68
- print(f"{result['fix']}\n")
69
-
70
- if result.get("ast_insight"):
71
- print(f"{Colors.MAGENTA}{Colors.BOLD} AST Insight:{Colors.RESET}")
72
- print(f"{result['ast_insight']}\n")
73
-
74
- def run_script(script_name: str):
75
- """Runs a python script in the background and catches its errors."""
76
- import subprocess
77
- try:
78
- # Run the script using the current Python environment
79
- result = subprocess.run(
80
- [sys.executable, script_name],
81
- capture_output=True,
82
- text=True
83
- )
84
-
85
- # If the script ran perfectly (Return Code 0), print standard output
86
- if result.returncode == 0:
87
- print(result.stdout, end="")
88
-
89
- # If the script crashed, print whatever succeeded, THEN translate the error
90
- else:
91
- if result.stdout:
92
- print(result.stdout, end="")
93
-
94
- translation = translate_error(result.stderr)
95
- print_result(translation)
96
-
97
- except FileNotFoundError:
98
- print(f"{Colors.RED}Error: Could not find script '{script_name}'{Colors.RESET}")
99
-
100
- # Entry point of the program
101
- def main():
102
- parser = argparse.ArgumentParser(
103
- prog="explain-error",
104
- description="Error Translator — Turn cryptic Python tracebacks into clear, actionable advice.",
105
- epilog="""
106
- Examples:
107
- # Run a Python script and translate any unhandled errors
108
- explain-error run my_script.py
109
-
110
- # Translate a raw error string directly
111
- explain-error "NameError: name 'usr_count' is not defined"
112
-
113
- # Pipe a traceback from a log file or another command
114
- cat error.log | explain-error
115
-
116
- For more information, visit: https://github.com/gourabanandad/error-translator
117
- """,
118
- formatter_class=argparse.RawDescriptionHelpFormatter
119
- )
120
-
121
- parser.add_argument(
122
- "-a",
123
- "--about",
124
- action="store_true",
125
- help="Display information about the tool."
126
- )
127
-
128
- parser.add_argument(
129
- "-v",
130
- "--version",
131
- action="store_true",
132
- help="Show the current version of the tool."
133
- )
134
-
135
- parser.add_argument(
136
- "args",
137
- nargs="*",
138
- help=(
139
- "Positional arguments. Use 'run <script.py>' to execute a Python file, "
140
- "or provide an error string to translate. If no arguments are given and "
141
- "stdin is not piped, this help message is displayed."
142
- )
143
- )
144
-
145
- parsed_args = parser.parse_args()
146
-
147
- if parsed_args.about:
148
- print_about()
149
- sys.exit(0)
150
-
151
- if parsed_args.version:
152
- print(f"Error Translator CLI Version: {Colors.GREEN}{VERSION}{Colors.RESET}")
153
- sys.exit(0)
154
-
155
- # 1. Handle Piped Input (e.g., cat error.log | explain-error)
156
- if not sys.stdin.isatty():
157
- error_input = sys.stdin.read()
158
- if error_input.strip():
159
- print_result(translate_error(error_input))
160
- return
161
-
162
- # 2. Print help if no arguments and no piped input
163
- if not parsed_args.args:
164
- parser.print_help()
165
- sys.exit(1)
166
-
167
- # 3. Check if the user used the "run" command
168
- if parsed_args.args[0] == "run" and len(parsed_args.args) > 1:
169
- script_name = parsed_args.args[1]
170
- run_script(script_name)
171
-
172
- # 4. Fallback: Treat the input as a raw error string
173
- else:
174
- error_input = " ".join(parsed_args.args)
175
- print_result(translate_error(error_input))
176
-
177
- if __name__ == "__main__":
178
- main()
@@ -1,47 +0,0 @@
1
- from error_translator.core import translate_error
2
- from pydantic import BaseModel
3
- from fastapi import FastAPI
4
- from fastapi.staticfiles import StaticFiles
5
- from fastapi.responses import FileResponse
6
- import os
7
-
8
- from importlib.metadata import version, PackageNotFoundError
9
-
10
- try:
11
- VERSION = version("error-translator-cli-v2")
12
- except PackageNotFoundError:
13
- VERSION = "unknown (not installed via pip)"
14
-
15
- app = FastAPI(
16
- title="Error translator API",
17
- description="An API that translates Python errors into human-readable English.",
18
- version=VERSION
19
- )
20
- class ErrorRequest(BaseModel):
21
- traceback_setting: str
22
-
23
- # API endpoint (existing functionality, unchanged)
24
- @app.post("/translate")
25
- def translation_endpoint(request: ErrorRequest):
26
- translation_result = translate_error(request.traceback_setting)
27
- return translation_result
28
-
29
- # Serve the web UI at the root
30
- @app.get("/")
31
- def read_root():
32
- index_path = os.path.join(os.path.dirname(__file__), "static", "index.html")
33
- if os.path.exists(index_path):
34
- return FileResponse(index_path)
35
- return {
36
- "message": "Error translation API is running. Web UI not found. Please ensure static/index.html exists."
37
- }
38
-
39
- # Health check (useful for monitoring)
40
- @app.get("/health")
41
- def health_check():
42
- return {"status": "ok"}
43
-
44
- # Mount static files directory (CSS, etc.)
45
- static_path = os.path.join(os.path.dirname(__file__), "static")
46
- if os.path.exists(static_path):
47
- app.mount("/static", StaticFiles(directory=static_path), name="static")
@@ -1,78 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Error Translator</title>
7
- <link rel="stylesheet" href="/static/style.css">
8
- </head>
9
- <body>
10
- <div class="container">
11
- <h1>Error Translator</h1>
12
- <p class="subtitle">Paste a Python traceback or error message below.</p>
13
-
14
- <textarea id="errorInput" placeholder="e.g.&#10;Traceback (most recent call last):&#10; File &quot;app.py&quot;, line 14, in &lt;module&gt;&#10; total = &quot;Users: &quot; + 42&#10;TypeError: can only concatenate str (not &quot;int&quot;) to str"></textarea>
15
-
16
- <button id="translateBtn">Translate</button>
17
-
18
- <div id="result" class="result hidden">
19
- <h3>Explanation</h3>
20
- <pre id="explanationText"></pre>
21
- <h3>Suggested Fix</h3>
22
- <pre id="fixText"></pre>
23
- </div>
24
-
25
- <div id="error" class="error hidden"></div>
26
- </div>
27
-
28
- <script>
29
- const input = document.getElementById('errorInput');
30
- const btn = document.getElementById('translateBtn');
31
- const resultDiv = document.getElementById('result');
32
- const explanationText = document.getElementById('explanationText');
33
- const fixText = document.getElementById('fixText');
34
- const errorDiv = document.getElementById('error');
35
-
36
- btn.addEventListener('click', async () => {
37
- const errorText = input.value.trim();
38
- if (!errorText) {
39
- showError('Please enter an error message.');
40
- return;
41
- }
42
-
43
- btn.disabled = true;
44
- btn.textContent = 'Translating...';
45
- resultDiv.classList.add('hidden');
46
- errorDiv.classList.add('hidden');
47
-
48
- try {
49
- const response = await fetch('/translate', {
50
- method: 'POST',
51
- headers: { 'Content-Type': 'application/json' },
52
- body: JSON.stringify({ traceback_setting: errorText })
53
- });
54
-
55
- const data = await response.json();
56
-
57
- if (response.ok) {
58
- explanationText.textContent = data.explanation || 'No explanation provided.';
59
- fixText.textContent = data.fix || 'No fix suggested.';
60
- resultDiv.classList.remove('hidden');
61
- } else {
62
- showError(data.detail || 'Translation failed.');
63
- }
64
- } catch (err) {
65
- showError('Network error. Is the server running?');
66
- } finally {
67
- btn.disabled = false;
68
- btn.textContent = 'Translate';
69
- }
70
- });
71
-
72
- function showError(msg) {
73
- errorDiv.textContent = msg;
74
- errorDiv.classList.remove('hidden');
75
- }
76
- </script>
77
- </body>
78
- </html>
@@ -1,93 +0,0 @@
1
- body {
2
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
3
- max-width: 900px;
4
- margin: 40px auto;
5
- padding: 0 20px;
6
- background-color: #f8f9fa;
7
- color: #212529;
8
- }
9
-
10
- .container {
11
- background: white;
12
- border-radius: 12px;
13
- padding: 30px;
14
- box-shadow: 0 4px 12px rgba(0,0,0,0.05);
15
- }
16
-
17
- h1 {
18
- margin-top: 0;
19
- color: #0d6efd;
20
- }
21
-
22
- .subtitle {
23
- color: #6c757d;
24
- margin-bottom: 20px;
25
- }
26
-
27
- textarea {
28
- width: 100%;
29
- height: 200px;
30
- padding: 15px;
31
- font-family: 'Courier New', monospace;
32
- font-size: 14px;
33
- border: 1px solid #ced4da;
34
- border-radius: 8px;
35
- resize: vertical;
36
- box-sizing: border-box;
37
- background-color: #fdfdfd;
38
- }
39
-
40
- button {
41
- background-color: #0d6efd;
42
- color: white;
43
- border: none;
44
- padding: 12px 24px;
45
- font-size: 16px;
46
- border-radius: 6px;
47
- cursor: pointer;
48
- margin-top: 15px;
49
- transition: background-color 0.2s;
50
- }
51
-
52
- button:hover {
53
- background-color: #0b5ed7;
54
- }
55
-
56
- button:disabled {
57
- background-color: #6c757d;
58
- cursor: not-allowed;
59
- }
60
-
61
- .result {
62
- margin-top: 30px;
63
- border-top: 1px solid #dee2e6;
64
- padding-top: 20px;
65
- }
66
-
67
- .result h3 {
68
- margin-bottom: 8px;
69
- color: #198754;
70
- }
71
-
72
- .result pre {
73
- background-color: #f1f3f5;
74
- padding: 15px;
75
- border-radius: 6px;
76
- overflow-x: auto;
77
- white-space: pre-wrap;
78
- font-family: 'Courier New', monospace;
79
- font-size: 14px;
80
- }
81
-
82
- .error {
83
- margin-top: 20px;
84
- color: #dc3545;
85
- background-color: #f8d7da;
86
- border: 1px solid #f5c2c7;
87
- padding: 12px;
88
- border-radius: 6px;
89
- }
90
-
91
- .hidden {
92
- display: none;
93
- }
@@ -1,19 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- error_translator/__init__.py
5
- error_translator/ast_handlers.py
6
- error_translator/auto.py
7
- error_translator/cli.py
8
- error_translator/core.py
9
- error_translator/rules.json
10
- error_translator/server.py
11
- error_translator/static/index.html
12
- error_translator/static/style.css
13
- error_translator_cli_v2.egg-info/PKG-INFO
14
- error_translator_cli_v2.egg-info/SOURCES.txt
15
- error_translator_cli_v2.egg-info/dependency_links.txt
16
- error_translator_cli_v2.egg-info/entry_points.txt
17
- error_translator_cli_v2.egg-info/requires.txt
18
- error_translator_cli_v2.egg-info/top_level.txt
19
- tests/test_core.py