From de876b3cb964e9d6f37368e46f3181cd1dea5a2d Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 12 Oct 2025 17:29:01 +0000 Subject: [PATCH 1/3] docs: remove note about the code structure --- README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/README.md b/README.md index 249eb3a..a9b711b 100644 --- a/README.md +++ b/README.md @@ -252,20 +252,3 @@ except ZeroDivisionError as e: # Handle the exception. pass ``` - -## Architecture - -All code is located in the `src/_api` directory and follows the Static-Plugin Design (SPD) pattern. This architectural approach ensures: - -- Clear separation of concerns through static plugins -- Full static analysis capabilities -- Predictable code execution paths -- Zero runtime overhead - -The project utilizes class composition rather than dynamic plugins, making the codebase easier to maintain and debug while preserving extensibility. - -### Project's Specs and Guidelines - -- [spec2: Static-Plugin Design](https://github.com/thecodecrate/guidelines/blob/main/specs/spec-002--static-plugin-design/README.md) -- [spec3: SPD Manifest Files](https://github.com/thecodecrate/guidelines/blob/main/specs/spec-003--spd-manifest-files/README.md) -- [spec4: SPD Naming Convention](https://github.com/thecodecrate/guidelines/blob/main/specs/spec-004--spd-naming-convention/README.md) From 6258fe6ac3d96330e9408dbb6050d2ce059fc2ae Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 12 Oct 2025 17:40:53 +0000 Subject: [PATCH 2/3] fix(ci): pin GitHub Actions to commit hashes for security --- .github/workflows/format-ruff.yaml | 4 ++-- .github/workflows/lint-ruff.yaml | 2 +- .github/workflows/release.yaml | 4 ++-- .github/workflows/security-zizmor.yaml | 2 +- .github/workflows/test.yaml | 2 +- tests/test_linting.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/format-ruff.yaml b/.github/workflows/format-ruff.yaml index 5dce6af..fa31cf4 100644 --- a/.github/workflows/format-ruff.yaml +++ b/.github/workflows/format-ruff.yaml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@e4db8464a088ece1b920f60402e813ea4de65b8f # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} enable-cache: true @@ -31,4 +31,4 @@ jobs: run: uvx ruff format . - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v5 + uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5 diff --git a/.github/workflows/lint-ruff.yaml b/.github/workflows/lint-ruff.yaml index 8020104..48c7caa 100644 --- a/.github/workflows/lint-ruff.yaml +++ b/.github/workflows/lint-ruff.yaml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@e4db8464a088ece1b920f60402e813ea4de65b8f # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} enable-cache: true diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bbde8a7..91e67f2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -19,10 +19,10 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@e4db8464a088ece1b920f60402e813ea4de65b8f # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} - enable-cache: true + enable-cache: false cache-dependency-glob: uv.lock - name: Set up Python diff --git a/.github/workflows/security-zizmor.yaml b/.github/workflows/security-zizmor.yaml index 2c35426..75f8f28 100644 --- a/.github/workflows/security-zizmor.yaml +++ b/.github/workflows/security-zizmor.yaml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@e4db8464a088ece1b920f60402e813ea4de65b8f # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} enable-cache: true diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 71c1d0a..56b27eb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -28,7 +28,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@e4db8464a088ece1b920f60402e813ea4de65b8f # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} enable-cache: true diff --git a/tests/test_linting.py b/tests/test_linting.py index fba86c7..911ba46 100644 --- a/tests/test_linting.py +++ b/tests/test_linting.py @@ -18,7 +18,7 @@ def test_zizmor_compliance(): """Test to ensure codebase is compliant with Zizmor linting.""" result = subprocess.run( - ["uvx", "zizmor", ".github/workflows/"], + ["uvx", "zizmor", "--min-severity", "low", ".github/workflows/"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, From 931c1df1f9ded81a54b36cda2a34a833c9b10e3b Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 12 Oct 2025 17:41:35 +0000 Subject: [PATCH 3/3] docs: add CLAUDE.md file for claude integration --- CLAUDE.md | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..124233c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,156 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a Python implementation of the Pipeline pattern, distributed as `thecodecrate-pipeline`. The package allows composing sequential stages into reusable, immutable pipelines for processing data. It's inspired by the PHP League Pipeline package. + +## Development Commands + +### Environment Setup +```bash +# The project uses uv for dependency management +# Dependencies are managed in pyproject.toml under [dependency-groups] +uv sync +``` + +### Testing +```bash +# Run all tests +pytest + +# Run tests with coverage +pytest --cov + +# Run a specific test file +pytest tests/test_pipeline.py + +# Run a specific test function +pytest tests/test_pipeline.py::test_function_name +``` + +### Code Quality +```bash +# Format code with ruff +ruff format . + +# Lint with ruff +ruff check . + +# Fix auto-fixable linting issues +ruff check --fix . + +# Format with black (line length: 79) +black . + +# Type checking is configured with strict mode in pyrightconfig.json +# Type check manually: pyright (if installed) +``` + +### Documentation +```bash +# Build documentation locally +mkdocs serve + +# Documentation is built with mkdocs-material and auto-generates API docs +# from docstrings using mkdocstrings-python +``` + +### Version Management +```bash +# Bump version (uses bumpver) +bumpver update --patch # 1.26.0 -> 1.26.1 +bumpver update --minor # 1.26.0 -> 1.27.0 +bumpver update --major # 1.26.0 -> 2.0.0 + +# Note: bumpver automatically commits and tags, but does NOT push +``` + +## Architecture + +### Core Concepts + +The codebase implements a pipeline pattern with three main abstractions: + +1. **Stage**: A callable unit that transforms input to output (`StageInterface[T_in, T_out]`) +2. **Pipeline**: An immutable chain of stages (`PipelineInterface[T_in, T_out]`) +3. **Processor**: Controls how stages are executed (`ProcessorInterface[T_in, T_out]`) + +### Directory Structure + +``` +src/ +├── _lib/ # Internal implementation +│ ├── pipeline/ # Core pipeline implementation +│ │ ├── pipeline.py # Main Pipeline class +│ │ ├── pipeline_factory.py # Factory for building pipelines +│ │ ├── processor.py # Base Processor class +│ │ ├── stage.py # Base Stage class +│ │ ├── processors/ # Built-in processors +│ │ │ ├── chained_processor.py +│ │ │ └── ... +│ │ └── traits/ # Mixins (Clonable, ActAsFactory) +│ └── processors/ # Additional processor implementations +│ ├── chained_processor/ # Processor that chains stages +│ └── interruptible_processor/ # Processor with interruption support +└── thecodecrate_pipeline/ # Public API package + ├── __init__.py # Re-exports from _lib + ├── processors/ # Public processor exports + └── types/ # Public type exports +``` + +### Key Design Patterns + +**Immutability**: Pipelines use copy-on-write semantics. The `pipe()` method creates a new pipeline instance with the added stage, preserving the original pipeline. + +**Traits System**: The codebase uses a trait-like pattern with mixins: +- `Clonable`: Provides shallow cloning capability +- `ActAsFactory`: Enables objects to act as factories for creating instances + +**Interface Segregation**: Each core concept has an interface (`*Interface`) and implementation, enabling custom implementations while maintaining type safety. + +**Async-First**: All processing is async (`async def process(...)`). The processor handles both sync and async callables transparently using `inspect.isawaitable()`. + +### Type System + +The codebase uses generic type variables for type safety: +- `T_in`: Input type to a stage or pipeline +- `T_out`: Output type from a stage or pipeline (defaults to `T_in`) + +Stages can transform types: +```python +Pipeline[int, str] # Takes int, returns str +StageInterface[int, int] # Takes int, returns int +``` + +### Processing Flow + +1. A Pipeline is created with stages (either via `.pipe()` or declaratively) +2. When `.process(payload)` is called, the pipeline: + - Instantiates stages if needed (converts classes to instances) + - Delegates to the processor's `.process()` method + - The processor iterates through stages, passing output to next stage +3. Processors can customize execution (e.g., ChainedProcessor for error handling) + +### Stream Processing + +Pipelines support processing `AsyncIterator` streams, allowing real-time data transformation where each stage can yield results consumed immediately by the next stage. + +### PipelineFactory + +Because pipelines are immutable, `PipelineFactory` provides mutable stage collection during composition. It builds the final immutable pipeline via `.build()`. + +## Testing Notes + +- Test files use stub classes in `tests/stubs/` for consistent test fixtures +- Tests are async-aware (configured via `pytest.ini` with `pytest-asyncio`) +- Mock stages implement `StageInterface` for type safety + +## Python Version + +Requires Python 3.13+ (specified in pyproject.toml). + +## Package Distribution + +Built with `hatchling`. The wheel includes both `thecodecrate_pipeline` (public API) and `_api` packages (internal). The public package re-exports symbols from `_lib`.