135 lines
4.4 KiB
Markdown
135 lines
4.4 KiB
Markdown
# 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/
|