Files
AI-Proxy-Worker/docs/Examples.en.md
2025-08-17 19:59:10 +08:00

32 KiB

Usage Examples

🌍 Language / 语言

🇺🇸 English | 🇨🇳 中文

Practical examples of integrating AI Proxy Worker with various programming languages and frameworks. Copy and adapt these examples for your specific use case.

🌐 Web Applications

JavaScript (Vanilla)

Basic web implementation:

<!DOCTYPE html>
<html>
<head>
    <title>AI Chat Demo</title>
</head>
<body>
    <div id="chat-container">
        <div id="messages"></div>
        <input type="text" id="user-input" placeholder="Type your message...">
        <button onclick="sendMessage()">Send</button>
    </div>

    <script>
        const PROXY_URL = 'https://your-worker.workers.dev';
        const PROXY_KEY = 'your-proxy-key';

        async function sendMessage() {
            const input = document.getElementById('user-input');
            const message = input.value.trim();
            
            if (!message) return;
            
            // Add user message to chat
            addMessage('user', message);
            input.value = '';
            
            try {
                const response = await fetch(`${PROXY_URL}/chat`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${PROXY_KEY}`
                    },
                    body: JSON.stringify({
                        model: 'deepseek-chat',
                        messages: [
                            { role: 'user', content: message }
                        ]
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const data = await response.json();
                addMessage('assistant', data.choices[0].message.content);
                
            } catch (error) {
                console.error('Error:', error);
                addMessage('error', 'Failed to get response from AI');
            }
        }

        function addMessage(role, content) {
            const messages = document.getElementById('messages');
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${role}`;
            messageDiv.textContent = `${role}: ${content}`;
            messages.appendChild(messageDiv);
            messages.scrollTop = messages.scrollHeight;
        }

        // Allow sending message with Enter key
        document.getElementById('user-input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                sendMessage();
            }
        });
    </script>

    <style>
        #chat-container {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }
        
        #messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
        }
        
        .message {
            margin-bottom: 10px;
            padding: 5px;
        }
        
        .message.user {
            background-color: #e3f2fd;
        }
        
        .message.assistant {
            background-color: #f3e5f5;
        }
        
        .message.error {
            background-color: #ffebee;
            color: #c62828;
        }
        
        #user-input {
            width: 70%;
            padding: 10px;
            margin-right: 10px;
        }
        
        button {
            padding: 10px 20px;
            background-color: #2196f3;
            color: white;
            border: none;
            cursor: pointer;
        }
        
        button:hover {
            background-color: #1976d2;
        }
    </style>
</body>
</html>

React.js

React component with streaming support:

import React, { useState, useEffect } from 'react';

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

function ChatComponent() {
    const [messages, setMessages] = useState([]);
    const [input, setInput] = useState('');
    const [isLoading, setIsLoading] = useState(false);

    const sendMessage = async () => {
        if (!input.trim()) return;

        const userMessage = { role: 'user', content: input };
        setMessages(prev => [...prev, userMessage]);
        setInput('');
        setIsLoading(true);

        try {
            const response = await fetch(`${PROXY_URL}/chat`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${PROXY_KEY}`,
                    'Accept': 'text/event-stream'
                },
                body: JSON.stringify({
                    model: 'deepseek-chat',
                    messages: [...messages, userMessage],
                    stream: true
                })
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            // Handle streaming response
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let assistantMessage = { role: 'assistant', content: '' };
            
            setMessages(prev => [...prev, assistantMessage]);

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                const chunk = decoder.decode(value);
                const lines = chunk.split('\n');

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const data = line.slice(6);
                        if (data === '[DONE]') continue;

                        try {
                            const parsed = JSON.parse(data);
                            const content = parsed.choices?.[0]?.delta?.content || '';
                            
                            if (content) {
                                setMessages(prev => {
                                    const updated = [...prev];
                                    updated[updated.length - 1].content += content;
                                    return updated;
                                });
                            }
                        } catch (e) {
                            console.error('Error parsing chunk:', e);
                        }
                    }
                }
            }

        } catch (error) {
            console.error('Error:', error);
            setMessages(prev => [...prev, { 
                role: 'error', 
                content: 'Failed to get response from AI' 
            }]);
        } finally {
            setIsLoading(false);
        }
    };

    return (
        <div className="chat-container">
            <div className="messages">
                {messages.map((message, index) => (
                    <div key={index} className={`message ${message.role}`}>
                        <strong>{message.role}:</strong> {message.content}
                    </div>
                ))}
                {isLoading && <div className="loading">AI is thinking...</div>}
            </div>
            
            <div className="input-container">
                <input
                    type="text"
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
                    placeholder="Type your message..."
                    disabled={isLoading}
                />
                <button onClick={sendMessage} disabled={isLoading}>
                    Send
                </button>
            </div>
        </div>
    );
}

export default ChatComponent;

Vue.js

Vue 3 composition API example:

<template>
  <div class="chat-container">
    <div class="messages" ref="messagesContainer">
      <div 
        v-for="(message, index) in messages" 
        :key="index" 
        :class="`message ${message.role}`"
      >
        <strong>{{ message.role }}:</strong> {{ message.content }}
      </div>
      <div v-if="isLoading" class="loading">AI is thinking...</div>
    </div>
    
    <div class="input-container">
      <input
        v-model="input"
        @keypress.enter="sendMessage"
        placeholder="Type your message..."
        :disabled="isLoading"
      />
      <button @click="sendMessage" :disabled="isLoading">
        Send
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted } from 'vue';

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

const messages = ref([]);
const input = ref('');
const isLoading = ref(false);
const messagesContainer = ref(null);

const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};

const sendMessage = async () => {
  if (!input.value.trim()) return;

  const userMessage = { role: 'user', content: input.value };
  messages.value.push(userMessage);
  input.value = '';
  isLoading.value = true;
  scrollToBottom();

  try {
    const response = await fetch(`${PROXY_URL}/chat`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${PROXY_KEY}`
      },
      body: JSON.stringify({
        model: 'deepseek-chat',
        messages: messages.value
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    messages.value.push({
      role: 'assistant',
      content: data.choices[0].message.content
    });
    
    scrollToBottom();

  } catch (error) {
    console.error('Error:', error);
    messages.value.push({
      role: 'error',
      content: 'Failed to get response from AI'
    });
  } finally {
    isLoading.value = false;
  }
};

onMounted(() => {
  // Add welcome message
  messages.value.push({
    role: 'assistant',
    content: 'Hello! I\'m your AI assistant. How can I help you today?'
  });
});
</script>

<style scoped>
.chat-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.messages {
  height: 400px;
  overflow-y: auto;
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 10px;
}

.message {
  margin-bottom: 10px;
  padding: 8px;
  border-radius: 4px;
}

.message.user {
  background-color: #e3f2fd;
}

.message.assistant {
  background-color: #f3e5f5;
}

.message.error {
  background-color: #ffebee;
  color: #c62828;
}

.loading {
  font-style: italic;
  color: #666;
}

.input-container {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  padding: 10px 20px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover:not(:disabled) {
  background-color: #1976d2;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}
</style>

📱 Mobile Applications

iOS (Swift)

Swift implementation with async/await:

import Foundation

class AIProxyService {
    private let proxyURL = "https://your-worker.workers.dev"
    private let proxyKey = "your-proxy-key"
    
    struct ChatRequest: Codable {
        let model: String
        let messages: [Message]
        let stream: Bool?
    }
    
    struct Message: Codable {
        let role: String
        let content: String
    }
    
    struct ChatResponse: Codable {
        let choices: [Choice]
    }
    
    struct Choice: Codable {
        let message: Message
    }
    
    func sendMessage(_ messages: [Message]) async throws -> String {
        guard let url = URL(string: "\(proxyURL)/chat") else {
            throw URLError(.badURL)
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(proxyKey)", forHTTPHeaderField: "Authorization")
        
        let chatRequest = ChatRequest(
            model: "deepseek-chat",
            messages: messages,
            stream: false
        )
        
        request.httpBody = try JSONEncoder().encode(chatRequest)
        
        let (data, response) = try await URLSession.shared.data(for: request)
        
        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
            throw URLError(.badServerResponse)
        }
        
        let chatResponse = try JSONDecoder().decode(ChatResponse.self, from: data)
        return chatResponse.choices.first?.message.content ?? ""
    }
}

// Usage in SwiftUI View
import SwiftUI

struct ChatView: View {
    @State private var messages: [AIProxyService.Message] = []
    @State private var inputText = ""
    @State private var isLoading = false
    
    private let aiService = AIProxyService()
    
    var body: some View {
        VStack {
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 10) {
                    ForEach(messages.indices, id: \.self) { index in
                        MessageBubble(message: messages[index])
                    }
                    
                    if isLoading {
                        HStack {
                            ProgressView()
                                .scaleEffect(0.8)
                            Text("AI is thinking...")
                                .foregroundColor(.secondary)
                        }
                        .padding()
                    }
                }
            }
            
            HStack {
                TextField("Type your message...", text: $inputText)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .disabled(isLoading)
                
                Button("Send") {
                    Task {
                        await sendMessage()
                    }
                }
                .disabled(inputText.isEmpty || isLoading)
            }
            .padding()
        }
        .navigationTitle("AI Chat")
    }
    
    private func sendMessage() async {
        let userMessage = AIProxyService.Message(role: "user", content: inputText)
        messages.append(userMessage)
        
        let currentInput = inputText
        inputText = ""
        isLoading = true
        
        do {
            let response = try await aiService.sendMessage(messages)
            let assistantMessage = AIProxyService.Message(role: "assistant", content: response)
            messages.append(assistantMessage)
        } catch {
            let errorMessage = AIProxyService.Message(role: "error", content: "Failed to get response: \(error.localizedDescription)")
            messages.append(errorMessage)
        }
        
        isLoading = false
    }
}

struct MessageBubble: View {
    let message: AIProxyService.Message
    
    var body: some View {
        HStack {
            if message.role == "user" {
                Spacer()
            }
            
            VStack(alignment: .leading) {
                Text(message.role.capitalized)
                    .font(.caption)
                    .foregroundColor(.secondary)
                
                Text(message.content)
                    .padding()
                    .background(backgroundColor)
                    .cornerRadius(10)
            }
            
            if message.role == "assistant" || message.role == "error" {
                Spacer()
            }
        }
        .padding(.horizontal)
    }
    
    private var backgroundColor: Color {
        switch message.role {
        case "user":
            return .blue.opacity(0.2)
        case "assistant":
            return .purple.opacity(0.2)
        case "error":
            return .red.opacity(0.2)
        default:
            return .gray.opacity(0.2)
        }
    }
}

Android (Kotlin)

Kotlin implementation with Retrofit:

// API Service Interface
interface AIProxyService {
    @POST("chat")
    suspend fun sendMessage(
        @Header("Authorization") authorization: String,
        @Body request: ChatRequest
    ): Response<ChatResponse>
}

// Data Classes
data class ChatRequest(
    val model: String,
    val messages: List<Message>,
    val stream: Boolean = false
)

data class Message(
    val role: String,
    val content: String
)

data class ChatResponse(
    val choices: List<Choice>
)

data class Choice(
    val message: Message
)

// Repository
class AIRepository {
    private val proxyKey = "your-proxy-key"
    private val service = Retrofit.Builder()
        .baseUrl("https://your-worker.workers.dev/")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(AIProxyService::class.java)
    
    suspend fun sendMessage(messages: List<Message>): Result<String> {
        return try {
            val request = ChatRequest(
                model = "deepseek-chat",
                messages = messages
            )
            
            val response = service.sendMessage("Bearer $proxyKey", request)
            
            if (response.isSuccessful) {
                val content = response.body()?.choices?.firstOrNull()?.message?.content
                if (content != null) {
                    Result.success(content)
                } else {
                    Result.failure(Exception("Empty response"))
                }
            } else {
                Result.failure(Exception("HTTP ${response.code()}: ${response.message()}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}

// ViewModel
class ChatViewModel : ViewModel() {
    private val repository = AIRepository()
    
    private val _messages = MutableLiveData<List<Message>>()
    val messages: LiveData<List<Message>> = _messages
    
    private val _isLoading = MutableLiveData<Boolean>()
    val isLoading: LiveData<Boolean> = _isLoading
    
    fun sendMessage(content: String) {
        val currentMessages = _messages.value?.toMutableList() ?: mutableListOf()
        val userMessage = Message("user", content)
        currentMessages.add(userMessage)
        _messages.value = currentMessages
        
        _isLoading.value = true
        
        viewModelScope.launch {
            repository.sendMessage(currentMessages).fold(
                onSuccess = { response ->
                    currentMessages.add(Message("assistant", response))
                    _messages.value = currentMessages
                },
                onFailure = { error ->
                    currentMessages.add(Message("error", "Failed to get response: ${error.message}"))
                    _messages.value = currentMessages
                }
            )
            _isLoading.value = false
        }
    }
}

// Activity/Fragment
class ChatActivity : AppCompatActivity() {
    private lateinit var binding: ActivityChatBinding
    private lateinit var viewModel: ChatViewModel
    private lateinit var adapter: MessageAdapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityChatBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        viewModel = ViewModelProvider(this)[ChatViewModel::class.java]
        
        setupRecyclerView()
        observeViewModel()
        setupClickListeners()
    }
    
    private fun setupRecyclerView() {
        adapter = MessageAdapter()
        binding.recyclerViewMessages.adapter = adapter
        binding.recyclerViewMessages.layoutManager = LinearLayoutManager(this)
    }
    
    private fun observeViewModel() {
        viewModel.messages.observe(this) { messages ->
            adapter.submitList(messages)
            binding.recyclerViewMessages.scrollToPosition(messages.size - 1)
        }
        
        viewModel.isLoading.observe(this) { isLoading ->
            binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
            binding.buttonSend.isEnabled = !isLoading
        }
    }
    
    private fun setupClickListeners() {
        binding.buttonSend.setOnClickListener {
            val message = binding.editTextMessage.text.toString().trim()
            if (message.isNotEmpty()) {
                viewModel.sendMessage(message)
                binding.editTextMessage.text.clear()
            }
        }
    }
}

🖥️ Desktop Applications

Python

Python desktop application with tkinter:

import tkinter as tk
from tkinter import scrolledtext, messagebox
import requests
import json
import threading
from typing import List, Dict

class AIProxyClient:
    def __init__(self, proxy_url: str, proxy_key: str):
        self.proxy_url = proxy_url
        self.proxy_key = proxy_key
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {proxy_key}',
            'Content-Type': 'application/json'
        })
    
    def send_message(self, messages: List[Dict[str, str]]) -> str:
        try:
            response = self.session.post(
                f'{self.proxy_url}/chat',
                json={
                    'model': 'deepseek-chat',
                    'messages': messages
                },
                timeout=30
            )
            response.raise_for_status()
            
            data = response.json()
            return data['choices'][0]['message']['content']
            
        except requests.exceptions.RequestException as e:
            raise Exception(f"Request failed: {str(e)}")
        except (KeyError, IndexError) as e:
            raise Exception(f"Invalid response format: {str(e)}")

class ChatGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("AI Chat Assistant")
        self.root.geometry("600x500")
        
        # Initialize AI client
        self.ai_client = AIProxyClient(
            proxy_url="https://your-worker.workers.dev",
            proxy_key="your-proxy-key"
        )
        
        self.messages = []
        self.setup_ui()
        
    def setup_ui(self):
        # Chat display area
        self.chat_display = scrolledtext.ScrolledText(
            self.root,
            wrap=tk.WORD,
            state=tk.DISABLED,
            height=20,
            font=('Arial', 10)
        )
        self.chat_display.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # Input frame
        input_frame = tk.Frame(self.root)
        input_frame.pack(fill=tk.X, padx=10, pady=5)
        
        # Message input
        self.message_entry = tk.Entry(input_frame, font=('Arial', 10))
        self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.message_entry.bind('<Return>', self.send_message)
        
        # Send button
        self.send_button = tk.Button(
            input_frame,
            text="Send",
            command=self.send_message,
            font=('Arial', 10),
            bg='#2196f3',
            fg='white',
            relief=tk.FLAT,
            padx=20
        )
        self.send_button.pack(side=tk.RIGHT)
        
        # Status bar
        self.status_var = tk.StringVar()
        self.status_var.set("Ready")
        status_bar = tk.Label(
            self.root,
            textvariable=self.status_var,
            relief=tk.SUNKEN,
            anchor=tk.W
        )
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # Add welcome message
        self.add_message("assistant", "Hello! I'm your AI assistant. How can I help you today?")
    
    def add_message(self, role: str, content: str):
        self.chat_display.config(state=tk.NORMAL)
        
        # Add role label
        self.chat_display.insert(tk.END, f"{role.title()}: ", f"{role}_label")
        
        # Add message content
        self.chat_display.insert(tk.END, f"{content}\n\n")
        
        # Configure tags for styling
        self.chat_display.tag_config("user_label", foreground="blue", font=('Arial', 10, 'bold'))
        self.chat_display.tag_config("assistant_label", foreground="purple", font=('Arial', 10, 'bold'))
        self.chat_display.tag_config("error_label", foreground="red", font=('Arial', 10, 'bold'))
        
        self.chat_display.config(state=tk.DISABLED)
        self.chat_display.see(tk.END)
    
    def send_message(self, event=None):
        message = self.message_entry.get().strip()
        if not message:
            return
        
        # Add user message
        self.add_message("user", message)
        self.messages.append({"role": "user", "content": message})
        
        # Clear input
        self.message_entry.delete(0, tk.END)
        
        # Disable send button and show loading
        self.send_button.config(state=tk.DISABLED)
        self.status_var.set("AI is thinking...")
        
        # Send request in background thread
        threading.Thread(target=self.get_ai_response, daemon=True).start()
    
    def get_ai_response(self):
        try:
            response = self.ai_client.send_message(self.messages)
            
            # Update UI in main thread
            self.root.after(0, lambda: self.handle_ai_response(response))
            
        except Exception as e:
            error_msg = f"Error: {str(e)}"
            self.root.after(0, lambda: self.handle_error(error_msg))
    
    def handle_ai_response(self, response: str):
        self.add_message("assistant", response)
        self.messages.append({"role": "assistant", "content": response})
        
        # Re-enable send button
        self.send_button.config(state=tk.NORMAL)
        self.status_var.set("Ready")
        self.message_entry.focus()
    
    def handle_error(self, error_msg: str):
        self.add_message("error", error_msg)
        
        # Re-enable send button
        self.send_button.config(state=tk.NORMAL)
        self.status_var.set("Ready")
        self.message_entry.focus()
    
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = ChatGUI()
    app.run()

🔧 Backend Integration

Node.js/Express

Express middleware for proxying AI requests:

const express = require('express');
const fetch = require('node-fetch');

const app = express();
app.use(express.json());

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

// Middleware to proxy AI requests
app.post('/api/chat', async (req, res) => {
    try {
        const response = await fetch(`${PROXY_URL}/chat`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${PROXY_KEY}`
            },
            body: JSON.stringify(req.body)
        });

        if (!response.ok) {
            throw new Error(`Proxy error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        res.json(data);

    } catch (error) {
        console.error('AI Proxy Error:', error);
        res.status(500).json({
            error: 'ai_proxy_error',
            message: 'Failed to get AI response'
        });
    }
});

// Health check endpoint
app.get('/api/health', (req, res) => {
    res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Python FastAPI

FastAPI implementation with streaming support:

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import StreamingResponse
import httpx
import json
from typing import List, Dict, Optional
from pydantic import BaseModel

app = FastAPI(title="AI Proxy Backend")

PROXY_URL = "https://your-worker.workers.dev"
PROXY_KEY = "your-proxy-key"

class Message(BaseModel):
    role: str
    content: str

class ChatRequest(BaseModel):
    model: str
    messages: List[Message]
    stream: Optional[bool] = False
    temperature: Optional[float] = None
    max_tokens: Optional[int] = None

@app.post("/api/chat")
async def chat_endpoint(request: ChatRequest):
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(
                f"{PROXY_URL}/chat",
                json=request.dict(exclude_none=True),
                headers={
                    "Authorization": f"Bearer {PROXY_KEY}",
                    "Content-Type": "application/json"
                },
                timeout=30.0
            )
            
            response.raise_for_status()
            return response.json()
            
        except httpx.RequestError as e:
            raise HTTPException(status_code=502, detail=f"Proxy request failed: {str(e)}")
        except httpx.HTTPStatusError as e:
            raise HTTPException(status_code=e.response.status_code, detail=e.response.text)

@app.post("/api/chat/stream")
async def chat_stream_endpoint(request: ChatRequest):
    request.stream = True
    
    async def generate():
        async with httpx.AsyncClient() as client:
            try:
                async with client.stream(
                    "POST",
                    f"{PROXY_URL}/chat",
                    json=request.dict(exclude_none=True),
                    headers={
                        "Authorization": f"Bearer {PROXY_KEY}",
                        "Content-Type": "application/json"
                    }
                ) as response:
                    response.raise_for_status()
                    
                    async for chunk in response.aiter_text():
                        if chunk:
                            yield chunk
                            
            except Exception as e:
                yield f"data: {json.dumps({'error': str(e)})}\n\n"
    
    return StreamingResponse(
        generate(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive"
        }
    )

@app.get("/api/health")
async def health_check():
    return {"status": "healthy", "timestamp": "2025-01-01T00:00:00Z"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

📊 Testing Examples

Unit Tests (Jest)

JavaScript testing examples:

// ai-proxy-client.test.js
const AIProxyClient = require('./ai-proxy-client');

describe('AIProxyClient', () => {
    let client;
    
    beforeEach(() => {
        client = new AIProxyClient(
            'https://test-worker.workers.dev',
            'test-proxy-key'
        );
    });
    
    test('should send chat message successfully', async () => {
        // Mock fetch
        global.fetch = jest.fn().mockResolvedValue({
            ok: true,
            json: async () => ({
                choices: [{
                    message: {
                        role: 'assistant',
                        content: 'Hello! How can I help you?'
                    }
                }]
            })
        });
        
        const messages = [{ role: 'user', content: 'Hello' }];
        const response = await client.sendMessage(messages);
        
        expect(response).toBe('Hello! How can I help you?');
        expect(fetch).toHaveBeenCalledWith(
            'https://test-worker.workers.dev/chat',
            expect.objectContaining({
                method: 'POST',
                headers: expect.objectContaining({
                    'Authorization': 'Bearer test-proxy-key'
                })
            })
        );
    });
    
    test('should handle API errors gracefully', async () => {
        global.fetch = jest.fn().mockResolvedValue({
            ok: false,
            status: 500,
            statusText: 'Internal Server Error'
        });
        
        const messages = [{ role: 'user', content: 'Hello' }];
        
        await expect(client.sendMessage(messages))
            .rejects.toThrow('HTTP error! status: 500');
    });
});

Ready to integrate? 🚀

Choose the example that best fits your technology stack and customize it for your specific needs. All examples include proper error handling and can be extended with additional features like conversation history, user authentication, and more.