This guide helps you migrate from the old Tags: approach to the new Section: approach in FastMarkDocs v0.5.0.
FastMarkDocs v0.5.0 introduces a cleaner, more semantic approach to organizing API documentation using Sections instead of Tags. This change provides better separation of concerns between FastAPI operational tags and documentation organization.
## GET /users
Get all users in the system.
### Description
Returns a list of users with pagination support.
Tags: users, admin## GET /users
Get all users in the system.
### Description
Returns a list of users with pagination support.
Section: User Management| Aspect | Old (Tags) | New (Sections) |
|---|---|---|
| Keyword | Tags: tag1, tag2 |
Section: Section Name |
| Multiple Values | ✅ Multiple tags supported | ❌ Single section per endpoint |
| Naming | lowercase-tags |
Title Case Sections |
| Purpose | Mixed operational/documentation | Pure documentation organization |
| FastAPI Integration | Conflated with router tags | Separate from router tags |
Find and Replace:
Tags:→Section:- Multiple tags → Single descriptive section name
Example transformations:
- Tags: users, list, admin
+ Section: User Management
- Tags: auth, login
+ Section: Authentication
- Tags: health, monitoring
+ Section: Health ChecksUse descriptive, title-case section names:
| Old Tags | New Section |
|---|---|
users, admin |
User Management |
auth, login, session |
Authentication |
health, ping |
Health Checks |
metrics, stats |
Metrics |
orders, billing |
Order Management |
settings, config |
Configuration |
FastAPI router tags continue to work as scaffolding hints during documentation generation:
# This still works and provides scaffolding hints
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/")
def get_users():
"""Get users endpoint"""
return {"users": []}When you run fmd-init, it will use users as a scaffolding hint and suggest User Management as the section name.
FastMarkDocs v0.5.0 includes intelligent section inference with a 6-step fallback chain:
- Router tags (scaffolding hints)
- Endpoint tags (scaffolding hints)
- Path-based inference (
/users→User Management) - File-based inference (
users.py→User Management) - Function name inference (
get_users→User Management) - Ultimate fallback (
API)
This means even without explicit sections, the system will intelligently organize your documentation.
The fmd-lint tool now enforces section requirements:
# This will now fail
$ fmd-lint
❌ Missing Section: GET /users endpoint missing required Section: line
💡 Add 'Section: User Management' to your documentationAll error messages now reference "sections" instead of "tags":
❌ Endpoint GET /users is missing required Section: line
💡 Choose an appropriate section name like 'User Management', 'Authentication', 'Health', etc.
If you're using configuration files that reference tag_order, update them to sections_order:
# Old
tag_order:
- users
- auth
- health
# New
sections_order:
- "User Management"
- "Authentication"
- "Health Checks"# Basic Tags → Section replacement
find docs/ -name "*.md" -exec sed -i 's/^Tags:/Section:/g' {} \;
# Convert common tag patterns to sections
find docs/ -name "*.md" -exec sed -i 's/Section: users.*/Section: User Management/g' {} \;
find docs/ -name "*.md" -exec sed -i 's/Section: auth.*/Section: Authentication/g' {} \;
find docs/ -name "*.md" -exec sed -i 's/Section: health.*/Section: Health Checks/g' {} \;import re
from pathlib import Path
def migrate_file(file_path):
content = file_path.read_text()
# Replace Tags: with Section:
content = re.sub(r'^Tags:\s*(.+)$', lambda m: f'Section: {convert_tags_to_section(m.group(1))}', content, flags=re.MULTILINE)
file_path.write_text(content)
def convert_tags_to_section(tags_str):
"""Convert comma-separated tags to a single section name"""
tags = [tag.strip() for tag in tags_str.split(',')]
# Common mappings
mappings = {
'users': 'User Management',
'auth': 'Authentication',
'health': 'Health Checks',
'metrics': 'Metrics',
'orders': 'Order Management',
'settings': 'Configuration'
}
# Use first tag's mapping or title case
first_tag = tags[0].lower()
return mappings.get(first_tag, first_tag.replace('-', ' ').replace('_', ' ').title())
# Migrate all markdown files
for md_file in Path('docs').rglob('*.md'):
migrate_file(md_file)-
Run the linter:
fmd-lint
-
Check for missing sections:
# Should show no "missing section" errors fmd-lint --format json | jq '.incomplete_documentation[] | select(.issues[] | contains("missing_section"))'
-
Verify section organization:
# Generate OpenAPI spec and check tag organization python -c " from your_app import app import json print(json.dumps(app.openapi()['tags'], indent=2)) "
Issue: fmd-lint reports missing sections
❌ Endpoint GET /users is missing required Section: line
Solution: Add a Section: line to each endpoint in your markdown files.
Issue: Multiple sections per endpoint
Section: User Management, Admin Panel # ❌ Not supported
Solution: Choose one primary section per endpoint:
Section: User Management # ✅ Correct
Issue: Lowercase section names
Section: user management # ❌ Not recommended
Solution: Use title case:
Section: User Management # ✅ Recommended
- 🎯 Clear Separation: Documentation sections are separate from FastAPI operational tags
- 📝 Better Organization: Single, descriptive section names improve readability
- 🤖 Intelligent Inference: Automatic section detection reduces manual work
- 🔍 Better Validation: Stricter linting ensures complete documentation
- 🚀 Future-Proof: Cleaner architecture for future enhancements
- Documentation Issues: Check the updated examples in the README
- Migration Problems: Use the automated scripts above
- Complex Cases: Create an issue on GitHub with your specific use case
- v1.x: Uses
Tags:approach (deprecated) - v2.0+: Uses
Section:approach (current) - Migration Window: Both approaches supported during transition period
Next Steps: After migration, run fmd-lint to ensure all documentation meets the new requirements, then enjoy the improved organization and intelligent section inference!