Skip to content

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 wrappers

Dependencies

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 .venv

2. Activate Virtual Environment

Windows:

bash
.venv/Scripts/activate

macOS/Linux:

bash
source .venv/bin/activate

3. Install Dependencies

bash
pip install -r requirements.txt

4. 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.py

The 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:

app_factory.py
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 resp

See Error Handling Strategies for detailed error handling patterns.

Static File Serving

The template is configured to serve frontend static files from the dist/ folder:

app_factory.py
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 catchAll

A catch-all route ensures the frontend handles client-side routing:

app_factory.py
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:

Next Steps