- 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.
284 lines
8.5 KiB
Markdown
284 lines
8.5 KiB
Markdown
# 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/
|