You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

109 lines
3.4 KiB

from __future__ import annotations
from typing import Any, Dict, Optional
import requests
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
class WebEgressError(Exception):
def __init__(
self,
message: str,
*,
status_code: Optional[int] = None,
response_data: Optional[Dict[str, Any]] = None,
):
super().__init__(message)
self.status_code = status_code
self.response_data = response_data or {}
class WebEgressClient:
def __init__(
self,
*,
base_url: Optional[str] = None,
service_token: Optional[str] = None,
timeout: Optional[float] = None,
):
self.base_url = (
base_url
or getattr(settings, "ONLINE_CLASS_WEB_EGRESS_SERVICE_URL", "")
).rstrip("/")
self.service_token = (
service_token
or getattr(settings, "ONLINE_CLASS_WEB_EGRESS_SERVICE_TOKEN", "")
)
self.timeout = timeout or getattr(
settings, "ONLINE_CLASS_WEB_EGRESS_TIMEOUT", 20.0
)
if not self.base_url:
raise ImproperlyConfigured(
"ONLINE_CLASS_WEB_EGRESS_SERVICE_URL must be configured."
)
def start_recording(self, payload: Dict[str, Any]) -> Dict[str, Any]:
return self._request("POST", "/api/web-egress/start/", json=payload)
def stop_recording(self, payload: Dict[str, Any]) -> Dict[str, Any]:
return self._request("POST", "/api/web-egress/stop/", json=payload)
def get_status(self, *, room_id: str, session_id: int) -> Dict[str, Any]:
return self._request(
"GET",
"/api/web-egress/status/",
params={"room_id": room_id, "session_id": session_id},
)
def _request(self, method: str, path: str, **kwargs) -> Dict[str, Any]:
headers = kwargs.pop("headers", {})
headers["Content-Type"] = "application/json"
if self.service_token:
headers["Authorization"] = f"Bearer {self.service_token}"
try:
response = requests.request(
method,
f"{self.base_url}{path}",
headers=headers,
timeout=self.timeout,
**kwargs,
)
except requests.RequestException as exc:
raise WebEgressError("Failed to reach WebEgress service.") from exc
data = self._safe_json(response)
if response.status_code >= 400:
message = (
(data or {}).get("message")
or (data or {}).get("detail")
or response.text
or "WebEgress service request failed."
)
raise WebEgressError(
message,
status_code=response.status_code,
response_data=data,
)
if data is None:
raise WebEgressError("WebEgress service returned an invalid response.")
if isinstance(data, dict) and data.get("status") is False:
raise WebEgressError(
data.get("message") or data.get("detail") or "WebEgress failed.",
status_code=response.status_code,
response_data=data,
)
return data
@staticmethod
def _safe_json(response: requests.Response) -> Optional[Dict[str, Any]]:
try:
return response.json()
except ValueError:
return None