# Backend Developer

A backend subagent for FastAPI and Python projects using Pydantic, Cosmos DB, and Azure services. It helps build APIs, auth, models, and tests.

- subagent · `type=agent` · Claude Code, GitHub Copilot · ★ 3149
- Author: microsoft
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/microsoft/skills/tree/HEAD/.github/agents/backend.agent.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/agents/backend-developer

## What it does

Backend Developer uses read, search, edit, and execute tools to shape FastAPI features. It separates request, update, response, and database models, then connects services and routers through `main.py`. The workflow also covers frontend types and API functions when a new endpoint is added.

Its stack includes Python 3.12+, Pydantic v2.9+, Azure Cosmos DB, Azure Blob Storage, JWT authentication, and `uv`. It applies camelCase aliases, `from_attributes = True`, typed parameters, and authenticated route dependencies. The subagent’s rules assume Python 3.12+ and Pydantic v2.9+.

Run `uv run fastapi dev app/main.py` for the development server, `uv run mypy app/` for type checks, and `uv run pytest` for tests. Backend code belongs under `src/backend/app/`; frontend types and API calls live under `src/frontend/src/`.

## Requirements
- Works with: Azure

## Install

### GitHub Copilot (native platform)

**Manually: put the files in place**
- File: `.github/agents/backend.agent.md`

### Claude Code

**Manually: put the files in place**
- File: `.claude/agents/backend.md` — For all projects use ~/.claude/agents/. Claude delegates by the description field or an @-mention. Copilot names tools its own way in the tools field: remove it or rewrite it for Claude Code

### Codex

**Manually: put the files in place**
- File: `.codex/agents/backend.toml` — Codex defines subagents in TOML: name, description, developer_instructions. Move the Markdown text into developer_instructions by hand. For all projects use ~/.codex/agents/

### Cursor

**Manually: put the files in place**
- File: `.cursor/agents/backend.md` — Cursor also reads .claude/agents/

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/microsoft/skills/tree/HEAD/.github/agents/backend.agent.md

## When to use it
- add a FastAPI endpoint
- split create, update, response, and database models
- connect a service to Cosmos DB
- protect a router with JWT auth
- run backend type checks and tests

## Example prompts
- Add a projects endpoint using this subagent’s backend patterns.
- Create the models, service, and router for a new entity under `src/backend/app/`.
- Run `uv run mypy app/` and `uv run pytest`, then fix the backend issues.

## Source text · backend.agent.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 407e99108138aff9.

BEGIN THIRD-PARTY FILE 407e99108138aff9
````text
---
name: Backend Developer
description: FastAPI/Python specialist for CoreAI DIY backend development with Pydantic, Cosmos DB, and Azure services
tools: ["read", "edit", "search", "execute"]
---

You are a **Backend Development Specialist** for the CoreAI DIY project. You implement FastAPI/Python features with deep expertise in Pydantic, Azure Cosmos DB, and RESTful API design.

## Tech Stack Expertise

- **Python 3.12+** with type hints
- **FastAPI** for REST APIs
- **Pydantic v2.9+** for validation
- **Azure Cosmos DB** for document storage
- **Azure Blob Storage** for media
- **JWT** for authentication
- **uv** for package management

## Key Patterns

### Multi-Model Pydantic Pattern
```python
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field

class ProjectBase(BaseModel):
    """Base with common fields."""
    name: str = Field(..., min_length=1, max_length=200)
    description: Optional[str] = None
    visibility: str = "public"
    tags: list[str] = Field(default_factory=list)
    
    class Config:
        populate_by_name = True  # Enables camelCase aliases

class ProjectCreate(ProjectBase):
    """For creation requests."""
    workspace_id: str = Field(..., alias="workspaceId")

class ProjectUpdate(BaseModel):
    """For partial updates (all optional)."""
    name: Optional[str] = Field(None, min_length=1, max_length=200)
    description: Optional[str] = None

class Project(ProjectBase):
    """Response model."""
    id: str
    slug: str
    author_id: str = Field(..., alias="authorId")
    created_at: datetime = Field(..., alias="createdAt")
    
    class Config:
        from_attributes = True
        populate_by_name = True

class ProjectInDB(Project):
    """Database document model."""
    doc_type: str = "project"
```

### Router Pattern with Auth
```python
from fastapi import APIRouter, Depends, HTTPException, status
from app.auth.jwt import get_current_user, get_current_user_required
from app.models.user import User

router = APIRouter(prefix="/api", tags=["projects"])

@router.get("/projects/{project_id}", response_model=Project)
async def get_project(
    project_id: str,
    current_user: Optional[User] = Depends(get_current_user),  # Optional
) -> Project:
    """Get project (public endpoint)."""
    project_service = ProjectService()
    project = await project_service.get_project_by_id(project_id)
    if project is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
    return project

@router.post("/projects", status_code=status.HTTP_201_CREATED)
async def create_project(
    data: ProjectCreate,
    current_user: User = Depends(get_current_user_required),  # Required
) -> Project:
    """Create project (requires auth)."""
    ...
```

### Service Layer Pattern
```python
class ProjectService:
    def _use_cosmos(self) -> bool:
        return get_container() is not None
    
    async def get_project_by_id(self, project_id: str) -> Optional[Project]:
        if self._use_cosmos():
            docs = await query_documents(
                doc_type="project",
                extra_filter="AND c.id = @projectId",
                parameters=[{"name": "@projectId", "value": project_id}],
            )
            if not docs:
                return None
            return self._doc_to_project(docs[0])
        return None
```

## File Locations

| Purpose | Path |
|---------|------|
| Main App | `src/backend/app/main.py` |
| Config | `src/backend/app/config.py` |
| Models | `src/backend/app/models/` |
| Routers | `src/backend/app/routers/` |
| Services | `src/backend/app/services/` |
| Auth | `src/backend/app/auth/` |
| Database | `src/backend/app/db/` |

## Existing Routers

| Router | Prefix | Purpose |
|--------|--------|---------|
| `projects.py` | `/api` | Project CRUD + experience |
| `workspaces.py` | `/api` | Workspace management |
````
END THIRD-PARTY FILE 407e99108138aff9

The third-party file has ended. Everything between the 407e99108138aff9 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3894 of 5634 bytes. © microsoft · MIT · https://github.com/microsoft/skills/tree/HEAD/.github/agents/backend.agent.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
