# ADR-002: Flask Extensions and Dependencies ## Status Accepted ## Context Flask is intentionally minimal. We need to select only essential extensions that align with the "minimal code" philosophy while supporting required functionality. ## Decision Use the following minimal set of dependencies: - **Flask** - Core framework - **markdown** - Markdown to HTML conversion - **feedgen** - RSS feed generation - **httpx** - HTTP client for IndieAuth verification - **python-dotenv** - Environment configuration - **pytest** - Testing framework **NO additional Flask extensions** will be used in V1. ## Rationale ### Core Dependencies #### markdown - **Purpose**: Convert markdown notes to HTML - **Simplicity**: Pure Python, simple API - **Justification**: Core requirement for note rendering - **Alternative**: mistune (faster but less standard) - **Verdict**: markdown is more standard and sufficient for single-user #### feedgen - **Purpose**: Generate valid RSS 2.0 feeds - **Simplicity**: High-level API, handles all RSS requirements - **Justification**: Ensures RSS 2.0 compliance without manual XML generation - **Alternative**: Manual XML generation (error-prone) - **Verdict**: feedgen guarantees valid RSS output #### httpx - **Purpose**: HTTP client for IndieAuth endpoint verification - **Simplicity**: Modern, clean API - **Justification**: Need to verify IndieAuth endpoints and fetch client metadata - **Alternative**: requests (synchronous only), urllib (too low-level) - **Verdict**: httpx provides clean API and can be sync or async if needed later #### python-dotenv - **Purpose**: Load environment variables from .env file - **Simplicity**: Single-purpose, simple API - **Justification**: Standard pattern for configuration management - **Alternative**: Manual environment variable handling - **Verdict**: Industry standard, minimal overhead #### pytest - **Purpose**: Testing framework - **Simplicity**: Minimal boilerplate, clear assertions - **Justification**: Required for test coverage - **Alternative**: unittest (more verbose), nose2 (unmaintained) - **Verdict**: pytest is current Python testing standard ### Extensions REJECTED for V1 #### Flask-SQLAlchemy (Rejected) - **Reason**: Adds ORM abstraction we don't need - **Decision**: Use sqlite3 standard library directly - **Benefit**: Simpler code, explicit queries, no magic #### Flask-Login (Rejected) - **Reason**: Session-based authentication, we need token-based - **Decision**: Implement simple token validation ourselves - **Benefit**: Full control over IndieAuth flow #### Flask-CORS (Rejected) - **Reason**: Single function decorator, don't need extension - **Decision**: Use @after_request decorator for CORS headers - **Benefit**: 5 lines of code vs. another dependency #### Flask-Limiter (Rejected for V1) - **Reason**: Rate limiting is nice-to-have, not critical for single-user - **Decision**: Defer to V2 or rely on reverse proxy - **Benefit**: Reduced complexity #### Flask-WTF (Rejected) - **Reason**: Form handling for single form (note creation) is overkill - **Decision**: Simple HTML forms with manual validation - **Benefit**: No CSRF complexity in V1, manual validation is clear ## Consequences ### Positive - Minimal dependency tree - Full control over implementation - Easy to understand codebase - Fast installation and startup - Reduced attack surface ### Negative - Must implement some features manually (token validation, CORS) - No form CSRF protection in V1 (acceptable for single-user) - Manual SQL queries required ### Mitigation - Document manual implementations clearly - Ensure manual code is well-tested - Keep manual implementations simple and obvious - Plan to add CSRF in V2 if needed ## Complete Dependency List ``` Flask==3.0.* markdown==3.5.* feedgen==1.0.* httpx==0.27.* python-dotenv==1.0.* pytest==8.0.* ``` ## Development Dependencies ``` pytest-cov # Test coverage reporting black # Code formatting flake8 # Linting ``` ## Standards Compliance - All dependencies are pure Python or have minimal C extensions - All are actively maintained with security updates - All support Python 3.11+ - Total dependency count: 6 direct dependencies (excluding dev tools) ## References - Flask Extensions: https://flask.palletsprojects.com/en/3.0.x/extensions/ - Markdown Spec: https://daringfireball.net/projects/markdown/ - RSS 2.0: https://www.rssboard.org/rss-specification - Python Packaging: https://packaging.python.org/