@@ -5,10 +5,12 @@ from uuid import uuid4
|
||||
from fastapi import APIRouter, HTTPException, Request, status
|
||||
|
||||
from cloud.auth import AuthProvider, GOVERNANCE_ADMIN_SCOPE, GOVERNANCE_READ_SCOPE
|
||||
from cloud.governance import GovernancePolicyConflictError
|
||||
from cloud.observability import current_correlation_id
|
||||
from cloud.sdk.models import (
|
||||
HostGovernancePolicyRequest,
|
||||
HostGovernancePolicyResponse,
|
||||
HostTokenUsageSummaryResponse,
|
||||
UserSubmissionPolicyRequest,
|
||||
UserSubmissionPolicyResponse,
|
||||
)
|
||||
@@ -79,10 +81,13 @@ def create_governance_router(*, repository, auth_provider: AuthProvider) -> APIR
|
||||
if payload.allowed_device_targets is not None
|
||||
else None
|
||||
),
|
||||
expected_revision=payload.expected_revision,
|
||||
updated_at=utc_now(),
|
||||
)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail="user not found") from exc
|
||||
except GovernancePolicyConflictError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
_audit(repository, principal.id, user_id, "user_submission_policy_update")
|
||||
return UserSubmissionPolicyResponse(
|
||||
user_id=policy.user_id,
|
||||
@@ -111,6 +116,27 @@ def create_governance_router(*, repository, auth_provider: AuthProvider) -> APIR
|
||||
raise HTTPException(status_code=404, detail="Host policy not found")
|
||||
return _host_response(policy)
|
||||
|
||||
@router.get(
|
||||
"/hosts/{host_id}/token-usage",
|
||||
response_model=HostTokenUsageSummaryResponse,
|
||||
)
|
||||
def get_host_token_usage(
|
||||
host_id: str, request: Request
|
||||
) -> HostTokenUsageSummaryResponse:
|
||||
authorize(request, GOVERNANCE_READ_SCOPE)
|
||||
now = utc_now()
|
||||
summary = repository.get_host_token_usage_summary(
|
||||
host_id=host_id, usage_day=now.date().isoformat(), now=now
|
||||
)
|
||||
return HostTokenUsageSummaryResponse(
|
||||
host_id=summary.host_id,
|
||||
usage_day=summary.usage_day,
|
||||
daily_token_budget=summary.daily_token_budget,
|
||||
used_tokens=summary.used_tokens,
|
||||
reserved_tokens=summary.reserved_tokens,
|
||||
remaining_tokens=summary.remaining_tokens,
|
||||
)
|
||||
|
||||
@router.put(
|
||||
"/hosts/{host_id}/governance-policy",
|
||||
response_model=HostGovernancePolicyResponse,
|
||||
@@ -127,10 +153,13 @@ def create_governance_router(*, repository, auth_provider: AuthProvider) -> APIR
|
||||
self_submission_enabled=payload.self_submission_enabled,
|
||||
max_active_tasks=payload.max_active_tasks,
|
||||
daily_token_budget=payload.daily_token_budget,
|
||||
expected_revision=payload.expected_revision,
|
||||
updated_at=utc_now(),
|
||||
)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail="Host not found") from exc
|
||||
except GovernancePolicyConflictError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
_audit(repository, principal.id, host_id, "host_governance_policy_update")
|
||||
return _host_response(policy)
|
||||
|
||||
|
||||
@@ -162,11 +162,15 @@ class UserSubmissionPolicyRequest(BaseModel):
|
||||
submission_enabled: bool = True
|
||||
allowed_host_ids: list[str] | None = None
|
||||
allowed_device_targets: list[DeviceTargetModel] | None = None
|
||||
expected_revision: int | None = Field(default=None, ge=0)
|
||||
|
||||
|
||||
class UserSubmissionPolicyResponse(UserSubmissionPolicyRequest):
|
||||
class UserSubmissionPolicyResponse(BaseModel):
|
||||
user_id: str
|
||||
revision: int
|
||||
submission_enabled: bool
|
||||
allowed_host_ids: list[str] | None = None
|
||||
allowed_device_targets: list[DeviceTargetModel] | None = None
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
@@ -174,9 +178,22 @@ class HostGovernancePolicyRequest(BaseModel):
|
||||
self_submission_enabled: bool = True
|
||||
max_active_tasks: int | None = Field(default=None, ge=1)
|
||||
daily_token_budget: int | None = Field(default=None, ge=1)
|
||||
expected_revision: int | None = Field(default=None, ge=0)
|
||||
|
||||
|
||||
class HostGovernancePolicyResponse(HostGovernancePolicyRequest):
|
||||
class HostGovernancePolicyResponse(BaseModel):
|
||||
host_id: str
|
||||
revision: int
|
||||
self_submission_enabled: bool
|
||||
max_active_tasks: int | None = None
|
||||
daily_token_budget: int | None = None
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class HostTokenUsageSummaryResponse(BaseModel):
|
||||
host_id: str
|
||||
usage_day: str
|
||||
daily_token_budget: int | None = None
|
||||
used_tokens: int
|
||||
reserved_tokens: int
|
||||
remaining_tokens: int | None = None
|
||||
|
||||
Reference in New Issue
Block a user