Code Examples

Các ví dụ code thực tế cho từng AI service

Medical Transcribe - Chuyển đổi Audio Y tế

Python

⚠️ LƯU Ý: Bạn cần API token để sử dụng service. Liên hệ admin để lấy token.

import requests
import os

# ===== BƯỚC 1: CÀI ĐẶT TOKEN =====
# Cách 1: Environment variable (Khuyến nghị)
# Chạy: export API_AI_TOKEN="your_token_here"
API_TOKEN = os.getenv('API_AI_TOKEN')

# Cách 2: Hard-code CHỈ trong development
# API_TOKEN = "demo_token_12345_for_testing_only"

if not API_TOKEN:
    raise ValueError("⚠️ API_TOKEN chưa được set! Liên hệ admin để lấy token.")

# ===== BƯỚC 2: TRANSCRIBE VỚI TOKEN =====
API_URL = 'https://pnt.badt.vn/medical_transcribe/transcribe'

def transcribe_medical_audio(audio_file_path):
    """Transcribe audio với authentication token"""
    
    # Token PHẢI có trong mỗi request
    headers = {'Authorization': f'Bearer {API_TOKEN}'}
    
    with open(audio_file_path, 'rb') as f:
        files = {'audio_file': f}
        data = {
            'language': 'vi',
            'model_size': 'large-v2',
            'task': 'transcribe'
        }
        
        response = requests.post(API_URL, headers=headers, files=files, data=data)
        
        if response.status_code == 200:
            result = response.json()
            return result['transcription']
        elif response.status_code == 401:
            print("❌ Token không hợp lệ hoặc chưa cung cấp!")
            return None
        elif response.status_code == 403:
            print("❌ Token hết hạn hoặc không có quyền!")
            return None
        else:
            print(f"⚠️ Error: {response.status_code}")
            print(response.text)
            return None

# ===== BƯỚC 3: SỬ DỤNG =====
transcription = transcribe_medical_audio('patient_consultation.wav')
if transcription:
    print(f"✅ Transcription: {transcription}")

cURL

⚠️ QUAN TRỌNG: Thay YOUR_API_TOKEN bằng token thật!

# ===== CÁCH 1: Dùng biến môi trường (Bảo mật nhất) =====
# Set token:
export API_TOKEN="your_token_here"

# Gọi API:
curl -X POST "https://pnt.badt.vn/medical_transcribe/transcribe" \
  -H "Authorization: Bearer $API_TOKEN" \
  -F "audio_file=@consultation.wav" \
  -F "language=vi" \
  -F "model_size=large-v2"

# ===== CÁCH 2: Hard-code token (CHỈ dùng cho testing) =====
curl -X POST "https://pnt.badt.vn/medical_transcribe/transcribe" \
  -H "Authorization: Bearer demo_token_12345_for_testing_only" \
  -F "audio_file=@consultation.wav" \
  -F "language=vi" \
  -F "model_size=large-v2"

# Response thành công:
# {
#   "success": true,
#   "transcription": "Bệnh nhân có triệu chứng...",
#   "processing_time": 1.23
# }

# Response lỗi token:
# HTTP 401: {"success": false, "error": "No API token provided"}
# HTTP 403: {"success": false, "error": "Invalid or inactive token"}

Face Recognition - Nhận diện Khuôn mặt

Python

⚠️ LƯU Ý: Face Recognition cần API token cho mọi request.

import requests
import os

# ===== BƯỚC 1: CÀI ĐẶT TOKEN =====
API_TOKEN = os.getenv('API_AI_TOKEN')  # Khuyến nghị: Dùng env var
# API_TOKEN = "demo_token_12345_for_testing_only"  # Hoặc hard-code cho dev

if not API_TOKEN:
    raise ValueError("⚠️ API_TOKEN chưa được set!")

# ===== BƯỚC 2: REGISTER FACE VỚI TOKEN =====
def register_face(image_path, person_name, person_id):
    """Đăng ký khuôn mặt mới - CẦN TOKEN"""
    url = 'https://pnt.badt.vn/face_recognition/register_face'
    
    # Token PHẢI có trong header
    headers = {'Authorization': f'Bearer {API_TOKEN}'}
    
    with open(image_path, 'rb') as f:
        files = {'file': f}
        data = {
            'person_name': person_name,
            'person_id': person_id
        }
        
        response = requests.post(url, headers=headers, files=files, data=data)
        
        if response.status_code == 401:
            return {"error": "Token không hợp lệ!"}
        return response.json()

# ===== BƯỚC 3: RECOGNIZE FACES VỚI TOKEN =====
def recognize_faces(image_path):
    """Nhận diện khuôn mặt - CẦN TOKEN"""
    url = 'https://pnt.badt.vn/face_recognition/recognize_faces'
    
    # Token PHẢI có trong header
    headers = {'Authorization': f'Bearer {API_TOKEN}'}
    
    with open(image_path, 'rb') as f:
        files = {'file': f}
        response = requests.post(url, headers=headers, files=files)
        
        if response.status_code == 401:
            return {"error": "Token không hợp lệ!"}
        return response.json()

# ===== BƯỚC 4: SỬ DỤNG =====
# Đăng ký khuôn mặt mới
register_result = register_face('john_doe.jpg', 'John Doe', 'P001')
print(f"✅ Registration: {register_result}")

# Nhận diện trong ảnh nhóm
recognition_result = recognize_faces('group_photo.jpg')
if 'recognized_faces' in recognition_result:
    print(f"✅ Recognized: {recognition_result['recognized_faces']}")
else:
    print(f"❌ Error: {recognition_result.get('error', 'Unknown error')}")

JavaScript

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

const API_TOKEN = process.env.API_AI_TOKEN;

async function recognizeFaces(imagePath) {
    const form = new FormData();
    form.append('file', fs.createReadStream(imagePath));
    
    try {
        const response = await axios.post(
            'https://pnt.badt.vn/face_recognition/recognize_faces',
            form,
            {
                headers: {
                    'Authorization': `Bearer ${API_TOKEN}`,
                    ...form.getHeaders()
                }
            }
        );
        
        return response.data;
    } catch (error) {
        console.error('Error:', error.response?.data || error.message);
        throw error;
    }
}

// Usage
recognizeFaces('photo.jpg')
    .then(result => console.log('Faces:', result.recognized_faces))
    .catch(err => console.error(err));

Vistral Vietnamese - LLM Tiếng Việt

Python (OpenAI Compatible)

🔥 ĐẶC BIỆT: Vistral tương thích 100% với OpenAI API! Dùng API token như api_key.

from openai import OpenAI
import os

# ===== BƯỚC 1: LẤY API TOKEN =====
# QUAN TRỌNG: api_key của OpenAI client = API_TOKEN của hệ thống
API_TOKEN = os.getenv('API_AI_TOKEN')
# API_TOKEN = "demo_token_12345_for_testing_only"  # Hoặc hard-code

if not API_TOKEN:
    raise ValueError("⚠️ API_TOKEN chưa được set!")

# ===== BƯỚC 2: TẠO CLIENT VỚI TOKEN =====
# Sử dụng OpenAI client với base_url tùy chỉnh
client = OpenAI(
    api_key=API_TOKEN,  # ← Token của bạn đi vào đây!
    base_url="https://pnt.badt.vn/vistral/v1"
)

# ===== BƯỚC 3: CHAT COMPLETION VỚI TOKEN =====
try:
    response = client.chat.completions.create(
        model="SeaLLM-7B-v2.5",
        messages=[
            {"role": "system", "content": "Bạn là trợ lý AI thông minh."},
            {"role": "user", "content": "Viết một email cảm ơn bệnh nhân sau khám."}
        ],
        max_tokens=500,
        temperature=0.7
    )
    
    print("✅ Response:", response.choices[0].message.content)
    
except Exception as e:
    if "401" in str(e):
        print("❌ Token không hợp lệ!")
    elif "403" in str(e):
        print("❌ Token hết hạn hoặc không có quyền!")
    else:
        print(f"⚠️ Error: {e}")

# ===== BƯỚC 4: STREAMING RESPONSE VỚI TOKEN =====
print("\n🔄 Streaming response:")
try:
    stream = client.chat.completions.create(
        model="SeaLLM-7B-v2.5",
        messages=[
            {"role": "user", "content": "Giải thích về bệnh tiểu đường"}
        ],
        stream=True
    )
    
    for chunk in stream:
        if chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end='')
            
except Exception as e:
    print(f"\n❌ Streaming error: {e}")

cURL

curl -X POST "https://pnt.badt.vn/vistral/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "SeaLLM-7B-v2.5",
    "messages": [
      {"role": "user", "content": "Triệu chứng của cảm cúm là gì?"}
    ],
    "max_tokens": 300
  }'

DeepSeek OCR - Trích xuất Text

Python

import requests
import os

API_TOKEN = os.getenv('API_AI_TOKEN')

def extract_text_from_image(image_path, task_type='ocr'):
    """
    task_type options:
    - 'ocr': Extract all text
    - 'table': Extract tables
    - 'form': Extract form fields
    - 'invoice': Extract invoice data
    """
    url = 'https://pnt.badt.vn/deepseek_ocr/extract'
    headers = {'Authorization': f'Bearer {API_TOKEN}'}
    
    with open(image_path, 'rb') as f:
        files = {'file': f}
        data = {'task_type': task_type}
        
        response = requests.post(url, headers=headers, files=files, data=data)
        return response.json()

# Extract text from medical document
result = extract_text_from_image('medical_report.jpg', task_type='ocr')
print("Extracted text:", result['text'])

# Extract table from lab results
table_result = extract_text_from_image('lab_results.png', task_type='table')
print("Table data:", table_result['tables'])

PHP


                

Virtual Patient - RAG Medical Simulator

Python - Text Chat

import requests
import os

API_TOKEN = os.getenv('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/virtualpatient'

def chat_with_patient(patient_file, query):
    """Chat với bệnh nhân ảo qua text"""
    headers = {
        'Authorization': f'Bearer {API_TOKEN}',
        'Content-Type': 'application/json'
    }
    
    data = {
        'patient_file': patient_file,
        'query': query
    }
    
    response = requests.post(f'{BASE_URL}/chat', headers=headers, json=data)
    return response.json()

# Hỏi bệnh nhân về triệu chứng
result = chat_with_patient('bn001.txt', 'Anh có triệu chứng gì không?')
print(f"Bệnh nhân: {result['answer']}")

# Hỏi thêm chi tiết
result = chat_with_patient('bn001.txt', 'Đau ngực của anh ra sao?')
print(f"Bệnh nhân: {result['answer']}")

Python - Voice Interaction 🎤 NEW

Tính năng mới: Upload file âm thanh để tự động chuyển thành text và nhận phản hồi từ bệnh nhân ảo!

import requests
import os

API_TOKEN = os.getenv('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/virtualpatient'

def voice_interaction(audio_file_path, patient_file='bn001.txt'):
    """
    Tương tác bằng giọng nói với bệnh nhân ảo
    
    Args:
        audio_file_path: Đường dẫn file âm thanh (WAV, MP3, FLAC, WebM, OGG, M4A)
        patient_file: File dữ liệu bệnh nhân (mặc định: bn001.txt)
    
    Returns:
        dict: {
            'audio_url': URL để phát lại audio,
            'user_question': Câu hỏi được transcribe,
            'system_response': Phản hồi từ bệnh nhân ảo,
            'processing_time_ms': Thời gian xử lý
        }
    """
    url = f'{BASE_URL}/voice-interaction'
    
    headers = {
        'Authorization': f'Bearer {API_TOKEN}'
    }
    
    # Upload file âm thanh
    with open(audio_file_path, 'rb') as audio_file:
        files = {
            'audio_file': audio_file
        }
        data = {
            'patient_file': patient_file
        }
        
        response = requests.post(url, headers=headers, files=files, data=data, timeout=120)
        
        if response.status_code == 200:
            return response.json()
        elif response.status_code == 503:
            print("❌ Lỗi: Service Speech-to-Text chưa khởi động!")
            return None
        else:
            print(f"❌ Lỗi {response.status_code}: {response.text}")
            return None

# ===== SỬ DỤNG =====
# 1. Gửi file âm thanh
result = voice_interaction('patient_question.wav', 'bn001.txt')

if result:
    print(f"🔊 Audio URL: {result['audio_url']}")
    print(f"❓ Câu hỏi (transcribed): {result['user_question']}")
    print(f"💬 Trả lời từ bệnh nhân: {result['system_response']}")
    print(f"⏱️  Thời gian xử lý: {result['processing_time_ms']:.2f} ms")
    
    # 2. Download audio về để phát lại (optional)
    audio_url = f"https://pnt.badt.vn{result['audio_url']}"
    audio_response = requests.get(audio_url)
    with open('recorded_question.wav', 'wb') as f:
        f.write(audio_response.content)
    print("✅ Audio đã được lưu: recorded_question.wav")

# ===== VÍ DỤ: Xử lý nhiều file âm thanh =====
audio_files = ['question1.wav', 'question2.mp3', 'question3.flac']

for audio_file in audio_files:
    print(f"\n📂 Đang xử lý: {audio_file}")
    result = voice_interaction(audio_file, 'bn002.txt')
    
    if result:
        print(f"  ✅ Câu hỏi: {result['user_question'][:50]}...")
        print(f"  💬 Trả lời: {result['system_response'][:100]}...")
    else:
        print(f"  ❌ Lỗi khi xử lý {audio_file}")

JavaScript - Voice Recording & Upload 🎤

// ===== Voice Recording với MediaRecorder API =====
class VoiceInteractionClient {
    constructor(apiToken, baseUrl = 'https://pnt.badt.vn/virtualpatient') {
        this.apiToken = apiToken;
        this.baseUrl = baseUrl;
        this.mediaRecorder = null;
        this.audioChunks = [];
    }
    
    // Bắt đầu ghi âm
    async startRecording() {
        try {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            this.mediaRecorder = new MediaRecorder(stream);
            this.audioChunks = [];
            
            this.mediaRecorder.ondataavailable = (event) => {
                this.audioChunks.push(event.data);
            };
            
            this.mediaRecorder.start();
            console.log('🎤 Đang ghi âm...');
        } catch (error) {
            console.error('❌ Không thể truy cập microphone:', error);
        }
    }
    
    // Dừng ghi âm và gửi lên server
    async stopRecordingAndSend(patientFile = 'bn001.txt') {
        return new Promise((resolve, reject) => {
            this.mediaRecorder.onstop = async () => {
                // Tạo audio blob từ chunks
                const audioBlob = new Blob(this.audioChunks, { type: 'audio/wav' });
                console.log('⏹️ Đã dừng ghi âm. Đang gửi lên server...');
                
                try {
                    const result = await this.sendVoiceQuery(audioBlob, patientFile);
                    resolve(result);
                } catch (error) {
                    reject(error);
                }
            };
            
            this.mediaRecorder.stop();
            
            // Dừng tất cả audio tracks
            this.mediaRecorder.stream.getTracks().forEach(track => track.stop());
        });
    }
    
    // Gửi audio blob lên server
    async sendVoiceQuery(audioBlob, patientFile = 'bn001.txt') {
        const formData = new FormData();
        formData.append('audio_file', audioBlob, 'recording.wav');
        formData.append('patient_file', patientFile);
        
        const response = await fetch(`${this.baseUrl}/voice-interaction`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${this.apiToken}`
            },
            body: formData
        });
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${await response.text()}`);
        }
        
        return await response.json();
    }
}

// ===== SỬ DỤNG TRONG HTML =====
const API_TOKEN = 'your_api_token_here';
const client = new VoiceInteractionClient(API_TOKEN);

// Button handlers
document.getElementById('recordBtn').addEventListener('click', async () => {
    const btn = document.getElementById('recordBtn');
    
    if (btn.textContent === '🎤 Ghi âm') {
        await client.startRecording();
        btn.textContent = '⏹️ Dừng & Gửi';
        btn.style.background = '#ef4444';
    } else {
        btn.disabled = true;
        btn.textContent = '⏳ Đang xử lý...';
        
        try {
            const result = await client.stopRecordingAndSend('bn001.txt');
            
            // Hiển thị kết quả
            document.getElementById('transcription').textContent = result.user_question;
            document.getElementById('response').textContent = result.system_response;
            document.getElementById('processingTime').textContent = 
                `${result.processing_time_ms.toFixed(2)} ms`;
            
            // Phát lại audio đã ghi
            const audioPlayer = document.getElementById('audioPlayer');
            audioPlayer.src = result.audio_url;
            audioPlayer.style.display = 'block';
            
            console.log('✅ Hoàn tất!', result);
        } catch (error) {
            console.error('❌ Lỗi:', error);
            alert('Lỗi: ' + error.message);
        } finally {
            btn.disabled = false;
            btn.textContent = '🎤 Ghi âm';
            btn.style.background = '#3b82f6';
        }
    }
});

// ===== HTML MẪU =====
/*


Câu hỏi của bạn:

Trả lời từ bệnh nhân:

Thời gian xử lý: -

*/

cURL - Voice Interaction

# Upload file âm thanh để chat với bệnh nhân ảo
curl -X POST "https://pnt.badt.vn/virtualpatient/voice-interaction" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "audio_file=@patient_question.wav" \
  -F "patient_file=bn001.txt"

# Response:
# {
#   "audio_url": "/virtualpatient/uploads/audio/abc123_1701234567.wav",
#   "user_question": "Anh có triệu chứng gì khiến anh phải đến bệnh viện?",
#   "system_response": "Tôi bị đau ngực dữ dội từ sáng nay, đau lan ra cánh tay trái...",
#   "patient_file": "bn001.txt",
#   "processing_time_ms": 2345.67
# }

# Download audio về để phát lại
curl "https://pnt.badt.vn/virtualpatient/uploads/audio/abc123_1701234567.wav" \
  -o recorded_question.wav

Error Handling Best Practices

Python - Robust Error Handling

import requests
import time
from requests.exceptions import RequestException

class APIClient:
    def __init__(self, api_token):
        self.api_token = api_token
        self.base_url = 'https://pnt.badt.vn'
        self.max_retries = 3
        
    def _make_request(self, method, endpoint, **kwargs):
        """Make API request with retry logic"""
        headers = kwargs.pop('headers', {})
        headers['Authorization'] = f'Bearer {self.api_token}'
        
        for attempt in range(self.max_retries):
            try:
                response = requests.request(
                    method,
                    f'{self.base_url}{endpoint}',
                    headers=headers,
                    timeout=30,
                    **kwargs
                )
                
                # Handle rate limiting
                if response.status_code == 429:
                    retry_after = int(response.headers.get('Retry-After', 60))
                    print(f"Rate limited. Waiting {retry_after}s...")
                    time.sleep(retry_after)
                    continue
                
                # Handle other errors
                if response.status_code >= 400:
                    error_data = response.json()
                    raise APIError(
                        error_data.get('error', 'Unknown error'),
                        response.status_code
                    )
                
                return response.json()
                
            except RequestException as e:
                if attempt == self.max_retries - 1:
                    raise
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Request failed. Retrying in {wait_time}s...")
                time.sleep(wait_time)
    
    def transcribe_audio(self, audio_file_path):
        """Transcribe audio with error handling"""
        with open(audio_file_path, 'rb') as f:
            files = {'audio_file': f}
            return self._make_request(
                'POST',
                '/medical_transcribe/transcribe',
                files=files
            )

class APIError(Exception):
    def __init__(self, message, status_code):
        self.message = message
        self.status_code = status_code
        super().__init__(f"API Error {status_code}: {message}")

# Usage
try:
    client = APIClient(os.getenv('API_AI_TOKEN'))
    result = client.transcribe_audio('audio.wav')
    print(result['transcription'])
except APIError as e:
    print(f"API Error: {e.message} (Status: {e.status_code})")
except Exception as e:
    print(f"Unexpected error: {e}")