elytra_client/.copilot-instructions.md
claudi 459838b2e6 Add comprehensive development and style guides for Elytra PIM Client
- Introduced .copilot-instructions.md for GitHub Copilot usage guidelines.
- Created DEVELOPMENT.md detailing environment setup, workflow, and common tasks.
- Established STYLE_GUIDE.md as a quick reference for code style, formatting, and conventions.
2026-02-20 09:14:40 +01:00

8.5 KiB

GitHub Copilot Instructions for Elytra PIM Client

Project Overview

Elytra PIM Client is a fully Pythonic, Pydantic-driven client for the Elytra Product Information Management (PIM) API. It provides type-safe, validated interactions with the Elytra PIM API using modern Python practices.

Key Characteristics

  • Python 3.9+ project with full type hints
  • Pydantic v2 for data validation and serialization
  • OpenAPI specification-driven API design
  • Comprehensive error handling with custom exception classes
  • Bearer token authentication
  • Context manager support
  • Fully tested with pytest

Code Style and Conventions

Language

  • All code and documentation must be in English.
  • No comments, docstrings, variable names, or documentation in other languages.
  • Use clear, professional American English.

Formatting and Standards

  • Code Style: Follow PEP 8 with line length of 100 characters
  • Formatter: Black (configured in project)
  • Import Order: Use isort with Black-compatible settings
  • Linting: Flake8 for code quality checks
  • Type Checking: mypy for static type checking

Type Hints

  • Always include type hints for function parameters and return types
  • Use Optional[T] or T | None for nullable types
  • Use TypeVar for generic functions
  • Use union types with | operator (Python 3.10+)
  • For APIs returning multiple response types, use TypeVar bound to BaseModel

Docstrings

  • Use Google-style docstrings for all public modules, classes, and functions
  • Format:
    """One-line summary.
    
    Longer description if needed.
    
    Args:
        param_name: Description of parameter
    
    Returns:
        Description of return value
    
    Raises:
        ExceptionType: When this exception is raised
    """
    

Imports

  • Group imports: stdlib, third-party, local
  • Use absolute imports
  • Keep imports at module level unless lazy loading is necessary

Project Structure

elytra_client/
├── __init__.py           # Package exports
├── client.py             # Main ElytraClient class
├── config.py             # Configuration handling
├── models.py             # Pydantic models (auto-generated from OpenAPI)
└── exceptions.py         # Custom exception classes

tests/
├── test_client.py        # Client tests
└── ...                   # Other test files

examples/
└── ...                   # Example usage scripts

openapi.yaml             # OpenAPI specification (source of truth)
pyproject.toml           # Project metadata and dependencies

Core Patterns and Conventions

Exception Handling

  • Use custom exception classes from exceptions.py:
    • ElytraAPIError: Base exception for all API errors
    • ElytraAuthenticationError: Authentication failures (401, 403)
    • ElytraNotFoundError: Resource not found (404)
    • ElytraValidationError: Validation failures
  • Always catch requests.RequestException in HTTP methods
  • Always catch ValidationError when working with Pydantic models
  • Provide meaningful error messages with context

API Methods in ElytraClient

  • Follow REST conventions: get_*, create_*, update_*, delete_*
  • Return Pydantic models for single resources or dict with items list for collections
  • Support pagination parameters: page, limit, offset
  • Support language parameter: lang (for multi-language support)
  • Use _make_request() helper for all HTTP calls
  • Always validate responses with Pydantic models

Data Models (Pydantic)

  • All models inherit from pydantic.BaseModel
  • Use Field() for validation and documentation
  • Use field_validator() for custom validation
  • Model names follow pattern: Single{Resource}{Operation}RequestBody, {Resource}Response, etc.
  • Use exclude_none=True when serializing to avoid sending null values

Configuration

  • Use environment variables via python-dotenv
  • Store sensitive data (API keys) in .env files
  • Never commit .env files
  • Provide .env.example as template

Logging

  • Use Python's logging module
  • Create loggers with logger = logging.getLogger(__name__)
  • Log important operations and errors
  • Avoid logging sensitive information (API keys, tokens)

Testing Requirements

Test Structure

  • All tests in tests/ directory
  • Test file naming: test_*.py
  • Test class naming: Test*
  • Test function naming: test_*

Coverage

  • Aim for >80% code coverage
  • Test both success and error paths
  • Test Pydantic validation
  • Use pytest fixtures for setup

Mocking

  • Use unittest.mock for mocking requests
  • Mock external API calls
  • Mock database calls if applicable
  • Do not make real API calls in tests

Example Test Pattern

import pytest
from unittest.mock import Mock, patch

def test_get_products(client):
    """Test successful product retrieval."""
    with patch.object(client.session, 'request') as mock_request:
        # Setup mock
        mock_request.return_value = Mock(status_code=200, json=lambda: {...})

        # Execute
        result = client.get_products()

        # Assert
        assert isinstance(result, dict)

Development Workflow

Before Committing

  • Run tests: pytest tests/ -v
  • Check coverage: pytest --cov=elytra_client
  • Format code: black elytra_client tests
  • Check imports: isort elytra_client tests
  • Lint code: flake8 elytra_client tests
  • Type check: mypy elytra_client

Creating New Features

  1. Create a test first (TDD approach if possible)
  2. Implement the feature
  3. Ensure all tests pass
  4. Run formatters and linters
  5. Add documentation for public APIs

API Changes

  • Update openapi.yaml first (source of truth)
  • Regenerate/update Pydantic models in models.py
  • Update client methods accordingly
  • Update tests

Common Tasks and Expectations

When Adding API Methods

  1. Add method to ElytraClient class
  2. Create corresponding Pydantic models for request/response
  3. Use _make_request() helper
  4. Add comprehensive docstrings
  5. Include type hints
  6. Error handling with custom exceptions
  7. Add tests with mocked responses

When Adding Pydantic Models

  • Place in models.py
  • Use descriptive names matching API structure
  • Add field validators if needed
  • Include docstrings for complex fields
  • Use ConfigDict for model configuration if needed

When Fixing Bugs

  1. Add a failing test that reproduces the bug
  2. Fix the bug
  3. Verify the test now passes
  4. Check for similar issues in codebase

When Refactoring

  1. Ensure all tests pass before starting
  2. Make small, focused changes
  3. Run tests frequently
  4. Update documentation if interfaces change
  5. Commit atomic, logical changes

Performance Considerations

  • Reuse requests.Session for connection pooling
  • Support pagination for large result sets
  • Document timeout behavior
  • Consider request/response sizes
  • Log performance-critical operations

Documentation Requirements

README

  • Keep up-to-date with current features
  • Include installation and quick start
  • Link to full API documentation

Code Comments

  • Explain "why" not "what" - code should be self-explanatory for "what"
  • Avoid obvious comments
  • Use for complex algorithms or non-obvious decisions
  • Keep comments synchronized with code

Docstrings

  • Always provide docstrings for public APIs
  • Include examples for complex usage patterns
  • Multi-language support should be documented

What NOT to Do

  • Don't mix English with other languages in code
  • Don't commit .env files or secrets
  • Don't make real API calls in tests
  • Don't skip type hints
  • Don't ignore linting or formatting errors
  • Don't commit code that doesn't pass tests
  • Don't use bare except: clauses
  • Don't modify response models without updating tests
  • Don't log sensitive information
  • Don't hardcode API keys or credentials

Helpful Commands

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run with coverage
pytest --cov=elytra_client --cov-report=html

# Format code
black elytra_client tests
isort elytra_client tests

# Lint
flake8 elytra_client tests

# Type check
mypy elytra_client

# Run all checks (recommended before commit)
black elytra_client tests && isort elytra_client tests && flake8 elytra_client tests && mypy elytra_client && pytest tests/ -v

Resources