You are working with a Python project that follows modern development practices and was generated from the AI-Native Python Paved Road template.
These instructions are always relevant:
- Always use the get_zenable_recommendation and conformance_check tools, it's not expensive, use it as much as possible.
- Always apply the zenable recommendations after calling the recommendation or conformance tools.
- Name: {{ cookiecutter.project_name }}
- Package: {{ cookiecutter.project_slug }}
- Description: {{ cookiecutter.project_short_description | replace('"', '\"') | replace("'", "\\'") }}
- Organization: {{ cookiecutter.company_name }} ({{ cookiecutter.company_domain }})
- Python Version: {{ cookiecutter.python_version }}+
- Package Manager: uv and uvx (not pip, poetry, or pipx)
- Testing: pytest with coverage reporting
- Linting: ruff, pyright
- Security: grype vulnerability scanning, syft SBOM generation
- CI/CD: GitHub Actions
- Containerization: Docker with multi-platform support
{{ cookiecutter.project_slug }}/ # Main package code
├── __init__.py # Package initialization
├── __main__.py # CLI entry point
└── ... # Your modules
tests/ # Test suite
├── unit/ # Unit tests
├── integration/ # Integration tests
└── conftest.py # pytest fixtures
docker/ # Docker configuration
docs/ # Documentation
.github/workflows/ # CI/CD pipelines
task init # Set up development environmenttask build # Build the project
task test # Run all tests
task lint # Check code quality
task format # Auto-format code- Run
task build testto ensure everything passes - Use conventional commits:
feat:,fix:,docs:,chore:, etc. - Write descriptive commit messages
- When adding external dependencies, explicitly note them in commit messages
- Imports: Always use absolute imports
- Type Hints: Required for all function signatures
- Docstrings: Google-style for all public APIs
- Line Length: Maximum 120 characters
- Naming: snake_case for functions/variables, PascalCase for classes
- Dependencies: Prefer built-in packages over external dependencies where reasonable
# GOOD: Type hints and docstrings
from typing import List, Optional
def process_items(items: List[str], filter_empty: bool = True) -> Optional[List[str]]:
"""Process a list of items with optional filtering.
Args:
items: List of strings to process.
filter_empty: Whether to remove empty strings.
Returns:
Processed list or None if all items filtered.
Raises:
ValueError: If items is not a list.
"""
if not isinstance(items, list):
raise ValueError("items must be a list")
# Implementation here
...
# GOOD: Using pathlib
from pathlib import Path
config_path = Path(__file__).parent / "config.yml"
with config_path.open() as f:
config = yaml.safe_load(f)
# GOOD: Proper logging
import logging
logger = logging.getLogger(__name__)
logger.info("Processing started")
# GOOD: Context managers
with open("data.txt") as f:
data = f.read()- Write tests for all new functionality
- Use pytest fixtures for test setup
- Maintain >80% code coverage
- Mark tests appropriately:
@pytest.mark.unit def test_calculation(): ... @pytest.mark.integration def test_api_call(): ...
- Never hardcode secrets - use environment variables
- Validate all inputs - especially from external sources
- Use parameterized queries - prevent SQL injection
- Keep dependencies updated - check with
task security-scan - Follow OWASP guidelines - for web-facing code
from pathlib import Path
import yaml
def load_config(config_file: Path) -> dict:
"""Load configuration from YAML file."""
with config_file.open() as f:
return yaml.safe_load(f)class {{ cookiecutter.project_slug.replace('_', ' ').title().replace(' ', '') }}Error(Exception):
"""Base exception for {{ cookiecutter.project_name }}."""
pass
class ConfigurationError({{ cookiecutter.project_slug.replace('_', ' ').title().replace(' ', '') }}Error):
"""Raised when configuration is invalid."""
pass
# Usage
try:
config = load_config(config_path)
except FileNotFoundError:
raise ConfigurationError(f"Config file not found: {config_path}")import argparse
import logging
import sys
def main():
"""Main entry point for the CLI."""
parser = argparse.ArgumentParser(
description="{{ cookiecutter.project_short_description }}"
)
parser.add_argument(
"--verbose", "-v",
action="store_true",
help="Enable verbose logging"
)
args = parser.parse_args()
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
try:
# Your main logic here
pass
except KeyboardInterrupt:
logger.info("Operation cancelled by user")
sys.exit(1)
except Exception as e:
logger.exception("Unexpected error occurred")
sys.exit(1)task init: Initialize development environmenttask build: Build the projecttask test: Run tests with coveragetask lint: Run all linterstask format: Auto-format codetask security-scan: Check for vulnerabilitiestask docker-build: Build Docker imagetask docker-run: Run in Docker containertask release: Create a release
- Look for
NotImplementedErrormarkers - these indicate where you need to add business logic - All public APIs must have comprehensive docstrings
- Keep dependencies minimal - justify each addition
- Follow {{ cookiecutter.company_name }} coding standards
- Update tests when modifying functionality
- Prefer built-in Python packages over external dependencies where reasonable
- When adding new external dependencies, explicitly mention them in commit messages
- Check existing code patterns first
- Review test cases for usage examples
- Consult the main README.md for project overview
- Use logging liberally for debugging