Models ====== The Community DevOps Agent API uses Pydantic models for data validation and type safety. Overview -------- All API responses and request data are validated using Pydantic models, providing: - **Type Safety**: Runtime type checking and validation - **IDE Support**: Autocomplete and type hints - **Data Validation**: Automatic validation of API responses - **Serialization**: Easy conversion to/from JSON Core Models ----------- .. automodule:: devopsagent_api.models :members: :undoc-members: :show-inheritance: Model Hierarchy --------------- The models are organized hierarchically: - **Base Models**: Common fields and validation - **Request Models**: Data sent to the API - **Response Models**: Data received from the API - **Enum Models**: Fixed choice values Common Patterns --------------- **Optional Fields** Many models use optional fields to handle varying API responses: .. code-block:: python from typing import Optional from pydantic import BaseModel class Task(BaseModel): id: str title: str status: str description: Optional[str] = None # Optional field **Enum Validation** Enums ensure only valid values are accepted: .. code-block:: python from enum import Enum class TaskStatus(str, Enum): PENDING = "PENDING" IN_PROGRESS = "IN_PROGRESS" COMPLETED = "COMPLETED" FAILED = "FAILED" **Nested Models** Complex responses use nested models: .. code-block:: python class TaskResponse(BaseModel): task: Task metadata: TaskMetadata Validation Rules ---------------- Models include validation rules for data integrity: - **Field Types**: Strict type checking - **Required Fields**: Mandatory vs optional fields - **Value Constraints**: Min/max values, patterns - **Custom Validators**: Business logic validation Usage Examples -------------- **Creating Model Instances** .. code-block:: python from devopsagent_api.models import Task task = Task( id="task-123", title="Deploy application", status="IN_PROGRESS", description="Deploy to production" ) **Parsing API Responses** .. code-block:: python import json from devopsagent_api.models import TaskResponse # Parse JSON response response_data = json.loads(api_response) task_response = TaskResponse(**response_data) **Validation Errors** Models raise validation errors for invalid data: .. code-block:: python from pydantic import ValidationError try: task = Task(id="123") # Missing required fields except ValidationError as e: print(f"Validation error: {e}") Model Serialization ------------------- Models can be easily serialized to JSON: .. code-block:: python # Convert to dict task_dict = task.dict() # Convert to JSON task_json = task.json() # Exclude None values task_dict = task.dict(exclude_none=True) Type Hints ---------- All models include comprehensive type hints for IDE support: .. code-block:: python def process_task(task: Task) -> TaskResponse: # IDE will provide autocomplete and type checking return TaskResponse(task=task, metadata=TaskMetadata()) Inheritance ----------- Models use inheritance for code reuse: .. code-block:: python class BaseModel(BaseModel): id: str created_at: datetime updated_at: Optional[datetime] = None class Task(BaseModel): title: str status: TaskStatus # Inherits id, created_at, updated_at from BaseModel Custom Validators ----------------- Some models include custom validation logic: .. code-block:: python from pydantic import validator class Task(BaseModel): title: str status: TaskStatus @validator('title') def title_must_not_be_empty(cls, v): if not v.strip(): raise ValueError('Title cannot be empty') return v Best Practices -------------- **Use Type Hints** .. code-block:: python # Good def create_task(title: str, status: TaskStatus) -> Task: return Task(title=title, status=status) # Avoid def create_task(title, status): return Task(title=title, status=status) **Handle Validation Errors** .. code-block:: python try: task = Task(**api_data) except ValidationError as e: logger.error(f"Invalid task data: {e}") raise **Use Model Methods** .. code-block:: python # Use model methods for serialization task_json = task.json(indent=2) # Use dict() for programmatic access if task.status == TaskStatus.COMPLETED: print(f"Task {task.id} is complete")