Files
claude-gen/.claude/plans/distributed-coalescing-breeze.md

361 lines
12 KiB
Markdown
Raw Permalink Normal View History

2026-03-18 20:21:56 +07:00
# Plan: Update Fission Python Template Based on Example Projects
## Context
The current Fission Python template (`fission-python/template/`) is essentially a copy of the `py-eom-quota` example project, making it **quota-specific** rather than a **generic starting point** for new Fission Python projects.
Three example projects were analyzed:
- `py-eom-quota` - User quota management API
- `py-eom-storage` - Storage resource management with S3 integration
- `py-ailbl-scheduler` - Background job scheduler with Dagster integration
All examples share common infrastructure patterns but differ in business logic. This plan will make the template **generic, reusable, and production-ready** by extracting shared best practices.
---
## Key Findings from Examples
### 1. Common Infrastructure (All Projects Share)
- **vault.py** - Identical across all three projects (encryption/decryption using PyNaCl)
- **helpers.py** - Nearly identical core utilities:
- `get_secret()` / `get_config()` (K8s secrets/configmaps with vault support)
- `init_db_connection()` (PostgreSQL connection)
- `db_row_to_dict()` / `db_rows_to_array()`
- `get_user_from_headers()` (extract user for audit logging)
- `format_error_response()` (standardized error format)
- `check_port_open()` (DB readiness check)
- `str_to_bool()` utility
- **Fission Configuration** - Using docstring format in `main()` functions
- **Exception Patterns** - Custom exception hierarchies with:
- `error_code` (machine-readable)
- `http_status` (HTTP status)
- `error_msg` (human-readable)
- `x_user` (optional user tracking)
- `details` (optional additional context)
- **Pydantic Models** - Request validation, response schemas, pagination/filtering
- **Project Structure** - Consistent layout:
```
project/
├── .fission/deployment.json
├── src/
│ ├── __init__.py
│ ├── exceptions.py
│ ├── helpers.py
│ ├── models.py
│ ├── vault.py
│ ├── build.sh
│ └── <business logic>.py
├── test/
├── migrates/
├── manifests/
├── specs/
├── requirements.txt
├── dev-requirements.txt
└── README.md
```
### 2. Variations Between Projects
**Database Connection:**
- `py-eom-quota`: Advanced `DBConfig` dataclass with `from_remote_config()` support
- `py-eom-storage` & `py-ailbl-scheduler`: Simplified direct connection from secrets
**Additional Dependencies:**
- Storage: `boto3` (S3/MinIO), `botocore`
- Scheduler: `gql` (GraphQL), `cron-descriptor`
- All: `pydantic`, `psycopg2-binary`, `PyNaCl`, `Flask`, `requests`
**Executors:**
- Quota: `poolmgr` (concurrency=1)
- Storage: `poolmgr` (concurrency=3, maxscale=3)
- Scheduler: `newdeploy` (minscale=1, maxscale=1)
### 3. Issues to Fix
- **README outdated** - References `pymake`, `fission.json`, `fission.yaml` (not used)
- **Missing Flask** - `src/requirements.txt` needs Flask (currently only in dev-requirements)
- **Quota-specific code** - Template should be generic (no `QuotaException`, `QuotaResponse`, etc.)
- **No .env.example** - Missing environment variable template
- **Test dependencies minimal** - Should include `pytest`, `pytest-mock`, `requests`, `flake8`, `black`
- **build.sh** - Should handle both alpine (apk) and debian (apt) properly
- **deployment.json** - Should not hardcode `fission-eom-quota-env` secret names
- **Missing Python version** - Should specify Python 3.11+ (scheduler uses 3.11-alpine)
---
## Recommended Changes
### Phase 1: Core Infrastructure (Keep Generic)
**Files to MODIFY:**
1. **`src/vault.py`** - Keep as-is (already perfect, identical in all examples)
2. **`src/helpers.py`** - Use the simplified pattern from `py-eom-storage` but add:
- Keep: `get_secret()`, `get_config()`, `init_db_connection()`, `db_row_to_dict()`, `db_rows_to_array()`, `get_current_namespace()`, `str_to_bool()`, `check_port_open()`, `get_user_from_headers()`, `format_error_response()`
- Remove: `DBConfig` class (too specific to quota, keep it simple)
- Add: `.strip()` when reading files (as in scheduler)
- Keep CORS_HEADERS and constants but make them configurable
3. **`src/exceptions.py`** - Replace quota-specific with generic patterns:
```python
class ServiceException(Exception):
"""Base exception for service errors."""
def __init__(self, error_code, http_status, error_msg, x_user=None, details=None):
...
class ValidationError(ServiceException): # 400
class NotFoundError(ServiceException): # 404
class ConflictError(ServiceException): # 409
class DatabaseError(ServiceException): # 500
```
(Based on `py-eom-storage` pattern - cleaner and more generic)
4. **`src/models.py`** - Replace with generic example patterns:
- Remove: All quota-specific models
- Add: Generic `ItemResponse`, `PaginatedResponse`, `ErrorResponse`
- Include examples of Pydantic models with Field descriptions and json_schema_extra
- Show patterns for: Enums, nested models, dataclasses for filters
5. **`src/requirements.txt`** - Update to include actual runtime deps:
```
Flask==2.1.1
pydantic==2.11.7
psycopg2-binary==2.9.10
PyNaCl==1.6.0
requests==2.32.2
```
(Remove commented examples - these go in docs, not requirements.txt)
6. **`dev-requirements.txt`** - Expand with useful dev tools:
```
Flask==2.1.1
requests==2.32.2
pytest==8.2.0
pytest-mock==3.14.0
flake8==7.0.0
black==24.1.1
mypy==1.8.0
```
7. **`README.md`** - Complete rewrite:
- Remove references to pymake, fission.json
- Explain actual project structure
- Document Fission configuration in docstrings
- Show how to use deployment.json
- Document environment variables (secrets/configmaps)
- Explain testing approach
- Add development workflow
- Include examples from all three projects as inspiration
8. **`.fission/deployment.json`** - Make generic with placeholders:
- Use `your-service-py` as environment name
- Use `your-package` as package name
- Use generic secret/configmap names: `fission-${PROJECT_NAME}-env`, `fission-${PROJECT_NAME}-config`
- Show both `poolmgr` and `newdeploy` executor examples (commented)
- Include optional fields like `imagepullsecret`, `runtime_envs`, `configmaps`
9. **`test/requirements.txt`** - Add:
```
pytest==8.2.0
pytest-mock==3.14.0
requests==2.32.3
```
10. **`build.sh`** - Fix to use `${SRC_PKG}` properly (current version is correct)
### Phase 2: Documentation & Examples
**New Files to ADD:**
1. **`src/__init__.py`** - Already exists, keep as is
2. **`examples/` directory** (new) - Sample function implementations:
- `example_crud.py` - Basic CRUD with Pydantic validation
- `example_webhook.py` - Webhook receiver pattern
- `example_scheduler.py` - Background job pattern (from ailbl-scheduler)
- Each should have proper Fission docstring config
3. **`.env.example`** - Template showing all environment variables:
```
# PostgreSQL
PG_HOST=
PG_PORT=5432
PG_DB=
PG_USER=
PG_PASS=
PG_DBSCHEMA=
# Optional: Service-specific config (via ConfigMap)
# YOUR_SERVICE_CONFIG_ENDPOINT=
# Optional: Vault encryption key (if using encrypted secrets)
# CRYPTO_KEY=
```
4. **`docs/` directory** (new) - Additional documentation:
- `STRUCTURE.md` - Detailed file structure explanation
- `TESTING.md` - How to write and run tests
- `DEPLOYMENT.md` - Deployment options and tuning
- `SECRETS.md` - Managing secrets and configmaps
- `MIGRATIONS.md` - Database migration workflow
5. **`pytest.ini`** - Default pytest configuration:
```ini
[pytest]
testpaths = test
python_files = test_*.py
python_classes = Test*
python_functions = test_*
log_cli = true
log_cli_level = INFO
```
6. **`.gitignore`** - Ensure it excludes:
- `__pycache__/`
- `*.pyc`
- `.env`
- `.venv/`
- `venv/`
- `.pytest_cache/`
- `.mypy_cache/`
- `.coverage`
- `coverage.xml`
- `specs/` (optional - generated files)
7. **`MANIFEST.md`** - Template for Kubernetes manifests (if not using auto-generated)
### Phase 3: Modernization
**Update CI/CD:**
Review `.gitea/workflows/` files:
- Ensure they install dependencies correctly
- Add linting (flake8/black) steps
- Add test execution
- Add deployment steps with proper environment detection
- Consider adding security scanning
**Python Version:**
- Ensure all files are compatible with Python 3.11+
- Update `build.sh` to use Python 3.11 image (like scheduler does) or keep generic
- Consider adding `runtime.txt` or `pyproject.toml` to specify Python version
---
## Files to Modify Summary
**Direct modifications:**
- `src/helpers.py` - Simplify, improve
- `src/exceptions.py` - Make generic
- `src/models.py` - Replace with generic patterns
- `src/requirements.txt` - Add Flask, remove commented section
- `dev-requirements.txt` - Comprehensive dev dependencies
- `test/requirements.txt` - Test dependencies
- `README.md` - Complete rewrite
- `.fission/deployment.json` - Generic placeholders
- `build.sh` - Already good, just ensure compatibility
**New files to add:**
- `.env.example`
- `pytest.ini`
- `.gitignore` (enhance)
- `examples/` directory with sample functions
- `docs/` directory with detailed guides
- `src/example_crud.py` (or in examples/)
- `src/example_webhook.py` (or in examples/)
- `src/example_scheduler.py` (or in examples/)
**New directories:**
- `examples/`
- `docs/`
---
## Implementation Approach
1. **Backup current template** (git branch)
2. **Modify core files** in order: helpers → exceptions → models → requirements → deployment.json → README
3. **Add new files** (examples, docs, configs)
4. **Test the template**:
- Run `create-project.sh` to generate a new project
- Verify build.sh works
- Run tests
- Check Fission spec generation
5. **Commit with clear message**
6. **Update plugin documentation** if needed
---
## Verification Steps
After implementing the changes:
1. **Create a test project** from the updated template:
```bash
./create-project.sh test-project ./tmp-test/
```
2. **Inspect generated project**:
- Verify all files are present
- Check that placeholders are substituted correctly
- Ensure imports work
3. **Build the package**:
```bash
cd tmp-test
./src/build.sh
```
4. **Run tests** (if any):
```bash
pip install -r dev-requirements.txt
pytest
```
5. **Check syntax**:
```bash
python -m py_compile src/*.py
flake8 src/
black --check src/
```
6. **Validate Fission config**:
```bash
fission spec verify --file=.fission/deployment.json
```
7. **Review README** - Does it accurately describe the project?
---
## Success Criteria
- Template is **generic**, not domain-specific
- All examples' best practices are incorporated
- Documentation is accurate and complete
- Dependencies are correctly listed (Flask in requirements, not just dev)
- README reflects actual Fission workflow (docstrings, not fission.yaml)
- Multiple example implementations provided (CRUD, webhook, scheduler)
- Secrets/configuration clearly explained
- Testing setup is comprehensive
- Project passes linting and type checks
---
## Risks & Mitigations
| Risk | Mitigation |
|------|------------|
| Breaking existing template users | Keep changes minimal in helpers; preserve backward compatibility where possible |
| Over-engineering | Stick to patterns that appear in at least 2 of 3 examples |
| Missing edge cases | Include optional advanced patterns (like DBConfig) in docs, not in core |
| Documentation drift | Keep docs close to code; add examples that mirror real projects |
---
## Post-Implementation
After the template is updated:
1. Consider creating a **template validation script** to ensure quality
2. Update the **plugin SKILL.md** to reflect template changes
3. Add **templating tests** to the fission-python-skill test suite
4. Document the **update process** for future template modifications
5. Consider **versioning** the template (e.g., `template-v2/`)