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.
- azathoth-0.0.1/.gitignore +20 -0
- azathoth-0.0.1/LICENSE +21 -0
- azathoth-0.0.1/PKG-INFO +101 -0
- azathoth-0.0.1/README.md +50 -0
- azathoth-0.0.1/assets/attributions.md +11 -0
- azathoth-0.0.1/assets/img/abstract-shape.png +0 -0
- azathoth-0.0.1/assets/meta-prompt/core-philosophy.md +45 -0
- azathoth-0.0.1/assets/meta-prompt/d-python.md +163 -0
- azathoth-0.0.1/assets/meta-prompt/d-python.py +121 -0
- azathoth-0.0.1/assets/meta-prompt/d-readme.md +171 -0
- azathoth-0.0.1/assets/meta-prompt/d-rust.md +212 -0
- azathoth-0.0.1/assets/meta-prompt/d-rust.rs +150 -0
- azathoth-0.0.1/assets/meta-prompt/new-version-release.md +59 -0
- azathoth-0.0.1/assets/meta-prompt/proactive-advisor.md +57 -0
- azathoth-0.0.1/assets/skills/agent-loop.md +7 -0
- azathoth-0.0.1/assets/skills/i18n-guide.md +88 -0
- azathoth-0.0.1/assets/skills/ts-guide-patterns.md +1280 -0
- azathoth-0.0.1/dist/.gitignore +1 -0
- azathoth-0.0.1/flake.nix +24 -0
- azathoth-0.0.1/i18n/project.inlang/.gitignore +19 -0
- azathoth-0.0.1/i18n/project.inlang/project_id +1 -0
- azathoth-0.0.1/i18n/project.inlang/settings.json +26 -0
- azathoth-0.0.1/pyproject.toml +48 -0
- azathoth-0.0.1/src/azathoth/__init__.py +20 -0
- azathoth-0.0.1/src/azathoth/agent/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/agent/tasks/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/cli/__init__.py +6 -0
- azathoth-0.0.1/src/azathoth/cli/commands/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/cli/commands/i18n.py +273 -0
- azathoth-0.0.1/src/azathoth/cli/commands/ingest.py +316 -0
- azathoth-0.0.1/src/azathoth/cli/commands/workflow.py +244 -0
- azathoth-0.0.1/src/azathoth/cli/main.py +16 -0
- azathoth-0.0.1/src/azathoth/config.py +77 -0
- azathoth-0.0.1/src/azathoth/core/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/core/directives.py +79 -0
- azathoth-0.0.1/src/azathoth/core/exceptions.py +34 -0
- azathoth-0.0.1/src/azathoth/core/i18n.py +360 -0
- azathoth-0.0.1/src/azathoth/core/ingest.py +312 -0
- azathoth-0.0.1/src/azathoth/core/llm.py +68 -0
- azathoth-0.0.1/src/azathoth/core/prompts.py +153 -0
- azathoth-0.0.1/src/azathoth/core/scout.py +68 -0
- azathoth-0.0.1/src/azathoth/core/utils.py +23 -0
- azathoth-0.0.1/src/azathoth/core/workflow.py +115 -0
- azathoth-0.0.1/src/azathoth/directives/core.toml +13 -0
- azathoth-0.0.1/src/azathoth/mcp/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/mcp/i18n.py +105 -0
- azathoth-0.0.1/src/azathoth/mcp/workflow.py +153 -0
- azathoth-0.0.1/src/azathoth/providers/__init__.py +0 -0
- azathoth-0.0.1/src/azathoth/transforms/__init__.py +0 -0
- azathoth-0.0.1/tests/conftest.py +28 -0
- azathoth-0.0.1/tests/core/test_directives.py +15 -0
- azathoth-0.0.1/tests/core/test_i18n.py +172 -0
- azathoth-0.0.1/tests/core/test_ingest.py +46 -0
- azathoth-0.0.1/tests/core/test_llm.py +82 -0
- 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.
|
azathoth-0.0.1/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://github.com/Yrrrrrf/Azathoth)
|
|
62
|
+
[](./LICENSE)
|
|
63
|
+
|
|
64
|
+
<!-- Rust based projects -->
|
|
65
|
+
|
|
66
|
+
[](https://crates.io/crates/azathoth)
|
|
67
|
+
[](https://crates.io/crates/azathoth)
|
|
68
|
+
[](https://docs.rs/azathoth)
|
|
69
|
+
|
|
70
|
+
<!-- Python based projects -->
|
|
71
|
+
<!-- [](https://pypi.org/project/azathoth/) -->
|
|
72
|
+
<!-- [](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.
|
azathoth-0.0.1/README.md
ADDED
|
@@ -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
|
+
[](https://github.com/Yrrrrrf/Azathoth)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
|
|
13
|
+
<!-- Rust based projects -->
|
|
14
|
+
|
|
15
|
+
[](https://crates.io/crates/azathoth)
|
|
16
|
+
[](https://crates.io/crates/azathoth)
|
|
17
|
+
[](https://docs.rs/azathoth)
|
|
18
|
+
|
|
19
|
+
<!-- Python based projects -->
|
|
20
|
+
<!-- [](https://pypi.org/project/azathoth/) -->
|
|
21
|
+
<!-- [](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"> |
|
|
Binary file
|
|
@@ -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()
|