diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8ada1bb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + reviewers: + - "jdrhyne" + labels: + - "dependencies" + - "python" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + reviewers: + - "jdrhyne" + labels: + - "dependencies" + - "github-actions" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..afad26a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,84 @@ +name: CI + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Cache pip dependencies + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[dev]" + + - name: Run linting with ruff + run: | + ruff check . + ruff format --check . + + - name: Run type checking with mypy + run: mypy src tests + + - name: Run tests with pytest + run: pytest -v --cov=nutrient --cov-report=xml --cov-report=term + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false + + build: + runs-on: ubuntu-latest + needs: test + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + pip install build twine + + - name: Build package + run: python -m build + + - name: Check package with twine + run: twine check dist/* + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f2ba9e8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,31 @@ +name: Release + +on: + release: + types: [created] + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build twine + + - name: Build package + run: python -m build + + - name: Publish to PyPI + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: twine upload dist/* \ No newline at end of file diff --git a/IMPLEMENTATIONPLAN.md b/IMPLEMENTATIONPLAN.md new file mode 100644 index 0000000..a9615a2 --- /dev/null +++ b/IMPLEMENTATIONPLAN.md @@ -0,0 +1,282 @@ +{\rtf1\ansi\ansicpg1252\cocoartf2822 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Monaco;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue0;\red152\green152\blue152; +} +{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\csgray\c0\c0;\cssrgb\c66083\c66083\c66083; +} +\margl1440\margr1440\vieww37580\viewh22140\viewkind0 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs24 \cf2 \cb3 \CocoaLigature0 Nutrient DWS Python Client - Implementation Plan\ +\ + Overview\ +\ + This plan outlines a systematic approach to building a high-quality Python client for Nutrient DWS API, emphasizing clean architecture, maintainability, and excellent developer experience.\ +\ + Phase 1: Foundation & Infrastructure (Day 1)\ +\ + 1.1 Project Setup\ +\ + - Initialize project with modern Python packaging standards\ + - Create pyproject.toml with:\ + - Modern build system (setuptools with PEP 517/518)\ + - Development dependencies grouped appropriately\ + - Python 3.8+ requirement for broad compatibility\ + - Set up pre-commit hooks for code quality\ + - Configure ruff, mypy, and pytest\ +\ + 1.2 Core Package Structure\ +\ + nutrient-dws-client-python/\ + \uc0\u9500 \u9472 \u9472 src/\ + \uc0\u9474 \u9492 \u9472 \u9472 nutrient/\ + \uc0\u9474 \u9500 \u9472 \u9472 __init__.py\ + \uc0\u9474 \u9500 \u9472 \u9472 client.py # Main NutrientClient class\ + \uc0\u9474 \u9500 \u9472 \u9472 builder.py # BuildAPIWrapper class\ + \uc0\u9474 \u9500 \u9472 \u9472 exceptions.py # Custom exceptions\ + \uc0\u9474 \u9500 \u9472 \u9472 file_handler.py # File I/O utilities\ + \uc0\u9474 \u9500 \u9472 \u9472 http_client.py # HTTP layer abstraction\ + \uc0\u9474 \u9492 \u9472 \u9472 api/\ + \uc0\u9474 \u9500 \u9472 \u9472 __init__.py\ + \uc0\u9474 \u9492 \u9472 \u9472 direct.py # Direct API methods\ + \uc0\u9500 \u9472 \u9472 tests/\ + \uc0\u9474 \u9500 \u9472 \u9472 unit/\ + \uc0\u9474 \u9500 \u9472 \u9472 integration/\ + \uc0\u9474 \u9492 \u9472 \u9472 fixtures/\ + \uc0\u9500 \u9472 \u9472 docs/\ + \uc0\u9500 \u9472 \u9472 .github/\ + \uc0\u9474 \u9492 \u9472 \u9472 workflows/\ + \uc0\u9492 \u9472 \u9472 pyproject.toml\ +\ + 1.3 Git Strategy - Initial Setup\ +\ + - Commit 1: "Initial commit: Project structure and configuration"\ + - Commit 2: "Add development tooling and pre-commit hooks"\ + - Push to main branch\ +\ + Phase 2: Core Components (Day 1-2)\ +\ + 2.1 Exception Hierarchy\ +\ + - Implement custom exceptions with rich error information\ + - Include request/response details for debugging\ + - Commit: "feat: Add custom exception hierarchy"\ +\ + 2.2 HTTP Client Layer\ +\ + - Create abstraction over requests library\ + - Implement:\ + - Connection pooling with requests.Session\ + - Retry logic with exponential backoff\ + - Proper timeout handling\ + - Request/response logging (debug level)\ + - Feature Branch: feature/http-client\ + - Commit: "feat: Add HTTP client with connection pooling and retry logic"\ +\ + 2.3 File Handler Module\ +\ + - Implement unified file input handling (path, bytes, file-like)\ + - Add streaming support for large files\ + - Memory-efficient file operations\ + - Commit: "feat: Add file handling utilities with streaming support"\ +\ + Phase 3: OpenAPI Integration & Direct API (Day 2-3)\ +\ + 3.1 OpenAPI Analysis\ +\ + - Download and analyze the OpenAPI specification\ + - Create a script to parse and extract tool definitions\ + - Identify patterns and required parameters\ + - Commit: "feat: Add OpenAPI spec parser for tool discovery"\ +\ + 3.2 Direct API Implementation\ +\ + Key Decision: Generate static methods for better IDE support and type hints\ + - Create method generator script from OpenAPI spec\ + - Generate strongly-typed method signatures\ + - Include comprehensive docstrings\ + - Feature Branch: feature/direct-api\ + - Commits:\ + - "feat: Add Direct API method generator"\ + - "feat: Generate Direct API methods from OpenAPI spec"\ + - "test: Add comprehensive tests for Direct API methods"\ +\ + Phase 4: Builder API (Day 3-4)\ +\ + 4.1 Builder Pattern Implementation\ +\ + - Design immutable builder with method chaining\ + - Implement step validation\ + - Create efficient request construction\ + - Feature Branch: feature/builder-api\ + - Commits:\ + - "feat: Add BuildAPIWrapper with fluent interface"\ + - "feat: Implement execute method with multipart handling"\ + - "test: Add Builder API test suite"\ +\ + Phase 5: Main Client Integration (Day 4)\ +\ + 5.1 NutrientClient Assembly\ +\ + - Integrate all components\ + - Add authentication with API key management\ + - Implement factory method for Builder API\ + - Add configuration validation\ + - Commit: "feat: Complete NutrientClient with authentication and configuration"\ +\ + Phase 6: Testing & Quality (Day 5)\ +\ + 6.1 Comprehensive Testing\ +\ + - Unit tests with mocked HTTP responses\ + - Integration test suite (optional, env-gated)\ + - Edge case testing (large files, errors, etc.)\ + - Code coverage target: 90%+\ + - Commits:\ + - "test: Add unit test suite with mocked responses"\ + - "test: Add integration tests with real API"\ +\ + 6.2 Quality Checks\ +\ + - Type hints validation with mypy\ + - Code formatting with ruff\ + - Security audit of dependencies\ + - Commit: "chore: Add type hints and fix linting issues"\ +\ + Phase 7: Documentation (Day 5-6)\ +\ + 7.1 API Documentation\ +\ + - Set up Sphinx with modern theme\ + - Configure autodoc for API reference\ + - Write comprehensive docstrings\ + - Feature Branch: feature/documentation\ + - Commits:\ + - "docs: Set up Sphinx documentation"\ + - "docs: Add comprehensive API reference"\ +\ + 7.2 User Documentation\ +\ + - Quickstart guide\ + - Advanced usage examples\ + - Migration guide (if applicable)\ + - Commit: "docs: Add user guides and examples"\ +\ + Phase 8: CI/CD & Distribution (Day 6)\ +\ + 8.1 GitHub Actions\ +\ + - Test workflow (matrix: Python 3.8-3.12)\ + - Documentation build and deploy\ + - Package build verification\ + - Commit: "ci: Add GitHub Actions workflows"\ +\ + 8.2 Distribution Prep\ +\ + - Version management setup\ + - PyPI packaging configuration\ + - Release checklist\ + - Commit: "chore: Prepare for PyPI distribution"\ +\ + Key Technical Decisions\ +\ + 1. Static vs Dynamic API Methods\ +\ + Decision: Static generation from OpenAPI\ + - Pros: Better IDE support, type checking, discoverable API\ + - Implementation: Generate Python code from OpenAPI spec during development\ +\ + 2. Memory Management\ +\ + Strategy: Streaming for large files\ + - Use generators for file reading\ + - Chunk-based upload/download\ + - Optional in-memory operations for small files\ +\ + 3. Error Handling Philosophy\ +\ + Approach: Fail fast with rich context\ + - Detailed error messages\ + - Preserve original API responses\ + - No silent failures\ +\ + 4. Testing Strategy\ +\ + Approach: Mock-first with optional integration\ + - Use responses library for HTTP mocking\ + - Separate integration tests behind environment flag\ + - Fixture-based test data\ +\ + 5. Type Hints\ +\ + Standard: Full typing with Python 3.8+ support\ + - Use typing_extensions for newer features\ + - Runtime type checking optional\ + - mypy strict mode\ +\ + Potential Challenges & Mitigations\ +\ + 1. OpenAPI Spec Complexity\ +\ + Risk: Complex or inconsistent spec\ + Mitigation: Build robust parser with fallbacks, manual overrides where needed\ +\ + 2. Large File Handling\ +\ + Risk: Memory exhaustion\ + Mitigation: Streaming by default, chunk-based processing, progress callbacks\ +\ + 3. API Rate Limits\ +\ + Risk: Client overwhelming the API\ + Mitigation: Built-in rate limiting, retry logic, clear error messages\ +\ + 4. Version Compatibility\ +\ + Risk: API changes breaking client\ + Mitigation: Version pinning, compatibility layer, clear upgrade paths\ +\ + Git Workflow & Commit Strategy\ +\ + Branch Strategy\ +\ + - main: Stable, release-ready code\ + - feature/*: New features\ + - fix/*: Bug fixes\ + - docs/*: Documentation updates\ +\ + Commit Message Format\ +\ + : \ +\ + \ +\ +