call-to-text/setup_directus.py
ed0ss 7f03949593 Первая версия: транскрипция звонков из Novofon DATA API в Directus
- Клиент Novofon DATA API (JSON-RPC, get.calls_report, чанки по 90 дней)
- faster-whisper (модель turbo) на CUDA с разделением стереоканалов
- Маркировка спикеров: левый канал = caller, правый = callee
- Directus: коллекции calls, calls_74951284933, contacts
- CLI: process, process-file, export, daemon (polling 5 мин)
- Docker Compose для Directus + PostgreSQL
- Архив email-парсинга в old/
2026-06-26 12:44:50 +03:00

141 lines
4.9 KiB
Python

import sys
import time
import httpx
from config import config
def wait_for_directus(url: str, timeout: int = 60):
start = time.time()
while time.time() - start < timeout:
try:
resp = httpx.get(f"{url}/server/ping", timeout=5)
if resp.status_code == 200:
print("Directus is ready.")
return True
except Exception:
pass
print("Waiting for Directus...")
time.sleep(3)
print("Directus did not become ready.")
return False
def login_and_get_token(url: str, email: str, password: str) -> str:
resp = httpx.post(
f"{url}/auth/login",
json={"email": email, "password": password},
)
resp.raise_for_status()
return resp.json()["data"]["access_token"]
def create_collection(client: httpx.Client, collection: str, meta: dict):
resp = client.post("/collections", json={
"collection": collection,
"meta": {
"singleton": False,
"archive_field": None,
"archive_app_filter": True,
"hidden": False,
"sort": None,
**meta,
},
"schema": {},
})
if resp.status_code not in (200, 201):
if resp.status_code == 409:
print(f" Collection '{collection}' already exists.")
return
print(f" Failed to create collection '{collection}': {resp.text}")
return
print(f" Created collection '{collection}'.")
def create_field(client: httpx.Client, collection: str, field: str, field_type: str, meta: dict = None):
payload = {
"field": field,
"type": field_type,
"meta": meta or {},
"schema": {},
}
if field_type == "json":
payload["schema"] = {"default": None}
elif field_type in ("integer", "bigInteger"):
payload["schema"] = {}
elif field_type == "text":
payload["schema"] = {}
else:
payload["schema"] = {}
resp = client.post(f"/fields/{collection}", json=payload)
if resp.status_code not in (200, 201):
if resp.status_code == 409:
print(f" Field '{collection}.{field}' already exists.")
return
print(f" Failed to create field '{collection}.{field}': {resp.text}")
return
print(f" Created field '{collection}.{field}' ({field_type}).")
def setup():
url = config.DIRECTUS_URL.rstrip("/")
if not wait_for_directus(url):
sys.exit(1)
token = login_and_get_token(url, "admin@example.com", "admin-password-123")
client = httpx.Client(
base_url=url,
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
timeout=30,
)
collections = {
"calls": {"note": "Call recordings with transcripts"},
"calls_74951284933": {"note": "Calls involving +74951284933"},
"contacts": {"note": "Phonebook for caller/callee lookup"},
}
for col_name, col_meta in collections.items():
create_collection(client, col_name, col_meta)
calls_fields = [
("call_id", "string", {"interface": "input", "unique": True}),
("datetime", "dateTime", {"interface": "datetime"}),
("direction", "string", {"interface": "input"}),
("caller_number", "string", {"interface": "input"}),
("caller_name", "string", {"interface": "input"}),
("caller_company", "string", {"interface": "input"}),
("callee_number", "string", {"interface": "input"}),
("callee_name", "string", {"interface": "input"}),
("callee_company", "string", {"interface": "input"}),
("employee", "string", {"interface": "input"}),
("duration_sec", "integer", {"interface": "input"}),
("audio_url", "string", {"interface": "input"}),
("transcript", "text", {"interface": "input-multiline"}),
("segments", "json", {"interface": "input-code", "options": {"language": "json"}}),
("source_email_id", "string", {"interface": "input"}),
("raw_metadata", "json", {"interface": "input-code", "options": {"language": "json"}}),
("status", "string", {"interface": "input", "default_value": "pending"}),
]
for col in ["calls", "calls_74951284933"]:
for field_name, field_type, field_meta in calls_fields:
create_field(client, col, field_name, field_type, field_meta)
contacts_fields = [
("phone_number", "string", {"interface": "input", "unique": True}),
("name", "string", {"interface": "input"}),
("company", "string", {"interface": "input"}),
("notes", "text", {"interface": "input-multiline"}),
]
for field_name, field_type, field_meta in contacts_fields:
create_field(client, "contacts", field_name, field_type, field_meta)
print("\nDirectus setup complete! Collections 'calls', 'calls_74951284933', and 'contacts' are ready.")
client.close()
if __name__ == "__main__":
setup()