diff --git a/sdk-endpoints.txt b/sdk-endpoints.txt index c5c92a9..e3138fe 100644 --- a/sdk-endpoints.txt +++ b/sdk-endpoints.txt @@ -218,6 +218,10 @@ GET /v1/organizations/me/pricing # dashboard-only POST /v1/organizations/me/pricing # dashboard-only PUT /v1/organizations/me/pricing/{pricing_id} # dashboard-only DELETE /v1/organizations/me/pricing/{pricing_id} # dashboard-only +GET /v1/organizations/me/guardrails # operator surface +POST /v1/organizations/me/guardrails # operator surface +PATCH /v1/organizations/me/guardrails/{guardrail_id} # operator surface +DELETE /v1/organizations/me/guardrails/{guardrail_id} # operator surface POST /v1/organizations/me/member-invitations # dashboard-only DELETE /v1/organizations/me/member-invitations/{invitation_id} # dashboard-only # The invitation accept flow is reached by a browser following an emailed diff --git a/src/otari/_client/__init__.py b/src/otari/_client/__init__.py index b929280..166171b 100644 --- a/src/otari/_client/__init__.py +++ b/src/otari/_client/__init__.py @@ -36,6 +36,7 @@ "MessagesApi", "ModelsApi", "ModerationsApi", + "OrganizationGuardrailsApi", "OrganizationPricingApi", "OrganizationsApi", "OtelApi", @@ -349,6 +350,10 @@ "OrgProviderKeyPublic", "OrgProviderKeyUpdateRequest", "OrgProviderKeysPublic", + "OrganizationGuardrailCreate", + "OrganizationGuardrailPublic", + "OrganizationGuardrailUpdate", + "OrganizationGuardrailsPublic", "OrganizationMembershipContextPublic", "OrganizationModelPricingCreate", "OrganizationModelPricingPublic", @@ -509,6 +514,7 @@ from otari._client.api.messages_api import MessagesApi as MessagesApi from otari._client.api.models_api import ModelsApi as ModelsApi from otari._client.api.moderations_api import ModerationsApi as ModerationsApi +from otari._client.api.organization_guardrails_api import OrganizationGuardrailsApi as OrganizationGuardrailsApi from otari._client.api.organization_pricing_api import OrganizationPricingApi as OrganizationPricingApi from otari._client.api.organizations_api import OrganizationsApi as OrganizationsApi from otari._client.api.otel_api import OtelApi as OtelApi @@ -826,6 +832,10 @@ from otari._client.models.org_provider_key_public import OrgProviderKeyPublic as OrgProviderKeyPublic from otari._client.models.org_provider_key_update_request import OrgProviderKeyUpdateRequest as OrgProviderKeyUpdateRequest from otari._client.models.org_provider_keys_public import OrgProviderKeysPublic as OrgProviderKeysPublic +from otari._client.models.organization_guardrail_create import OrganizationGuardrailCreate as OrganizationGuardrailCreate +from otari._client.models.organization_guardrail_public import OrganizationGuardrailPublic as OrganizationGuardrailPublic +from otari._client.models.organization_guardrail_update import OrganizationGuardrailUpdate as OrganizationGuardrailUpdate +from otari._client.models.organization_guardrails_public import OrganizationGuardrailsPublic as OrganizationGuardrailsPublic from otari._client.models.organization_membership_context_public import OrganizationMembershipContextPublic as OrganizationMembershipContextPublic from otari._client.models.organization_model_pricing_create import OrganizationModelPricingCreate as OrganizationModelPricingCreate from otari._client.models.organization_model_pricing_public import OrganizationModelPricingPublic as OrganizationModelPricingPublic diff --git a/src/otari/_client/api/__init__.py b/src/otari/_client/api/__init__.py index f3e2a20..a2ebc6c 100644 --- a/src/otari/_client/api/__init__.py +++ b/src/otari/_client/api/__init__.py @@ -19,6 +19,7 @@ from otari._client.api.messages_api import MessagesApi from otari._client.api.models_api import ModelsApi from otari._client.api.moderations_api import ModerationsApi +from otari._client.api.organization_guardrails_api import OrganizationGuardrailsApi from otari._client.api.organization_pricing_api import OrganizationPricingApi from otari._client.api.organizations_api import OrganizationsApi from otari._client.api.otel_api import OtelApi diff --git a/src/otari/_client/api/organization_guardrails_api.py b/src/otari/_client/api/organization_guardrails_api.py new file mode 100644 index 0000000..67aefff --- /dev/null +++ b/src/otari/_client/api/organization_guardrails_api.py @@ -0,0 +1,1163 @@ +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field +from typing import Optional +from typing_extensions import Annotated +from uuid import UUID +from otari._client.models.message import Message +from otari._client.models.organization_guardrail_create import OrganizationGuardrailCreate +from otari._client.models.organization_guardrail_public import OrganizationGuardrailPublic +from otari._client.models.organization_guardrail_update import OrganizationGuardrailUpdate +from otari._client.models.organization_guardrails_public import OrganizationGuardrailsPublic + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class OrganizationGuardrailsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_organization_guardrail_v1_organizations_me_guardrails_post( + self, + organization_guardrail_create: OrganizationGuardrailCreate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> OrganizationGuardrailPublic: + """Create Organization Guardrail + + Mandate a guardrail across the organization. Organization owners and admins only. The guardrail runs on every request from the workspaces it is scoped to, in addition to whatever the caller asked for, with the stricter of the two settings applying to a profile both name. Set ``applies_to_all_workspaces`` for it to cover workspaces created later; otherwise a new workspace inherits nothing and the entry runs only in the workspaces ``workspace_ids`` lists. + + :param organization_guardrail_create: (required) + :type organization_guardrail_create: OrganizationGuardrailCreate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_organization_guardrail_v1_organizations_me_guardrails_post_serialize( + organization_guardrail_create=organization_guardrail_create, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_organization_guardrail_v1_organizations_me_guardrails_post_with_http_info( + self, + organization_guardrail_create: OrganizationGuardrailCreate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[OrganizationGuardrailPublic]: + """Create Organization Guardrail + + Mandate a guardrail across the organization. Organization owners and admins only. The guardrail runs on every request from the workspaces it is scoped to, in addition to whatever the caller asked for, with the stricter of the two settings applying to a profile both name. Set ``applies_to_all_workspaces`` for it to cover workspaces created later; otherwise a new workspace inherits nothing and the entry runs only in the workspaces ``workspace_ids`` lists. + + :param organization_guardrail_create: (required) + :type organization_guardrail_create: OrganizationGuardrailCreate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_organization_guardrail_v1_organizations_me_guardrails_post_serialize( + organization_guardrail_create=organization_guardrail_create, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_organization_guardrail_v1_organizations_me_guardrails_post_without_preload_content( + self, + organization_guardrail_create: OrganizationGuardrailCreate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Organization Guardrail + + Mandate a guardrail across the organization. Organization owners and admins only. The guardrail runs on every request from the workspaces it is scoped to, in addition to whatever the caller asked for, with the stricter of the two settings applying to a profile both name. Set ``applies_to_all_workspaces`` for it to cover workspaces created later; otherwise a new workspace inherits nothing and the entry runs only in the workspaces ``workspace_ids`` lists. + + :param organization_guardrail_create: (required) + :type organization_guardrail_create: OrganizationGuardrailCreate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_organization_guardrail_v1_organizations_me_guardrails_post_serialize( + organization_guardrail_create=organization_guardrail_create, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_organization_guardrail_v1_organizations_me_guardrails_post_serialize( + self, + organization_guardrail_create, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if organization_guardrail_create is not None: + _body_params = organization_guardrail_create + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/organizations/me/guardrails', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete( + self, + guardrail_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Message: + """Delete Organization Guardrail + + Stop mandating a guardrail, discarding its credential and scope. Organization owners and admins only. Use ``enabled: false`` instead to stop it everywhere while keeping both. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_serialize( + guardrail_id=guardrail_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Message", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_with_http_info( + self, + guardrail_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Message]: + """Delete Organization Guardrail + + Stop mandating a guardrail, discarding its credential and scope. Organization owners and admins only. Use ``enabled: false`` instead to stop it everywhere while keeping both. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_serialize( + guardrail_id=guardrail_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Message", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_without_preload_content( + self, + guardrail_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Organization Guardrail + + Stop mandating a guardrail, discarding its credential and scope. Organization owners and admins only. Use ``enabled: false`` instead to stop it everywhere while keeping both. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_serialize( + guardrail_id=guardrail_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Message", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_delete_serialize( + self, + guardrail_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if guardrail_id is not None: + _path_params['guardrail_id'] = guardrail_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/organizations/me/guardrails/{guardrail_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_organization_guardrails_v1_organizations_me_guardrails_get( + self, + skip: Annotated[Optional[Annotated[int, Field(strict=True, ge=0)]], Field(description="Number of records to skip")] = None, + limit: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="Maximum number of records to return")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> OrganizationGuardrailsPublic: + """List Organization Guardrails + + List the guardrails the caller's organization mandates. Organization owners and admins only, unlike the pricing overrides next door that any member may read: these rows name the endpoints this gateway connects to and say which of them carry a credential. A credential is never returned, only whether one is set. + + :param skip: Number of records to skip + :type skip: int + :param limit: Maximum number of records to return + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_organization_guardrails_v1_organizations_me_guardrails_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailsPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_organization_guardrails_v1_organizations_me_guardrails_get_with_http_info( + self, + skip: Annotated[Optional[Annotated[int, Field(strict=True, ge=0)]], Field(description="Number of records to skip")] = None, + limit: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="Maximum number of records to return")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[OrganizationGuardrailsPublic]: + """List Organization Guardrails + + List the guardrails the caller's organization mandates. Organization owners and admins only, unlike the pricing overrides next door that any member may read: these rows name the endpoints this gateway connects to and say which of them carry a credential. A credential is never returned, only whether one is set. + + :param skip: Number of records to skip + :type skip: int + :param limit: Maximum number of records to return + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_organization_guardrails_v1_organizations_me_guardrails_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailsPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_organization_guardrails_v1_organizations_me_guardrails_get_without_preload_content( + self, + skip: Annotated[Optional[Annotated[int, Field(strict=True, ge=0)]], Field(description="Number of records to skip")] = None, + limit: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="Maximum number of records to return")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Organization Guardrails + + List the guardrails the caller's organization mandates. Organization owners and admins only, unlike the pricing overrides next door that any member may read: these rows name the endpoints this gateway connects to and say which of them carry a credential. A credential is never returned, only whether one is set. + + :param skip: Number of records to skip + :type skip: int + :param limit: Maximum number of records to return + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_organization_guardrails_v1_organizations_me_guardrails_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailsPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_organization_guardrails_v1_organizations_me_guardrails_get_serialize( + self, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/organizations/me/guardrails', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch( + self, + guardrail_id: UUID, + organization_guardrail_update: OrganizationGuardrailUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> OrganizationGuardrailPublic: + """Update Organization Guardrail + + Change a guardrail's profile, endpoint, credential, modes, or scope. Organization owners and admins only. Omitted fields are left as they are; ``workspace_ids`` replaces the scope whole when sent, and ``url`` and ``credential`` are cleared by sending an empty string rather than null. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param organization_guardrail_update: (required) + :type organization_guardrail_update: OrganizationGuardrailUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_serialize( + guardrail_id=guardrail_id, + organization_guardrail_update=organization_guardrail_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_with_http_info( + self, + guardrail_id: UUID, + organization_guardrail_update: OrganizationGuardrailUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[OrganizationGuardrailPublic]: + """Update Organization Guardrail + + Change a guardrail's profile, endpoint, credential, modes, or scope. Organization owners and admins only. Omitted fields are left as they are; ``workspace_ids`` replaces the scope whole when sent, and ``url`` and ``credential`` are cleared by sending an empty string rather than null. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param organization_guardrail_update: (required) + :type organization_guardrail_update: OrganizationGuardrailUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_serialize( + guardrail_id=guardrail_id, + organization_guardrail_update=organization_guardrail_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_without_preload_content( + self, + guardrail_id: UUID, + organization_guardrail_update: OrganizationGuardrailUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update Organization Guardrail + + Change a guardrail's profile, endpoint, credential, modes, or scope. Organization owners and admins only. Omitted fields are left as they are; ``workspace_ids`` replaces the scope whole when sent, and ``url`` and ``credential`` are cleared by sending an empty string rather than null. + + :param guardrail_id: (required) + :type guardrail_id: UUID + :param organization_guardrail_update: (required) + :type organization_guardrail_update: OrganizationGuardrailUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_serialize( + guardrail_id=guardrail_id, + organization_guardrail_update=organization_guardrail_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "OrganizationGuardrailPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_organization_guardrail_v1_organizations_me_guardrails_guardrail_id_patch_serialize( + self, + guardrail_id, + organization_guardrail_update, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if guardrail_id is not None: + _path_params['guardrail_id'] = guardrail_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if organization_guardrail_update is not None: + _body_params = organization_guardrail_update + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/organizations/me/guardrails/{guardrail_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/models/__init__.py b/src/otari/_client/models/__init__.py index 0091468..10fd180 100644 --- a/src/otari/_client/models/__init__.py +++ b/src/otari/_client/models/__init__.py @@ -295,6 +295,10 @@ from otari._client.models.org_provider_key_public import OrgProviderKeyPublic from otari._client.models.org_provider_key_update_request import OrgProviderKeyUpdateRequest from otari._client.models.org_provider_keys_public import OrgProviderKeysPublic +from otari._client.models.organization_guardrail_create import OrganizationGuardrailCreate +from otari._client.models.organization_guardrail_public import OrganizationGuardrailPublic +from otari._client.models.organization_guardrail_update import OrganizationGuardrailUpdate +from otari._client.models.organization_guardrails_public import OrganizationGuardrailsPublic from otari._client.models.organization_membership_context_public import OrganizationMembershipContextPublic from otari._client.models.organization_model_pricing_create import OrganizationModelPricingCreate from otari._client.models.organization_model_pricing_public import OrganizationModelPricingPublic diff --git a/src/otari/_client/models/img_image.py b/src/otari/_client/models/img_image.py index 5ab195a..646bdf4 100644 --- a/src/otari/_client/models/img_image.py +++ b/src/otari/_client/models/img_image.py @@ -29,7 +29,7 @@ class IMGImage(BaseModel): """ # noqa: E501 b64_json: Optional[StrictStr] = Field(default=None, description="Filter to a single event type or metric name (e.g. 'tool_result', 'claude_code.commit.count')") revised_prompt: Optional[StrictStr] = Field(default=None, description="Filter to a single event type or metric name (e.g. 'tool_result', 'claude_code.commit.count')") - url: Optional[StrictStr] = Field(default=None, description="Filter to a single event type or metric name (e.g. 'tool_result', 'claude_code.commit.count')") + url: Optional[StrictStr] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["b64_json", "revised_prompt", "url"] diff --git a/src/otari/_client/models/organization_guardrail_create.py b/src/otari/_client/models/organization_guardrail_create.py new file mode 100644 index 0000000..ae23e79 --- /dev/null +++ b/src/otari/_client/models/organization_guardrail_create.py @@ -0,0 +1,141 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class OrganizationGuardrailCreate(BaseModel): + """ + Request body for mandating a guardrail across an organization. ``credential`` is never stored as sent: it is encrypted with ``OTARI_SECRET_KEY`` and only the ciphertext is kept, the same convention `entities.WorkspaceMcpServer` and `entities.ProviderCredential` use. It is sent to the endpoint as ``Authorization: Bearer`` when the guardrail runs, so it authenticates this gateway to the guardrails service the entry names. A guardrail *vendor's* own key is not this: the guardrails service builds its guardrails from the operator's YAML and holds those itself. A credential therefore requires ``url``. The deployment's ``guardrails_url`` is not necessarily encrypted (the shipped compose file makes it a same-host ``http://`` sidecar) and this row cannot see what it is set to, so an entry that fell back to it could not promise the bearer was sent over https. See `_require_url_for_credential`. ``on`` is not offered. This plane mandates input-direction checks, which is the only direction the request path enforces (`services.guardrails.run_input_guardrails`); an organization that could store an output-direction mandate would be storing one nothing runs. + """ # noqa: E501 + applies_to_all_workspaces: Optional[StrictBool] = Field(default=False, description="True runs this in every workspace of the organization, including one created later; false runs it only in the workspaces named by workspace_ids") + credential: Optional[Annotated[str, Field(strict=True, max_length=8192)]] = Field(default=None, description="Bearer credential for this entry's endpoint. Requires url to be set, and https: an entry with no endpoint of its own falls back to the deployment's guardrails_url, which is commonly a same-host http sidecar. Encrypted at rest, never returned") + enabled: Optional[StrictBool] = Field(default=True, description="False stops the guardrail everywhere without discarding it") + mode: Optional[StrictStr] = Field(default='monitor', description="block rejects a flagged request with 403; monitor annotates the response and forwards it") + on_unavailable: Optional[StrictStr] = Field(default='block', description="What a block-mode entry does when the guardrails service cannot be reached at all") + profile: Annotated[str, Field(min_length=1, strict=True, max_length=128)] = Field(description="Profile name configured on the guardrails service, unique within the organization") + url: Optional[Annotated[str, Field(strict=True, max_length=2048)]] = Field(default=None, description="Guardrails endpoint for this entry; null uses the deployment's guardrails_url") + validate_kwargs: Optional[Dict[str, Any]] = Field(default=None, description="Provider-native request fields used as defaults (e.g. exa's 'type', searxng's 'engines').") + workspace_ids: Optional[Annotated[List[UUID], Field(max_length=500)]] = Field(default=None, description="Workspaces this guardrail runs in. Must be empty when applies_to_all_workspaces is true") + __properties: ClassVar[List[str]] = ["applies_to_all_workspaces", "credential", "enabled", "mode", "on_unavailable", "profile", "url", "validate_kwargs", "workspace_ids"] + + @field_validator('mode') + def mode_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['block', 'monitor']): + raise ValueError("must be one of enum values ('block', 'monitor')") + return value + + @field_validator('on_unavailable') + def on_unavailable_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['block', 'monitor']): + raise ValueError("must be one of enum values ('block', 'monitor')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of OrganizationGuardrailCreate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if credential (nullable) is None + # and model_fields_set contains the field + if self.credential is None and "credential" in self.model_fields_set: + _dict['credential'] = None + + # set to None if url (nullable) is None + # and model_fields_set contains the field + if self.url is None and "url" in self.model_fields_set: + _dict['url'] = None + + # set to None if validate_kwargs (nullable) is None + # and model_fields_set contains the field + if self.validate_kwargs is None and "validate_kwargs" in self.model_fields_set: + _dict['validate_kwargs'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of OrganizationGuardrailCreate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "applies_to_all_workspaces": obj.get("applies_to_all_workspaces") if obj.get("applies_to_all_workspaces") is not None else False, + "credential": obj.get("credential"), + "enabled": obj.get("enabled") if obj.get("enabled") is not None else True, + "mode": obj.get("mode") if obj.get("mode") is not None else 'monitor', + "on_unavailable": obj.get("on_unavailable") if obj.get("on_unavailable") is not None else 'block', + "profile": obj.get("profile"), + "url": obj.get("url"), + "validate_kwargs": obj.get("validate_kwargs"), + "workspace_ids": obj.get("workspace_ids") + }) + return _obj + + diff --git a/src/otari/_client/models/organization_guardrail_public.py b/src/otari/_client/models/organization_guardrail_public.py new file mode 100644 index 0000000..d56fe3a --- /dev/null +++ b/src/otari/_client/models/organization_guardrail_public.py @@ -0,0 +1,123 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class OrganizationGuardrailPublic(BaseModel): + """ + The API-facing shape. Never carries the credential, only whether one is set. + """ # noqa: E501 + applies_to_all_workspaces: StrictBool + created_at: StrictStr + enabled: StrictBool + has_credential: StrictBool + id: UUID + mode: StrictStr + on_unavailable: StrictStr + organization_id: UUID + profile: StrictStr + updated_at: StrictStr + url: Optional[StrictStr] + validate_kwargs: Optional[Dict[str, Any]] = Field(description="Provider-native request fields used as defaults (e.g. exa's 'type', searxng's 'engines').") + workspace_ids: List[UUID] + __properties: ClassVar[List[str]] = ["applies_to_all_workspaces", "created_at", "enabled", "has_credential", "id", "mode", "on_unavailable", "organization_id", "profile", "updated_at", "url", "validate_kwargs", "workspace_ids"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of OrganizationGuardrailPublic from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if url (nullable) is None + # and model_fields_set contains the field + if self.url is None and "url" in self.model_fields_set: + _dict['url'] = None + + # set to None if validate_kwargs (nullable) is None + # and model_fields_set contains the field + if self.validate_kwargs is None and "validate_kwargs" in self.model_fields_set: + _dict['validate_kwargs'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of OrganizationGuardrailPublic from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "applies_to_all_workspaces": obj.get("applies_to_all_workspaces"), + "created_at": obj.get("created_at"), + "enabled": obj.get("enabled"), + "has_credential": obj.get("has_credential"), + "id": obj.get("id"), + "mode": obj.get("mode"), + "on_unavailable": obj.get("on_unavailable"), + "organization_id": obj.get("organization_id"), + "profile": obj.get("profile"), + "updated_at": obj.get("updated_at"), + "url": obj.get("url"), + "validate_kwargs": obj.get("validate_kwargs"), + "workspace_ids": obj.get("workspace_ids") + }) + return _obj + + diff --git a/src/otari/_client/models/organization_guardrail_update.py b/src/otari/_client/models/organization_guardrail_update.py new file mode 100644 index 0000000..a1ea31d --- /dev/null +++ b/src/otari/_client/models/organization_guardrail_update.py @@ -0,0 +1,146 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class OrganizationGuardrailUpdate(BaseModel): + """ + Partial update. Only the fields the caller sets are applied. ``credential`` and ``url`` have three states rather than two, which is what a write-only field and its nullable partner need: omit to leave the stored value alone, send ``\"\"`` to clear it, send a value to replace it. An explicit ``null`` also leaves them alone, matching `WorkspaceMcpServerUpdate`: a client that serializes its whole form back, with an empty credential box it never filled in, must not destroy a credential it was never shown. ``workspace_ids`` replaces the scope whole when sent; ``[]`` clears it. + """ # noqa: E501 + applies_to_all_workspaces: Optional[StrictBool] = None + credential: Optional[Annotated[str, Field(strict=True, max_length=8192)]] = None + enabled: Optional[StrictBool] = None + mode: Optional[StrictStr] = None + on_unavailable: Optional[StrictStr] = None + profile: Optional[Annotated[str, Field(min_length=1, strict=True, max_length=128)]] = None + url: Optional[Annotated[str, Field(strict=True, max_length=2048)]] = None + validate_kwargs: Optional[Dict[str, Any]] = None + workspace_ids: Optional[Annotated[List[UUID], Field(max_length=500)]] = None + __properties: ClassVar[List[str]] = ["applies_to_all_workspaces", "credential", "enabled", "mode", "on_unavailable", "profile", "url", "validate_kwargs", "workspace_ids"] + + @field_validator('mode') + def mode_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['block', 'monitor']): + raise ValueError("must be one of enum values ('block', 'monitor')") + return value + + @field_validator('on_unavailable') + def on_unavailable_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['block', 'monitor']): + raise ValueError("must be one of enum values ('block', 'monitor')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of OrganizationGuardrailUpdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if credential (nullable) is None + # and model_fields_set contains the field + if self.credential is None and "credential" in self.model_fields_set: + _dict['credential'] = None + + # set to None if url (nullable) is None + # and model_fields_set contains the field + if self.url is None and "url" in self.model_fields_set: + _dict['url'] = None + + # set to None if validate_kwargs (nullable) is None + # and model_fields_set contains the field + if self.validate_kwargs is None and "validate_kwargs" in self.model_fields_set: + _dict['validate_kwargs'] = None + + # set to None if workspace_ids (nullable) is None + # and model_fields_set contains the field + if self.workspace_ids is None and "workspace_ids" in self.model_fields_set: + _dict['workspace_ids'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of OrganizationGuardrailUpdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "applies_to_all_workspaces": obj.get("applies_to_all_workspaces"), + "credential": obj.get("credential"), + "enabled": obj.get("enabled"), + "mode": obj.get("mode"), + "on_unavailable": obj.get("on_unavailable"), + "profile": obj.get("profile"), + "url": obj.get("url"), + "validate_kwargs": obj.get("validate_kwargs"), + "workspace_ids": obj.get("workspace_ids") + }) + return _obj + + diff --git a/src/otari/_client/models/organization_guardrails_public.py b/src/otari/_client/models/organization_guardrails_public.py new file mode 100644 index 0000000..cfceb4b --- /dev/null +++ b/src/otari/_client/models/organization_guardrails_public.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from otari._client.models.organization_guardrail_public import OrganizationGuardrailPublic +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class OrganizationGuardrailsPublic(BaseModel): + """ + OrganizationGuardrailsPublic + """ # noqa: E501 + count: StrictInt + data: List[OrganizationGuardrailPublic] + __properties: ClassVar[List[str]] = ["count", "data"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of OrganizationGuardrailsPublic from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in data (list) + _items = [] + if self.data: + for _item_data in self.data: + if _item_data: + _items.append(_item_data.to_dict()) + _dict['data'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of OrganizationGuardrailsPublic from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "count": obj.get("count"), + "data": [OrganizationGuardrailPublic.from_dict(_item) for _item in obj["data"]] if obj.get("data") is not None else None + }) + return _obj + +