Files
Aether/_deprecated_py_src/api/internal/gateway_video.py

1361 lines
47 KiB
Python
Raw Normal View History

from __future__ import annotations
import base64
import time
import uuid
from dataclasses import asdict
from datetime import datetime, timezone
from typing import Any
from urllib.parse import urlsplit
from fastapi import BackgroundTasks, HTTPException, Request
from fastapi.responses import JSONResponse, Response
from sqlalchemy.orm import Session
from src.api.base.context import ApiRequestContext
from src.api.base.pipeline import get_pipeline
from src.core.api_format.headers import extract_client_api_key_for_endpoint_with_query
from src.core.api_format.metadata import get_auth_config_for_endpoint
from src.core.crypto import crypto_service
from src.core.http_compression import normalize_content_encoding
from src.core.logger import logger
from src.database import create_session, get_db
from src.models.database import ApiKey, RequestCandidate, User
from src.services.auth.service import AuthService
from src.utils.async_utils import safe_create_task
from .common import ensure_loopback
from .gateway_contract import (
_GEMINI_FILES_DOWNLOAD_ROUTE_RE,
_GEMINI_FILES_RESOURCE_ROUTE_RE,
_GEMINI_MODEL_OPERATION_CANCEL_RE,
_GEMINI_OPERATION_CANCEL_RE,
_GEMINI_SYNC_ROUTE_RE,
_GEMINI_VIDEO_CREATE_ROUTE_RE,
_GEMINI_VIDEO_MODEL_OPERATION_ANY_RE,
_OPENAI_VIDEO_CANCEL_ROUTE_RE,
_OPENAI_VIDEO_CONTENT_ROUTE_RE,
_OPENAI_VIDEO_REMIX_ROUTE_RE,
_OPENAI_VIDEO_TASK_ROUTE_RE,
CONTROL_ACTION_HEADER,
CONTROL_ACTION_PROXY_PUBLIC,
CONTROL_EXECUTED_HEADER,
GatewayAuthContext,
GatewayExecuteRequest,
GatewayExecutionDecisionResponse,
GatewayExecutionPlanResponse,
GatewayResolveRequest,
GatewayRouteDecision,
GatewayStreamReportRequest,
GatewaySyncReportRequest,
classify_gateway_route,
)
class _GatewayProxy:
def __getattr__(self, name: str) -> Any:
from . import gateway as gateway_module
return getattr(gateway_module, name)
gateway_module = _GatewayProxy()
def _build_video_sync_decision_from_plan(
*,
planned: GatewayExecutionPlanResponse | None,
decision_kind: str,
auth_context: GatewayAuthContext,
) -> GatewayExecutionDecisionResponse | None:
if planned is None:
return None
plan = planned.plan if isinstance(planned.plan, dict) else {}
if not plan:
return None
body = plan.get("body")
provider_request_body: dict[str, Any] | None = None
if isinstance(body, dict):
json_body = body.get("json_body")
if isinstance(json_body, dict):
provider_request_body = json_body
upstream_url = str(plan.get("url") or "").strip()
upstream_base_url = ""
if upstream_url:
parsed = urlsplit(upstream_url)
if parsed.scheme and parsed.netloc:
upstream_base_url = f"{parsed.scheme}://{parsed.netloc}"
provider_request_headers = plan.get("headers")
if not isinstance(provider_request_headers, dict):
provider_request_headers = None
timeouts = plan.get("timeouts")
if not isinstance(timeouts, dict):
timeouts = None
proxy = plan.get("proxy")
if not isinstance(proxy, dict):
proxy = None
provider_request_method = str(plan.get("method") or "").strip() or None
content_type = (
str(
plan.get("content_type")
or (
provider_request_headers.get("content-type")
if isinstance(provider_request_headers, dict)
else ""
)
or ""
).strip()
or None
)
return GatewayExecutionDecisionResponse(
action="executor_sync_decision",
decision_kind=decision_kind,
request_id=str(plan.get("request_id") or ""),
candidate_id=str(plan.get("candidate_id") or "").strip() or None,
provider_name=str(plan.get("provider_name") or ""),
provider_id=str(plan.get("provider_id") or ""),
endpoint_id=str(plan.get("endpoint_id") or ""),
key_id=str(plan.get("key_id") or ""),
upstream_base_url=upstream_base_url,
upstream_url=upstream_url or None,
provider_request_method=provider_request_method,
auth_header="",
auth_value="",
provider_api_format=str(plan.get("provider_api_format") or ""),
client_api_format=str(plan.get("client_api_format") or ""),
model_name=str(plan.get("model_name") or ""),
provider_request_headers=provider_request_headers,
provider_request_body=provider_request_body,
content_type=content_type,
proxy=proxy,
tls_profile=str(plan.get("tls_profile") or "").strip() or None,
timeouts=timeouts,
report_kind=planned.report_kind,
report_context=planned.report_context,
auth_context=auth_context,
)
async def _build_openai_video_create_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
decision: GatewayRouteDecision,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.base.request_builder import apply_body_rules
from src.api.handlers.openai.video_adapter import OpenAIVideoAdapter
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format import make_signature_key
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanTimeouts,
build_execution_plan_body,
is_remote_execution_runtime_contract_eligible,
)
if (
str(payload.method or "").strip().upper() != "POST"
or str(payload.path or "").strip() != "/v1/videos"
):
return None
if payload.body_base64:
return None
adapter = OpenAIVideoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
original_request_body = await context.ensure_json_body_async()
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
internal_request = handler._normalizer.video_request_to_internal(original_request_body)
candidate = await gateway_module._select_gateway_direct_candidate(
db=db,
redis_client=None,
api_format=handler.FORMAT_ID,
model_name=str(internal_request.model or "unknown"),
user_api_key=api_key,
request_id=context.request_id,
is_stream=False,
capability_requirements=None,
preferred_key_ids=None,
request_body=original_request_body,
)
if candidate is None:
return None
provider_api_format = make_signature_key(
str(getattr(candidate.endpoint, "api_family", "")).strip().lower(),
str(getattr(candidate.endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID or bool(
getattr(candidate, "needs_conversion", False)
):
return None
upstream_key, endpoint, provider_key, _auth_info = await handler._resolve_upstream_key(
candidate
)
request_body = dict(original_request_body)
if "seconds" in request_body and request_body["seconds"] is not None:
request_body["seconds"] = str(request_body["seconds"])
endpoint_body_rules = getattr(endpoint, "body_rules", None)
if endpoint_body_rules:
request_body = apply_body_rules(
request_body,
endpoint_body_rules,
original_body=original_request_body,
)
upstream_url = handler._build_upstream_url(endpoint.base_url)
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
body=request_body,
original_body=original_request_body,
)
content_type = str(headers.get("content-type") or "").strip() or "application/json"
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=str(
getattr(candidate, "request_candidate_id", "") or getattr(candidate, "id", "") or ""
)
or None,
provider_name=str(candidate.provider.name),
provider_id=str(candidate.provider.id),
endpoint_id=str(endpoint.id),
key_id=str(provider_key.id),
method="POST",
url=upstream_url,
headers=dict(headers),
body=build_execution_plan_body(request_body, content_type=content_type),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(internal_request.model or ""),
content_type=content_type,
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="openai_video_create_sync",
plan=contract.to_payload(),
report_kind="openai_video_create_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"request_id": str(context.request_id),
"model": str(internal_request.model or "unknown"),
"provider_name": str(candidate.provider.name),
"provider_id": str(candidate.provider.id),
"endpoint_id": str(endpoint.id),
"key_id": str(provider_key.id),
"provider_api_format": provider_api_format,
"client_api_format": handler.FORMAT_ID,
"original_headers": dict(context.original_headers),
"original_request_body": original_request_body,
"provider_request_headers": dict(headers),
"provider_request_body": request_body,
},
)
async def _build_openai_video_create_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
decision: GatewayRouteDecision,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_openai_video_create_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
decision=decision,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="openai_video_create_sync",
auth_context=auth_context,
)
async def _build_openai_video_remix_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.base.request_builder import apply_body_rules
from src.api.handlers.openai.video_adapter import OpenAIVideoAdapter
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format import make_signature_key
from src.core.api_format.conversion.internal_video import VideoStatus
from src.core.crypto import crypto_service
from src.models.database import Provider
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanTimeouts,
build_execution_plan_body,
is_remote_execution_runtime_contract_eligible,
)
if str(payload.method or "").strip().upper() != "POST" or not task_id or payload.body_base64:
return None
adapter = OpenAIVideoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={"task_id": task_id},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
original_request_body = await context.ensure_json_body_async()
try:
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
original_task = handler._get_task(task_id)
if original_task.status != VideoStatus.COMPLETED.value:
return None
if not original_task.external_task_id:
return None
endpoint, key = handler._get_endpoint_and_key(original_task)
if not getattr(key, "api_key", None):
return None
provider = db.query(Provider).filter(Provider.id == original_task.provider_id).first()
if provider is None:
return None
upstream_key = crypto_service.decrypt(key.api_key)
upstream_url = handler._build_upstream_url(
endpoint.base_url,
f"{original_task.external_task_id}/remix",
)
request_body = dict(original_request_body)
if "seconds" in request_body and request_body["seconds"] is not None:
request_body["seconds"] = str(request_body["seconds"])
endpoint_body_rules = getattr(endpoint, "body_rules", None)
if endpoint_body_rules:
request_body = apply_body_rules(
request_body,
endpoint_body_rules,
original_body=original_request_body,
)
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
body=request_body,
original_body=original_request_body,
)
provider_api_format = make_signature_key(
str(getattr(endpoint, "api_family", "")).strip().lower(),
str(getattr(endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID:
return None
except HTTPException:
return None
except Exception:
return None
content_type = str(headers.get("content-type") or "").strip() or "application/json"
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=None,
provider_name=str(provider.name),
provider_id=str(provider.id),
endpoint_id=str(endpoint.id),
key_id=str(key.id),
method="POST",
url=upstream_url,
headers=dict(headers),
body=build_execution_plan_body(request_body, content_type=content_type),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(getattr(original_task, "model", "") or ""),
content_type=content_type,
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="openai_video_remix_sync",
plan=contract.to_payload(),
report_kind="openai_video_remix_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"request_id": str(context.request_id),
"task_id": task_id,
"model": str(getattr(original_task, "model", "") or ""),
"original_headers": dict(context.original_headers),
"original_request_body": original_request_body,
},
)
async def _build_openai_video_remix_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_openai_video_remix_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
task_id=task_id,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="openai_video_remix_sync",
auth_context=auth_context,
)
async def _build_gemini_video_create_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
model: str,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.base.request_builder import apply_body_rules
from src.api.handlers.gemini.video_adapter import GeminiVeoAdapter
from src.api.handlers.gemini.video_handler import GeminiVeoHandler
from src.core.api_format import make_signature_key
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanTimeouts,
build_execution_plan_body,
is_remote_execution_runtime_contract_eligible,
)
if str(payload.method or "").strip().upper() != "POST" or not model or payload.body_base64:
return None
adapter = GeminiVeoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={"model": model},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
original_request_body = await context.ensure_json_body_async()
request_with_model = {**original_request_body, "model": model}
try:
handler = GeminiVeoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
internal_request = handler._normalizer.video_request_to_internal(request_with_model)
candidate = await gateway_module._select_gateway_direct_candidate(
db=db,
redis_client=None,
api_format=handler.FORMAT_ID,
model_name=str(internal_request.model or "unknown"),
user_api_key=api_key,
request_id=context.request_id,
is_stream=False,
capability_requirements=None,
preferred_key_ids=None,
request_body=request_with_model,
)
if candidate is None:
return None
provider_api_format = make_signature_key(
str(getattr(candidate.endpoint, "api_family", "")).strip().lower(),
str(getattr(candidate.endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID or bool(
getattr(candidate, "needs_conversion", False)
):
return None
upstream_key, endpoint, provider_key, auth_info = await handler._resolve_upstream_key(
candidate
)
endpoint_body_rules = getattr(endpoint, "body_rules", None)
request_body = dict(original_request_body)
if endpoint_body_rules:
request_body = apply_body_rules(
request_body,
endpoint_body_rules,
original_body=original_request_body,
)
upstream_url = handler._build_upstream_url(endpoint.base_url, internal_request.model)
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
auth_info,
body=request_body,
original_body=original_request_body,
)
except HTTPException:
return None
except Exception:
return None
content_type = str(headers.get("content-type") or "").strip() or "application/json"
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=str(
getattr(candidate, "request_candidate_id", "") or getattr(candidate, "id", "") or ""
)
or None,
provider_name=str(candidate.provider.name),
provider_id=str(candidate.provider.id),
endpoint_id=str(endpoint.id),
key_id=str(provider_key.id),
method="POST",
url=upstream_url,
headers=dict(headers),
body=build_execution_plan_body(request_body, content_type=content_type),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(internal_request.model or ""),
content_type=content_type,
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="gemini_video_create_sync",
plan=contract.to_payload(),
report_kind="gemini_video_create_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"request_id": str(context.request_id),
"model": str(internal_request.model or model),
"provider_name": str(candidate.provider.name),
"provider_id": str(candidate.provider.id),
"endpoint_id": str(endpoint.id),
"key_id": str(provider_key.id),
"provider_api_format": provider_api_format,
"client_api_format": handler.FORMAT_ID,
"original_headers": dict(context.original_headers),
"original_request_body": original_request_body,
"provider_request_headers": dict(headers),
"provider_request_body": request_body,
},
)
async def _build_gemini_video_create_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
model: str,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_gemini_video_create_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
model=model,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="gemini_video_create_sync",
auth_context=auth_context,
)
async def _build_openai_video_cancel_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.openai.video_adapter import OpenAIVideoAdapter
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format import make_signature_key
from src.core.api_format.conversion.internal_video import VideoStatus
from src.core.crypto import crypto_service
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanBody,
ExecutionPlanTimeouts,
is_remote_execution_runtime_contract_eligible,
)
if str(payload.method or "").strip().upper() != "POST" or not task_id:
return None
adapter = OpenAIVideoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={"task_id": task_id, "action": "cancel"},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
try:
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
task = handler._get_task(task_id)
if task.status in {
VideoStatus.COMPLETED.value,
VideoStatus.FAILED.value,
VideoStatus.CANCELLED.value,
VideoStatus.EXPIRED.value,
}:
return None
if not task.external_task_id:
return None
endpoint, key = handler._get_endpoint_and_key(task)
if not getattr(key, "api_key", None):
return None
upstream_key = crypto_service.decrypt(key.api_key)
upstream_url = handler._build_upstream_url(endpoint.base_url, task.external_task_id)
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
)
provider_api_format = make_signature_key(
str(getattr(endpoint, "api_family", "")).strip().lower(),
str(getattr(endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID:
return None
except HTTPException:
return None
except Exception:
return None
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=None,
provider_name="openai",
provider_id=str(getattr(endpoint, "provider_id", "") or ""),
endpoint_id=str(getattr(endpoint, "id", "") or ""),
key_id=str(getattr(key, "id", "") or ""),
method="DELETE",
url=upstream_url,
headers=dict(headers),
body=ExecutionPlanBody(),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(getattr(task, "model", "") or ""),
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="openai_video_cancel_sync",
plan=contract.to_payload(),
report_kind="openai_video_cancel_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"task_id": task_id,
},
)
async def _build_openai_video_cancel_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_openai_video_cancel_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
task_id=task_id,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="openai_video_cancel_sync",
auth_context=auth_context,
)
async def _build_openai_video_delete_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.openai.video_adapter import OpenAIVideoAdapter
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format import make_signature_key
from src.core.api_format.conversion.internal_video import VideoStatus
from src.core.crypto import crypto_service
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanBody,
ExecutionPlanTimeouts,
is_remote_execution_runtime_contract_eligible,
)
if str(payload.method or "").strip().upper() != "DELETE" or not task_id:
return None
adapter = OpenAIVideoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={"task_id": task_id},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
try:
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
task = handler._get_task(task_id)
if task.status not in (VideoStatus.COMPLETED.value, VideoStatus.FAILED.value):
return None
if not task.external_task_id:
return None
endpoint, key = handler._get_endpoint_and_key(task)
if not getattr(key, "api_key", None):
return None
upstream_key = crypto_service.decrypt(key.api_key)
upstream_url = handler._build_upstream_url(endpoint.base_url, task.external_task_id)
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
)
provider_api_format = make_signature_key(
str(getattr(endpoint, "api_family", "")).strip().lower(),
str(getattr(endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID:
return None
except HTTPException:
return None
except Exception:
return None
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=None,
provider_name="openai",
provider_id=str(getattr(endpoint, "provider_id", "") or ""),
endpoint_id=str(getattr(endpoint, "id", "") or ""),
key_id=str(getattr(key, "id", "") or ""),
method="DELETE",
url=upstream_url,
headers=dict(headers),
body=ExecutionPlanBody(),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(getattr(task, "model", "") or ""),
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="openai_video_delete_sync",
plan=contract.to_payload(),
report_kind="openai_video_delete_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"task_id": task_id,
},
)
async def _build_openai_video_delete_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_openai_video_delete_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
task_id=task_id,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="openai_video_delete_sync",
auth_context=auth_context,
)
async def _build_gemini_video_cancel_sync_plan(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionPlanResponse | None:
from src.api.handlers.gemini.video_adapter import GeminiVeoAdapter
from src.api.handlers.gemini.video_handler import GeminiVeoHandler
from src.core.api_format import make_signature_key
from src.core.api_format.conversion.internal_video import VideoStatus
from src.services.provider.auth import get_provider_auth
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanTimeouts,
build_execution_plan_body,
is_remote_execution_runtime_contract_eligible,
)
if str(payload.method or "").strip().upper() != "POST" or not task_id:
return None
adapter = GeminiVeoAdapter()
user, api_key = gateway_module._load_gateway_auth_models(db, auth_context)
gateway_request = gateway_module._build_gateway_forward_request(
request=request, payload=payload
)
pipeline = gateway_module.get_pipeline()
await pipeline._check_user_rate_limit(gateway_request, db, user, api_key)
context = gateway_module._build_gateway_request_context(
request=gateway_request,
payload=payload,
db=db,
user=user,
api_key=api_key,
adapter=adapter,
path_params={"task_id": task_id, "action": "cancel"},
balance_remaining=auth_context.balance_remaining,
)
authorize_result = adapter.authorize(context)
if hasattr(authorize_result, "__await__"):
await authorize_result
try:
handler = GeminiVeoHandler(
db=db,
user=user,
api_key=api_key,
request_id=context.request_id,
client_ip=context.client_ip,
user_agent=context.user_agent,
start_time=context.start_time,
allowed_api_formats=adapter.allowed_api_formats,
)
task = handler._get_task_by_external_id(task_id)
if task.status in {
VideoStatus.COMPLETED.value,
VideoStatus.FAILED.value,
VideoStatus.CANCELLED.value,
VideoStatus.EXPIRED.value,
}:
return None
if not task.external_task_id:
return None
endpoint, key = handler._get_endpoint_and_key(task)
if not getattr(key, "api_key", None):
return None
upstream_key = crypto_service.decrypt(key.api_key)
auth_info = await get_provider_auth(endpoint, key)
operation_name = str(task.external_task_id or "").strip()
if not (operation_name.startswith("operations/") or operation_name.startswith("models/")):
operation_name = f"operations/{operation_name}"
upstream_url = handler._build_cancel_url(endpoint.base_url, operation_name)
request_body: dict[str, Any] = {}
headers = handler._build_upstream_headers(
context.original_headers,
upstream_key,
endpoint,
auth_info,
body=request_body,
original_body=request_body,
)
provider_api_format = make_signature_key(
str(getattr(endpoint, "api_family", "")).strip().lower(),
str(getattr(endpoint, "endpoint_kind", "")).strip().lower(),
)
if provider_api_format != handler.FORMAT_ID:
return None
except HTTPException:
return None
except Exception:
return None
content_type = str(headers.get("content-type") or "").strip() or "application/json"
contract = ExecutionPlan(
request_id=str(context.request_id or ""),
candidate_id=None,
provider_name="gemini",
provider_id=str(getattr(endpoint, "provider_id", "") or ""),
endpoint_id=str(getattr(endpoint, "id", "") or ""),
key_id=str(getattr(key, "id", "") or ""),
method="POST",
url=upstream_url,
headers=dict(headers),
body=build_execution_plan_body(request_body, content_type=content_type),
stream=False,
provider_api_format=provider_api_format,
client_api_format=handler.FORMAT_ID,
model_name=str(getattr(task, "model", "") or ""),
content_type=content_type,
content_encoding=context.client_content_encoding,
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=300_000,
),
)
if not is_remote_execution_runtime_contract_eligible(contract):
return None
return GatewayExecutionPlanResponse(
action="executor_sync",
plan_kind="gemini_video_cancel_sync",
plan=contract.to_payload(),
report_kind="gemini_video_cancel_sync_finalize",
report_context={
"user_id": str(user.id),
"api_key_id": str(api_key.id),
"task_id": task_id,
},
)
async def _build_gemini_video_cancel_sync_decision(
*,
request: Request,
payload: GatewayExecuteRequest,
db: Session,
auth_context: GatewayAuthContext,
task_id: str,
) -> GatewayExecutionDecisionResponse | None:
planned = await _build_gemini_video_cancel_sync_plan(
request=request,
payload=payload,
db=db,
auth_context=auth_context,
task_id=task_id,
)
return _build_video_sync_decision_from_plan(
planned=planned,
decision_kind="gemini_video_cancel_sync",
auth_context=auth_context,
)
async def _build_openai_video_content_stream_plan(
*,
request: Request,
db: Session,
user: User,
user_api_key: ApiKey,
task_id: str,
) -> dict[str, Any]:
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format.conversion.internal_video import VideoStatus
from src.services.request.execution_runtime_plan import (
ExecutionPlan,
ExecutionPlanBody,
ExecutionPlanTimeouts,
)
request_id = str(getattr(request.state, "request_id", "") or uuid.uuid4().hex)
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=user_api_key,
request_id=request_id,
client_ip=request.client.host if request.client else "127.0.0.1",
user_agent=str(request.headers.get("user-agent") or "aether-gateway"),
start_time=time.time(),
)
task = handler._get_task(task_id)
if task.status in (
VideoStatus.PENDING.value,
VideoStatus.SUBMITTED.value,
VideoStatus.QUEUED.value,
VideoStatus.PROCESSING.value,
):
raise HTTPException(
status_code=202,
detail=f"Video is still processing (status: {task.status})",
)
if task.status == VideoStatus.FAILED.value:
raise HTTPException(
status_code=422,
detail=f"Video generation failed: {task.error_message or 'Unknown error'}",
)
if task.status == VideoStatus.CANCELLED.value:
raise HTTPException(status_code=404, detail="Video task was cancelled")
query_params = dict(request.query_params)
variant = str(query_params.get("variant") or "video")
if variant not in {"video", "thumbnail", "spritesheet"}:
raise HTTPException(
status_code=400,
detail=f"Invalid variant '{variant}'. Must be one of: video, thumbnail, spritesheet",
)
provider_id = ""
endpoint_id = ""
key_id = ""
if variant == "video" and task.video_url and str(task.video_url).startswith("http"):
upstream_url = str(task.video_url)
headers: dict[str, str] = {}
else:
if not task.external_task_id:
raise HTTPException(status_code=500, detail="Task missing external_task_id")
endpoint, key = handler._get_endpoint_and_key(task)
if not key.api_key:
raise HTTPException(status_code=500, detail="Provider key not configured")
try:
upstream_key = crypto_service.decrypt(key.api_key)
except Exception as exc:
raise HTTPException(status_code=500, detail="Failed to decrypt provider key") from exc
content_path = f"{task.external_task_id}/content"
if variant != "video":
content_path = f"{content_path}?variant={variant}"
upstream_url = handler._build_upstream_url(endpoint.base_url, content_path)
headers = handler._build_upstream_headers(dict(request.headers), upstream_key, endpoint)
provider_id = str(getattr(endpoint, "provider_id", "") or "")
endpoint_id = str(getattr(endpoint, "id", "") or "")
key_id = str(getattr(key, "id", "") or "")
plan = ExecutionPlan(
request_id=request_id,
candidate_id=None,
provider_name="openai",
provider_id=provider_id,
endpoint_id=endpoint_id,
key_id=key_id,
method="GET",
url=upstream_url,
headers=headers,
body=ExecutionPlanBody(),
stream=True,
provider_api_format="openai:video",
client_api_format="openai:video",
model_name=str(getattr(task, "model", "") or ""),
timeouts=ExecutionPlanTimeouts(
connect_ms=30_000,
read_ms=300_000,
write_ms=300_000,
pool_ms=30_000,
total_ms=None,
),
)
return plan.to_payload()
async def _build_openai_video_content_stream_decision(
*,
request: Request,
db: Session,
user: User,
user_api_key: ApiKey,
task_id: str,
) -> GatewayExecutionDecisionResponse:
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
from src.core.api_format.conversion.internal_video import VideoStatus
request_id = str(getattr(request.state, "request_id", "") or uuid.uuid4().hex)
handler = OpenAIVideoHandler(
db=db,
user=user,
api_key=user_api_key,
request_id=request_id,
client_ip=request.client.host if request.client else "127.0.0.1",
user_agent=str(request.headers.get("user-agent") or "aether-gateway"),
start_time=time.time(),
)
task = handler._get_task(task_id)
if task.status in (
VideoStatus.PENDING.value,
VideoStatus.SUBMITTED.value,
VideoStatus.QUEUED.value,
VideoStatus.PROCESSING.value,
):
raise HTTPException(
status_code=202,
detail=f"Video is still processing (status: {task.status})",
)
if task.status == VideoStatus.FAILED.value:
raise HTTPException(
status_code=422,
detail=f"Video generation failed: {task.error_message or 'Unknown error'}",
)
if task.status == VideoStatus.CANCELLED.value:
raise HTTPException(status_code=404, detail="Video task was cancelled")
query_params = dict(request.query_params)
variant = str(query_params.get("variant") or "video")
if variant not in {"video", "thumbnail", "spritesheet"}:
raise HTTPException(
status_code=400,
detail=f"Invalid variant '{variant}'. Must be one of: video, thumbnail, spritesheet",
)
provider_id = ""
endpoint_id = ""
key_id = ""
if variant == "video" and task.video_url and str(task.video_url).startswith("http"):
upstream_url = str(task.video_url)
headers: dict[str, str] = {}
else:
if not task.external_task_id:
raise HTTPException(status_code=500, detail="Task missing external_task_id")
endpoint, key = handler._get_endpoint_and_key(task)
if not key.api_key:
raise HTTPException(status_code=500, detail="Provider key not configured")
try:
upstream_key = crypto_service.decrypt(key.api_key)
except Exception as exc:
raise HTTPException(status_code=500, detail="Failed to decrypt provider key") from exc
content_path = f"{task.external_task_id}/content"
if variant != "video":
content_path = f"{content_path}?variant={variant}"
upstream_url = handler._build_upstream_url(endpoint.base_url, content_path)
headers = handler._build_upstream_headers(dict(request.headers), upstream_key, endpoint)
provider_id = str(getattr(endpoint, "provider_id", "") or "")
endpoint_id = str(getattr(endpoint, "id", "") or "")
key_id = str(getattr(key, "id", "") or "")
return GatewayExecutionDecisionResponse(
action="executor_stream_decision",
decision_kind="openai_video_content",
request_id=request_id,
provider_name="openai",
provider_id=provider_id,
endpoint_id=endpoint_id,
key_id=key_id,
upstream_base_url="",
upstream_url=upstream_url,
auth_header="",
auth_value="",
provider_api_format="openai:video",
client_api_format="openai:video",
model_name=str(getattr(task, "model", "") or ""),
provider_request_headers=headers,
timeouts={
"connect_ms": 30_000,
"read_ms": 300_000,
"write_ms": 300_000,
"pool_ms": 30_000,
},
)