Các ví dụ code thực tế cho từng AI service
⚠️ 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}")
⚠️ 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"}
⚠️ 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')}")
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));
🔥 ĐẶ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 -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
}'
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'])
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']}")
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}")
// ===== 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ý: -
*/
# 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
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}")