Coding Standards¶
Python Style¶
- Follow PEP 8 for formatting
- Use 4 spaces for indentation (no tabs)
- Max line length: 120 characters (relaxed from PEP 8's 79 for this codebase)
- Use f-strings for string formatting (not
.format()or%) - Type hints encouraged but not mandatory for existing code; required for new utility functions
Route Naming Conventions¶
| Type | Convention | Example |
|---|---|---|
| Guest upload routes | /upload/guest/... |
/upload/guest/initiate |
| Encrypted upload routes | /upload/guest/encrypted/... |
/upload/guest/encrypted/upload-part |
| Admin routes | /admin/... |
/admin/dashboard |
| Lab portal routes | /lab/... |
/lab/login |
| Android API routes | /android/... |
/android/list-files |
| Store routes | /store/... |
/store/products |
- Use kebab-case for URL segments (e.g.,
/upload-part, not/upload_part) - Use snake_case for Python function names (e.g.,
def guest_upload_encrypted_part) - Blueprint prefixes are defined in
lenzeye_database.pyregistration
Blueprint Structure¶
Every feature gets its own blueprint file:
```python from flask import Blueprint
guest_upload_bp = Blueprint('guest_upload', name)
@guest_upload_bp.route('/upload/guest/initiate', methods=['POST']) def guest_initiate_upload(): ... ```
Registered in lenzeye_database.py:
python
from Features.SecureStorage.guest_upload_routes import guest_upload_bp
app.register_blueprint(guest_upload_bp)
- One blueprint per logical feature area
- Blueprint files should be self-contained (imports at top, module state below, routes at bottom)
- Module-level shared state (semaphores, caches, registries) must be documented with a comment explaining thread-safety
JSON Response Pattern¶
All API routes must return consistent JSON:
```python
Success¶
return jsonify({"success": True, "data": result}), 200
Error¶
return jsonify({"success": False, "message": "Descriptive error message"}), 400 ```
Never return bare strings or HTML from API routes.
Error Handling¶
python
try:
resp = s3.complete_multipart_upload(...)
except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'NoSuchUpload':
return jsonify({"success": False, "message": "Upload session expired"}), 404
return jsonify({"success": False, "message": f"S3 error: {error_code}"}), 500
except Exception as e:
app.logger.error(f"Unexpected error in complete_upload: {e}", exc_info=True)
return jsonify({"success": False, "message": "Internal server error"}), 500
- Always catch specific exceptions before generic
Exception - Always log unexpected exceptions with
exc_info=True(includes traceback) - Never expose raw exception messages to the client (security risk)
Security-Critical Rules¶
These rules are non-negotiable
- Never hardcode secrets — all keys, passwords, tokens must come from environment variables
- Always validate input — validate type, length, and format before using any user-supplied data
- Never log sensitive data — no logging of keys, OTPs, tokens, or file contents
- Always use
hmac.compare_digestfor token comparison (not==) to prevent timing attacks - Never trust client-supplied encryption parameters — the session token contains the key; the client cannot modify it (GCM-authenticated)
- Always check
has_master_key()before any encryption operation - Validate
part_size >= 5 MBbefore accepting encrypted uploads (S3 minimum)
Logging Standards¶
```python import logging logger = logging.getLogger(name)
Info: normal operations¶
logger.info(f"Upload complete for {email}, folder {folder_name}")
Warning: recoverable issues¶
logger.warning(f"Wasabi head_object retry {attempt}/5 for {s3_key}")
Error: failures with full traceback¶
logger.error(f"Failed to complete upload for {s3_key}: {e}", exc_info=True) ```
- Log at appropriate level — don’t log everything at
ERROR - Never log: email+password, encryption keys, OTPs, session tokens
- Log enough to reconstruct what happened in production (email prefix, S3 key prefix, operation name)
TL;DR¶
Style: PEP 8, 4 spaces, f-strings, kebab-case routes. Blueprints: One per feature, self-contained. API responses: Always {"success": bool, ...} JSON. Security: No hardcoded secrets, validate all input, compare_digest for tokens, never log sensitive data.