http://localhost:8020
Все защищенные endpoints требуют JWT токен в заголовке Authorization:
Authorization: Bearer YOUR_JWT_TOKEN
POST /auth/login
Получение JWT токена для доступа к API.
{
"username": "string",
"password": "string"
}
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
Python:
import requests
url = "http://localhost:8020/auth/login"
data = {
"username": "admin",
"password": "admin123"
}
response = requests.post(url, json=data)
token = response.json()["access_token"]
print(f"Token: {token}")
PHP:
<?php
$url = "http://localhost:8020/auth/login";
$data = array(
"username" => "admin",
"password" => "admin123"
);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
$token = $response["access_token"];
echo "Token: " . $token;
?>
JavaScript:
async function login() {
const response = await fetch('http://localhost:8020/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'admin',
password: 'admin123'
})
});
const data = await response.json();
const token = data.access_token;
console.log('Token:', token);
return token;
}
cURL:
curl -X POST "http://localhost:8020/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
POST /auth/register
Создание нового пользователя.
{
"username": "string",
"email": "user@example.com",
"password": "string"
}
{
"id": "uuid",
"username": "string",
"email": "user@example.com",
"is_active": true,
"is_admin": false,
"created_at": "2024-01-01T00:00:00"
}
Python:
import requests
url = "http://localhost:8020/auth/register"
data = {
"username": "newuser",
"email": "newuser@example.com",
"password": "secure_password123"
}
response = requests.post(url, json=data)
user = response.json()
print(f"Created user: {user['username']} with ID: {user['id']}")
JavaScript:
async function registerUser() {
const response = await fetch('http://localhost:8020/auth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'newuser',
email: 'newuser@example.com',
password: 'secure_password123'
})
});
const user = await response.json();
console.log('Created user:', user);
return user;
}
GET /auth/me
Получение информации о текущем авторизованном пользователе.
Authorization: Bearer YOUR_JWT_TOKEN
{
"id": "uuid",
"username": "string",
"email": "user@example.com",
"is_active": true,
"is_admin": false,
"created_at": "2024-01-01T00:00:00"
}
Python:
import requests
url = "http://localhost:8020/auth/me"
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.get(url, headers=headers)
user = response.json()
print(f"Current user: {user['username']}")
POST /transcribe/
Загрузка и транскрибация аудиофайла.
{
"id": "uuid",
"filename": "audio.mp3",
"text": "Транскрибированный текст...",
"language": "ru",
"duration": 120.5,
"processing_time": 15.3,
"status": "completed",
"created_at": "2024-01-01T00:00:00",
"segments": [
{
"id": 0,
"start": 0.0,
"end": 5.2,
"text": "Первый сегмент текста",
"words": [ // Только если return_timestamps=true
{
"word": "Первый",
"start": 0.0,
"end": 0.8,
"probability": 0.95
},
{
"word": "сегмент",
"start": 0.8,
"end": 1.5,
"probability": 0.98
}
]
}
]
}
Python:
import requests
url = "http://localhost:8020/transcribe/"
headers = {
"Authorization": f"Bearer {token}"
}
with open("audio.mp3", "rb") as audio_file:
files = {"file": audio_file}
data = {
"language": "ru",
"return_segments": "true",
"return_timestamps": "true" # Включить пословные метки времени
}
response = requests.post(url, headers=headers, files=files, data=data)
result = response.json()
print(f"Transcription ID: {result['id']}")
print(f"Text: {result['text'][:100]}...")
print(f"Duration: {result['duration']} seconds")
# Обработка меток времени
if "segments" in result:
for segment in result["segments"]:
print(f"\nSegment {segment['id']}: {segment['start']:.1f}s - {segment['end']:.1f}s")
if "words" in segment:
for word in segment["words"]:
print(f" {word['word']}: {word['start']:.1f}s - {word['end']:.1f}s")
PHP:
<?php
$url = "http://localhost:8020/transcribe/";
$token = "YOUR_JWT_TOKEN";
$file = new CURLFile('audio.mp3');
$data = array(
'file' => $file,
'language' => 'ru',
'return_segments' => 'false'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer " . $token
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo "Text: " . $result['text'];
?>
JavaScript:
async function transcribeAudio(file, token) {
const formData = new FormData();
formData.append('file', file);
formData.append('language', 'ru');
formData.append('return_segments', 'false');
const response = await fetch('http://localhost:8020/transcribe/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
const result = await response.json();
console.log('Transcription:', result.text);
return result;
}
// Использование с input файла
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
await transcribeAudio(file, token);
});
cURL:
curl -X POST "http://localhost:8020/transcribe/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-F "file=@audio.mp3" \
-F "language=ru" \
-F "return_segments=false"
GET /transcribe/history
Получение списка всех транскрибаций пользователя.
[
{
"id": "uuid",
"filename": "audio.mp3",
"status": "completed",
"duration": 120.5,
"language": "ru",
"created_at": "2024-01-01T00:00:00"
}
]
Python:
import requests
url = "http://localhost:8020/transcribe/history"
headers = {
"Authorization": f"Bearer {token}"
}
params = {
"skip": 0,
"limit": 50
}
response = requests.get(url, headers=headers, params=params)
history = response.json()
for item in history:
print(f"{item['filename']} - {item['status']} - {item['created_at']}")
GET /transcribe/{transcription_id}
Получение полной информации о конкретной транскрибации.
{
"id": "uuid",
"filename": "audio.mp3",
"text": "Полный текст транскрибации...",
"language": "ru",
"duration": 120.5,
"processing_time": 15.3,
"status": "completed",
"created_at": "2024-01-01T00:00:00",
"segments": []
}
GET /transcriptions/{transcription_id}/audio
Получение аудиофайла для воспроизведения.
Python:
import requests
url = f"http://localhost:8020/transcriptions/{transcription_id}/audio"
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.get(url, headers=headers, stream=True)
# Сохранить аудио
with open("downloaded_audio.mp3", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
JavaScript:
async function playAudio(transcriptionId, token) {
const response = await fetch(
`http://localhost:8020/transcriptions/${transcriptionId}/audio`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const blob = await response.blob();
const audioUrl = URL.createObjectURL(blob);
const audio = new Audio(audioUrl);
audio.play();
}
GET /transcriptions/{transcription_id}/status
Проверка статуса обработки транскрибации.
{
"id": "uuid",
"status": "processing",
"filename": "audio.mp3",
"created_at": "2024-01-01T00:00:00",
"completed_at": null,
"duration": null,
"processing_time": null,
"error_message": null
}
Python:
import requests
import time
def wait_for_transcription(transcription_id, token):
url = f"http://localhost:8020/transcriptions/{transcription_id}/status"
headers = {"Authorization": f"Bearer {token}"}
while True:
response = requests.get(url, headers=headers)
status = response.json()
if status['status'] == 'completed':
print("Transcription completed!")
return True
elif status['status'] == 'failed':
print(f"Transcription failed: {status['error_message']}")
return False
print(f"Status: {status['status']}... waiting")
time.sleep(2)
GET /transcriptions/{transcription_id}/download
Скачивание текста транскрибации в различных форматах.
Python:
import requests
# Скачать как текст
url = f"http://localhost:8020/transcriptions/{transcription_id}/download?format=txt"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers)
with open("transcription.txt", "w", encoding="utf-8") as f:
f.write(response.text)
# Скачать как субтитры SRT
url = f"http://localhost:8020/transcriptions/{transcription_id}/download?format=srt"
response = requests.get(url, headers=headers)
with open("transcription.srt", "w", encoding="utf-8") as f:
f.write(response.text)
GET /admin/users
Получение списка всех пользователей (требуются права администратора).
[
{
"id": "uuid",
"username": "user1",
"email": "user1@example.com",
"is_active": true,
"is_admin": false,
"created_at": "2024-01-01T00:00:00"
}
]
PATCH /admin/users/{user_id}
Обновление данных пользователя.
{
"username": "new_username",
"email": "new@example.com",
"password": "new_password",
"is_active": true,
"is_admin": false
}
Python:
import requests
url = f"http://localhost:8020/admin/users/{user_id}"
headers = {
"Authorization": f"Bearer {admin_token}",
"Content-Type": "application/json"
}
data = {
"is_active": False,
"is_admin": True
}
response = requests.patch(url, headers=headers, json=data)
updated_user = response.json()
print(f"Updated user: {updated_user}")
DELETE /admin/users/{user_id}
Удаление пользователя из системы.
JavaScript:
async function deleteUser(userId, token) {
const response = await fetch(`http://localhost:8020/admin/users/${userId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
console.log('User deleted successfully');
} else {
console.error('Failed to delete user');
}
}
POST /api-keys/
Создание нового API ключа для программного доступа.
{
"name": "My Application",
"permissions": ["transcribe", "read"],
"rate_limit": 100,
"expires_in_days": 365
}
{
"id": "uuid",
"name": "My Application",
"key": "sk_live_abcdef123456789...",
"key_prefix": "sk_live_abc...",
"is_active": true,
"permissions": ["transcribe", "read"],
"rate_limit": 100,
"created_at": "2024-01-01T00:00:00",
"expires_at": "2025-01-01T00:00:00"
}
Важно: Полный ключ (key) показывается только один раз при создании!
Python:
import requests
url = "http://localhost:8020/api-keys/"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"name": "Python Client",
"permissions": ["transcribe"],
"rate_limit": 1000,
"expires_in_days": 90
}
response = requests.post(url, headers=headers, json=data)
api_key = response.json()
print(f"API Key created: {api_key['key']}")
print("Save this key securely! It won't be shown again.")
# Использование API ключа вместо JWT токена
api_headers = {
"X-API-Key": api_key['key']
}
GET /api-keys/
Получение списка всех API ключей пользователя.
[
{
"id": "uuid",
"name": "My Application",
"key_prefix": "sk_live_abc...",
"is_active": true,
"permissions": ["transcribe", "read"],
"rate_limit": 100,
"created_at": "2024-01-01T00:00:00",
"last_used_at": "2024-01-15T12:00:00",
"expires_at": "2025-01-01T00:00:00"
}
]
GET /metrics/system
Получение метрик системы и статистики использования.
{
"cpu_usage": 45.2,
"memory_usage": 62.8,
"disk_usage": 35.1,
"gpu_available": true,
"gpu_memory_used": "8.5 GB",
"whisper_model": "large-v3",
"active_users": 12,
"total_transcriptions_24h": 156,
"average_processing_time": 12.3,
"uptime_seconds": 86400
}
Python:
import requests
url = "http://localhost:8020/metrics/system"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers)
metrics = response.json()
print(f"CPU Usage: {metrics['cpu_usage']}%")
print(f"GPU Available: {metrics['gpu_available']}")
print(f"Model: {metrics['whisper_model']}")
print(f"Transcriptions (24h): {metrics['total_transcriptions_24h']}")
GET /metrics/user
Получение статистики использования для текущего пользователя.
{
"total_transcriptions": 523,
"total_duration_seconds": 125840.5,
"total_characters": 2456789,
"total_api_calls": 1523,
"monthly_transcriptions": 45,
"monthly_duration_seconds": 10234.2,
"monthly_characters": 234567,
"monthly_api_calls": 156,
"last_reset_date": "2024-01-01T00:00:00"
}
GET /admin/transcriptions
Получение списка всех транскрибаций в системе.
[
{
"id": "uuid",
"filename": "audio.mp3",
"status": "completed",
"duration": 120.5,
"language": "ru",
"created_at": "2024-01-01T00:00:00",
"user_id": "uuid",
"username": "user1"
}
]
Все ошибки возвращаются в стандартном формате:
{
"detail": "Описание ошибки"
}
import requests
def safe_api_call(url, headers, method="GET", **kwargs):
try:
if method == "GET":
response = requests.get(url, headers=headers, **kwargs)
elif method == "POST":
response = requests.post(url, headers=headers, **kwargs)
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
print("Authentication required. Please login.")
elif response.status_code == 403:
print("Access denied. Check permissions.")
elif response.status_code == 404:
print("Resource not found.")
elif response.status_code == 429:
print("Rate limit exceeded. Please wait.")
else:
error = response.json()
print(f"Error: {error.get('detail', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Network error: {e}")
return None
import requests
import time
class Speech2TextClient:
def __init__(self, base_url="http://localhost:8020"):
self.base_url = base_url
self.token = None
def login(self, username, password):
"""Авторизация в системе"""
response = requests.post(
f"{self.base_url}/auth/login",
json={"username": username, "password": password}
)
if response.status_code == 200:
self.token = response.json()["access_token"]
print("Login successful!")
return True
return False
def transcribe(self, audio_path, language=None):
"""Транскрибация аудиофайла"""
if not self.token:
print("Please login first")
return None
headers = {"Authorization": f"Bearer {self.token}"}
with open(audio_path, "rb") as f:
files = {"file": f}
data = {"language": language} if language else {}
response = requests.post(
f"{self.base_url}/transcribe/",
headers=headers,
files=files,
data=data
)
if response.status_code == 200:
return response.json()
else:
print(f"Error: {response.text}")
return None
def wait_for_completion(self, transcription_id, timeout=300):
"""Ожидание завершения транскрибации"""
headers = {"Authorization": f"Bearer {self.token}"}
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(
f"{self.base_url}/transcriptions/{transcription_id}/status",
headers=headers
)
if response.status_code == 200:
status = response.json()
if status["status"] == "completed":
return True
elif status["status"] == "failed":
print(f"Transcription failed: {status.get('error_message')}")
return False
time.sleep(2)
print("Timeout waiting for transcription")
return False
def get_transcription(self, transcription_id):
"""Получение результата транскрибации"""
headers = {"Authorization": f"Bearer {self.token}"}
response = requests.get(
f"{self.base_url}/transcribe/{transcription_id}",
headers=headers
)
if response.status_code == 200:
return response.json()
return None
def download_text(self, transcription_id, output_path):
"""Скачивание текста транскрибации"""
headers = {"Authorization": f"Bearer {self.token}"}
response = requests.get(
f"{self.base_url}/transcriptions/{transcription_id}/download",
headers=headers
)
if response.status_code == 200:
with open(output_path, "w", encoding="utf-8") as f:
f.write(response.text)
print(f"Transcription saved to {output_path}")
return True
return False
# Использование
if __name__ == "__main__":
client = Speech2TextClient()
# Авторизация
if client.login("admin", "admin123"):
# Транскрибация
result = client.transcribe("podcast.mp3", language="ru")
if result:
print(f"Transcription ID: {result['id']}")
print(f"Status: {result['status']}")
# Ожидание завершения
if result['status'] == 'processing':
if client.wait_for_completion(result['id']):
# Получение результата
full_result = client.get_transcription(result['id'])
print(f"Text: {full_result['text'][:200]}...")
# Сохранение в файл
client.download_text(result['id'], "transcription.txt")
class Speech2TextClient {
constructor(baseUrl = 'http://localhost:8020') {
this.baseUrl = baseUrl;
this.token = null;
}
async login(username, password) {
const response = await fetch(`${this.baseUrl}/auth/login`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({username, password})
});
if (response.ok) {
const data = await response.json();
this.token = data.access_token;
console.log('Login successful!');
return true;
}
return false;
}
async transcribe(file, language = null) {
if (!this.token) {
console.error('Please login first');
return null;
}
const formData = new FormData();
formData.append('file', file);
if (language) {
formData.append('language', language);
}
const response = await fetch(`${this.baseUrl}/transcribe/`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`
},
body: formData
});
if (response.ok) {
return await response.json();
}
return null;
}
async waitForCompletion(transcriptionId, timeout = 300000) {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const response = await fetch(
`${this.baseUrl}/transcriptions/${transcriptionId}/status`,
{
headers: {'Authorization': `Bearer ${this.token}`}
}
);
if (response.ok) {
const status = await response.json();
if (status.status === 'completed') {
return true;
} else if (status.status === 'failed') {
console.error('Transcription failed:', status.error_message);
return false;
}
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
console.error('Timeout waiting for transcription');
return false;
}
async getTranscription(transcriptionId) {
const response = await fetch(
`${this.baseUrl}/transcribe/${transcriptionId}`,
{
headers: {'Authorization': `Bearer ${this.token}`}
}
);
if (response.ok) {
return await response.json();
}
return null;
}
}
// Использование
async function main() {
const client = new Speech2TextClient();
// Авторизация
if (await client.login('admin', 'admin123')) {
// Выбор файла
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
// Транскрибация
const result = await client.transcribe(file, 'ru');
if (result) {
console.log('Transcription ID:', result.id);
// Ожидание завершения
if (result.status === 'processing') {
if (await client.waitForCompletion(result.id)) {
// Получение результата
const fullResult = await client.getTranscription(result.id);
console.log('Text:', fullResult.text);
// Отображение результата
document.getElementById('result').textContent = fullResult.text;
}
}
}
});
}
}
main();
При возникновении проблем: 1. Проверьте логи сервера 2. Убедитесь в правильности токена 3. Проверьте формат и размер файла 4. Обратитесь к документации API
Для технической поддержки создайте issue на GitHub или напишите на support@speech2text.com