dograh/api/constants.py

182 lines
6.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from pathlib import Path
from api.enums import Environment
ENVIRONMENT = os.getenv("ENVIRONMENT", Environment.LOCAL.value)
# Absolute path to the project root directory (i.e. the directory containing
# the top-level api/ package). Having a single canonical location helps
# when constructing file-system paths elsewhere in the codebase.
APP_ROOT_DIR: Path = Path(__file__).resolve().parent
FILLER_SOUND_PROBABILITY = 0.0
VOICEMAIL_RECORDING_DURATION = 5.0
# Cloudonix Answering Machine Detection (AMD) constants
# Ref: https://developers.cloudonix.com/Documentation/apiWorkflow/callControlAndSessionManagement#answering-machine-detection-results
# Enables AMD and waits for the full voicemail greeting to finish before reporting a result.
# Alternative: "Enable" — ends detection immediately upon determination.
AMD_MACHINE_DETECTION = "DetectMessageEnd"
# Runs AMD in the background while the call continues, posting results to asyncAmdStatusCallback.
# Default: disabled (False).
AMD_ASYNC = True
# HTTP method used when Cloudonix posts the AMD result to the callback URL.
# Allowed: "POST" or "GET". Default: "POST".
AMD_CALLBACK_METHOD = "POST"
# Maximum seconds to wait for a determination before returning "unknown".
# Range: 359 seconds. Default: 30.
AMD_MACHINE_DETECTION_TIMEOUT = 30
# Minimum greeting duration (ms) expected from an answering machine.
# Range: 10006000 ms. Default: 2400.
AMD_MACHINE_DETECTION_SPEECH_THRESHOLD = 2400
# Duration of silence (ms) after speech that confirms the greeting has ended.
# Range: 5005000 ms. Default: 1200.
AMD_MACHINE_DETECTION_SPEECH_END_THRESHOLD = 1200
# Maximum wait (ms) for any audio after the call is answered before timing out.
# Range: 200010000 ms. Default: 5000.
AMD_MACHINE_DETECTION_SILENCE_TIMEOUT = 5000
# Cloudonix AMD final result values
MACHINE_END_SILENCE = "machine_end_silence"
MACHINE_END_OTHER = "machine_end_other"
HUMAN = "human"
UNKNOWN = "unknown"
# Final (non-interim) AMD result values — only these are stored in gathered context.
AMD_FINAL_RESULTS = {MACHINE_END_SILENCE, MACHINE_END_OTHER, HUMAN, UNKNOWN}
# When enabled, Cloudonix calls answered by an answering machine are automatically hung up.
AMD_HANGUP_ENABLED = os.getenv("AMD_HANGUP_ENABLED", "false").lower() == "true"
# Configuration constants
ENABLE_TRACING = os.getenv("ENABLE_TRACING", "false").lower() == "true"
# Langfuse Configuration
LANGFUSE_HOST = os.getenv("LANGFUSE_HOST")
LANGFUSE_PUBLIC_KEY = os.getenv("LANGFUSE_PUBLIC_KEY")
LANGFUSE_SECRET_KEY = os.getenv("LANGFUSE_SECRET_KEY")
# URLs for deployment
BACKEND_API_ENDPOINT = os.getenv("BACKEND_API_ENDPOINT", "http://localhost:8000")
UI_APP_URL = os.getenv("UI_APP_URL", "http://localhost:3010")
DATABASE_URL = os.environ["DATABASE_URL"]
REDIS_URL = os.environ["REDIS_URL"]
DEPLOYMENT_MODE = os.getenv("DEPLOYMENT_MODE", "oss")
AUTH_PROVIDER = os.getenv("AUTH_PROVIDER", "local")
DOGRAH_MPS_SECRET_KEY = os.getenv("DOGRAH_MPS_SECRET_KEY", None)
MPS_API_URL = os.getenv("MPS_API_URL", "https://services.dograh.com")
# Storage Configuration
ENABLE_AWS_S3 = os.getenv("ENABLE_AWS_S3", "false").lower() == "true"
# MinIO Configuration
MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT", "localhost:9000")
MINIO_PUBLIC_ENDPOINT = os.getenv("MINIO_PUBLIC_ENDPOINT")
MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY", "minioadmin")
MINIO_BUCKET = os.getenv("MINIO_BUCKET", "voice-audio")
MINIO_SECURE = os.getenv("MINIO_SECURE", "false").lower() == "true"
# AWS S3 Configuration
S3_BUCKET = os.environ.get("S3_BUCKET")
S3_REGION = os.environ.get("S3_REGION", "us-east-1")
# Sentry configuration
SENTRY_DSN = os.getenv("SENTRY_DSN")
ENABLE_ARI_STASIS = os.getenv("ENABLE_ARI_STASIS", "false").lower() == "true"
SERIALIZE_LOG_OUTPUT = os.getenv("SERIALIZE_LOG_OUTPUT", "false").lower() == "true"
# Logging configuration
LOG_FILE_PATH = os.getenv("LOG_FILE_PATH", None)
LOG_LEVEL = os.getenv("LOG_LEVEL", "DEBUG").upper()
# Log rotation configuration
LOG_ROTATION_SIZE = os.getenv("LOG_ROTATION_SIZE", "100 MB")
LOG_RETENTION = os.getenv("LOG_RETENTION", "7 days")
LOG_COMPRESSION = os.getenv("LOG_COMPRESSION", "gz")
ENABLE_TELEMETRY = os.getenv("ENABLE_TELEMETRY", "false").lower() == "true"
def _get_version() -> str:
"""Read version from pyproject.toml."""
try:
import tomllib
pyproject_path = APP_ROOT_DIR / "pyproject.toml"
with open(pyproject_path, "rb") as f:
pyproject = tomllib.load(f)
return pyproject.get("project", {}).get("version", "dev")
except Exception:
return "dev"
# Application version (read from pyproject.toml)
APP_VERSION = _get_version()
# Country code mapping: ISO country code -> international dialing prefix
COUNTRY_CODES = {
"US": "1", # United States
"CA": "1", # Canada
"GB": "44", # United Kingdom
"IN": "91", # India
"AU": "61", # Australia
"DE": "49", # Germany
"FR": "33", # France
"BR": "55", # Brazil
"MX": "52", # Mexico
"IT": "39", # Italy
"ES": "34", # Spain
"NL": "31", # Netherlands
"SE": "46", # Sweden
"NO": "47", # Norway
"DK": "45", # Denmark
"FI": "358", # Finland
"CH": "41", # Switzerland
"AT": "43", # Austria
"BE": "32", # Belgium
"LU": "352", # Luxembourg
"IE": "353", # Ireland
}
DEFAULT_ORG_CONCURRENCY_LIMIT = os.getenv("DEFAULT_ORG_CONCURRENCY_LIMIT", 2)
DEFAULT_CAMPAIGN_RETRY_CONFIG = {
"enabled": True,
"max_retries": 1,
"retry_delay_seconds": 120,
"retry_on_busy": True,
"retry_on_no_answer": True,
"retry_on_voicemail": False,
}
# Circuit breaker defaults for campaign call failure detection
DEFAULT_CIRCUIT_BREAKER_CONFIG = {
"enabled": True,
"failure_threshold": 0.5, # 50% failure rate trips the breaker
"window_seconds": 120, # 2-minute sliding window
"min_calls_in_window": 5, # Don't trip until at least 5 outcomes
}
TURN_SECRET = os.getenv("TURN_SECRET")
TURN_HOST = os.getenv("TURN_HOST", "localhost")
TURN_PORT = int(os.getenv("TURN_PORT", "3478"))
TURN_TLS_PORT = int(os.getenv("TURN_TLS_PORT", "5349"))
TURN_CREDENTIAL_TTL = int(os.getenv("TURN_CREDENTIAL_TTL", "86400"))
# OSS Email/Password Auth
OSS_JWT_SECRET = os.getenv("OSS_JWT_SECRET", "change-me-in-production")
OSS_JWT_EXPIRY_HOURS = int(os.getenv("OSS_JWT_EXPIRY_HOURS", "720")) # 30 days