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 =====
# Chạy: export API_AI_TOKEN="your_token_here"
API_TOKEN = os.getenv('API_AI_TOKEN')

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"

# 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


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

# ===== BƯỚC 2: REGISTER FACE VỚI TOKEN =====
def register_person(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_person"'
    
    # 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_person('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));

cURL - Register & Recognize

# Đăng ký khuôn mặt
curl -X POST "https://pnt.badt.vn/face_recognition/register_person" \
  -H "Authorization: Bearer ***" \
  -F "file=@john_doe.jpg" \
  -F "person_name=John Doe" \
  -F "person_id=P001"

# Nhận diện khuôn mặt
curl -X POST "https://pnt.badt.vn/face_recognition/recognize_faces" \
  -H "Authorization: Bearer ***" \
  -F "file=@group_photo.jpg"

PHP - Register & Recognize

nullLỗi 0: 

Gemma4 E4B - LLM Tiếng Việt

Đang hoạt động. Tương thích OpenAI API, base_url: https://pnt.badt.vn/gemma4/v1

Python (OpenAI Compatible)

Gemma4 tương thích 100% với OpenAI API. Dùng API token như api_key.

from openai import OpenAI
import os

API_TOKEN = os.getenv('API_AI_TOKEN')
if not API_TOKEN:
    raise ValueError("⚠️ API_TOKEN chưa được set!")

client = OpenAI(
    api_key=API_TOKEN,
    base_url="https://pnt.badt.vn/gemma4/v1"
)

# Chat Completion
response = client.chat.completions.create(
    model="gemma-3-4b-it",
    messages=[
        {"role": "system", "content": "Bạn là trợ lý AI y tế 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)

# Streaming
stream = client.chat.completions.create(
    model="gemma-3-4b-it",
    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='')

cURL

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

PHP


                

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/ocr/file'
    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

PHP - Text Chat

Bệnh nhân: Dạ, dạo này tôi làm việc ở văn phòng thì cứ thấy hơi khó chịu. Tối qua thì đang làm việc thì tự nhiên ngực tôi đau dữ dội, đau như bị đè nặng. Rồi còn khó thở nữa, cứ phải ngồi phải để thở được. Cái cảm giác lo lắng và đổ mồ hôi lạnh nó cứ bao phủ lấy tôi luôn.

AI Agent - Unified AI Orchestrator

Đang hoạt động. Base URL: https://pnt.badt.vn/ai_agent — Hỗ trợ chat, ASR, OCR, Face, TTS, dịch thuật, tìm kiếm, phân tích

Python - Chat Completion

import requests
import os

API_TOKEN = os.environ.get('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/ai_agent'

# Text chat với AI Agent
def agent_chat(message, system_prompt=None):
    headers = {
        'Authorization': f'Bearer {API_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        'message': message
    }
    if system_prompt:
        payload['system_prompt'] = system_prompt
    
    resp = requests.post(f'{BASE_URL}/chat', headers=headers, json=payload)
    return resp.json()

# Gọi chat đơn giản
result = agent_chat('Giải thích triệu chứng đau đầu kéo dài')
print(result['response'])

# Chat với system prompt medical
result = agent_chat(
    'Bệnh nhân bị sốt 3 ngày, ho khan, khó thở. Chẩn đoán?',
    system_prompt='Bạn là bác sĩ nội khoa, trả lời chuyên môn bằng tiếng Việt.'
)
print(result['response'])

cURL - Chat

curl -X POST "https://pnt.badt.vn/ai_agent/chat" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Triệu chứng của viêm phổi là gì?",
    "system_prompt": "Bạn là bác sĩ chuyên khoa hô hấp."
  }'

Python - OpenAI Compatible (v1/chat/completions)

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get('API_AI_TOKEN'),
    base_url="https://pnt.badt.vn/ai_agent/v1"
)

response = client.chat.completions.create(
    model="ai-agent",
    messages=[
        {"role": "system", "content": "Bạn là trợ lý AI y tế."},
        {"role": "user", "content": "Kê đơn thuốc cho bệnh nhân cảm cúm."}
    ],
    max_tokens=500
)
print(response.choices[0].message.content)

PHP - Chat


                

Qwen3 14B - LLM Claude-Distilled

Đang hoạt động. Chạy trên RTX 5060 Ti 16GB. OpenAI-compatible, base_url: https://pnt.badt.vn/qwen3/v1

Python (OpenAI Compatible)

Tương thích 100% OpenAI API. Dùng api_key là token của bạn.

from openai import OpenAI
import os

API_TOKEN = os.environ.get('API_AI_TOKEN')
if not API_TOKEN:
    raise ValueError("⚠️ API_TOKEN chưa được set!")

client = OpenAI(
    api_key=API_TOKEN,
    base_url="https://pnt.badt.vn/qwen3/v1"
)

# Chat completion
response = client.chat.completions.create(
    model="qwen3-claude-distill",
    messages=[
        {"role": "system", "content": "Bạn là bác sĩ chuyên khoa nội."},
        {"role": "user", "content": "Bệnh nhân đau thượng vị, ợ chua, đầy bụng sau ăn. Chẩn đoán?"}
    ],
    max_tokens=800,
    temperature=0.3
)
print("✅", response.choices[0].message.content)

# Streaming
stream = client.chat.completions.create(
    model="qwen3-claude-distill",
    messages=[{"role": "user", "content": "Liệt kê 5 dấu hiệu cảnh báo đột quỵ."}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end='')

cURL

curl -X POST "https://pnt.badt.vn/qwen3/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-claude-distill",
    "messages": [
      {"role": "system", "content": "Bạn là bác sĩ chuyên khoa."},
      {"role": "user", "content": "Cách xử trí hạ đường huyết?"}
    ],
    "max_tokens": 500,
    "temperature": 0.3
  }'

PHP


                

CodeFinder - Tra cứu Mã Y tế (ICD10, ICPC2, CPT)

Đang hoạt động. Hybrid Vector + BM25 Search. Base: https://pnt.badt.vn/codefinder

Python - Lookup Code

import requests
import os

API_TOKEN = os.environ.get('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/codefinder'

headers = {
    'Authorization': f'Bearer {API_TOKEN}',
    'Content-Type': 'application/json'
}

# 1. Tra cứu một mã
def lookup_code(code_type, code):
    """Tra cứu mã ICD10, ICPC2 hoặc CPT"""
    resp = requests.get(
        f'{BASE_URL}/code/{code_type}/{code}',
        headers=headers
    )
    return resp.json()

result = lookup_code('icd10', 'J45')
print("Kết quả tra mã J45:", result)

# 2. Tìm kiếm theo từ khóa
def search_codes(query, code_type=None, limit=10):
    params = {'q': query, 'limit': limit}
    if code_type:
        params['code_type'] = code_type
    resp = requests.get(f'{BASE_URL}/search', headers=headers, params=params)
    return resp.json()

results = search_codes('hen suyễn', limit=5)
for r in results.get('results', []):
    print(f"{r['code']}: {r['description_vi']} (score: {r['score']:.3f})")

# 3. Batch lookup
def batch_lookup(codes):
    """codes: list of dict [{'code_type': 'icd10', 'code': 'J45'}]"""
    resp = requests.post(
        f'{BASE_URL}/batch-lookup',
        headers=headers,
        json={'codes': codes}
    )
    return resp.json()

batch = batch_lookup([
    {'code_type': 'icd10', 'code': 'J45'},
    {'code_type': 'icpc2', 'code': 'R96'}
])
print("Batch results:", batch)

cURL - Lookup

# Tra cứu mã ICD10
curl "https://pnt.badt.vn/codefinder/code/icd10/J45" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Tìm kiếm từ khóa
curl "https://pnt.badt.vn/codefinder/search?q=hen+suy%E1%BB%85n&limit=5" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Batch lookup
curl -X POST "https://pnt.badt.vn/codefinder/batch-lookup" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "codes": [
      {"code_type": "icd10", "code": "J45"},
      {"code_type": "icpc2", "code": "R96"}
    ]
  }'

PHP


                

DeepSeek OCR - Full API Examples

Endpoints: /deepseek_ocr/ocr/file, /deepseek_ocr/ocr/base64, /deepseek_ocr/ocr/url, /deepseek_ocr/tts/text

Python - Tất cả phương thức OCR

import requests
import base64
import os

API_TOKEN = os.environ.get('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/deepseek_ocr'

headers = {'Authorization': f'Bearer {API_TOKEN}'}

# === 1. OCR từ file upload ===
def ocr_file(image_path, task_type='ocr'):
    with open(image_path, 'rb') as f:
        files = {'file': f}
        data = {'task_type': task_type}  # ocr, table, form, invoice
        resp = requests.post(f'{BASE_URL}/ocr/file', headers=headers, files=files, data=data)
    return resp.json()

result = ocr_file('toa_thuoc.jpg', 'ocr')
print("File OCR:", result.get('text', ''))

# === 2. OCR từ base64 ===
def ocr_base64(image_base64, task_type='ocr'):
    resp = requests.post(f'{BASE_URL}/ocr/base64', headers=headers, json={
        'image': image_base64,
        'task_type': task_type
    })
    return resp.json()

with open('xquang.png', 'rb') as f:
    b64 = base64.b64encode(f.read()).decode()
result = ocr_base64(b64, 'ocr')
print("Base64 OCR:", result.get('text', ''))

# === 3. OCR từ URL ===
def ocr_url(image_url, task_type='ocr'):
    resp = requests.post(f'{BASE_URL}/ocr/url', headers=headers, json={
        'url': image_url,
        'task_type': task_type
    })
    return resp.json()

result = ocr_url('https://example.com/xet-nghiem.jpg', 'table')
print("URL OCR:", result.get('text', '') or result.get('tables', ''))

# === 4. OCR rồi TTS (text-to-speech) ===
def ocr_tts(image_path, lang='vi'):
    with open(image_path, 'rb') as f:
        files = {'file': f}
        data = {'language': lang}
        resp = requests.post(f'{BASE_URL}/ocr-tts/file', headers=headers, files=files, data=data)
    return resp.json()

result = ocr_tts('benh_an.jpg', 'vi')
print("Audio URL:", result.get('audio_url', ''))

cURL - OCR File + QR Từ URL

# OCR từ file upload
curl -X POST "https://pnt.badt.vn/deepseek_ocr/ocr/file" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "file=@toa_thuoc.jpg" \
  -F "task_type=ocr"

# OCR từ URL
curl -X POST "https://pnt.badt.vn/deepseek_ocr/ocr/url" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/ket-qua-xet-nghiem.png", "task_type": "table"}'

Medical Transcribe - Full API Examples

PHP - Upload Audio & Transcribe

Lỗi 0: 

cURL - Diagnose Audio

# Endpoint diagnose-audio: vừa transcribe vừa phân tích
curl -X POST "https://pnt.badt.vn/medical_transcribe/diagnose-audio" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "audio_file=@trieu_chung.wav" \
  -F "language=vi" \
  -F "include_diagnosis=true"

Text2Speech - Chuyển văn bản thành giọng nói

Đang hoạt động. Hỗ trợ 28+ ngôn ngữ, nhiều giọng vùng. Base: https://pnt.badt.vn/text2speech

Python - Text to Speech

import requests
import os

API_TOKEN = os.environ.get('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/text2speech'

headers = {'Authorization': f'Bearer {API_TOKEN}'}

# === 1. TTS từ text thuần ===
def tts_text(text, language='vi', speed=1.0):
    resp = requests.post(
        f'{BASE_URL}/tts/text',
        headers={**headers, 'Content-Type': 'application/json'},
        json={
            'text': text,
            'language': language,
            'speed': speed,
            'voice': 'vi-VN-Standard-A'  # Tùy chọn giọng
        }
    )
    if resp.status_code == 200:
        # Lưu audio file
        filename = f'audio_output_{int(time.time())}.mp3'
        with open(filename, 'wb') as f:
            f.write(resp.content)
        print(f"✅ Audio saved: {filename}")
        return filename
    else:
        print(f"❌ Error: {resp.status_code}")
        return None

tts_text('Xin chào, tôi là trợ lý y tế AI. Bạn cần giúp gì?', 'vi')

# === 2. TTS từ file văn bản ===
def tts_file(text_file, language='vi', speed=1.0):
    with open(text_file, 'r', encoding='utf-8') as f:
        text = f.read()
    return tts_text(text, language, speed)

tts_file('noi_dung_doc.txt', 'vi')

# === 3. Liệt kê giọng có sẵn ===
resp = requests.get(f'{BASE_URL}/tts/voices', headers=headers)
print("Available voices:", resp.json())

cURL - TTS

# TTS từ text (trả về file audio MP3)
curl -X POST "https://pnt.badt.vn/text2speech/tts/text" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Bệnh nhân cần uống thuốc đúng giờ, mỗi ngày 2 lần.",
    "language": "vi",
    "speed": 1.0
  }' \
  --output huong_dan_dung_thuoc.mp3

# TTS từ file
curl -X POST "https://pnt.badt.vn/text2speech/tts/file" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "file=@noi_dung.txt" \
  -F "language=vi" \
  --output output.mp3

PHP - TTS

❌ Error: 422

GPU Agent - Giám sát GPU Server

Đang hoạt động. Base URL: https://pnt.badt.vn/gpu-agent — Query GPU status, temperature, memory, processes

Python - Query GPU Status

import requests
import os
import json

API_TOKEN = os.environ.get('API_AI_TOKEN')
BASE_URL = 'https://pnt.badt.vn/gpu-agent'

headers = {
    'Authorization': f'Bearer {API_TOKEN}',
    'Content-Type': 'application/json'
}

# === 1. Lấy tất cả GPU ===
def get_all_gpus():
    """Get status of all GPUs on server"""
    resp = requests.get(f'{BASE_URL}/api/gpus', headers=headers)
    return resp.json()

gpus = get_all_gpus()
print(json.dumps(gpus, indent=2, ensure_ascii=False))
# Output mẫu:
# [
#   {
#     "gpu_id": 0,
#     "name": "NVIDIA RTX 3060",
#     "temperature_c": 62,
#     "memory_used_mb": 4096,
#     "memory_total_mb": 12288,
#     "utilization_pct": 45,
#     "processes": [
#       {"pid": 1234, "name": "python3", "memory_mb": 2048}
#     ]
#   }
# ]

# === 2. Lấy GPU cụ thể ===
def get_gpu(gpu_id=0):
    resp = requests.get(f'{BASE_URL}/api/gpus/{gpu_id}', headers=headers)
    return resp.json()

gpu0 = get_gpu(0)
print(f"GPU 0: {gpu0['name']} - {gpu0['temperature_c']}°C")

# === 3. Cảnh báo khi GPU quá nóng ===
def check_gpu_health(threshold_temp=80):
    gpus = get_all_gpus()
    alerts = []
    for gpu in gpus:
        if gpu['temperature_c'] > threshold_temp:
            alerts.append(f"⚠️ GPU {gpu['gpu_id']} ({gpu['name']}): {gpu['temperature_c']}°C!")
        if gpu['memory_used_mb'] / gpu['memory_total_mb'] > 0.9:
            alerts.append(f"⚠️ GPU {gpu['gpu_id']}: Memory >90%!")
    return alerts

alerts = check_gpu_health(75)
for alert in alerts:
    print(alert)

cURL - GPU Status

# Lấy tất cả GPU
curl "https://pnt.badt.vn/gpu-agent/api/gpus" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Lấy GPU cụ thể (GPU 0)
curl "https://pnt.badt.vn/gpu-agent/api/gpus/0" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Response mẫu:
# [
#   {
#     "gpu_id": 0,
#     "name": "NVIDIA GeForce RTX 3060",
#     "temperature_c": 58,
#     "memory_used_mb": 3200,
#     "memory_total_mb": 12288,
#     "utilization_pct": 35,
#     "processes": [
#       {"pid": 4567, "name": "python3", "memory_mb": 2048}
#     ]
#   },
#   {
#     "gpu_id": 1,
#     "name": "NVIDIA GeForce RTX 3070",
#     "temperature_c": 52,
#     "memory_used_mb": 6144,
#     "memory_total_mb": 8192,
#     "utilization_pct": 78,
#     "processes": [
#       {"pid": 4890, "name": "ollama", "memory_mb": 4096}
#     ]
#   }
# ]

PHP - GPU Status

 - °C
 - °C
 - °C
 - °C
 - °C
 - °C
°C

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}")