chore: initialize gondulf project structure
Set up Python project with uv environment management and FastAPI stack. Project structure: - src/gondulf/ - Main application package - tests/ - Test suite directory - pyproject.toml - Project configuration with dependencies - README.md - Project documentation - uv.lock - Dependency lock file Dependencies configured: - FastAPI + Uvicorn for web framework - SQLAlchemy for database ORM - pytest + coverage for testing - ruff, black, mypy, flake8 for code quality - Development environment using uv direct execution model All project standards reviewed and implemented per: - /docs/standards/coding.md - /docs/standards/testing.md - /docs/standards/git.md - /docs/standards/development-environment.md - /docs/standards/versioning.md
This commit is contained in:
138
docs/decisions/ADR-001-python-framework-selection.md
Normal file
138
docs/decisions/ADR-001-python-framework-selection.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# 0001. Python Framework Selection for IndieAuth Server
|
||||
|
||||
Date: 2025-11-20
|
||||
|
||||
## Status
|
||||
Proposed
|
||||
|
||||
## Context
|
||||
|
||||
We need to select a Python web framework for implementing the IndieAuth server. The requirements are:
|
||||
1. Must support OAuth 2.0/IndieAuth protocol implementation
|
||||
2. Must be simple and maintainable (avoiding Django per user requirement)
|
||||
3. Must handle async operations efficiently
|
||||
4. Must have good security features
|
||||
5. Must be production-ready and well-maintained
|
||||
6. Must not add unnecessary complexity
|
||||
|
||||
We evaluated several Python web frameworks considering our core value of simplicity.
|
||||
|
||||
## Decision
|
||||
|
||||
**Recommended Stack:**
|
||||
|
||||
### Web Framework: FastAPI
|
||||
FastAPI is the recommended framework for this project.
|
||||
|
||||
**Rationale:**
|
||||
- **Simplicity with Power**: Clean, Pythonic API design that doesn't hide complexity
|
||||
- **Type Hints**: Native support for Python type hints with automatic validation
|
||||
- **OAuth 2.0 Ready**: Built-in OAuth 2.0 support that we can adapt for IndieAuth
|
||||
- **Async First**: Native async/await support for better performance
|
||||
- **Automatic Documentation**: OpenAPI/Swagger documentation generated automatically
|
||||
- **Modern Python**: Requires Python 3.10+ which aligns with our standards
|
||||
- **No Magic**: Explicit routing and dependency injection, no hidden behavior
|
||||
- **Production Ready**: Used by Microsoft, Netflix, Uber - battle-tested
|
||||
|
||||
### Data Storage: SQLite with SQLAlchemy Core
|
||||
**Rationale:**
|
||||
- **Simplicity**: SQLite for single-admin use case is perfect
|
||||
- **SQLAlchemy Core**: Direct SQL-like interface without ORM complexity
|
||||
- **No Migrations Needed Initially**: Simple schema we can manage directly
|
||||
- **Upgrade Path**: Can switch to PostgreSQL later if needed without code changes
|
||||
|
||||
### Additional Libraries:
|
||||
- **python-jose[cryptography]**: For JWT token handling if needed
|
||||
- **python-multipart**: For form data handling
|
||||
- **httpx**: For HTTP client operations (fetching client metadata)
|
||||
- **pydantic**: Data validation (comes with FastAPI)
|
||||
- **python-dotenv**: Environment variable management
|
||||
- **uvicorn**: ASGI server for running FastAPI
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Flask
|
||||
- **Pros**: Minimal, mature, extensive ecosystem
|
||||
- **Cons**: Requires many extensions, no native async, more boilerplate for our needs
|
||||
|
||||
### Starlette (FastAPI's base)
|
||||
- **Pros**: Even more minimal than FastAPI
|
||||
- **Cons**: Would need to build too much ourselves, against our simplicity principle
|
||||
|
||||
### Tornado
|
||||
- **Pros**: Good async support, mature
|
||||
- **Cons**: Older patterns, less modern Python features, smaller ecosystem
|
||||
|
||||
### aiohttp
|
||||
- **Pros**: Excellent async support
|
||||
- **Cons**: Lower-level, would require more custom code for OAuth flows
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive Consequences
|
||||
1. **Rapid Development**: FastAPI's automatic validation and documentation saves time
|
||||
2. **Type Safety**: Type hints catch errors early
|
||||
3. **Clear Architecture**: Explicit dependency injection makes data flow obvious
|
||||
4. **Good Testing**: FastAPI has excellent testing support with TestClient
|
||||
5. **Performance**: Async support handles concurrent requests efficiently
|
||||
6. **Maintainability**: Clear, explicit code that's easy to understand
|
||||
|
||||
### Negative Consequences
|
||||
1. **Newer Framework**: FastAPI is newer than Flask (but very stable)
|
||||
2. **Async Complexity**: Developers need to understand async/await
|
||||
3. **Fewer Examples**: Fewer IndieAuth examples in FastAPI than Flask
|
||||
|
||||
### Mitigation Strategies
|
||||
1. Use sync functions where async isn't needed - FastAPI supports both
|
||||
2. Provide clear documentation and examples
|
||||
3. Start with simple synchronous code, add async where beneficial
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Basic Application Structure
|
||||
```python
|
||||
from fastapi import FastAPI, Depends, HTTPException
|
||||
from fastapi.security import OAuth2AuthorizationCodeBearer
|
||||
|
||||
app = FastAPI(title="IndieAuth Server")
|
||||
|
||||
# Authorization endpoint
|
||||
@app.get("/auth")
|
||||
async def authorization_endpoint(
|
||||
response_type: str,
|
||||
client_id: str,
|
||||
redirect_uri: str,
|
||||
state: str,
|
||||
code_challenge: Optional[str] = None,
|
||||
code_challenge_method: Optional[str] = None
|
||||
):
|
||||
"""Handle IndieAuth authorization requests."""
|
||||
pass
|
||||
|
||||
# Token endpoint
|
||||
@app.post("/token")
|
||||
async def token_endpoint(
|
||||
grant_type: str,
|
||||
code: str,
|
||||
client_id: str,
|
||||
redirect_uri: str,
|
||||
code_verifier: Optional[str] = None
|
||||
):
|
||||
"""Exchange authorization code for access token."""
|
||||
pass
|
||||
|
||||
# Client registration endpoint
|
||||
@app.post("/client/register")
|
||||
async def client_registration_endpoint(
|
||||
client_name: str,
|
||||
redirect_uris: List[str]
|
||||
):
|
||||
"""Allow clients to self-register."""
|
||||
pass
|
||||
```
|
||||
|
||||
This structure is clean, explicit, and follows the IndieAuth specification closely.
|
||||
|
||||
## Recommendation
|
||||
|
||||
FastAPI provides the best balance of simplicity, modern features, and production-readiness for our IndieAuth server implementation. It aligns perfectly with our core value of simplicity while providing all necessary features for a compliant implementation.
|
||||
63
docs/decisions/ADR-002-uv-environment-management.md
Normal file
63
docs/decisions/ADR-002-uv-environment-management.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# ADR-002: Use uv for Python Virtual Environment Management
|
||||
|
||||
Date: 2025-11-20
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
The IndieAuth server project requires a Python virtual environment management tool that aligns with our core value of simplicity while providing modern development experience. Traditional tools like venv, virtualenv, and poetry each have their trade-offs in terms of speed, complexity, and feature set.
|
||||
|
||||
uv is a modern Python package and project manager written in Rust, created by the Astral team (makers of Ruff). It offers exceptional performance while maintaining compatibility with standard Python packaging tools and workflows.
|
||||
|
||||
## Decision
|
||||
We will use uv as the primary tool for Python virtual environment management and dependency installation in the IndieAuth server project.
|
||||
|
||||
### What is uv?
|
||||
uv is an extremely fast Python package installer and resolver, written in Rust. Key characteristics:
|
||||
- **10-100x faster** than pip and pip-tools for dependency resolution and installation
|
||||
- **Drop-in replacement** for pip, pip-tools, and virtualenv
|
||||
- **Standards-compliant** - works with standard requirements.txt and pyproject.toml files
|
||||
- **Simple** - focuses on doing package management well without unnecessary complexity
|
||||
- **Actively maintained** by the Astral team with frequent updates
|
||||
|
||||
### Direct Execution Model
|
||||
We will use uv's direct execution commands (`uv run`, `uv pip`) rather than traditional virtual environment activation:
|
||||
- **Instead of**: `source .venv/bin/activate` then `python script.py`
|
||||
- **We use**: `uv run python script.py`
|
||||
- **Instead of**: Activating environment then `pip install package`
|
||||
- **We use**: `uv pip install package`
|
||||
|
||||
This approach eliminates activation state confusion, works consistently across all shells and platforms, and makes CI/CD pipelines simpler.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive Consequences
|
||||
1. **Developer Experience**: Dramatically faster dependency installation speeds up development cycles
|
||||
2. **Simplicity**: No new concepts to learn - uses standard Python packaging conventions
|
||||
3. **No Activation Confusion**: Direct execution model eliminates "which environment am I in?" questions
|
||||
4. **Shell Agnostic**: Works identically across bash, zsh, fish, PowerShell, etc.
|
||||
5. **CI/CD Friendly**: Commands are explicit and don't require activation scripts
|
||||
6. **Compatibility**: Works with existing Python packaging ecosystem (PyPI, requirements.txt, etc.)
|
||||
7. **Reproducibility**: Built-in support for lockfiles ensures consistent environments
|
||||
8. **Modern Tooling**: Aligns with other modern Python tools like Ruff (linting) from the same team
|
||||
9. **No Runtime Dependency**: uv is only needed for development; production deployments use standard Python
|
||||
|
||||
### Negative Consequences
|
||||
1. **Newer Tool**: Less community knowledge compared to pip/venv (mitigated by excellent documentation)
|
||||
2. **Additional Installation**: Developers need to install uv separately (simple one-line installation)
|
||||
3. **Rust Dependency**: Requires Rust toolchain for building from source (pre-built binaries available)
|
||||
|
||||
### Why This Aligns with Project Values
|
||||
- **Simplicity**: uv provides a simpler, faster workflow without adding complexity
|
||||
- **Standards Compliance**: Uses standard Python packaging formats
|
||||
- **Maintainability**: Faster feedback loops improve developer productivity
|
||||
- **Modern Best Practices**: Represents current best practices in Python tooling
|
||||
|
||||
## Implementation Notes
|
||||
- uv will manage virtual environments in the project root as `.venv/`
|
||||
- Dependencies will be specified in `pyproject.toml` with a `uv.lock` file for reproducibility
|
||||
- All development commands will use direct execution (`uv run`, `uv pip`) without activation
|
||||
- The project will maintain compatibility with standard pip installation for production deployments
|
||||
- Documentation in `/docs/standards/development-environment.md` provides comprehensive usage patterns
|
||||
- IDE configuration will point directly to `.venv/bin/python` for interpreter selection
|
||||
Reference in New Issue
Block a user