Files
StarPunk/docs/decisions/ADR-002-flask-extensions.md
2025-11-18 19:21:31 -07:00

4.4 KiB

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