Type of Documentation Issue
Missing Documentation
Location
The existing `.github/copilot-instructions.md` file. This issue proposes replacing it with a new, structured XML file.
Description
We need to replace the existing copilot-instructions.md with a new copilot-instructions.xml file. This new file will contain comprehensive, XML-tagged instructions designed to guide GitHub Copilot in generating code that strictly adheres to our project's specific development standards and best practices.
The current markdown file is less structured and might not be as effective in guiding an AI assistant as a clearly defined, XML-based instruction set. The goal is to provide Copilot with a precise and machine-readable guide to ensure consistency and quality in generated code, minimizing manual review and refactoring.
Suggested Changes
The new copilot-instructions.xml file should encompass the following key areas, structured with appropriate XML tags for clarity and machine readability:
Overall Structure:
- A root XML tag, e.g.,
<CopilotInstructions>.
- Sections for different categories of guidelines.
Core Development Principles:
- Language: Python 3.12 (
<Language>Python 3.12</Language>)
- Style: Functional programming, immutability, DRY (Don't Repeat Yourself), KISS (Keep It Simple, Stupid). (
<Style>, <Principle>...</Principle>)
- Tooling: Explicitly mention
uv commands for package management and virtual environments. (<Tooling>, <Command>uv install</Command>, etc.)
Code Formatting & Typing:
- Formatting: Black and isort compliance. (
<Formatting>, <Tool>Black</Tool>, <Tool>isort</Tool>)
- Typing: Strict mypy suggestions, favoring
TypedDict and dataclasses for data structures. (<Typing>, <Tool>mypy</Tool>, <Recommendation>TypedDict</Recommendation>)
FastAPI Best Practices:
- Structure:
APIRouter per feature. (<FastAPIBestPractices>, <Structure>APIRouter-per-feature</Structure>)
- Dependencies: Injection via
Depends. (<DependencyInjection>FastAPI.Depends</DependencyInjection>)
- Lifecycle:
lifespan/startup for I/O and resource initialization. (<Lifecycle>lifespan/startup</Lifecycle>)
- Data Models: Pydantic guidance for request/response models. (
<DataModels>Pydantic</DataModels>)
- Concurrency: Async-first approach. (
<Concurrency>async-first</Concurrency>)
- Error Handling: Centralized error handling in middleware. (
<ErrorHandling>middleware</ErrorHandling>)
Design Patterns:
- Factory Pattern: For configuring clients (e.g., database connections, external APIs). (
<DesignPattern>, <PatternType>Factory</PatternType>)
- Adapter Pattern: For wrapping third-party clients to ensure a consistent interface. (
<PatternType>Adapter</PatternType>)
- Pure Functions: Emphasis on small, pure functions where possible. (
<DesignPattern>, <PatternType>PureFunctions</PatternType>)
- Dependency Injection: General principle. (
<DesignPattern>, <PatternType>DependencyInjection</PatternType>)
Examples (within CDATA sections to avoid XML parsing issues by Copilot):
- A small FastAPI endpoint wiring example.
- Snippets demonstrating Factory and Adapter patterns.
CI Suggestions:
- Run
black, isort, mypy, and pytest in CI/CD pipelines. (<CISuggestions>, <Tool>black</Tool>)
Anti-Patterns / Do-Nots:
- No I/O at import time. (
<AntiPattern>No_IO_at_import</AntiPattern>)
- No global mutable singletons. (
<AntiPattern>No_Global_Mutable_Singletons</AntiPattern>)
- Avoid deep class hierarchies. (
<AntiPattern>Avoid_Deep_Class_Hierarchies</AntiPattern>)
Example XML Structure Snippet:
<CopilotInstructions>
<General>
<Language>Python 3.12</Language>
<Style>
<Principle>Functional Programming</Principle>
<Principle>Immutability</Principle>
<Principle>DRY (Don't Repeat Yourself)</Principle>
<Principle>KISS (Keep It Simple, Stupid)</Principle>
</Style>
<Tooling>
<Description>Always use 'uv' commands for package management and virtual environments.</Description>
<Command>uv install</Command>
<Command>uv run</Command>
<!-- Add other common uv commands -->
</Tooling>
</General>
<CodeQuality>
<Formatting>
<Tool>Black</Tool>
<Tool>isort</Tool>
<Guidance>Ensure generated code adheres to Black's formatting rules.</Guidance>
<Guidance>Ensure imports are sorted and grouped by isort's rules.</Guidance>
</Formatting>
<Typing>
<Tool>mypy</Tool>
<Guidance>Use strict type hints for all functions, variables, and arguments.</Guidance>
<Recommendation>Favor `typing.TypedDict` for simple dictionaries with fixed keys and types.</Recommendation>
<Recommendation>Favor `dataclasses` for simple data objects.</Recommendation>
</Typing>
</CodeQuality>
<FastAPIBestPractices>
<Structure>
<Pattern>Use `fastapi.APIRouter` for organizing routes by feature or domain.</Pattern>
</Structure>
<DependencyInjection>
<Mechanism>Use `fastapi.Depends` for dependency injection.</Mechanism>
<Guidance>Inject configured clients, repositories, and services using `Depends`.</Guidance>
</DependencyInjection>
<Lifecycle>
<Event>Use `lifespan` (FastAPI 0.100+) or `startup` (older FastAPI) events for I/O and resource initialization.</Event>
</Lifecycle>
<DataModels>
<Tool>Pydantic</Tool>
<Guidance>Define request and response body schemas using Pydantic `BaseModel`.</Guidance>
<Guidance>Use Pydantic for data validation and serialization.</Guidance>
</DataModels>
<Concurrency>
<Principle>Design API endpoints and internal functions to be `async` where I/O operations are involved.</Principle>
</Concurrency>
<ErrorHandling>
<Mechanism>Centralized error handling via FastAPI middleware or custom exception handlers.</Mechanism>
</ErrorHandling>
</FastAPIBestPractices>
<DesignPatterns>
<Pattern type="Factory">
<Description>Use the Factory pattern for creating and configuring external clients (e.g., database, API clients, LLM providers).</Description>
<Example><![CDATA[
from httpx import AsyncClient
def create_http_client(base_url: str) -> AsyncClient:
return AsyncClient(base_url=base_url, timeout=5.0)
# Usage via Depends in FastAPI
# async def get_client(client: AsyncClient = Depends(lambda: create_http_client("https://api.example.com"))):
# ...
]]></Example>
</Pattern>
<Pattern type="Adapter">
<Description>Use the Adapter pattern to wrap third-party client libraries, providing a consistent, internal interface.</Description>
<Example><![CDATA[
# Original third-party client
class ExternalService:
def fetch_data_legacy(self, param1: str) -> dict:
...
# Our adapter
class ExternalServiceAdapter:
def __init__(self, client: ExternalService):
self._client = client
def get_info(self, identifier: str) -> dict:
# Translate our interface to the third-party client's interface
return self._client.fetch_data_legacy(param1=identifier)
]]></Example>
</Pattern>
<Pattern type="PureFunctions">
<Description>Prefer small, self-contained, pure functions (no side effects, deterministic output for given input).</Description>
</Pattern>
<Pattern type="DependencyInjection">
<Description>Favor dependency injection over global state or hardcoded dependencies.</Description>
</Pattern>
</DesignPatterns>
<Examples>
<Example type="FastAPIEndpoint"><![CDATA[
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
router = APIRouter(prefix="/items", tags=["items"])
class Item(BaseModel):
id: str
name: str
description: str | None = None
class ItemCreate(BaseModel):
name: str
description: str | None = None
# Assume an in-memory db for simplicity, replace with real db client injected via Depends
_items_db: dict[str, Item] = {}
@router.post("/", response_model=Item, status_code=status.HTTP_201_CREATED)
async def create_item(item_data: ItemCreate) -> Item:
new_id = f"item-{len(_items_db) + 1}" # In real app, use UUID
new_item = Item(id=new_id, **item_data.model_dump())
_items_db[new_id] = new_item
return new_item
@router.get("/{item_id}", response_model=Item)
async def read_item(item_id: str) -> Item:
item = _items_db.get(item_id)
if not item:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Item not found")
return item
]]></Example>
</Examples>
<CISuggestions>
<Tool>black</Tool>
<Tool>isort</Tool>
<Tool>mypy</Tool>
<Tool>pytest</Tool>
<Guidance>Ensure these tools are run in CI/CD pipelines to enforce code quality.</Guidance>
</CISuggestions>
<AntiPatterns>
<Pattern>
<Name>No I/O at import time</Name>
<Reason>Avoid side effects when modules are imported to ensure predictable startup and testability.</Reason>
</Pattern>
<Pattern>
<Name>No global mutable singletons</Name>
<Reason>Leads to hard-to-test code, side effects, and concurrency issues. Prefer dependency injection.</Reason>
</Pattern>
<Pattern>
<Name>Avoid deep class hierarchies</Name>
<Reason>Favors composition over inheritance. Deep hierarchies can lead to rigid designs and the "Yo-yo problem".</Reason>
</Pattern>
</AntiPatterns>
</CopilotInstructions>
Type of Documentation Issue
Missing Documentation
Location
Description
We need to replace the existing
copilot-instructions.mdwith a newcopilot-instructions.xmlfile. This new file will contain comprehensive, XML-tagged instructions designed to guide GitHub Copilot in generating code that strictly adheres to our project's specific development standards and best practices.The current markdown file is less structured and might not be as effective in guiding an AI assistant as a clearly defined, XML-based instruction set. The goal is to provide Copilot with a precise and machine-readable guide to ensure consistency and quality in generated code, minimizing manual review and refactoring.
Suggested Changes
The new
copilot-instructions.xmlfile should encompass the following key areas, structured with appropriate XML tags for clarity and machine readability:Overall Structure:
<CopilotInstructions>.Core Development Principles:
<Language>Python 3.12</Language>)<Style>,<Principle>...</Principle>)uvcommands for package management and virtual environments. (<Tooling>,<Command>uv install</Command>, etc.)Code Formatting & Typing:
<Formatting>,<Tool>Black</Tool>,<Tool>isort</Tool>)TypedDictanddataclassesfor data structures. (<Typing>,<Tool>mypy</Tool>,<Recommendation>TypedDict</Recommendation>)FastAPI Best Practices:
APIRouterper feature. (<FastAPIBestPractices>,<Structure>APIRouter-per-feature</Structure>)Depends. (<DependencyInjection>FastAPI.Depends</DependencyInjection>)lifespan/startupfor I/O and resource initialization. (<Lifecycle>lifespan/startup</Lifecycle>)<DataModels>Pydantic</DataModels>)<Concurrency>async-first</Concurrency>)<ErrorHandling>middleware</ErrorHandling>)Design Patterns:
<DesignPattern>,<PatternType>Factory</PatternType>)<PatternType>Adapter</PatternType>)<DesignPattern>,<PatternType>PureFunctions</PatternType>)<DesignPattern>,<PatternType>DependencyInjection</PatternType>)Examples (within CDATA sections to avoid XML parsing issues by Copilot):
CI Suggestions:
black,isort,mypy, andpytestin CI/CD pipelines. (<CISuggestions>,<Tool>black</Tool>)Anti-Patterns / Do-Nots:
<AntiPattern>No_IO_at_import</AntiPattern>)<AntiPattern>No_Global_Mutable_Singletons</AntiPattern>)<AntiPattern>Avoid_Deep_Class_Hierarchies</AntiPattern>)Example XML Structure Snippet: