# 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: ```python """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 ```python 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 ```bash # 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 - **Pydantic v2 Docs**: https://docs.pydantic.dev/latest/ - **OpenAPI Specification**: See `openapi.yaml` in project root - **Type Hints**: https://docs.python.org/3/library/typing.html - **Pytest Documentation**: https://docs.pytest.org/ - **PEP 8 Style Guide**: https://www.python.org/dev/peps/pep-0008/