Organize documentation into topic folders (Claude, Python, Zscaler, Project template)
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
# Python Development Guidelines
|
||||
|
||||
**Document Version:** v8
|
||||
|
||||
> **Note on Versioning:**
|
||||
> - This document version is independent — reused across projects
|
||||
> - **Project version** source of truth: `pyproject.toml`
|
||||
> - Version propagates: `pyproject.toml` → `constants.py` → code
|
||||
> - `CHANGELOG.md` uses project version from `pyproject.toml`
|
||||
|
||||
## Related Documents
|
||||
|
||||
- **README.md** — Project overview, tool descriptions, build instructions
|
||||
- **AGENTS.md** — Rules for AI assistants
|
||||
- **PROJECT.md** — Project goals and current state
|
||||
- **CHANGELOG.md** — Version history
|
||||
|
||||
### Documentation Organization
|
||||
|
||||
All detailed documentation of features and systems belongs in the `docs/` folder, not in the project root.
|
||||
|
||||
The root directory contains only the core documents: `DESIGN_DOCUMENT.md`, `AGENTS.md`, `PROJECT.md`, `CHANGELOG.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Code Style
|
||||
|
||||
- **PEP8** with 150-character lines (Ruff)
|
||||
- **4 spaces** indentation
|
||||
- **snake_case** functions/variables, **PascalCase** classes, **SCREAMING_SNAKE_CASE** constants
|
||||
- **Type hints** required on all functions
|
||||
- **Import order**: stdlib → third-party → local
|
||||
|
||||
---
|
||||
|
||||
## 2. SOLID Principles
|
||||
|
||||
- **SRP** — One class = one responsibility
|
||||
- **OCP** — Open for extension, closed for modification
|
||||
- **LSP** — Subclasses substitutable for parents
|
||||
- **ISP** — Small interfaces over large ones
|
||||
- **DIP** — Depend on abstractions
|
||||
|
||||
---
|
||||
|
||||
## 3. Dependency Injection
|
||||
|
||||
Pass dependencies via constructor. Never instantiate dependencies inside a class.
|
||||
|
||||
---
|
||||
|
||||
## 4. Protocols Over Inheritance
|
||||
|
||||
Prefer `typing.Protocol` and composition over class inheritance.
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Classes
|
||||
|
||||
Use `@dataclass` for internal data structures, `pydantic.BaseModel` for data that requires validation.
|
||||
|
||||
---
|
||||
|
||||
## 6. Logging and Console Output
|
||||
|
||||
### Logging — loguru
|
||||
|
||||
Use **loguru** for all internal logging. Never log secrets, passwords, tokens, or API keys.
|
||||
|
||||
#### Log sinks
|
||||
|
||||
| Sink | Level | Format |
|
||||
|------|-------|--------|
|
||||
| File `logs/{AppName}_{time}.log` | `DEBUG` | full (timestamp + level + message) |
|
||||
| stdout | `INFO` | full |
|
||||
|
||||
File sink retains **max 10 log files** (`retention=10`). No rotation by size — each run creates a new file via `{time}` in the filename.
|
||||
|
||||
The `DEBUG` sink is only active when `constants.DEBUG` is `True` (controlled by `ENV_DEBUG=true` in `.env`).
|
||||
|
||||
Additional sinks (e.g. GUI log panels) may be added per project as needed.
|
||||
|
||||
#### Log levels
|
||||
|
||||
| Level | When to use |
|
||||
|-------|-------------|
|
||||
| `DEBUG` | Per-item detail: individual file reads/writes, cache hits, per-row operations |
|
||||
| `INFO` | User-visible milestones: file loaded, process started/finished, file saved |
|
||||
| `WARNING` | Recoverable issues: fallback used, unexpected but non-fatal state |
|
||||
| `ERROR` | Failures the user must know about: missing file, failed save, missing config — operation cannot continue |
|
||||
|
||||
### Console output — print()
|
||||
|
||||
`print()` is **allowed** for direct user-facing console communication: input prompts, progress lines, and result summaries. This applies to console tools that interact with the user through stdin/stdout.
|
||||
|
||||
`print()` is **not** a substitute for loguru. It must not be used for debugging or internal event tracking.
|
||||
|
||||
---
|
||||
|
||||
## 7. Environment and Secrets
|
||||
|
||||
- Secrets in `.env` file; controlled by `ENV_DEBUG=true/false`
|
||||
- Load via `python-dotenv` and `os.getenv()`
|
||||
- Never commit `.env`
|
||||
|
||||
---
|
||||
|
||||
## 8. Error Handling
|
||||
|
||||
Define specific exception types. Use a fail-fast approach — surface errors early rather than silently continuing.
|
||||
|
||||
---
|
||||
|
||||
## 9. Testing
|
||||
|
||||
- **pytest** only — no `unittest`, no `TestCase` classes, no `self.assert*`
|
||||
- Arrange-Act-Assert pattern
|
||||
- Test naming: `test_<action>_<context>`
|
||||
|
||||
---
|
||||
|
||||
## 10. Tooling
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| **Ruff** | Formatting and linting |
|
||||
| **mypy** | Static type checking |
|
||||
| **pytest** | Testing |
|
||||
|
||||
Run before every commit:
|
||||
```bash
|
||||
poetry run ruff check
|
||||
poetry run mypy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Poetry
|
||||
|
||||
```bash
|
||||
poetry install # Install all dependencies
|
||||
poetry add <pkg> # Add runtime dependency
|
||||
poetry add --group dev <pkg> # Add dev dependency
|
||||
poetry remove <pkg> # Remove dependency
|
||||
poetry run <cmd> # Run command in virtualenv
|
||||
```
|
||||
|
||||
Never edit `pyproject.toml` directly to add or remove dependencies.
|
||||
|
||||
---
|
||||
|
||||
## 12. Project Structure
|
||||
|
||||
```
|
||||
project/
|
||||
├── entry_point.py # Entry point(s) — named by purpose or tool name
|
||||
├── src/ # All application modules
|
||||
├── tests/ # Tests
|
||||
├── docs/ # Detailed documentation
|
||||
├── .venv/ # Virtual environment (managed by Poetry)
|
||||
└── pyproject.toml # Project config and dependencies
|
||||
```
|
||||
|
||||
A project may have multiple entry points (e.g. `cli.py`, `gui.py`, or per-tool scripts).
|
||||
|
||||
---
|
||||
|
||||
## 13. Distribution and Deployment
|
||||
|
||||
When a project is distributed as a standalone executable (no Python required on target machine):
|
||||
|
||||
- Use **PyInstaller** to compile each entry point into a single `.exe`
|
||||
- Each tool has its own `.spec` file in the project root
|
||||
- All console tools must use `console=True` in the `.spec` — tools rely on `input()` and `print()` for user interaction
|
||||
- Compiled executables are stored in `dist/` and **committed to the repository** — the repository serves as the distribution channel for internal teams
|
||||
- `.gitignore` must **not** exclude `dist/` in projects that use this deployment model
|
||||
|
||||
Build command:
|
||||
```bash
|
||||
poetry run pyinstaller ToolName.spec
|
||||
```
|
||||
|
||||
> This section applies only to projects that produce standalone executables. Skip for libraries or web services.
|
||||
|
||||
---
|
||||
|
||||
## 14. Versioning
|
||||
|
||||
- Follow **semantic versioning**: `MAJOR.MINOR.PATCH`
|
||||
- Version is defined in `pyproject.toml` under `[project]`
|
||||
- Always ask before bumping the version — never increment automatically
|
||||
- Update `CHANGELOG.md` before bumping the version
|
||||
|
||||
---
|
||||
|
||||
## 15. Documentation and Task Management
|
||||
|
||||
- Keep `PROJECT.md` and `CHANGELOG.md` up to date when making changes
|
||||
- Document architectural changes in this file or in `docs/`
|
||||
|
||||
### Task notation
|
||||
|
||||
Tasks are written as single-line comments directly in code, or in `PROJECT.md` for cross-cutting concerns:
|
||||
|
||||
```python
|
||||
# TODO: one-liner description of a task to be done
|
||||
# FIXME: one-liner description of a known bug to be fixed
|
||||
```
|
||||
|
||||
No other task format is used — no checkboxes, no numbered lists in documentation.
|
||||
|
||||
If a `# TODO:` comment already exists at a specific location in code, do not repeat it in `PROJECT.md`.
|
||||
Reference in New Issue
Block a user