diff --git a/src/antfly/client.py b/src/antfly/client.py index 73cbfca..c95dee3 100644 --- a/src/antfly/client.py +++ b/src/antfly/client.py @@ -1,18 +1,20 @@ """Main client interface for Antfly SDK.""" +import base64 from typing import Any, Optional, cast from httpx import Timeout from antfly.client_generated import Client -from antfly.client_generated.api.api_table import ( - batch, +from antfly.client_generated.api.table_management import ( create_table, drop_table, get_table, list_tables, +) +from antfly.client_generated.api.data_operations import ( + batch_write as batch, lookup_key, - query_table, ) from antfly.client_generated.client import AuthenticatedClient from antfly.client_generated.models import ( @@ -21,9 +23,6 @@ CreateTableRequest, CreateTableRequestIndexes, Error, - QueryRequest, - QueryRequestFullTextSearch, - QueryResponses, Table, TableSchema, TableStatus, @@ -41,28 +40,57 @@ def __init__( base_url: str, username: Optional[str] = None, password: Optional[str] = None, + api_key: Optional[tuple[str, str]] = None, + bearer_token: Optional[str] = None, timeout: float = 30.0, ): """ Initialize Antfly client. + Supports three authentication methods (mutually exclusive): + - Basic auth: provide ``username`` and ``password`` + - API key: provide ``api_key`` as ``(key_id, key_secret)`` + - Bearer token: provide ``bearer_token`` + Args: base_url: Base URL of the Antfly server - username: Username for authentication (optional) - password: Password for authentication (optional) + username: Username for basic authentication (optional) + password: Password for basic authentication (optional) + api_key: Tuple of (key_id, key_secret) for API key authentication (optional) + bearer_token: Bearer token string for token authentication (optional) timeout: Request timeout in seconds """ self.base_url = base_url.rstrip("/") httpx_args: dict[str, Any] = {} - if username and password: - httpx_args["auth"] = (username, password) - self._client = Client( - base_url=self.base_url, - timeout=Timeout(timeout), - httpx_args=httpx_args, - ) + if api_key is not None: + key_id, key_secret = api_key + encoded = base64.b64encode(f"{key_id}:{key_secret}".encode()).decode() + self._client = AuthenticatedClient( + base_url=self.base_url, + token=encoded, + prefix="ApiKey", + timeout=Timeout(timeout), + httpx_args=httpx_args, + ) + elif bearer_token is not None: + self._client = AuthenticatedClient( + base_url=self.base_url, + token=bearer_token, + prefix="Bearer", + timeout=Timeout(timeout), + httpx_args=httpx_args, + ) + else: + if username and password: + httpx_args["auth"] = (username, password) + + self._client = Client( + base_url=self.base_url, + timeout=Timeout(timeout), + httpx_args=httpx_args, + ) # Table operations @@ -171,70 +199,6 @@ def drop_table(self, name: str) -> None: if response is None: raise AntflyException(f"Failed to drop table '{name}'") - # Query operations - - def query( - self, - table: Optional[str] = None, - full_text_search: Optional[dict[str, Any]] = None, - semantic_search: Optional[str] = None, - filter_prefix: Optional[str] = None, - limit: int = 10, - offset: int = 0, - **kwargs: Any, - ) -> QueryResponses: - """ - Query a table or perform global query. - - Args: - table: Table name (optional for global query) - full_text_search: Full-text search query - semantic_search: Semantic search query - filter_prefix: Key prefix filter - limit: Maximum number of results - offset: Number of results to skip - **kwargs: Additional query parameters - - Returns: - Query result object - - Raises: - AntflyException: If query fails - """ - request = QueryRequest( - table=table if table is not None else UNSET, - full_text_search=( - cast(QueryRequestFullTextSearch, full_text_search) if full_text_search is not None else UNSET - ), - semantic_search=semantic_search if semantic_search is not None else UNSET, - filter_prefix=filter_prefix if filter_prefix is not None else UNSET, - limit=limit, - offset=offset, - **kwargs, - ) - - if table: - response = query_table.sync( - table_name=table, - client=cast(AuthenticatedClient, self._client), - body=request, - ) - else: - # Use global query endpoint - from antfly.client_generated.api.api_table import global_query - - response = global_query.sync( - client=cast(AuthenticatedClient, self._client), - body=request, - ) - - if isinstance(response, Error): - raise AntflyException(f"Query failed: {response.error}") - if response is None: - raise AntflyException("Query failed") - - return response - def get(self, table: str, key: str) -> dict[str, Any]: """ Get a single record by key. diff --git a/src/antfly/client_generated/api/api_key/__init__.py b/src/antfly/client_generated/api/api_key/__init__.py new file mode 100644 index 0000000..2d7c0b2 --- /dev/null +++ b/src/antfly/client_generated/api/api_key/__init__.py @@ -0,0 +1 @@ +"""Contains endpoint functions for accessing the API""" diff --git a/src/antfly/client_generated/api/api_key/create_api_key.py b/src/antfly/client_generated/api/api_key/create_api_key.py new file mode 100644 index 0000000..fd35977 --- /dev/null +++ b/src/antfly/client_generated/api/api_key/create_api_key.py @@ -0,0 +1,206 @@ +from http import HTTPStatus +from typing import Any, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.api_key_with_secret import ApiKeyWithSecret +from ...models.create_api_key_request import CreateApiKeyRequest +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + user_name: str, + *, + body: CreateApiKeyRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": f"/users/{user_name}/api-keys", + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[ApiKeyWithSecret, Error]]: + if response.status_code == 201: + response_201 = ApiKeyWithSecret.from_dict(response.json()) + + return response_201 + + if response.status_code == 400: + response_400 = Error.from_dict(response.json()) + + return response_400 + + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[ApiKeyWithSecret, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + user_name: str, + *, + client: AuthenticatedClient, + body: CreateApiKeyRequest, +) -> Response[Union[ApiKeyWithSecret, Error]]: + """Create a new API key + + Creates a new API key for the specified user. The cleartext secret is returned only in this + response. + + Args: + user_name (str): Example: johndoe. + body (CreateApiKeyRequest): Request to create a new API key. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[ApiKeyWithSecret, Error]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + user_name: str, + *, + client: AuthenticatedClient, + body: CreateApiKeyRequest, +) -> Optional[Union[ApiKeyWithSecret, Error]]: + """Create a new API key + + Creates a new API key for the specified user. The cleartext secret is returned only in this + response. + + Args: + user_name (str): Example: johndoe. + body (CreateApiKeyRequest): Request to create a new API key. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[ApiKeyWithSecret, Error] + """ + + return sync_detailed( + user_name=user_name, + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + user_name: str, + *, + client: AuthenticatedClient, + body: CreateApiKeyRequest, +) -> Response[Union[ApiKeyWithSecret, Error]]: + """Create a new API key + + Creates a new API key for the specified user. The cleartext secret is returned only in this + response. + + Args: + user_name (str): Example: johndoe. + body (CreateApiKeyRequest): Request to create a new API key. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[ApiKeyWithSecret, Error]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + user_name: str, + *, + client: AuthenticatedClient, + body: CreateApiKeyRequest, +) -> Optional[Union[ApiKeyWithSecret, Error]]: + """Create a new API key + + Creates a new API key for the specified user. The cleartext secret is returned only in this + response. + + Args: + user_name (str): Example: johndoe. + body (CreateApiKeyRequest): Request to create a new API key. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[ApiKeyWithSecret, Error] + """ + + return ( + await asyncio_detailed( + user_name=user_name, + client=client, + body=body, + ) + ).parsed diff --git a/src/antfly/client_generated/api/api_key/delete_api_key.py b/src/antfly/client_generated/api/api_key/delete_api_key.py new file mode 100644 index 0000000..b0fbba0 --- /dev/null +++ b/src/antfly/client_generated/api/api_key/delete_api_key.py @@ -0,0 +1,181 @@ +from http import HTTPStatus +from typing import Any, Optional, Union, cast + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + user_name: str, + key_id: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "delete", + "url": f"/users/{user_name}/api-keys/{key_id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[Any, Error]]: + if response.status_code == 204: + response_204 = cast(Any, None) + return response_204 + + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[Any, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + user_name: str, + key_id: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Any, Error]]: + """Delete an API key + + Permanently deletes the specified API key. Subsequent requests using this key will be rejected. + + Args: + user_name (str): Example: johndoe. + key_id (str): Example: aBcDeFgHiJkLmNoPqRsT. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, Error]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + key_id=key_id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + user_name: str, + key_id: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Any, Error]]: + """Delete an API key + + Permanently deletes the specified API key. Subsequent requests using this key will be rejected. + + Args: + user_name (str): Example: johndoe. + key_id (str): Example: aBcDeFgHiJkLmNoPqRsT. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, Error] + """ + + return sync_detailed( + user_name=user_name, + key_id=key_id, + client=client, + ).parsed + + +async def asyncio_detailed( + user_name: str, + key_id: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Any, Error]]: + """Delete an API key + + Permanently deletes the specified API key. Subsequent requests using this key will be rejected. + + Args: + user_name (str): Example: johndoe. + key_id (str): Example: aBcDeFgHiJkLmNoPqRsT. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, Error]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + key_id=key_id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + user_name: str, + key_id: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Any, Error]]: + """Delete an API key + + Permanently deletes the specified API key. Subsequent requests using this key will be rejected. + + Args: + user_name (str): Example: johndoe. + key_id (str): Example: aBcDeFgHiJkLmNoPqRsT. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, Error] + """ + + return ( + await asyncio_detailed( + user_name=user_name, + key_id=key_id, + client=client, + ) + ).parsed diff --git a/src/antfly/client_generated/api/api_key/list_api_keys.py b/src/antfly/client_generated/api/api_key/list_api_keys.py new file mode 100644 index 0000000..b314fe0 --- /dev/null +++ b/src/antfly/client_generated/api/api_key/list_api_keys.py @@ -0,0 +1,180 @@ +from http import HTTPStatus +from typing import Any, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.api_key import ApiKey +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + user_name: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/users/{user_name}/api-keys", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[Error, list["ApiKey"]]]: + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = ApiKey.from_dict(response_200_item_data) + + response_200.append(response_200_item) + + return response_200 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[Error, list["ApiKey"]]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + user_name: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Error, list["ApiKey"]]]: + """List API keys for a user + + Returns all API keys owned by the specified user. Secrets are never included. + + Args: + user_name (str): Example: johndoe. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, list['ApiKey']]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + user_name: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Error, list["ApiKey"]]]: + """List API keys for a user + + Returns all API keys owned by the specified user. Secrets are never included. + + Args: + user_name (str): Example: johndoe. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, list['ApiKey']] + """ + + return sync_detailed( + user_name=user_name, + client=client, + ).parsed + + +async def asyncio_detailed( + user_name: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Error, list["ApiKey"]]]: + """List API keys for a user + + Returns all API keys owned by the specified user. Secrets are never included. + + Args: + user_name (str): Example: johndoe. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, list['ApiKey']]] + """ + + kwargs = _get_kwargs( + user_name=user_name, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + user_name: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Error, list["ApiKey"]]]: + """List API keys for a user + + Returns all API keys owned by the specified user. Secrets are never included. + + Args: + user_name (str): Example: johndoe. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, list['ApiKey']] + """ + + return ( + await asyncio_detailed( + user_name=user_name, + client=client, + ) + ).parsed diff --git a/src/antfly/client_generated/api/cluster_management/delete_secret.py b/src/antfly/client_generated/api/cluster_management/delete_secret.py new file mode 100644 index 0000000..f89886b --- /dev/null +++ b/src/antfly/client_generated/api/cluster_management/delete_secret.py @@ -0,0 +1,177 @@ +from http import HTTPStatus +from typing import Any, Optional, Union, cast + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + key: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "delete", + "url": f"/secrets/{key}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[Any, Error]]: + if response.status_code == 204: + response_204 = cast(Any, None) + return response_204 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + + if response.status_code == 503: + response_503 = Error.from_dict(response.json()) + + return response_503 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[Any, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + key: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Any, Error]]: + """Delete a secret + + Remove a secret from the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, Error]] + """ + + kwargs = _get_kwargs( + key=key, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + key: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Any, Error]]: + """Delete a secret + + Remove a secret from the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, Error] + """ + + return sync_detailed( + key=key, + client=client, + ).parsed + + +async def asyncio_detailed( + key: str, + *, + client: AuthenticatedClient, +) -> Response[Union[Any, Error]]: + """Delete a secret + + Remove a secret from the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, Error]] + """ + + kwargs = _get_kwargs( + key=key, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + key: str, + *, + client: AuthenticatedClient, +) -> Optional[Union[Any, Error]]: + """Delete a secret + + Remove a secret from the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, Error] + """ + + return ( + await asyncio_detailed( + key=key, + client=client, + ) + ).parsed diff --git a/src/antfly/client_generated/api/cluster_management/list_secrets.py b/src/antfly/client_generated/api/cluster_management/list_secrets.py new file mode 100644 index 0000000..2110947 --- /dev/null +++ b/src/antfly/client_generated/api/cluster_management/list_secrets.py @@ -0,0 +1,150 @@ +from http import HTTPStatus +from typing import Any, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...models.secret_list import SecretList +from ...types import Response + + +def _get_kwargs() -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/secrets", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[Error, SecretList]]: + if response.status_code == 200: + response_200 = SecretList.from_dict(response.json()) + + return response_200 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[Error, SecretList]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient, +) -> Response[Union[Error, SecretList]]: + """List secrets status + + List all configured secret names and their status (keystore, env var, or both). + Never returns secret values — only names and configuration status. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, SecretList]] + """ + + kwargs = _get_kwargs() + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient, +) -> Optional[Union[Error, SecretList]]: + """List secrets status + + List all configured secret names and their status (keystore, env var, or both). + Never returns secret values — only names and configuration status. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, SecretList] + """ + + return sync_detailed( + client=client, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, +) -> Response[Union[Error, SecretList]]: + """List secrets status + + List all configured secret names and their status (keystore, env var, or both). + Never returns secret values — only names and configuration status. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, SecretList]] + """ + + kwargs = _get_kwargs() + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient, +) -> Optional[Union[Error, SecretList]]: + """List secrets status + + List all configured secret names and their status (keystore, env var, or both). + Never returns secret values — only names and configuration status. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, SecretList] + """ + + return ( + await asyncio_detailed( + client=client, + ) + ).parsed diff --git a/src/antfly/client_generated/api/cluster_management/put_secret.py b/src/antfly/client_generated/api/cluster_management/put_secret.py new file mode 100644 index 0000000..c08767a --- /dev/null +++ b/src/antfly/client_generated/api/cluster_management/put_secret.py @@ -0,0 +1,201 @@ +from http import HTTPStatus +from typing import Any, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error import Error +from ...models.secret_entry import SecretEntry +from ...models.secret_write_request import SecretWriteRequest +from ...types import Response + + +def _get_kwargs( + key: str, + *, + body: SecretWriteRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "put", + "url": f"/secrets/{key}", + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[Union[Error, SecretEntry]]: + if response.status_code == 200: + response_200 = SecretEntry.from_dict(response.json()) + + return response_200 + + if response.status_code == 400: + response_400 = Error.from_dict(response.json()) + + return response_400 + + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + + if response.status_code == 503: + response_503 = Error.from_dict(response.json()) + + return response_503 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[Union[Error, SecretEntry]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + key: str, + *, + client: AuthenticatedClient, + body: SecretWriteRequest, +) -> Response[Union[Error, SecretEntry]]: + """Store a secret + + Store a secret in the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + body (SecretWriteRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, SecretEntry]] + """ + + kwargs = _get_kwargs( + key=key, + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + key: str, + *, + client: AuthenticatedClient, + body: SecretWriteRequest, +) -> Optional[Union[Error, SecretEntry]]: + """Store a secret + + Store a secret in the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + body (SecretWriteRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, SecretEntry] + """ + + return sync_detailed( + key=key, + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + key: str, + *, + client: AuthenticatedClient, + body: SecretWriteRequest, +) -> Response[Union[Error, SecretEntry]]: + """Store a secret + + Store a secret in the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + body (SecretWriteRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Error, SecretEntry]] + """ + + kwargs = _get_kwargs( + key=key, + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + key: str, + *, + client: AuthenticatedClient, + body: SecretWriteRequest, +) -> Optional[Union[Error, SecretEntry]]: + """Store a secret + + Store a secret in the keystore. Only available in swarm (single-node) mode. + Returns 503 in multi-node mode. + + Args: + key (str): + body (SecretWriteRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Error, SecretEntry] + """ + + return ( + await asyncio_detailed( + key=key, + client=client, + body=body, + ) + ).parsed diff --git a/src/antfly/client_generated/models/__init__.py b/src/antfly/client_generated/models/__init__.py index 5d57571..c6ba23b 100644 --- a/src/antfly/client_generated/models/__init__.py +++ b/src/antfly/client_generated/models/__init__.py @@ -14,6 +14,8 @@ from .antfly_reranker_config import AntflyRerankerConfig from .antfly_type import AntflyType from .anthropic_generator_config import AnthropicGeneratorConfig +from .api_key import ApiKey +from .api_key_with_secret import ApiKeyWithSecret from .backup_info import BackupInfo from .backup_list_response import BackupListResponse from .backup_request import BackupRequest @@ -66,6 +68,7 @@ from .cohere_reranker_config import CohereRerankerConfig from .confidence_step_config import ConfidenceStepConfig from .conjunction_query import ConjunctionQuery +from .create_api_key_request import CreateApiKeyRequest from .create_table_request import CreateTableRequest from .create_table_request_indexes import CreateTableRequestIndexes from .create_user_request import CreateUserRequest @@ -223,6 +226,10 @@ from .retry_config import RetryConfig from .route_type import RouteType from .schemas_antfly_type import SchemasAntflyType +from .secret_entry import SecretEntry +from .secret_list import SecretList +from .secret_status import SecretStatus +from .secret_write_request import SecretWriteRequest from .semantic_query_mode import SemanticQueryMode from .serper_search_config import SerperSearchConfig from .serper_search_config_search_type import SerperSearchConfigSearchType @@ -292,6 +299,8 @@ "AntflyRerankerConfig", "AntflyType", "AnthropicGeneratorConfig", + "ApiKey", + "ApiKeyWithSecret", "BackupInfo", "BackupListResponse", "BackupRequest", @@ -344,6 +353,7 @@ "CohereRerankerConfig", "ConfidenceStepConfig", "ConjunctionQuery", + "CreateApiKeyRequest", "CreateTableRequest", "CreateTableRequestIndexes", "CreateUserRequest", @@ -501,6 +511,10 @@ "RetryConfig", "RouteType", "SchemasAntflyType", + "SecretEntry", + "SecretList", + "SecretStatus", + "SecretWriteRequest", "SemanticQueryMode", "SerperSearchConfig", "SerperSearchConfigSearchType", diff --git a/src/antfly/client_generated/models/api_key.py b/src/antfly/client_generated/models/api_key.py new file mode 100644 index 0000000..b2ac41f --- /dev/null +++ b/src/antfly/client_generated/models/api_key.py @@ -0,0 +1,164 @@ +import datetime +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, Union, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.permission import Permission + + +T = TypeVar("T", bound="ApiKey") + + +@_attrs_define +class ApiKey: + """Public metadata for an API key (secrets are never returned after creation). + + Attributes: + key_id (str): Unique identifier for the API key. Example: aBcDeFgHiJkLmNoPqRsT. + name (str): Human-readable name for the API key. Example: CI pipeline key. + username (str): Owner of the API key. Example: johndoe. + created_at (datetime.datetime): When the API key was created. + permissions (Union[None, Unset, list['Permission']]): Optional permission scoping. If empty, inherits owner's + full permissions. + expires_at (Union[None, Unset, datetime.datetime]): When the API key expires. Null means never. + """ + + key_id: str + name: str + username: str + created_at: datetime.datetime + permissions: Union[None, Unset, list["Permission"]] = UNSET + expires_at: Union[None, Unset, datetime.datetime] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + key_id = self.key_id + + name = self.name + + username = self.username + + created_at = self.created_at.isoformat() + + permissions: Union[None, Unset, list[dict[str, Any]]] + if isinstance(self.permissions, Unset): + permissions = UNSET + elif isinstance(self.permissions, list): + permissions = [] + for permissions_type_0_item_data in self.permissions: + permissions_type_0_item = permissions_type_0_item_data.to_dict() + permissions.append(permissions_type_0_item) + + else: + permissions = self.permissions + + expires_at: Union[None, Unset, str] + if isinstance(self.expires_at, Unset): + expires_at = UNSET + elif isinstance(self.expires_at, datetime.datetime): + expires_at = self.expires_at.isoformat() + else: + expires_at = self.expires_at + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "key_id": key_id, + "name": name, + "username": username, + "created_at": created_at, + } + ) + if permissions is not UNSET: + field_dict["permissions"] = permissions + if expires_at is not UNSET: + field_dict["expires_at"] = expires_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.permission import Permission + + d = dict(src_dict) + key_id = d.pop("key_id") + + name = d.pop("name") + + username = d.pop("username") + + created_at = isoparse(d.pop("created_at")) + + def _parse_permissions(data: object) -> Union[None, Unset, list["Permission"]]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + permissions_type_0 = [] + _permissions_type_0 = data + for permissions_type_0_item_data in _permissions_type_0: + permissions_type_0_item = Permission.from_dict(permissions_type_0_item_data) + + permissions_type_0.append(permissions_type_0_item) + + return permissions_type_0 + except: # noqa: E722 + pass + return cast(Union[None, Unset, list["Permission"]], data) + + permissions = _parse_permissions(d.pop("permissions", UNSET)) + + def _parse_expires_at(data: object) -> Union[None, Unset, datetime.datetime]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + expires_at_type_0 = isoparse(data) + + return expires_at_type_0 + except: # noqa: E722 + pass + return cast(Union[None, Unset, datetime.datetime], data) + + expires_at = _parse_expires_at(d.pop("expires_at", UNSET)) + + api_key = cls( + key_id=key_id, + name=name, + username=username, + created_at=created_at, + permissions=permissions, + expires_at=expires_at, + ) + + api_key.additional_properties = d + return api_key + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/antfly/client_generated/models/api_key_with_secret.py b/src/antfly/client_generated/models/api_key_with_secret.py new file mode 100644 index 0000000..cbbe704 --- /dev/null +++ b/src/antfly/client_generated/models/api_key_with_secret.py @@ -0,0 +1,182 @@ +import datetime +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, Union, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.permission import Permission + + +T = TypeVar("T", bound="ApiKeyWithSecret") + + +@_attrs_define +class ApiKeyWithSecret: + """API key creation response including the cleartext secret (shown once). + + Attributes: + key_id (str): Unique identifier for the API key. Example: aBcDeFgHiJkLmNoPqRsT. + name (str): Human-readable name for the API key. Example: CI pipeline key. + username (str): Owner of the API key. Example: johndoe. + created_at (datetime.datetime): When the API key was created. + key_secret (str): Cleartext secret for the API key. Store securely — it cannot be retrieved again. Example: + dGhpcyBpcyBhIHNlY3JldA. + encoded (str): Pre-encoded credential ready for the Authorization header: base64(key_id:key_secret). Example: + YUJjRGVGZ0hpSmtMbU5vUHFSc1Q6ZEdocGN5QnBjeUJoSUhObFkzSmxkQQ==. + permissions (Union[None, Unset, list['Permission']]): Optional permission scoping. If empty, inherits owner's + full permissions. + expires_at (Union[None, Unset, datetime.datetime]): When the API key expires. Null means never. + """ + + key_id: str + name: str + username: str + created_at: datetime.datetime + key_secret: str + encoded: str + permissions: Union[None, Unset, list["Permission"]] = UNSET + expires_at: Union[None, Unset, datetime.datetime] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + key_id = self.key_id + + name = self.name + + username = self.username + + created_at = self.created_at.isoformat() + + key_secret = self.key_secret + + encoded = self.encoded + + permissions: Union[None, Unset, list[dict[str, Any]]] + if isinstance(self.permissions, Unset): + permissions = UNSET + elif isinstance(self.permissions, list): + permissions = [] + for permissions_type_0_item_data in self.permissions: + permissions_type_0_item = permissions_type_0_item_data.to_dict() + permissions.append(permissions_type_0_item) + + else: + permissions = self.permissions + + expires_at: Union[None, Unset, str] + if isinstance(self.expires_at, Unset): + expires_at = UNSET + elif isinstance(self.expires_at, datetime.datetime): + expires_at = self.expires_at.isoformat() + else: + expires_at = self.expires_at + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "key_id": key_id, + "name": name, + "username": username, + "created_at": created_at, + "key_secret": key_secret, + "encoded": encoded, + } + ) + if permissions is not UNSET: + field_dict["permissions"] = permissions + if expires_at is not UNSET: + field_dict["expires_at"] = expires_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.permission import Permission + + d = dict(src_dict) + key_id = d.pop("key_id") + + name = d.pop("name") + + username = d.pop("username") + + created_at = isoparse(d.pop("created_at")) + + key_secret = d.pop("key_secret") + + encoded = d.pop("encoded") + + def _parse_permissions(data: object) -> Union[None, Unset, list["Permission"]]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + permissions_type_0 = [] + _permissions_type_0 = data + for permissions_type_0_item_data in _permissions_type_0: + permissions_type_0_item = Permission.from_dict(permissions_type_0_item_data) + + permissions_type_0.append(permissions_type_0_item) + + return permissions_type_0 + except: # noqa: E722 + pass + return cast(Union[None, Unset, list["Permission"]], data) + + permissions = _parse_permissions(d.pop("permissions", UNSET)) + + def _parse_expires_at(data: object) -> Union[None, Unset, datetime.datetime]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + expires_at_type_0 = isoparse(data) + + return expires_at_type_0 + except: # noqa: E722 + pass + return cast(Union[None, Unset, datetime.datetime], data) + + expires_at = _parse_expires_at(d.pop("expires_at", UNSET)) + + api_key_with_secret = cls( + key_id=key_id, + name=name, + username=username, + created_at=created_at, + key_secret=key_secret, + encoded=encoded, + permissions=permissions, + expires_at=expires_at, + ) + + api_key_with_secret.additional_properties = d + return api_key_with_secret + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/antfly/client_generated/models/cluster_status.py b/src/antfly/client_generated/models/cluster_status.py index 98d7262..89f0d2f 100644 --- a/src/antfly/client_generated/models/cluster_status.py +++ b/src/antfly/client_generated/models/cluster_status.py @@ -17,11 +17,13 @@ class ClusterStatus: health (ClusterHealth): Overall health status of the cluster message (Union[Unset, str]): Optional message providing details about the health status auth_enabled (Union[Unset, bool]): Indicates whether authentication is enabled for the cluster + swarm_mode (Union[Unset, bool]): Indicates whether the cluster is running in single-node swarm mode """ health: ClusterHealth message: Union[Unset, str] = UNSET auth_enabled: Union[Unset, bool] = UNSET + swarm_mode: Union[Unset, bool] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -31,6 +33,8 @@ def to_dict(self) -> dict[str, Any]: auth_enabled = self.auth_enabled + swarm_mode = self.swarm_mode + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -42,6 +46,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["message"] = message if auth_enabled is not UNSET: field_dict["auth_enabled"] = auth_enabled + if swarm_mode is not UNSET: + field_dict["swarm_mode"] = swarm_mode return field_dict @@ -54,10 +60,13 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: auth_enabled = d.pop("auth_enabled", UNSET) + swarm_mode = d.pop("swarm_mode", UNSET) + cluster_status = cls( health=health, message=message, auth_enabled=auth_enabled, + swarm_mode=swarm_mode, ) cluster_status.additional_properties = d diff --git a/src/antfly/client_generated/models/create_api_key_request.py b/src/antfly/client_generated/models/create_api_key_request.py new file mode 100644 index 0000000..bd761a1 --- /dev/null +++ b/src/antfly/client_generated/models/create_api_key_request.py @@ -0,0 +1,118 @@ +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, Union, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.permission import Permission + + +T = TypeVar("T", bound="CreateApiKeyRequest") + + +@_attrs_define +class CreateApiKeyRequest: + """Request to create a new API key. + + Attributes: + name (str): Human-readable name for the API key. Example: CI pipeline key. + expires_in (Union[Unset, str]): Duration until expiration (e.g., '720h' for 30 days). Empty means never. + Example: 720h. + permissions (Union[None, Unset, list['Permission']]): Optional permission scoping. Each permission must be a + subset of the creator's permissions. + """ + + name: str + expires_in: Union[Unset, str] = UNSET + permissions: Union[None, Unset, list["Permission"]] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + name = self.name + + expires_in = self.expires_in + + permissions: Union[None, Unset, list[dict[str, Any]]] + if isinstance(self.permissions, Unset): + permissions = UNSET + elif isinstance(self.permissions, list): + permissions = [] + for permissions_type_0_item_data in self.permissions: + permissions_type_0_item = permissions_type_0_item_data.to_dict() + permissions.append(permissions_type_0_item) + + else: + permissions = self.permissions + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "name": name, + } + ) + if expires_in is not UNSET: + field_dict["expires_in"] = expires_in + if permissions is not UNSET: + field_dict["permissions"] = permissions + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.permission import Permission + + d = dict(src_dict) + name = d.pop("name") + + expires_in = d.pop("expires_in", UNSET) + + def _parse_permissions(data: object) -> Union[None, Unset, list["Permission"]]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + permissions_type_0 = [] + _permissions_type_0 = data + for permissions_type_0_item_data in _permissions_type_0: + permissions_type_0_item = Permission.from_dict(permissions_type_0_item_data) + + permissions_type_0.append(permissions_type_0_item) + + return permissions_type_0 + except: # noqa: E722 + pass + return cast(Union[None, Unset, list["Permission"]], data) + + permissions = _parse_permissions(d.pop("permissions", UNSET)) + + create_api_key_request = cls( + name=name, + expires_in=expires_in, + permissions=permissions, + ) + + create_api_key_request.additional_properties = d + return create_api_key_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/antfly/client_generated/models/secret_entry.py b/src/antfly/client_generated/models/secret_entry.py new file mode 100644 index 0000000..6c8cf44 --- /dev/null +++ b/src/antfly/client_generated/models/secret_entry.py @@ -0,0 +1,113 @@ +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..models.secret_status import SecretStatus +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SecretEntry") + + +@_attrs_define +class SecretEntry: + """ + Attributes: + key (str): Secret name (e.g., openai.api_key) + status (SecretStatus): Source of the secret configuration + env_var (Union[Unset, str]): Corresponding environment variable name (e.g., OPENAI_API_KEY) + created_at (Union[Unset, datetime.datetime]): + updated_at (Union[Unset, datetime.datetime]): + """ + + key: str + status: SecretStatus + env_var: Union[Unset, str] = UNSET + created_at: Union[Unset, datetime.datetime] = UNSET + updated_at: Union[Unset, datetime.datetime] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + key = self.key + + status = self.status.value + + env_var = self.env_var + + created_at: Union[Unset, str] = UNSET + if not isinstance(self.created_at, Unset): + created_at = self.created_at.isoformat() + + updated_at: Union[Unset, str] = UNSET + if not isinstance(self.updated_at, Unset): + updated_at = self.updated_at.isoformat() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "key": key, + "status": status, + } + ) + if env_var is not UNSET: + field_dict["env_var"] = env_var + if created_at is not UNSET: + field_dict["created_at"] = created_at + if updated_at is not UNSET: + field_dict["updated_at"] = updated_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + key = d.pop("key") + + status = SecretStatus(d.pop("status")) + + env_var = d.pop("env_var", UNSET) + + _created_at = d.pop("created_at", UNSET) + created_at: Union[Unset, datetime.datetime] + if isinstance(_created_at, Unset): + created_at = UNSET + else: + created_at = isoparse(_created_at) + + _updated_at = d.pop("updated_at", UNSET) + updated_at: Union[Unset, datetime.datetime] + if isinstance(_updated_at, Unset): + updated_at = UNSET + else: + updated_at = isoparse(_updated_at) + + secret_entry = cls( + key=key, + status=status, + env_var=env_var, + created_at=created_at, + updated_at=updated_at, + ) + + secret_entry.additional_properties = d + return secret_entry + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/antfly/client_generated/models/secret_list.py b/src/antfly/client_generated/models/secret_list.py new file mode 100644 index 0000000..7cd04f8 --- /dev/null +++ b/src/antfly/client_generated/models/secret_list.py @@ -0,0 +1,73 @@ +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +if TYPE_CHECKING: + from ..models.secret_entry import SecretEntry + + +T = TypeVar("T", bound="SecretList") + + +@_attrs_define +class SecretList: + """ + Attributes: + secrets (list['SecretEntry']): + """ + + secrets: list["SecretEntry"] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + secrets = [] + for secrets_item_data in self.secrets: + secrets_item = secrets_item_data.to_dict() + secrets.append(secrets_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "secrets": secrets, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.secret_entry import SecretEntry + + d = dict(src_dict) + secrets = [] + _secrets = d.pop("secrets") + for secrets_item_data in _secrets: + secrets_item = SecretEntry.from_dict(secrets_item_data) + + secrets.append(secrets_item) + + secret_list = cls( + secrets=secrets, + ) + + secret_list.additional_properties = d + return secret_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/antfly/client_generated/models/secret_status.py b/src/antfly/client_generated/models/secret_status.py new file mode 100644 index 0000000..a272f0f --- /dev/null +++ b/src/antfly/client_generated/models/secret_status.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class SecretStatus(str, Enum): + CONFIGURED_BOTH = "configured_both" + CONFIGURED_ENV = "configured_env" + CONFIGURED_KEYSTORE = "configured_keystore" + + def __str__(self) -> str: + return str(self.value) diff --git a/src/antfly/client_generated/models/secret_write_request.py b/src/antfly/client_generated/models/secret_write_request.py new file mode 100644 index 0000000..4cc2285 --- /dev/null +++ b/src/antfly/client_generated/models/secret_write_request.py @@ -0,0 +1,59 @@ +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="SecretWriteRequest") + + +@_attrs_define +class SecretWriteRequest: + """ + Attributes: + value (str): Secret value (stored encrypted, never returned) + """ + + value: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + value = self.value + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "value": value, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + value = d.pop("value") + + secret_write_request = cls( + value=value, + ) + + secret_write_request.additional_properties = d + return secret_write_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties