azathoth 0.0.1__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 (55) hide show
  1. azathoth-0.0.1/.gitignore +20 -0
  2. azathoth-0.0.1/LICENSE +21 -0
  3. azathoth-0.0.1/PKG-INFO +101 -0
  4. azathoth-0.0.1/README.md +50 -0
  5. azathoth-0.0.1/assets/attributions.md +11 -0
  6. azathoth-0.0.1/assets/img/abstract-shape.png +0 -0
  7. azathoth-0.0.1/assets/meta-prompt/core-philosophy.md +45 -0
  8. azathoth-0.0.1/assets/meta-prompt/d-python.md +163 -0
  9. azathoth-0.0.1/assets/meta-prompt/d-python.py +121 -0
  10. azathoth-0.0.1/assets/meta-prompt/d-readme.md +171 -0
  11. azathoth-0.0.1/assets/meta-prompt/d-rust.md +212 -0
  12. azathoth-0.0.1/assets/meta-prompt/d-rust.rs +150 -0
  13. azathoth-0.0.1/assets/meta-prompt/new-version-release.md +59 -0
  14. azathoth-0.0.1/assets/meta-prompt/proactive-advisor.md +57 -0
  15. azathoth-0.0.1/assets/skills/agent-loop.md +7 -0
  16. azathoth-0.0.1/assets/skills/i18n-guide.md +88 -0
  17. azathoth-0.0.1/assets/skills/ts-guide-patterns.md +1280 -0
  18. azathoth-0.0.1/dist/.gitignore +1 -0
  19. azathoth-0.0.1/flake.nix +24 -0
  20. azathoth-0.0.1/i18n/project.inlang/.gitignore +19 -0
  21. azathoth-0.0.1/i18n/project.inlang/project_id +1 -0
  22. azathoth-0.0.1/i18n/project.inlang/settings.json +26 -0
  23. azathoth-0.0.1/pyproject.toml +48 -0
  24. azathoth-0.0.1/src/azathoth/__init__.py +20 -0
  25. azathoth-0.0.1/src/azathoth/agent/__init__.py +0 -0
  26. azathoth-0.0.1/src/azathoth/agent/tasks/__init__.py +0 -0
  27. azathoth-0.0.1/src/azathoth/cli/__init__.py +6 -0
  28. azathoth-0.0.1/src/azathoth/cli/commands/__init__.py +0 -0
  29. azathoth-0.0.1/src/azathoth/cli/commands/i18n.py +273 -0
  30. azathoth-0.0.1/src/azathoth/cli/commands/ingest.py +316 -0
  31. azathoth-0.0.1/src/azathoth/cli/commands/workflow.py +244 -0
  32. azathoth-0.0.1/src/azathoth/cli/main.py +16 -0
  33. azathoth-0.0.1/src/azathoth/config.py +77 -0
  34. azathoth-0.0.1/src/azathoth/core/__init__.py +0 -0
  35. azathoth-0.0.1/src/azathoth/core/directives.py +79 -0
  36. azathoth-0.0.1/src/azathoth/core/exceptions.py +34 -0
  37. azathoth-0.0.1/src/azathoth/core/i18n.py +360 -0
  38. azathoth-0.0.1/src/azathoth/core/ingest.py +312 -0
  39. azathoth-0.0.1/src/azathoth/core/llm.py +68 -0
  40. azathoth-0.0.1/src/azathoth/core/prompts.py +153 -0
  41. azathoth-0.0.1/src/azathoth/core/scout.py +68 -0
  42. azathoth-0.0.1/src/azathoth/core/utils.py +23 -0
  43. azathoth-0.0.1/src/azathoth/core/workflow.py +115 -0
  44. azathoth-0.0.1/src/azathoth/directives/core.toml +13 -0
  45. azathoth-0.0.1/src/azathoth/mcp/__init__.py +0 -0
  46. azathoth-0.0.1/src/azathoth/mcp/i18n.py +105 -0
  47. azathoth-0.0.1/src/azathoth/mcp/workflow.py +153 -0
  48. azathoth-0.0.1/src/azathoth/providers/__init__.py +0 -0
  49. azathoth-0.0.1/src/azathoth/transforms/__init__.py +0 -0
  50. azathoth-0.0.1/tests/conftest.py +28 -0
  51. azathoth-0.0.1/tests/core/test_directives.py +15 -0
  52. azathoth-0.0.1/tests/core/test_i18n.py +172 -0
  53. azathoth-0.0.1/tests/core/test_ingest.py +46 -0
  54. azathoth-0.0.1/tests/core/test_llm.py +82 -0
  55. azathoth-0.0.1/tests/core/test_workflow.py +27 -0
@@ -0,0 +1,20 @@
1
+ # all that start with a dot except .gitignore
2
+ .*
3
+ !.gitignore
4
+
5
+ # Python-generated files
6
+ __pycache__/
7
+ *.py[oc]
8
+ build/
9
+ dist/
10
+ wheels/
11
+ *.egg-info
12
+
13
+ # Rust-generated files
14
+ /target/
15
+ temp/
16
+
17
+ # lock files
18
+ **/**.lock
19
+
20
+ translations
azathoth-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fernando Bryan Reza Campos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: azathoth
3
+ Version: 0.0.1
4
+ Summary: Azathoth: Dual-Protocol AI Intelligence Layer (MCP + A2A)
5
+ Author-email: Fernando Bryan Reza Campos <fer.rezac@outlook.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Fernando Bryan Reza Campos
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ License-File: LICENSE
28
+ Keywords: a2a,agent,ai,automation,mcp
29
+ Requires-Python: >=3.14
30
+ Requires-Dist: fastmcp>=3.2.4
31
+ Requires-Dist: gitingest>=0.3.1
32
+ Requires-Dist: google-genai>=1.73.1
33
+ Requires-Dist: httpx>=0.28.1
34
+ Requires-Dist: pydantic-settings>=2.13.1
35
+ Requires-Dist: pydantic>=2.13.1
36
+ Requires-Dist: python-dotenv>=1.2.2
37
+ Requires-Dist: rich>=15.0.0
38
+ Requires-Dist: tiktoken>=0.12.0
39
+ Requires-Dist: typer>=0.24.1
40
+ Provides-Extra: agent
41
+ Requires-Dist: a2a-sdk[http-server]>=0.3.24; extra == 'agent'
42
+ Provides-Extra: clipboard
43
+ Requires-Dist: pyperclip>=1.11.0; extra == 'clipboard'
44
+ Provides-Extra: dev
45
+ Requires-Dist: pyright>=1.1.408; extra == 'dev'
46
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
47
+ Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
48
+ Requires-Dist: pytest>=9.0.3; extra == 'dev'
49
+ Requires-Dist: ruff>=0.15.10; extra == 'dev'
50
+ Description-Content-Type: text/markdown
51
+
52
+ <h1 align="center">
53
+ <img src="https://raw.githubusercontent.com/Yrrrrrf/azathoth/main/assets/img/abstract-shape.png" alt="Azathoth Icon" width="128" height="128">
54
+ <div align="center">Azathoth</div>
55
+ </h1>
56
+
57
+ <div align="center">
58
+
59
+ <!-- CORE BADGES -->
60
+
61
+ [![GitHub: Repo](https://img.shields.io/badge/Azathoth-58A6FF?&logo=github)](https://github.com/Yrrrrrf/Azathoth)
62
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
63
+
64
+ <!-- Rust based projects -->
65
+
66
+ [![Crates.io](https://img.shields.io/crates/v/azathoth)](https://crates.io/crates/azathoth)
67
+ [![Crates.io Downloads](https://img.shields.io/crates/d/azathoth)](https://crates.io/crates/azathoth)
68
+ [![docs.rs](https://img.shields.io/badge/docs.rs-azathoth-66c2a5)](https://docs.rs/azathoth)
69
+
70
+ <!-- Python based projects -->
71
+ <!-- [![PyPI version](https://img.shields.io/pypi/v/azathoth.svg)](https://pypi.org/project/azathoth/) -->
72
+ <!-- [![PyPI Downloads](https://img.shields.io/pypi/dm/azathoth.svg)](https://pypi.org/project/azathoth/) -->
73
+
74
+ </div>
75
+
76
+ > My personal AI architect and development partner, designed to enforce
77
+ > high-level coding standards and automate complex workflows.
78
+
79
+ Azathoth is not just a tool; it's an opinionated AI agent framework. It serves
80
+ as a collection of specialized MCP (Master Control Program) servers that
81
+ encapsulate a specific, high-level development philosophy.
82
+
83
+ > **Note:** Azathoth is the production-ready assistant, ensuring that every
84
+ > piece of code and every workflow adheres to predefined best practices and
85
+ > personal standards.
86
+
87
+ ## 🚦 Getting Started
88
+
89
+ ### Quick Start
90
+
91
+ The Azathoth project provides a suite of tools and servers that can be
92
+ integrated with any MCP-compatible AI agent or CLI:
93
+
94
+ ```sh
95
+ azathoth --help
96
+ ```
97
+
98
+ ## 📄 License
99
+
100
+ This project is licensed under the **MIT License**. See the [LICENSE](./LICENSE)
101
+ file for details.
@@ -0,0 +1,50 @@
1
+ <h1 align="center">
2
+ <img src="https://raw.githubusercontent.com/Yrrrrrf/azathoth/main/assets/img/abstract-shape.png" alt="Azathoth Icon" width="128" height="128">
3
+ <div align="center">Azathoth</div>
4
+ </h1>
5
+
6
+ <div align="center">
7
+
8
+ <!-- CORE BADGES -->
9
+
10
+ [![GitHub: Repo](https://img.shields.io/badge/Azathoth-58A6FF?&logo=github)](https://github.com/Yrrrrrf/Azathoth)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
12
+
13
+ <!-- Rust based projects -->
14
+
15
+ [![Crates.io](https://img.shields.io/crates/v/azathoth)](https://crates.io/crates/azathoth)
16
+ [![Crates.io Downloads](https://img.shields.io/crates/d/azathoth)](https://crates.io/crates/azathoth)
17
+ [![docs.rs](https://img.shields.io/badge/docs.rs-azathoth-66c2a5)](https://docs.rs/azathoth)
18
+
19
+ <!-- Python based projects -->
20
+ <!-- [![PyPI version](https://img.shields.io/pypi/v/azathoth.svg)](https://pypi.org/project/azathoth/) -->
21
+ <!-- [![PyPI Downloads](https://img.shields.io/pypi/dm/azathoth.svg)](https://pypi.org/project/azathoth/) -->
22
+
23
+ </div>
24
+
25
+ > My personal AI architect and development partner, designed to enforce
26
+ > high-level coding standards and automate complex workflows.
27
+
28
+ Azathoth is not just a tool; it's an opinionated AI agent framework. It serves
29
+ as a collection of specialized MCP (Master Control Program) servers that
30
+ encapsulate a specific, high-level development philosophy.
31
+
32
+ > **Note:** Azathoth is the production-ready assistant, ensuring that every
33
+ > piece of code and every workflow adheres to predefined best practices and
34
+ > personal standards.
35
+
36
+ ## 🚦 Getting Started
37
+
38
+ ### Quick Start
39
+
40
+ The Azathoth project provides a suite of tools and servers that can be
41
+ integrated with any MCP-compatible AI agent or CLI:
42
+
43
+ ```sh
44
+ azathoth --help
45
+ ```
46
+
47
+ ## 📄 License
48
+
49
+ This project is licensed under the **MIT License**. See the [LICENSE](./LICENSE)
50
+ file for details.
@@ -0,0 +1,11 @@
1
+ # Attributions
2
+
3
+ This file records the attributions for all the assets used in the project.
4
+
5
+ ## Icons
6
+
7
+ ### favicon.ico
8
+
9
+ | URL | Icon |
10
+ | ------------------------------------------------------------------ | ------------------------------------------------ |
11
+ | [Shape](https://www.flaticon.com/free-icon/abstract-shape_6009688) | <img src="./img/abstract-shape.png" width="128"> |
@@ -0,0 +1,45 @@
1
+ ---
2
+ tags:
3
+ - meta-prompt
4
+ ---
5
+
6
+ # AI DIRECTIVE: MY CORE DEVELOPMENT PHILOSOPHY
7
+
8
+ **ACT AS:** An Expert Lead Software Engineer who has completely internalized my
9
+ specific, high-level coding standards. The following principles are your primary
10
+ programming doctrine and are non-negotiable.
11
+
12
+ ---
13
+
14
+ ### 1. Modernity and Best Practices
15
+
16
+ - **Syntax:** You **MUST NOT** use deprecated syntax for any language or
17
+ framework. You **MUST** prioritize the latest, stable, and idiomatic syntax.
18
+ - **Functional & Expressive Patterns:** You **MUST** prefer functional
19
+ constructs over imperative loops for data transformation.
20
+ - **GOOD:** `squares = [x * x for x in numbers]` (Python)
21
+ - **GOOD:** `const squares = numbers.map(n => n * n);` (JS/TS)
22
+ - **BAD:** `squares = []; for x in numbers: squares.append(x * x)`
23
+
24
+ ### 2. Clarity and Simplicity
25
+
26
+ - **Readability First:** Your code must be easily understood by a human
27
+ developer. Use concise constructs like ternary operators for simple
28
+ conditions, but expand to full `if/else` blocks if the logic is non-trivial.
29
+ The ultimate goal is clarity.
30
+ - **Meaningful Comments:** You **MUST** write comments for complex logic,
31
+ algorithms, or business rules. Comments should explain the **"why,"** not the
32
+ "what."
33
+ - **GOOD:** `# We normalize the vector to prevent issues with scaling.`
34
+ - **BAD:** `# Loop over the items.`
35
+ - **Avoid Over-Engineering:** You **MUST** favor simplicity and avoid premature
36
+ optimization or overly complex design patterns for simple problems.
37
+
38
+ ### 3. Strictness and Safety
39
+
40
+ - **Strict Typing:** All code for typed languages (like Python and TypeScript)
41
+ **MUST** be fully and accurately type-hinted. This is a top-priority,
42
+ non-negotiable requirement.
43
+ - **Robust Error Handling:** You **MUST NOT** let potential errors fail
44
+ silently. Implement graceful error handling (e.g., `try...except` blocks,
45
+ `Result` types where idiomatic) and provide meaningful error messages.
@@ -0,0 +1,163 @@
1
+ # AI DIRECTIVE: PYTHON MANDATE
2
+
3
+ **CONTEXT:** This directive contains my personal, non-negotiable coding style
4
+ and patterns for Python. It is an extension of the `core-philosophy.md` and
5
+ **MUST** be treated as the ultimate source of truth, overriding any general
6
+ Python knowledge you have.
7
+
8
+ ---
9
+
10
+ ### 1. Environment & Dependency Management
11
+
12
+ - **Manager:** All Python project and dependency management **MUST** be
13
+ performed using `uv`. You will not use `pip`, `venv`, or `conda`.
14
+ - **Initialization:** A new project is started with `uv init`.
15
+ - **Dependencies:** Dependencies are added with `uv add <package>` or
16
+ `uv add -d <dev-package>`. All dependencies are managed in `pyproject.toml`.
17
+ - **Execution:** Scripts **MUST** be run via `uv run <script_name>.py`. Tools
18
+ not installed in the venv **MUST** be run with `uvx <command>`.
19
+ - **GOOD:** `uv run src/main.py`
20
+ - **GOOD:** `uvx ruff format .`
21
+ - **BAD:** `python src/main.py`
22
+
23
+ ### 2. Code Formatting & Linting
24
+
25
+ `This will be done using the [astral](https://astral.rs/) toolchain, which is tightly integrated with [`uv`](https://astral.rs/uv/).
26
+
27
+ - **Formatter [`(ruff)`](https://astral.rs/ruff/):** The sole, mandatory code
28
+ formatter is `ruff format`. The command to use is `uvx ruff format .`.
29
+ - **Type Checking [`(ty)`](https://docs.astral.sh/ty/):** Type checking is
30
+ handled by `ty`. The command to use is `uvx ty check`.
31
+
32
+ ### 3. Syntax, Idioms, and Patterns
33
+
34
+ This is the core of my Python philosophy. Your generated code **MUST** reflect
35
+ these patterns.
36
+
37
+ - **Conciseness:** Prefer one-line constructs where readable. The goal is
38
+ expressive, not verbose, code.
39
+ - **Comprehensions & Generators:** These are **MANDATORY** for creating lists,
40
+ dictionaries, or sets from iterables. Imperative `for` loops for simple data
41
+ transformation are forbidden.
42
+ - **GOOD:** `squares = {x: x * x for x in numbers if x > 0}`
43
+ - **BAD:** `squares = {}; for x in numbers: if x > 0: squares[x] = x * x`
44
+ - **Assignment Expressions (Walrus Operator `:=`):** You **MUST** use the walrus
45
+ operator in `while` loops, comprehensions, and `if` statements to reduce
46
+ verbosity and improve flow.
47
+ - **GOOD:** `if (match := re.search(pattern, text)): print(match.group(1))`
48
+ - **BAD:** `match = re.search(pattern, text); if match: print(match.group(1))`
49
+ - **Structural Pattern Matching (`match...case`):** For any logic involving more
50
+ than two `elif` conditions, you **MUST** use a `match...case` block. This is
51
+ the standard for complex conditional branching.
52
+ - **Strict Typing:** Reaffirming the core philosophy, all definitions
53
+ (variables, function arguments, and return values) **MUST** have precise type
54
+ hints from Python `3.12+`. Use `typing.TypeAlias` for complex type
55
+ definitions.
56
+ - **Filesystem Operations:** You **MUST** use the `pathlib` library (`Path`) for
57
+ all filesystem interactions. The `os` module for path manipulation is
58
+ forbidden.
59
+
60
+ ### 4. Preferred Technology Stack
61
+
62
+ Unless specified otherwise, you **MUST** default to these libraries when
63
+ generating new projects or features.
64
+
65
+ - **Web APIs [`(FastAPI)`](https://fastapi.tiangolo.com/):** FastAPI is the
66
+ sole, mandatory framework for building web APIs. Its modern, type-driven
67
+ approach with automatic OpenAPI documentation is the standard.
68
+ - **CLI Applications [`(Typer)`](https://typer.tiangolo.com/):** Typer is the
69
+ mandatory framework for command-line interfaces. It integrates seamlessly with
70
+ the FastAPI philosophy and provides automatic help generation.
71
+ - **Data Manipulation [`(Polars)`](https://docs.pola.rs/):** Polars is the
72
+ default choice over Pandas for all data manipulation tasks. Its performance
73
+ and modern API make it the standard for data processing.
74
+ - **Asynchronous HTTP [`(httpx)`](https://www.python-httpx.org/):** httpx is the
75
+ standard client for both synchronous and asynchronous HTTP requests. It
76
+ provides a modern, fully typed API.
77
+ - **Configuration [`(Pydantic)`](https://docs.pydantic.dev/):** Pydantic's
78
+ `BaseSettings` is the mandatory approach for configuration management. This
79
+ allows for type-safe configuration loaded from environment variables with
80
+ validation.
81
+ - **Terminal User Interfaces [`(Textual)`](https://textual.textualize.io/):**
82
+ Textual is the mandatory framework for building interactive terminal
83
+ applications. It provides a modern, reactive approach to TUI development with
84
+ CSS-like styling and component-based architecture.
85
+
86
+ ### 5. Project Structure
87
+
88
+ - **Source Layout:** All projects **MUST** use a `src/` layout. `uv init` helps
89
+ establish this, and it should be maintained. All Python packages and modules
90
+ will reside within the `src/<project_name>` directory.
91
+ - **Tests:** All tests **MUST** be placed in a top-level `tests/` directory,
92
+ mirroring the structure of the `src/` directory.
93
+
94
+ ### 6. Testing
95
+
96
+ - **Framework:** `pytest` is the mandatory testing framework.
97
+ - **Execution:** Tests should be run via `uvx pytest`. For faster execution,
98
+ `pytest-xdist` **MUST** be used to run tests in parallel
99
+ (`uvx pytest -n auto`).
100
+ - **Assertions:** Use plain `assert` statements. Do not use `unittest.TestCase`
101
+ style assertions.
102
+
103
+ ### 7. Naming, Docstrings, and Comments
104
+
105
+ - **Naming Conventions:**
106
+ - Constants **MUST** be `UPPER_SNAKE_CASE`.
107
+ - Non-public functions or methods **MUST** be prefixed with a single
108
+ underscore (`_internal_function`).
109
+ - **Docstrings:** All public modules, functions, classes, and methods **MUST**
110
+ have Google-style docstrings. This is non-negotiable.
111
+ - **Example:** '''python def my_function(param1: int, param2: str) -> bool:
112
+ """This is a short summary of the function.
113
+
114
+ This is the longer description section, which can span multiple lines.
115
+
116
+ Args:
117
+ param1: The first parameter.
118
+ param2: The second parameter.
119
+
120
+ Returns:
121
+ True if successful, False otherwise.
122
+ """
123
+ # ...
124
+ '''
125
+ - **Comments:** Use comments to explain the _why_, not the _what_. Code should
126
+ be self-documenting.
127
+
128
+ ### 8. Error Handling
129
+
130
+ - **Custom Exceptions:** For domain-specific errors, you **MUST** define custom
131
+ exception classes.
132
+ - **Base Class:** All custom exceptions for a project **MUST** inherit from a
133
+ common `ProjectBaseError` to allow for unified error handling.
134
+ - **Example:** '''python class ProjectBaseError(Exception): """Base exception
135
+ for this project."""
136
+
137
+ class SpecificError(ProjectBaseError): """A more specific error.""" '''
138
+
139
+ ### 9. Logging & Console Output
140
+
141
+ This will be done using the [`rich`](https://rich.readthedocs.io/) library,
142
+ which provides beautiful terminal output and structured logging.
143
+
144
+ - **Console Output [`(rich)`](https://rich.readthedocs.io/):** The sole,
145
+ mandatory library for console output is `rich`. Use `rich.print()` for
146
+ enhanced output and `rich.console.Console()` for advanced formatting.
147
+ - **Logging:** For application logging, use `rich.logging.RichHandler` as the
148
+ handler for Python's standard `logging` library. This combines structured
149
+ logging with rich formatting.
150
+ - **Standard Setup:** '''python import logging from rich.logging import
151
+ RichHandler
152
+
153
+ logging.basicConfig( level=logging.INFO, format="%(message)s",
154
+ handlers=[RichHandler(rich_tracebacks=True, markup=True)] ) log =
155
+ logging.getLogger(**name**) '''
156
+ - **Progress & Status:** For long-running operations, you **MUST** use
157
+ `rich.progress.Progress` or `rich.status.Status` to provide user feedback.
158
+
159
+ ### Correct Usage Example
160
+
161
+ The following script is a "golden" example that perfectly encapsulates all the
162
+ rules defined in this mandate. You **MUST** use it as your primary reference for
163
+ my Python style.
@@ -0,0 +1,121 @@
1
+ # Python coding style example
2
+
3
+ # FILE: d-python.py
4
+
5
+ # Example of a small, compliant CLI tool.
6
+ # To run: uv run d-python.py --source-dir ./assets
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from pathlib import Path
12
+ from typing import TypeAlias
13
+
14
+ import typer
15
+ from rich.console import Console
16
+
17
+ # Rule 3: Use TypeAlias for complex type definitions. (Updated to include float)
18
+ JsonPayload: TypeAlias = dict[str, str | int | float]
19
+
20
+ # Rule 4: Typer for CLIs, rich for output.
21
+ app = typer.Typer(
22
+ name="file-analyzer",
23
+ help="A CLI tool demonstrating the preferred Python coding style.",
24
+ no_args_is_help=True,
25
+ add_completion=False, # A cleaner help menu for this example
26
+ )
27
+ console = Console()
28
+
29
+
30
+ def process_file(file_path: Path) -> JsonPayload | None:
31
+ """Processes a file based on its suffix using pattern matching."""
32
+ # Rule 3: Use match...case for complex conditions.
33
+ match file_path.suffix:
34
+ case ".md":
35
+ # Rule 3: Use the walrus operator within a simple if.
36
+ if (size := file_path.stat().st_size) > 1024:
37
+ console.print(
38
+ f"[yellow]Large markdown file found: {file_path.name}[/yellow]"
39
+ )
40
+ return {
41
+ "file": file_path.name,
42
+ "type": "markdown",
43
+ "size_kb": round(size / 1024, 2),
44
+ }
45
+ case ".json":
46
+ try:
47
+ content = json.loads(file_path.read_text(encoding="utf-8"))
48
+
49
+ # Rule 3: Use match...case for complex conditions - handle different JSON types
50
+ match content:
51
+ case dict():
52
+ count = len(content.keys())
53
+ payload_type = "json_object"
54
+ case list():
55
+ count = len(content)
56
+ payload_type = "json_array"
57
+ case _:
58
+ # Handle other valid JSON types like a single string or number
59
+ count = 1
60
+ payload_type = "json_value"
61
+
62
+ return {"file": file_path.name, "type": payload_type, "count": count}
63
+
64
+ except json.JSONDecodeError, UnicodeDecodeError:
65
+ console.print(
66
+ f"[bold red]Error parsing invalid JSON file: {file_path.name}[/bold red]"
67
+ )
68
+ return None
69
+ case _:
70
+ return None
71
+
72
+
73
+ @app.command()
74
+ def analyze(
75
+ source_dir: Path = typer.Option(
76
+ ..., # Make it a required option
77
+ "--source-dir",
78
+ "-d",
79
+ exists=True,
80
+ file_okay=False,
81
+ dir_okay=True,
82
+ readable=True,
83
+ resolve_path=True,
84
+ help="The source directory to analyze.",
85
+ ),
86
+ recursive: bool = typer.Option(
87
+ True, # Default to recursive search
88
+ "--recursive/--no-recursive",
89
+ "-r/-nr",
90
+ help="Search for files recursively through subdirectories.",
91
+ ),
92
+ ) -> None:
93
+ """Analyzes all supported files in the target directory."""
94
+ console.print(f"🚀 Analyzing directory: [bold cyan]{source_dir}[/bold cyan]")
95
+ console.print(
96
+ f" Recursive search: {'[green]Enabled[/green]' if recursive else '[yellow]Disabled[/yellow]'}"
97
+ )
98
+
99
+ iterator = source_dir.rglob("*") if recursive else source_dir.iterdir()
100
+
101
+ # Rule 3: Use a generator expression for memory efficiency and conciseness.
102
+ # Rule 3: Use the walrus operator to process and filter in one pass.
103
+ valid_files = (
104
+ processed
105
+ for file in iterator
106
+ if file.is_file() and (processed := process_file(file))
107
+ )
108
+
109
+ # Rule 3: Use a list comprehension to realize the final list for output.
110
+ results = [result for result in valid_files if result]
111
+
112
+ if not results:
113
+ console.print("[bold red]No supported files found to analyze.[/bold red]")
114
+ raise typer.Exit(1)
115
+
116
+ console.print(results)
117
+ console.print("\n[bold green]Analysis complete![/bold green]")
118
+
119
+
120
+ if __name__ == "__main__":
121
+ app()