mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 04:39:06 +00:00
chore: whereby & s3 settings env error reporting (#637)
Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
from pydantic.types import PositiveInt
|
from pydantic.types import PositiveInt
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
from reflector.utils.string import NonEmptyString
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
model_config = SettingsConfigDict(
|
model_config = SettingsConfigDict(
|
||||||
@@ -120,7 +122,7 @@ class Settings(BaseSettings):
|
|||||||
|
|
||||||
# Whereby integration
|
# Whereby integration
|
||||||
WHEREBY_API_URL: str = "https://api.whereby.dev/v1"
|
WHEREBY_API_URL: str = "https://api.whereby.dev/v1"
|
||||||
WHEREBY_API_KEY: str | None = None
|
WHEREBY_API_KEY: NonEmptyString | None = None
|
||||||
WHEREBY_WEBHOOK_SECRET: str | None = None
|
WHEREBY_WEBHOOK_SECRET: str | None = None
|
||||||
AWS_WHEREBY_ACCESS_KEY_ID: str | None = None
|
AWS_WHEREBY_ACCESS_KEY_ID: str | None = None
|
||||||
AWS_WHEREBY_ACCESS_KEY_SECRET: str | None = None
|
AWS_WHEREBY_ACCESS_KEY_SECRET: str | None = None
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ NonEmptyString = Annotated[
|
|||||||
non_empty_string_adapter = TypeAdapter(NonEmptyString)
|
non_empty_string_adapter = TypeAdapter(NonEmptyString)
|
||||||
|
|
||||||
|
|
||||||
def parse_non_empty_string(s: str) -> NonEmptyString:
|
def parse_non_empty_string(s: str, error: str | None = None) -> NonEmptyString:
|
||||||
|
try:
|
||||||
return non_empty_string_adapter.validate_python(s)
|
return non_empty_string_adapter.validate_python(s)
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"{e}: {error}" if error else e) from e
|
||||||
|
|
||||||
|
|
||||||
def try_parse_non_empty_string(s: str) -> NonEmptyString | None:
|
def try_parse_non_empty_string(s: str) -> NonEmptyString | None:
|
||||||
|
|||||||
@@ -1,18 +1,60 @@
|
|||||||
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
from reflector.db.rooms import Room
|
from reflector.db.rooms import Room
|
||||||
from reflector.settings import settings
|
from reflector.settings import settings
|
||||||
|
from reflector.utils.string import parse_non_empty_string
|
||||||
|
|
||||||
HEADERS = {
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_headers():
|
||||||
|
api_key = parse_non_empty_string(
|
||||||
|
settings.WHEREBY_API_KEY, "WHEREBY_API_KEY value is required."
|
||||||
|
)
|
||||||
|
return {
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
"Authorization": f"Bearer {settings.WHEREBY_API_KEY}",
|
"Authorization": f"Bearer {api_key}",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT = 10 # seconds
|
TIMEOUT = 10 # seconds
|
||||||
|
|
||||||
|
|
||||||
|
def _get_whereby_s3_auth():
|
||||||
|
errors = []
|
||||||
|
try:
|
||||||
|
bucket_name = parse_non_empty_string(
|
||||||
|
settings.RECORDING_STORAGE_AWS_BUCKET_NAME,
|
||||||
|
"RECORDING_STORAGE_AWS_BUCKET_NAME value is required.",
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
errors.append(e)
|
||||||
|
try:
|
||||||
|
key_id = parse_non_empty_string(
|
||||||
|
settings.AWS_WHEREBY_ACCESS_KEY_ID,
|
||||||
|
"AWS_WHEREBY_ACCESS_KEY_ID value is required.",
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
errors.append(e)
|
||||||
|
try:
|
||||||
|
key_secret = parse_non_empty_string(
|
||||||
|
settings.AWS_WHEREBY_ACCESS_KEY_SECRET,
|
||||||
|
"AWS_WHEREBY_ACCESS_KEY_SECRET value is required.",
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
errors.append(e)
|
||||||
|
if len(errors) > 0:
|
||||||
|
raise Exception(
|
||||||
|
f"Failed to get Whereby auth settings: {', '.join(str(e) for e in errors)}"
|
||||||
|
)
|
||||||
|
return bucket_name, key_id, key_secret
|
||||||
|
|
||||||
|
|
||||||
async def create_meeting(room_name_prefix: str, end_date: datetime, room: Room):
|
async def create_meeting(room_name_prefix: str, end_date: datetime, room: Room):
|
||||||
|
s3_bucket_name, s3_key_id, s3_key_secret = _get_whereby_s3_auth()
|
||||||
data = {
|
data = {
|
||||||
"isLocked": room.is_locked,
|
"isLocked": room.is_locked,
|
||||||
"roomNamePrefix": room_name_prefix,
|
"roomNamePrefix": room_name_prefix,
|
||||||
@@ -23,23 +65,26 @@ async def create_meeting(room_name_prefix: str, end_date: datetime, room: Room):
|
|||||||
"type": room.recording_type,
|
"type": room.recording_type,
|
||||||
"destination": {
|
"destination": {
|
||||||
"provider": "s3",
|
"provider": "s3",
|
||||||
"bucket": settings.RECORDING_STORAGE_AWS_BUCKET_NAME,
|
"bucket": s3_bucket_name,
|
||||||
"accessKeyId": settings.AWS_WHEREBY_ACCESS_KEY_ID,
|
"accessKeyId": s3_key_id,
|
||||||
"accessKeySecret": settings.AWS_WHEREBY_ACCESS_KEY_SECRET,
|
"accessKeySecret": s3_key_secret,
|
||||||
"fileFormat": "mp4",
|
"fileFormat": "mp4",
|
||||||
},
|
},
|
||||||
"startTrigger": room.recording_trigger,
|
"startTrigger": room.recording_trigger,
|
||||||
},
|
},
|
||||||
"fields": ["hostRoomUrl"],
|
"fields": ["hostRoomUrl"],
|
||||||
}
|
}
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
f"{settings.WHEREBY_API_URL}/meetings",
|
f"{settings.WHEREBY_API_URL}/meetings",
|
||||||
headers=HEADERS,
|
headers=_get_headers(),
|
||||||
json=data,
|
json=data,
|
||||||
timeout=TIMEOUT,
|
timeout=TIMEOUT,
|
||||||
)
|
)
|
||||||
|
if response.status_code == 403:
|
||||||
|
logger.warning(
|
||||||
|
f"Failed to create meeting: access denied on Whereby: {response.text}"
|
||||||
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
@@ -48,7 +93,7 @@ async def get_room_sessions(room_name: str):
|
|||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
f"{settings.WHEREBY_API_URL}/insights/room-sessions?roomName={room_name}",
|
f"{settings.WHEREBY_API_URL}/insights/room-sessions?roomName={room_name}",
|
||||||
headers=HEADERS,
|
headers=_get_headers(),
|
||||||
timeout=TIMEOUT,
|
timeout=TIMEOUT,
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|||||||
Reference in New Issue
Block a user