--- name: integration-helpers description: Integration templates for FastAPI endpoints, Next.js UI components, and Supabase schemas for ML model deployment. Use when deploying ML models, creating inference APIs, building ML prediction UIs, designing ML database schemas, integrating trained models with applications, or when user mentions FastAPI ML endpoints, prediction forms, model serving, ML API deployment, inference integration, or production ML deployment. allowed-tools: Bash, Read, Write, Edit, WebFetch --- # integration-helpers ## Instructions This skill provides production-ready integration templates for deploying machine learning models into full-stack applications. It covers FastAPI inference endpoints, Next.js prediction interfaces, and Supabase schemas for ML metadata storage. ### 1. FastAPI Inference Endpoints Create production-ready ML inference APIs with proper error handling and validation: ```bash # Generate FastAPI ML router bash ./skills/integration-helpers/scripts/add-fastapi-endpoint.sh # Model types: classification, regression, text-generation, image-classification, embeddings ``` **What This Creates:** - Pydantic models for request/response validation - Inference endpoint with proper error handling - Model loading and caching logic - Health check endpoint - Batch prediction support - Async request handling **Router Structure:** ```python from fastapi import APIRouter, HTTPException, UploadFile from pydantic import BaseModel, Field import numpy as np router = APIRouter( prefix="/ml", tags=["machine-learning"], responses={500: {"description": "Model inference error"}}, ) ``` **Example Usage:** ```bash # Create text classification endpoint bash ./skills/integration-helpers/scripts/add-fastapi-endpoint.sh classification sentiment-analysis # Creates: app/routers/ml_sentiment_analysis.py ``` ### 2. Request/Response Models Define type-safe ML inference contracts: **Classification Model:** ```python class ClassificationRequest(BaseModel): text: str = Field(..., min_length=1, max_length=10000) model_version: str | None = None return_probabilities: bool = False class ClassificationResponse(BaseModel): prediction: str confidence: float = Field(..., ge=0.0, le=1.0) probabilities: dict[str, float] | None = None model_version: str inference_time_ms: float ``` **Regression Model:** ```python class RegressionRequest(BaseModel): features: list[float] = Field(..., min_items=1) feature_names: list[str] | None = None class RegressionResponse(BaseModel): prediction: float feature_importance: dict[str, float] | None = None model_version: str ``` **Image Classification:** ```python class ImageClassificationResponse(BaseModel): predictions: list[dict[str, Any]] top_prediction: str confidence: float processing_time_ms: float ``` ### 3. Model Loading and Caching Implement efficient model loading with caching: ```python from functools import lru_cache import joblib import torch # Singleton model loader class ModelLoader: _instance = None _model = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def load_model(self, model_path: str): if self._model is None: # Load based on framework if model_path.endswith('.pkl'): self._model = joblib.load(model_path) elif model_path.endswith('.pt'): self._model = torch.load(model_path) # Add TensorFlow, ONNX, etc. return self._model # Dependency for endpoints async def get_model(): loader = ModelLoader() return loader.load_model("models/latest.pkl") ``` ### 4. Inference Endpoints with Error Handling Implement robust inference with proper error handling: ```python @router.post("/predict", response_model=ClassificationResponse) async def predict( request: ClassificationRequest, model = Depends(get_model) ): try: start_time = time.time() # Preprocess input processed_input = preprocess_text(request.text) # Run inference prediction = model.predict([processed_input])[0] probabilities = None if request.return_probabilities: probs = model.predict_proba([processed_input])[0] probabilities = { label: float(prob) for label, prob in zip(model.classes_, probs) } inference_time = (time.time() - start_time) * 1000 return ClassificationResponse( prediction=str(prediction), confidence=float(max(probs)) if probabilities else 0.0, probabilities=probabilities, model_version=MODEL_VERSION, inference_time_ms=inference_time ) except ValueError as e: raise HTTPException( status_code=400, detail=f"Invalid input: {str(e)}" ) except Exception as e: raise HTTPException( status_code=500, detail=f"Model inference failed: {str(e)}" ) ``` ### 5. Batch Prediction Support Enable efficient batch inference: ```python class BatchClassificationRequest(BaseModel): texts: list[str] = Field(..., min_items=1, max_items=100) model_version: str | None = None class BatchClassificationResponse(BaseModel): predictions: list[ClassificationResponse] total_inference_time_ms: float @router.post("/predict/batch", response_model=BatchClassificationResponse) async def predict_batch( request: BatchClassificationRequest, model = Depends(get_model) ): start_time = time.time() predictions = [] # Process in batches for efficiency for text in request.texts: pred = await predict( ClassificationRequest(text=text), model=model ) predictions.append(pred) total_time = (time.time() - start_time) * 1000 return BatchClassificationResponse( predictions=predictions, total_inference_time_ms=total_time ) ``` ### 6. Next.js Prediction Forms Create React components for ML model interaction: ```bash # Generate Next.js prediction form bash ./skills/integration-helpers/scripts/add-nextjs-component.sh # Component types: classification-form, regression-form, image-upload, chat-interface ``` **What This Creates:** - TypeScript React component with shadcn/ui - Form validation with react-hook-form and zod - Loading states and error handling - Result visualization components - API integration with fetch/axios **Example Component:** ```typescript // components/ml/sentiment-form.tsx 'use client' import { useState } from 'react' import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import * as z from 'zod' import { Button } from '@/components/ui/button' import { Textarea } from '@/components/ui/textarea' import { Card } from '@/components/ui/card' const formSchema = z.object({ text: z.string().min(1).max(10000), }) export function SentimentForm() { const [result, setResult] = useState(null) const [loading, setLoading] = useState(false) const form = useForm>({ resolver: zodResolver(formSchema), }) async function onSubmit(values: z.infer) { setLoading(true) try { const response = await fetch('/api/ml/predict', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values), }) const data = await response.json() setResult(data) } catch (error) { console.error(error) } finally { setLoading(false) } } return (