# SkillPatch skill: pydantic-models-py

This skill guides agents in creating Pydantic v2 models following a structured multi-model pattern (Base, Create, Update, Response, InDB). It provides actionable templates, code examples, and integration steps for defining API request/response schemas, database models, and data validation in Python applications. It is particularly useful for FastAPI or similar backend projects that interface with databases like Cosmos DB.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/pydantic-models-py
curl -sSL https://skillpatch.dev/install_skill/pydantic-models-py | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (2)

- `SKILL.md`
- `assets/template.py`


### `SKILL.md`

````markdown
---
name: pydantic-models-py
description: Create Pydantic models following the multi-model pattern with Base, Create, Update, Response, and InDB variants. Use when defining API request/response schemas, database models, or data validation in Python applications using Pydantic v2.
license: MIT
metadata:
  author: Microsoft
  version: "1.0.0"
---

# Pydantic Models

Create Pydantic models following the multi-model pattern for clean API contracts.

## Quick Start

Copy the template from [assets/template.py](assets/template.py) and replace placeholders:
- `{{ResourceName}}` → PascalCase name (e.g., `Project`)
- `{{resource_name}}` → snake_case name (e.g., `project`)

## Multi-Model Pattern

| Model | Purpose |
|-------|---------|
| `Base` | Common fields shared across models |
| `Create` | Request body for creation (required fields) |
| `Update` | Request body for updates (all optional) |
| `Response` | API response with all fields |
| `InDB` | Database document with `doc_type` |

## camelCase Aliases

```python
class MyModel(BaseModel):
    workspace_id: str = Field(..., alias="workspaceId")
    created_at: datetime = Field(..., alias="createdAt")
    
    class Config:
        populate_by_name = True  # Accept both snake_case and camelCase
```

## Optional Update Fields

```python
class MyUpdate(BaseModel):
    """All fields optional for PATCH requests."""
    name: Optional[str] = Field(None, min_length=1)
    description: Optional[str] = None
```

## Database Document

```python
class MyInDB(MyResponse):
    """Adds doc_type for Cosmos DB queries."""
    doc_type: str = "my_resource"
```

## Integration Steps

1. Create models in `src/backend/app/models/`
2. Export from `src/backend/app/models/__init__.py`
3. Add corresponding TypeScript types

````


### `assets/template.py`

```
"""
{{ResourceName}} Models

Pydantic models for {{resource_name}} resource following the multi-model pattern.
"""

from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field


# ============================================================================
# Base Model
# ============================================================================


class {{ResourceName}}Base(BaseModel):
    """
    Base model with common fields.

    Used as the foundation for Create, Update, and Response models.
    """

    name: str = Field(
        ...,
        min_length=1,
        max_length=200,
        description="Display name for the {{resource_name}}",
    )
    description: Optional[str] = Field(
        None,
        max_length=2000,
        description="Optional description",
    )
    # Add additional common fields here

    class Config:
        populate_by_name = True  # Allows both snake_case and camelCase


# ============================================================================
# Create Model
# ============================================================================


class {{ResourceName}}Create({{ResourceName}}Base):
    """
    Request model for creating a new {{resource_name}}.

    Includes all required fields for creation.
    """

    # Add required creation-only fields
    workspace_id: str = Field(
        ...,
        alias="workspaceId",
        description="ID of the parent workspace",
    )


# ============================================================================
# Update Model
# ============================================================================


class {{ResourceName}}Update(BaseModel):
    """
    Request model for partial updates.

    All fields are optional - only provided fields will be updated.
    """

    name: Optional[str] = Field(
        None,
        min_length=1,
        max_length=200,
    )
    description: Optional[str] = Field(
        None,
        max_length=2000,
    )
    # Add additional updatable fields here

    class Config:
        populate_by_name = True


# ============================================================================
# Response Model
# ============================================================================


class {{ResourceName}}({{ResourceName}}Base):
    """
    Response model with all fields.

    Returned from API endpoints.
    """

    id: str = Field(..., description="Unique identifier")
    slug: str = Field(..., description="URL-friendly identifier")
    workspace_id: str = Field(..., alias="workspaceId")
    author_id: str = Field(..., alias="authorId")
    created_at: datetime = Field(..., alias="createdAt")
    updated_at: Optional[datetime] = Field(None, alias="updatedAt")

    class Config:
        from_attributes = True  # Enable ORM mode for SQLAlchemy/etc
        populate_by_name = True


# ============================================================================
# Database Model
# ============================================================================


class {{ResourceName}}InDB({{ResourceName}}):
    """
    Database document model.

    Includes doc_type for Cosmos DB partitioning and queries.
    """

    doc_type: str = "{{resource_name}}"

```
