Appearance
Python Template
The Python template provides a Flask-based backend with type hints and structured error handling. It includes pre-configured platform integration utilities and a clean approach to building REST APIs.
Project Structure
src/
├── server.py # Application entry point with route definitions
├── lib/
│ ├── __init__.py # Package initialization and exports
│ ├── app_factory.py # Flask app factory with error handlers
│ ├── errors.py # Custom error classes
│ ├── utils.py # Platform API utilities
│ └── services/ # Business logic and API service wrappersDependencies
The template uses the following key packages (defined in requirements.txt):
- Flask - Web framework for building REST APIs
- requests - HTTP library for making API calls to the platform gateway
- python-dotenv - Environment variable management
- Werkzeug - WSGI utilities (included with Flask)
Setup Instructions
1. Create Virtual Environment
bash
python -m venv .venv2. Activate Virtual Environment
Windows:
bash
.venv/Scripts/activatemacOS/Linux:
bash
source .venv/bin/activate3. Install Dependencies
bash
pip install -r requirements.txt4. Configure Environment Variables
Create a .env file in the project root with the required platform configuration. See Creating Your First Application for details on obtaining these values.
Development Workflow
Running the Development Server
bash
python src/server.pyThe Flask development server will start on http://localhost:5000 with debug mode enabled, providing:
- Automatic reloading on code changes
- Detailed error pages with stack traces
- Interactive debugger in the browser
Hot Reload
Flask's built-in development server automatically detects changes to Python files and reloads the application. No additional configuration is needed.
Error Handler Registration
Error handlers are registered in app_factory.py using the @app.errorhandler() decorator:
py
@app.errorhandler(UpstreamHTTPError)
def handle_upstream_error(err: UpstreamHTTPError) -> Response:
"""Handle errors from upstream requests."""
payload = {"error": err.message}
resp = jsonify(payload)
resp.status_code = err.status_code
if "Location" in err.headers and err.headers["Location"]:
resp.headers["Location"] = err.headers["Location"]
return respSee Error Handling Strategies for detailed error handling patterns.
Static File Serving
The template is configured to serve frontend static files from the dist/ folder:
py
from flask import Flask, Response, jsonify
from werkzeug.exceptions import HTTPException
from dotenv import load_dotenv
from .errors import UpstreamHTTPError
def create_app() -> Flask:
"""Factory function to create and configure the Flask application."""
load_dotenv()
app = Flask(__name__, static_folder="../dist", static_url_path="/")
# Register error handlers
_register_error_handlers(app)
# Register catch-all route that serves the frontend for any unmatched paths
_register_catch_all_route(app)
return app
def _register_error_handlers(app: Flask) -> None:
"""Register all error handlers for the application."""
#region handleUpstreamError
@app.errorhandler(UpstreamHTTPError)
def handle_upstream_error(err: UpstreamHTTPError) -> Response:
"""Handle errors from upstream requests."""
payload = {"error": err.message}
resp = jsonify(payload)
resp.status_code = err.status_code
if "Location" in err.headers and err.headers["Location"]:
resp.headers["Location"] = err.headers["Location"]
return resp
#endregion handleUpstreamError
@app.errorhandler(HTTPException)
def handle_http_exception(err: HTTPException) -> Response:
"""Handle Flask/Werkzeug HTTP exceptions."""
assert err.code is not None
resp = jsonify({"error": err.description})
resp.status_code = err.code
return resp
@app.errorhandler(Exception)
def handle_unexpected(err: Exception) -> Response:
"""Catch-all for unexpected exceptions."""
resp = jsonify({"error": str(err)})
resp.status_code = 500
return resp
def _register_catch_all_route(app: Flask) -> None:
"""Register a catch-all route to serve the frontend for any unmatched paths."""
#region catchAll
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path: str) -> Response:
"""Serves the frontend entry point."""
return app.send_static_file("index.html")
#endregion catchAllA catch-all route ensures the frontend handles client-side routing:
py
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path: str) -> Response:
"""Serves the frontend entry point."""
return app.send_static_file("index.html")Platform Integration
The template includes utilities in lib/utils.py for interacting with the platform gateway. For detailed information on authentication and API access patterns, see:
- Authentication & Authorization - Understanding
fetch_as_principal()vsfetch_as_app() - Backend API Access Patterns - Making API calls to the platform gateway
- Error Handling Strategies - Handling upstream errors
Next Steps
- Review Backend API Access Patterns to learn how to make platform API calls
- Explore Framework Specific Backend Conventions for advanced Flask patterns
- Check Demo Applications & Examples for complete working examples