|
| 1 | +# C4 Annotation Schema for Literate Python |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document defines the annotation schema used to embed C4 model metadata within Python source code. These annotations enable automated generation of C4 diagrams from well-documented codebases. |
| 6 | + |
| 7 | +## Design Philosophy |
| 8 | + |
| 9 | +The annotation schema is designed to be: |
| 10 | +- **Non-invasive**: Uses comments and docstrings, doesn't affect code execution |
| 11 | +- **Human-readable**: Clear semantic meaning without parsing tools |
| 12 | +- **Literate**: Encourages narrative documentation alongside technical specs |
| 13 | +- **Extractable**: Structured enough for automated parsing |
| 14 | +- **Flexible**: Supports both inline tags and structured documentation |
| 15 | + |
| 16 | +## Annotation Types |
| 17 | + |
| 18 | +### Module-Level Annotations |
| 19 | + |
| 20 | +Placed at the top of Python modules (in module docstring). |
| 21 | + |
| 22 | +#### @c4-container |
| 23 | +Declares that this module represents a C4 Container. |
| 24 | + |
| 25 | +```python |
| 26 | +""" |
| 27 | +@c4-container: API Application |
| 28 | +@c4-technology: Python 3.12, FastAPI 0.104 |
| 29 | +@c4-description: REST API providing CRUD operations for notes |
| 30 | +@c4-responsibilities: |
| 31 | + - Accept and validate HTTP requests |
| 32 | + - Route requests to business logic |
| 33 | + - Transform responses to JSON |
| 34 | +""" |
| 35 | +``` |
| 36 | + |
| 37 | +**Fields:** |
| 38 | +- `@c4-container`: Container name (required) |
| 39 | +- `@c4-technology`: Tech stack description (required) |
| 40 | +- `@c4-description`: Brief description (required) |
| 41 | +- `@c4-responsibilities`: Bullet list of responsibilities (optional) |
| 42 | + |
| 43 | +#### @c4-component |
| 44 | +Declares that this module/class represents a C4 Component. |
| 45 | + |
| 46 | +```python |
| 47 | +""" |
| 48 | +@c4-component: Data Validation Layer |
| 49 | +@c4-technology: Python 3.12, Pydantic 2.0 |
| 50 | +@c4-description: Schema definitions for API validation |
| 51 | +""" |
| 52 | +``` |
| 53 | + |
| 54 | +**Fields:** |
| 55 | +- `@c4-component`: Component name (required) |
| 56 | +- `@c4-technology`: Tech stack (required) |
| 57 | +- `@c4-description`: Brief description (required) |
| 58 | + |
| 59 | +### Relationship Annotations |
| 60 | + |
| 61 | +Define interactions between C4 elements. |
| 62 | + |
| 63 | +#### @c4-uses |
| 64 | +Declares a dependency on another container/component. |
| 65 | + |
| 66 | +```python |
| 67 | +""" |
| 68 | +@c4-uses: Database Layer (app.database) - "Manages note persistence" - "SQLAlchemy ORM" |
| 69 | +@c4-uses: Data Models (app.models) - "Validates requests" - "Pydantic" |
| 70 | +``` |
| 71 | +
|
| 72 | +**Format:** |
| 73 | +``` |
| 74 | +@c4-uses: <target> - "<description>" - "<technology>" |
| 75 | +``` |
| 76 | +
|
| 77 | +- `<target>`: Name of the container/component being used |
| 78 | +- `<description>`: What interaction occurs (action phrase) |
| 79 | +- `<technology>`: Protocol/technology used for interaction |
| 80 | +
|
| 81 | +#### @c4-used-by |
| 82 | +Declares usage by another element (inverse relationship). |
| 83 | +
|
| 84 | +```python |
| 85 | +""" |
| 86 | +@c4-used-by: API Application - "Requests database sessions" - "SQLAlchemy ORM" |
| 87 | +@c4-used-by-person: API Consumer - "Creates notes via HTTP" - "HTTPS/JSON" |
| 88 | +""" |
| 89 | +``` |
| 90 | +
|
| 91 | +**Variants:** |
| 92 | +- `@c4-used-by`: Used by another container/component |
| 93 | +- `@c4-used-by-person`: Used by an external person/actor |
| 94 | +
|
| 95 | +#### @c4-calls |
| 96 | +Function/method level annotation for operation calls. |
| 97 | +
|
| 98 | +```python |
| 99 | +""" |
| 100 | +@c4-operation: create_note |
| 101 | +@c4-calls: Database Layer - "Persists new note" |
| 102 | +""" |
| 103 | +def create_note(note: NoteCreate, db: Session): |
| 104 | + ... |
| 105 | +``` |
| 106 | +
|
| 107 | +### Inline Annotations |
| 108 | +
|
| 109 | +Shorter annotations for specific code elements. |
| 110 | +
|
| 111 | +```python |
| 112 | +# @c4-component: FastAPI Application Instance |
| 113 | +# @c4-technology: FastAPI 0.104 |
| 114 | +app = FastAPI(...) |
| 115 | +``` |
| 116 | +
|
| 117 | +## Annotation Placement |
| 118 | +
|
| 119 | +### Module Docstring (Top of File) |
| 120 | +Place container/component declarations and module-level relationships: |
| 121 | +
|
| 122 | +```python |
| 123 | +""" |
| 124 | +================================================================================ |
| 125 | +MODULE TITLE |
| 126 | +================================================================================ |
| 127 | + |
| 128 | +Module: app.main |
| 129 | +Purpose: Brief purpose statement |
| 130 | + |
| 131 | +ARCHITECTURAL CONTEXT |
| 132 | +--------------------- |
| 133 | +Narrative explanation of this module's role in the system. |
| 134 | + |
| 135 | +C4 MODEL MAPPING |
| 136 | +---------------- |
| 137 | +@c4-container: API Application |
| 138 | +@c4-technology: Python, FastAPI |
| 139 | +@c4-description: Main API container |
| 140 | +@c4-uses: Database Layer - "Persists data" - "SQLAlchemy" |
| 141 | +""" |
| 142 | +``` |
| 143 | +
|
| 144 | +### Class Docstrings |
| 145 | +For component-level detail: |
| 146 | +
|
| 147 | +```python |
| 148 | +class NoteDB(Base): |
| 149 | + """ |
| 150 | + Note ORM Model |
| 151 | + |
| 152 | + Represents the 'notes' table in the database. |
| 153 | + |
| 154 | + @c4-component: Note Data Model |
| 155 | + @c4-technology: SQLAlchemy ORM |
| 156 | + """ |
| 157 | +``` |
| 158 | +
|
| 159 | +### Function Docstrings |
| 160 | +For operation-level detail: |
| 161 | +
|
| 162 | +```python |
| 163 | +def create_note(note: NoteCreate, db: Session): |
| 164 | + """ |
| 165 | + Create Note Endpoint |
| 166 | + |
| 167 | + Workflow explanation... |
| 168 | + |
| 169 | + @c4-operation: create_note |
| 170 | + @c4-calls: Database Layer - "Persists new note" |
| 171 | + """ |
| 172 | +``` |
| 173 | +
|
| 174 | +### Inline Comments |
| 175 | +For simple declarations: |
| 176 | +
|
| 177 | +```python |
| 178 | +# @c4-component: Application Instance |
| 179 | +# @c4-technology: FastAPI |
| 180 | +app = FastAPI(...) |
| 181 | +``` |
| 182 | +
|
| 183 | +## Literate Documentation Guidelines |
| 184 | +
|
| 185 | +### Structure |
| 186 | +
|
| 187 | +Each module should follow this structure: |
| 188 | +
|
| 189 | +1. **Module Header** (separators, title, metadata) |
| 190 | +2. **Architectural Context** - Why this module exists |
| 191 | +3. **C4 Model Mapping** - Structured C4 annotations |
| 192 | +4. **Design Decisions** - Architecture Decision Records (ADRs) |
| 193 | +5. **System Interactions** - Relationship annotations |
| 194 | +6. **Implementation Details** - Technical specifics |
| 195 | +7. **Future Enhancements** - Planned improvements |
| 196 | +
|
| 197 | +### Writing Style |
| 198 | +
|
| 199 | +**DO:** |
| 200 | +- Write in narrative prose explaining "why" not just "what" |
| 201 | +- Explain design decisions and trade-offs |
| 202 | +- Document alternatives considered |
| 203 | +- Use clear section headers |
| 204 | +- Include examples |
| 205 | +- Reference specific line numbers or code sections |
| 206 | +- Explain future enhancement plans |
| 207 | +
|
| 208 | +**DON'T:** |
| 209 | +- Repeat what the code already says |
| 210 | +- Write generic boilerplate |
| 211 | +- Use jargon without explanation |
| 212 | +- Assume reader knows the context |
| 213 | +- Skip the "why" behind decisions |
| 214 | +
|
| 215 | +### Example: Good vs Bad |
| 216 | +
|
| 217 | +**Bad (Just restates code):** |
| 218 | +```python |
| 219 | +""" |
| 220 | +This module contains the database code. |
| 221 | +It uses SQLAlchemy. |
| 222 | +""" |
| 223 | +``` |
| 224 | +
|
| 225 | +**Good (Explains context and decisions):** |
| 226 | +```python |
| 227 | +""" |
| 228 | +DATABASE LAYER - PERSISTENCE AND ORM |
| 229 | + |
| 230 | +This module provides the persistence layer using SQLAlchemy ORM. |
| 231 | + |
| 232 | +DESIGN DECISION: SQLite |
| 233 | +We chose SQLite for its zero-configuration setup, making it ideal |
| 234 | +for development and small deployments. For production with >100 concurrent |
| 235 | +users, we recommend PostgreSQL due to SQLite's single-writer limitation. |
| 236 | + |
| 237 | +@c4-container: Database Layer |
| 238 | +@c4-technology: SQLAlchemy 2.0, SQLite 3 |
| 239 | +@c4-uses: SQLite Database - "Persists note data" - "SQL" |
| 240 | +""" |
| 241 | +``` |
| 242 | +
|
| 243 | +## Extracting C4 Models |
| 244 | +
|
| 245 | +A tangler tool will parse these annotations to generate C4 DSL. The extraction process: |
| 246 | +
|
| 247 | +1. **Parse Module Docstrings** - Extract container/component declarations |
| 248 | +2. **Parse Relationship Annotations** - Build interaction graph |
| 249 | +3. **Parse Narrative Documentation** - Extract design decisions and context |
| 250 | +4. **Generate C4 DSL** - Map to Structurizr DSL format |
| 251 | +
|
| 252 | +## Example: Complete Module |
| 253 | +
|
| 254 | +See `app/main.py`, `app/database.py`, and `app/models.py` for complete examples of literate, annotated Python modules. |
| 255 | +
|
| 256 | +## Future Extensions |
| 257 | +
|
| 258 | +### Planned Annotation Types |
| 259 | +
|
| 260 | +- `@c4-deployment-node`: For deployment architecture |
| 261 | +- `@c4-database`: For data stores |
| 262 | +- `@c4-external-system`: For external dependencies |
| 263 | +- `@c4-security-boundary`: For security zones |
| 264 | +- `@c4-async`: For asynchronous interactions |
| 265 | +
|
| 266 | +### Planned Metadata |
| 267 | +
|
| 268 | +- `@c4-performance`: Performance characteristics |
| 269 | +- `@c4-scalability`: Scaling limits and strategies |
| 270 | +- `@c4-reliability`: Failure modes and recovery |
| 271 | +- `@c4-security`: Security considerations |
| 272 | +
|
| 273 | +## References |
| 274 | +
|
| 275 | +- C4 Model: https://c4model.com/ |
| 276 | +- Structurizr DSL: https://github.com/structurizr/dsl |
| 277 | +- Literate Programming: http://www.literateprogramming.com/ |
0 commit comments