Helpers & body builders¶
Errors¶
FaigError ¶
Bases: RuntimeError
An HTTP status >= 400 from FortiAIGate. body is the raw response text,
data its decoded JSON (None if it is not JSON), code the gateway's
OpenAI-style error.code and field the field a 409/422 names.
Raised as the subclass for its status (NotFound, Conflict, ...), so
except FaigError still catches every one.
AuthError ¶
Bases: FaigError
401 or 403: bad credentials, an expired session that would not renew, a rejected virtual key, or a call the account's role may not make.
ModelNotAvailable ¶
Bases: NotFound
The gateway's 404 for a model the virtual key is not granted
(code: model_not_found). available_models(key) lists what it may call.
Conflict ¶
Bases: FaigError
409: a name already used in the workspace (field names it), or an
approval that lost a race.
ValidationError ¶
RateLimited ¶
Bases: FaigError
429: a key's rpm/tpm limit. 8.0.2 sends no Retry-After; set
rate_limit_wait on the client to wait and retry instead of raising.
error_for ¶
error_for(method: str, path: str, status: int, body: str) -> FaigError
The FaigError subclass for an HTTP status (and gateway error code).
Results¶
Ensured ¶
Bases: NamedTuple
What an ensure_* call did. action is created, updated or
unchanged; record is the object as it now stands; secret is a
new virtual key's one-time secret (None otherwise).
Renewed ¶
Bases: NamedTuple
What renew_virtual_key did. The key keeps its id; secret is its new
one-time secret. method is rotated (the key was active) or
extended_and_rotated (it had expired, so its expiry was moved to
expires_at first: 8.0.2 rotates only an active key).
Body builders¶
regex_detector_body ¶
regex_detector_body(name: str, rules: Iterable[tuple[str, str, str]], description: str = '') -> dict[str, Any]
rules: [(rule_name, pattern, disposition)]. Fills BOTH regexRules
(the editor's grouping) and the flat rules list the engine matches on.
dlp_detector_body ¶
dlp_detector_body(name: str, categories: Iterable[str], disposition: str = 'block', threshold: float = 0.7, description: str = '') -> dict[str, Any]
categories: DLP label names as dlp_labels() spells them.
ai_detector_body ¶
ai_detector_body(name: str, rules: Iterable[tuple[Any, ...]], action: str = 'block', description: str = '') -> dict[str, Any]
A Natural Language detector: the engine judges text against plain-language
descriptions. rules: [(rule_name, violate_if)] or
[(rule_name, violate_if, exempt_if)], where each is a string or a list of
strings. Like a regex detector it fills BOTH aiRules (the editor's
grouping) and the flat rules list the engine matches on.
guardrail_body ¶
guardrail_body(name: str, detector_ids: list[str], description: str = '', *, deny_suspicious_characters: bool = False) -> dict[str, Any]
Workflow¶
approve_new ¶
approve_new(admin: FortiAIGate, ws_id: WsRef, kind: str, obj: Mapping[str, Any]) -> JSON
Walk a workspace object draft -> pending -> active, or approve an active one's pending change. Losing the race to another approver (it is no longer pending) is not an error.
Responses¶
items ¶
items(data: JSON) -> list[dict[str, Any]]
A list endpoint's records, whether it answers a bare list or {"items": [...]}.
rank_items ¶
rank_items(data: JSON, end: str = 'top') -> list[dict[str, Any]]
The rows of a usage_rankings/cost_rankings result. The API answers
items, or top and bottom lists for end="both", or only
meta when nothing was used in the window.
breakdown_items ¶
breakdown_items(data: JSON) -> list[dict[str, Any]]
The rows of a usage_breakdown/cost_breakdown result. A key, user
or workspace splits by models; a model splits by consumers (usage)
or spenders (cost), each {"count", "items"}.
collect_stream ¶
collect_stream(chunks: Iterable[Mapping[str, Any]]) -> ChatCompletion
Join chat_completion_stream chunks into one chat.completion:
each choice's message.content is its deltas joined, finish_reason
the last one given. A non-streamed completion passes through unchanged.
secret_from_response ¶
secret_from_response(data: JSON) -> str | None
The one-time faig_... secret in a create or rotate response, if any.
key_id_from_secret ¶
A virtual key secret embeds its record id: faig_<uuid-no-dashes>_....
Anything else is a ValueError rather than a made-up id.
key_update_body ¶
A virtual-key record (as read) reduced to what an update may send. A
read returns policyIds as {"id", "assignedByOrg"} objects; the
update takes plain id strings.
origin ¶
host, https://host, https://host/api -> https://host. Any
path, query or fragment is dropped, so the console address (.../ui) or the
gateway's chat URL works as well as the bare host.