Tutorial Factory

Powered by Telnyx

Dev Docs Low Latency Club GitHub Log in
AI Assistants Python Flask

Create AI Assistant with Python and Flask

Overview

Build a production-ready Flask endpoint that creates AI assistants using the Telnyx AI Assistants API. This tutorial demonstrates the client-based initialization pattern, proper error handling for AI services, and secure credential management via environment variables.

Prerequisites

  • Python 3.8 or higher.
  • A Telnyx account with an active API key from the Telnyx Portal.
  • pip (Python package manager).
  • Basic understanding of REST APIs and JSON.

Step 1: Setup

Install the required dependencies:

pip install telnyx flask python-dotenv

Create a project directory and navigate into it:

mkdir telnyx-ai-assistant-creator
cd telnyx-ai-assistant-creator

Step 2: Configuration

Create a .env file in your project root to store credentials securely:

TELNYX_API_KEY=YOUR_API_KEY_HERE

Replace YOUR_API_KEY_HERE with your actual API key from the Telnyx Portal.

Step 3: Implementation

Create app.py and initialize the Telnyx client using the new pattern. Define a helper function to handle assistant creation with proper validation:

import os
import telnyx
from dotenv import load_dotenv

load_dotenv()

# Initialize client with the new SDK pattern
client = telnyx.Telnyx(api_key=os.getenv("TELNYX_API_KEY"))


def create_ai_assistant(name: str, instructions: str, model: str = "meta-llama/Meta-Llama-3.1-70B-Instruct", enabled_features: list = None) -> dict:
    """Create AI assistant via Telnyx and return JSON-serializable response data."""
    if not name or not instructions:
        raise ValueError("Name and instructions are required")

    # Default to messaging if no features specified
    if enabled_features is None:
        enabled_features = ["messaging"]

    # Validate enabled features
    valid_features = ["messaging", "telephony"]
    for feature in enabled_features:
        if feature not in valid_features:
            raise ValueError(f"Invalid feature: {feature}. Must be one of: {valid_features}")

    # Use client.ai_assistants.create() — NOT client.ai_assistants.create()
    response = client.ai_assistants.create(
        name=name,
        instructions=instructions,
        model=model,
        enabled_features=enabled_features,
    )

    # Extract serializable data — SDK objects are NOT JSON-serializable
    return {
        "id": response.data.id,
        "name": response.data.name,
        "model": response.data.model,
        "instructions": response.data.instructions,
        "enabled_features": response.data.enabled_features,
        "created_at": response.data.created_at,
    }

Step 4: Testing

Add the Flask route with comprehensive error handling for production resilience:

from flask import Flask, jsonify, request

app = Flask(__name__)


@app.route("/ai/assistants", methods=["POST"])
def create_assistant_endpoint():
    """HTTP endpoint to create AI assistant."""
    data = request.get_json()

    if not data:
        return jsonify({"error": "Request body required"}), 400

    name = data.get("name")
    instructions = data.get("instructions")
    model = data.get("model", "meta-llama/Meta-Llama-3.1-70B-Instruct")
    enabled_features = data.get("enabled_features", ["messaging"])

    if not name or not instructions:
        return jsonify({"error": "Missing required fields: 'name' and 'instructions'"}), 400

    try:
        result = create_ai_assistant(name, instructions, model, enabled_features)
        return jsonify(result), 201

    except telnyx.AuthenticationError:
        return jsonify({"error": "Invalid API key"}), 401
    except telnyx.RateLimitError:
        return jsonify({"error": "Rate limit exceeded. Please slow down."}), 429
    except telnyx.APIStatusError as e:
        return jsonify({"error": str(e), "status_code": e.status_code}), e.status_code
    except telnyx.APIConnectionError:
        return jsonify({"error": "Network error connecting to Telnyx"}), 503
    except ValueError as e:
        return jsonify({"error": str(e)}), 400


if __name__ == "__main__":
    app.run(debug=True, port=5000)

Start the server:

python app.py

Test the endpoint using curl:

curl -X POST http://localhost:5000/ai/assistants \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Customer Support Bot",
    "instructions": "You are a helpful customer support assistant. Be polite, professional, and provide accurate information about our products and services.",
    "enabled_features": ["messaging", "telephony"]
  }'

Expected response:

{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "Customer Support Bot",
  "model": "meta-llama/Meta-Llama-3.1-70B-Instruct",
  "instructions": "You are a helpful customer support assistant. Be polite, professional, and provide accurate information about our products and services.",
  "enabled_features": ["messaging", "telephony"],
  "created_at": "2026-04-21T10:30:00.000Z"
}

Complete Code

#!/usr/bin/env python3
"""Production-ready Flask endpoint for creating AI assistants via Telnyx."""

import os
import telnyx
from dotenv import load_dotenv
from flask import Flask, jsonify, request

load_dotenv()

app = Flask(__name__)

# Initialize client with the new SDK pattern
client = telnyx.Telnyx(api_key=os.getenv("TELNYX_API_KEY"))


def create_ai_assistant(name: str, instructions: str, model: str = "meta-llama/Meta-Llama-3.1-70B-Instruct", enabled_features: list = None) -> dict:
    """Create AI assistant via Telnyx and return JSON-serializable response data."""
    if not name or not instructions:
        raise ValueError("Name and instructions are required")

    # Default to messaging if no features specified
    if enabled_features is None:
        enabled_features = ["messaging"]

    # Validate enabled features
    valid_features = ["messaging", "telephony"]
    for feature in enabled_features:
        if feature not in valid_features:
            raise ValueError(f"Invalid feature: {feature}. Must be one of: {valid_features}")

    # Use client.ai_assistants.create() — NOT client.ai_assistants.create()
    response = client.ai_assistants.create(
        name=name,
        instructions=instructions,
        model=model,
        enabled_features=enabled_features,
    )

    # Extract serializable data — SDK objects are NOT JSON-serializable
    return {
        "id": response.data.id,
        "name": response.data.name,
        "model": response.data.model,
        "instructions": response.data.instructions,
        "enabled_features": response.data.enabled_features,
        "created_at": response.data.created_at,
    }


@app.route("/ai/assistants", methods=["POST"])
def create_assistant_endpoint():
    """HTTP endpoint to create AI assistant."""
    data = request.get_json()

    if not data:
        return jsonify({"error": "Request body required"}), 400

    name = data.get("name")
    instructions = data.get("instructions")
    model = data.get("model", "meta-llama/Meta-Llama-3.1-70B-Instruct")
    enabled_features = data.get("enabled_features", ["messaging"])

    if not name or not instructions:
        return jsonify({"error": "Missing required fields: 'name' and 'instructions'"}), 400

    try:
        result = create_ai_assistant(name, instructions, model, enabled_features)
        return jsonify(result), 201

    except telnyx.AuthenticationError:
        return jsonify({"error": "Invalid API key"}), 401
    except telnyx.RateLimitError:
        return jsonify({"error": "Rate limit exceeded. Please slow down."}), 429
    except telnyx.APIStatusError as e:
        return jsonify({"error": str(e), "status_code": e.status_code}), e.status_code
    except telnyx.APIConnectionError:
        return jsonify({"error": "Network error connecting to Telnyx"}), 503
    except ValueError as e:
        return jsonify({"error": str(e)}), 400


if __name__ == "__main__":
    app.run(debug=True, port=5000)

Troubleshooting

Issue Problem Solution
Authentication Error (401) The endpoint returns {"error": "Invalid API key"} with HTTP 401. Verify your TELNYX_API_KEY in the .env file matches the key shown in the Telnyx Portal. Ensure there are no trailing spaces or quotes. If the key was regenerated recently, update your environment file and restart the Flask server.
Invalid Model Error You receive a 400 error about an unsupported model or the assistant creation fails with model validation errors. Check that the model string matches exactly one of the supported models. The default meta-llama/Meta-Llama-3.1-70B-Instruct should work for most use cases. Verify the model name has no typos and uses the correct case sensitivity.
Feature Validation Error The application raises ValueError: Invalid feature when creating an assistant with custom enabled features. Ensure enabled_features contains only valid values: ["messaging"], ["telephony"], or ["messaging", "telephony"]. Check for typos in feature names and verify the array format in your JSON request body.

Next Steps