diff --git a/agenta-backend/agenta_backend/tests/conftest.py b/agenta-backend/agenta_backend/tests/conftest.py index 36866f2d45..22f08588aa 100644 --- a/agenta-backend/agenta_backend/tests/conftest.py +++ b/agenta-backend/agenta_backend/tests/conftest.py @@ -1,7 +1,10 @@ import pytest import asyncio -from agenta_backend.tests.engine import test_db_engine as db_engine +from agenta_backend.utils.common import isOss + +if isOss(): + from agenta_backend.tests.engine import test_db_engine as db_engine @pytest.fixture(scope="session", autouse=True) @@ -17,6 +20,8 @@ def event_loop(): yield res - res.run_until_complete(db_engine.remove_db()) # drop database - res.run_until_complete(db_engine.close_db()) # close connections to database + if isOss(): + res.run_until_complete(db_engine.remove_db()) # drop database + res.run_until_complete(db_engine.close_db()) # close connections to database + res._close() # close event loop # type: ignore diff --git a/agenta-cli/agenta/client/backend/__init__.py b/agenta-cli/agenta/client/backend/__init__.py index 8907b11d29..ad2226148b 100644 --- a/agenta-cli/agenta/client/backend/__init__.py +++ b/agenta-cli/agenta/client/backend/__init__.py @@ -10,11 +10,13 @@ AgentaTreesResponse, AggregatedResult, AggregatedResultEvaluatorConfig, + AnalyticsResponse, App, AppVariantResponse, AppVariantRevision, BaseOutput, BodyImportTestset, + BucketDto, CollectStatusResponse, ConfigDb, ConfigDto, @@ -42,6 +44,7 @@ EvaluatorOutputInterface, ExceptionDto, GetConfigResponse, + HeaderDto, HttpValidationError, HumanEvaluation, HumanEvaluationScenario, @@ -51,12 +54,14 @@ HumanEvaluationUpdate, Image, InviteRequest, + LegacyAnalyticsResponse, + LegacyDataPoint, LifecycleDto, LinkDto, ListApiKeysResponse, LlmRunRateLimit, LlmTokens, - LmProvidersEnum, + MetricsDto, NewHumanEvaluation, NewTestset, NodeDto, @@ -74,11 +79,17 @@ Outputs, ParentDto, Permission, + ProjectsResponse, + ProviderKeyDto, + ProviderKind, ReferenceDto, ReferenceRequestModel, Result, RootDto, Score, + SecretDto, + SecretKind, + SecretResponseDto, SimpleEvaluationOutput, Span, SpanDetail, @@ -111,6 +122,7 @@ ) from .errors import UnprocessableEntityError from . import ( + access_control, apps, bases, configs, @@ -120,12 +132,14 @@ evaluators, observability, observability_v_1, + scopes, testsets, variants, + vault, ) from .client import AgentaApi, AsyncAgentaApi from .containers import ContainerTemplatesResponse -from .observability_v_1 import Format, QueryTracesResponse +from .observability_v_1 import Format, QueryAnalyticsResponse, QueryTracesResponse from .variants import AddVariantFromBaseAndConfigResponse __all__ = [ @@ -140,12 +154,14 @@ "AgentaTreesResponse", "AggregatedResult", "AggregatedResultEvaluatorConfig", + "AnalyticsResponse", "App", "AppVariantResponse", "AppVariantRevision", "AsyncAgentaApi", "BaseOutput", "BodyImportTestset", + "BucketDto", "CollectStatusResponse", "ConfigDb", "ConfigDto", @@ -175,6 +191,7 @@ "ExceptionDto", "Format", "GetConfigResponse", + "HeaderDto", "HttpValidationError", "HumanEvaluation", "HumanEvaluationScenario", @@ -184,12 +201,14 @@ "HumanEvaluationUpdate", "Image", "InviteRequest", + "LegacyAnalyticsResponse", + "LegacyDataPoint", "LifecycleDto", "LinkDto", "ListApiKeysResponse", "LlmRunRateLimit", "LlmTokens", - "LmProvidersEnum", + "MetricsDto", "NewHumanEvaluation", "NewTestset", "NodeDto", @@ -207,12 +226,19 @@ "Outputs", "ParentDto", "Permission", + "ProjectsResponse", + "ProviderKeyDto", + "ProviderKind", + "QueryAnalyticsResponse", "QueryTracesResponse", "ReferenceDto", "ReferenceRequestModel", "Result", "RootDto", "Score", + "SecretDto", + "SecretKind", + "SecretResponseDto", "SimpleEvaluationOutput", "Span", "SpanDetail", @@ -243,6 +269,7 @@ "WorkspaceResponse", "WorkspaceRole", "WorkspaceRoleResponse", + "access_control", "apps", "bases", "configs", @@ -252,6 +279,8 @@ "evaluators", "observability", "observability_v_1", + "scopes", "testsets", "variants", + "vault", ] diff --git a/agenta-cli/agenta/client/backend/access_control/__init__.py b/agenta-cli/agenta/client/backend/access_control/__init__.py new file mode 100644 index 0000000000..67a41b2742 --- /dev/null +++ b/agenta-cli/agenta/client/backend/access_control/__init__.py @@ -0,0 +1 @@ +# This file was auto-generated by Fern from our API Definition. diff --git a/agenta-cli/agenta/client/backend/access_control/client.py b/agenta-cli/agenta/client/backend/access_control/client.py new file mode 100644 index 0000000000..0a23474e41 --- /dev/null +++ b/agenta-cli/agenta/client/backend/access_control/client.py @@ -0,0 +1,167 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.client_wrapper import SyncClientWrapper +import typing +from ..core.request_options import RequestOptions +from ..core.pydantic_utilities import parse_obj_as +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.http_validation_error import HttpValidationError +from json.decoder import JSONDecodeError +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper + + +class AccessControlClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def verify_permissions( + self, + *, + action: typing.Optional[str] = None, + resource_type: typing.Optional[str] = None, + resource_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[typing.Any]: + """ + Parameters + ---------- + action : typing.Optional[str] + + resource_type : typing.Optional[str] + + resource_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[typing.Any] + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.access_control.verify_permissions() + """ + _response = self._client_wrapper.httpx_client.request( + "permissions/verify", + method="GET", + params={ + "action": action, + "resource_type": resource_type, + "resource_id": resource_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncAccessControlClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def verify_permissions( + self, + *, + action: typing.Optional[str] = None, + resource_type: typing.Optional[str] = None, + resource_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[typing.Any]: + """ + Parameters + ---------- + action : typing.Optional[str] + + resource_type : typing.Optional[str] + + resource_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[typing.Any] + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.access_control.verify_permissions() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "permissions/verify", + method="GET", + params={ + "action": action, + "resource_type": resource_type, + "resource_id": resource_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/agenta-cli/agenta/client/backend/apps/client.py b/agenta-cli/agenta/client/backend/apps/client.py index b709a8538e..b85b34d6cf 100644 --- a/agenta-cli/agenta/client/backend/apps/client.py +++ b/agenta-cli/agenta/client/backend/apps/client.py @@ -216,7 +216,9 @@ def list_apps( _response = self._client_wrapper.httpx_client.request( "apps", method="GET", - params={"app_name": app_name}, + params={ + "app_name": app_name, + }, request_options=request_options, ) try: @@ -248,13 +250,15 @@ def create_app( *, app_name: str, project_id: typing.Optional[str] = OMIT, + workspace_id: typing.Optional[str] = OMIT, + organization_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CreateAppOutput: """ - Create a new app for a user. + Create a new app for a user or organization. Args: - payload (CreateApp): The payload containing the app name. + payload (CreateApp): The payload containing the app name and organization ID (optional). stoken_session (SessionContainer): The session container containing the user's session token. Returns: @@ -269,6 +273,10 @@ def create_app( project_id : typing.Optional[str] + workspace_id : typing.Optional[str] + + organization_id : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -295,6 +303,11 @@ def create_app( json={ "app_name": app_name, "project_id": project_id, + "workspace_id": workspace_id, + "organization_id": organization_id, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -393,7 +406,7 @@ def update_app( request_options: typing.Optional[RequestOptions] = None, ) -> UpdateAppOutput: """ - Update an app for a user. + Update an app for a user or organization. Args: app_id (str): The ID of the app. @@ -439,6 +452,9 @@ def update_app( json={ "app_name": app_name, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -538,6 +554,9 @@ def add_variant_from_image( "base_name": base_name, "config_name": config_name, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -572,6 +591,8 @@ def create_app_and_variant_from_template( template_id: str, env_vars: typing.Dict[str, str], project_id: typing.Optional[str] = OMIT, + workspace_id: typing.Optional[str] = OMIT, + organization_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AppVariantResponse: """ @@ -597,6 +618,10 @@ def create_app_and_variant_from_template( project_id : typing.Optional[str] + workspace_id : typing.Optional[str] + + organization_id : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -626,7 +651,12 @@ def create_app_and_variant_from_template( "app_name": app_name, "template_id": template_id, "project_id": project_id, + "workspace_id": workspace_id, "env_vars": env_vars, + "organization_id": organization_id, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -752,7 +782,7 @@ def environment_revisions( base_url="https://yourhost.com/path/to/api", ) client.apps.environment_revisions( - app_id="string", + app_id="app_id", environment_name={"key": "value"}, ) """ @@ -1005,7 +1035,9 @@ async def main() -> None: _response = await self._client_wrapper.httpx_client.request( "apps", method="GET", - params={"app_name": app_name}, + params={ + "app_name": app_name, + }, request_options=request_options, ) try: @@ -1037,13 +1069,15 @@ async def create_app( *, app_name: str, project_id: typing.Optional[str] = OMIT, + workspace_id: typing.Optional[str] = OMIT, + organization_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CreateAppOutput: """ - Create a new app for a user. + Create a new app for a user or organization. Args: - payload (CreateApp): The payload containing the app name. + payload (CreateApp): The payload containing the app name and organization ID (optional). stoken_session (SessionContainer): The session container containing the user's session token. Returns: @@ -1058,6 +1092,10 @@ async def create_app( project_id : typing.Optional[str] + workspace_id : typing.Optional[str] + + organization_id : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1092,6 +1130,11 @@ async def main() -> None: json={ "app_name": app_name, "project_id": project_id, + "workspace_id": workspace_id, + "organization_id": organization_id, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -1198,7 +1241,7 @@ async def update_app( request_options: typing.Optional[RequestOptions] = None, ) -> UpdateAppOutput: """ - Update an app for a user. + Update an app for a user or organization. Args: app_id (str): The ID of the app. @@ -1252,6 +1295,9 @@ async def main() -> None: json={ "app_name": app_name, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1359,6 +1405,9 @@ async def main() -> None: "base_name": base_name, "config_name": config_name, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1393,6 +1442,8 @@ async def create_app_and_variant_from_template( template_id: str, env_vars: typing.Dict[str, str], project_id: typing.Optional[str] = OMIT, + workspace_id: typing.Optional[str] = OMIT, + organization_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AppVariantResponse: """ @@ -1418,6 +1469,10 @@ async def create_app_and_variant_from_template( project_id : typing.Optional[str] + workspace_id : typing.Optional[str] + + organization_id : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1455,7 +1510,12 @@ async def main() -> None: "app_name": app_name, "template_id": template_id, "project_id": project_id, + "workspace_id": workspace_id, "env_vars": env_vars, + "organization_id": organization_id, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -1594,7 +1654,7 @@ async def environment_revisions( async def main() -> None: await client.apps.environment_revisions( - app_id="string", + app_id="app_id", environment_name={"key": "value"}, ) diff --git a/agenta-cli/agenta/client/backend/client.py b/agenta-cli/agenta/client/backend/client.py index 9fc9784d8a..2f022a7f4b 100644 --- a/agenta-cli/agenta/client/backend/client.py +++ b/agenta-cli/agenta/client/backend/client.py @@ -4,6 +4,9 @@ import httpx from .core.client_wrapper import SyncClientWrapper from .observability.client import ObservabilityClient +from .vault.client import VaultClient +from .access_control.client import AccessControlClient +from .scopes.client import ScopesClient from .apps.client import AppsClient from .variants.client import VariantsClient from .evaluations.client import EvaluationsClient @@ -19,9 +22,9 @@ from .core.pydantic_utilities import parse_obj_as from json.decoder import JSONDecodeError from .core.api_error import ApiError +from .core.jsonable_encoder import jsonable_encoder from .errors.unprocessable_entity_error import UnprocessableEntityError from .types.http_validation_error import HttpValidationError -from .core.jsonable_encoder import jsonable_encoder from .types.organization import Organization from .types.organization_output import OrganizationOutput from .types.invite_request import InviteRequest @@ -32,6 +35,9 @@ from .types.permission import Permission from .core.client_wrapper import AsyncClientWrapper from .observability.client import AsyncObservabilityClient +from .vault.client import AsyncVaultClient +from .access_control.client import AsyncAccessControlClient +from .scopes.client import AsyncScopesClient from .apps.client import AsyncAppsClient from .variants.client import AsyncVariantsClient from .evaluations.client import AsyncEvaluationsClient @@ -101,6 +107,9 @@ def __init__( timeout=_defaulted_timeout, ) self.observability = ObservabilityClient(client_wrapper=self._client_wrapper) + self.vault = VaultClient(client_wrapper=self._client_wrapper) + self.access_control = AccessControlClient(client_wrapper=self._client_wrapper) + self.scopes = ScopesClient(client_wrapper=self._client_wrapper) self.apps = AppsClient(client_wrapper=self._client_wrapper) self.variants = VariantsClient(client_wrapper=self._client_wrapper) self.evaluations = EvaluationsClient(client_wrapper=self._client_wrapper) @@ -166,10 +175,7 @@ def list_api_keys( raise ApiError(status_code=_response.status_code, body=_response_json) def create_api_key( - self, - *, - workspace_id: str, - request_options: typing.Optional[RequestOptions] = None, + self, *, request_options: typing.Optional[RequestOptions] = None ) -> str: """ Creates an API key for a user. @@ -182,8 +188,6 @@ def create_api_key( Parameters ---------- - workspace_id : str - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -200,16 +204,11 @@ def create_api_key( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.create_api_key( - workspace_id="workspace_id", - ) + client.create_api_key() """ _response = self._client_wrapper.httpx_client.request( "keys", method="POST", - params={ - "workspace_id": workspace_id, - }, request_options=request_options, ) try: @@ -221,16 +220,6 @@ def create_api_key( object_=_response.json(), ), ) - if _response.status_code == 422: - raise UnprocessableEntityError( - typing.cast( - HttpValidationError, - parse_obj_as( - type_=HttpValidationError, # type: ignore - object_=_response.json(), - ), - ) - ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) @@ -476,6 +465,9 @@ def create_organization( "description": description, "type": type, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -660,6 +652,9 @@ def update_organization( "description": description, "updated_at": updated_at, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -821,6 +816,9 @@ def resend_invitation( json={ "email": email, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -910,6 +908,9 @@ def accept_invitation( json={ "token": token, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -986,6 +987,9 @@ def create_workspace( "description": description, "type": type, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1065,6 +1069,9 @@ def update_workspace( "description": description, "updated_at": updated_at, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1262,6 +1269,9 @@ def assign_role_to_user( "organization_id": organization_id, "role": role, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1632,6 +1642,11 @@ def __init__( self.observability = AsyncObservabilityClient( client_wrapper=self._client_wrapper ) + self.vault = AsyncVaultClient(client_wrapper=self._client_wrapper) + self.access_control = AsyncAccessControlClient( + client_wrapper=self._client_wrapper + ) + self.scopes = AsyncScopesClient(client_wrapper=self._client_wrapper) self.apps = AsyncAppsClient(client_wrapper=self._client_wrapper) self.variants = AsyncVariantsClient(client_wrapper=self._client_wrapper) self.evaluations = AsyncEvaluationsClient(client_wrapper=self._client_wrapper) @@ -1705,10 +1720,7 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response_json) async def create_api_key( - self, - *, - workspace_id: str, - request_options: typing.Optional[RequestOptions] = None, + self, *, request_options: typing.Optional[RequestOptions] = None ) -> str: """ Creates an API key for a user. @@ -1721,8 +1733,6 @@ async def create_api_key( Parameters ---------- - workspace_id : str - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1744,9 +1754,7 @@ async def create_api_key( async def main() -> None: - await client.create_api_key( - workspace_id="workspace_id", - ) + await client.create_api_key() asyncio.run(main()) @@ -1754,9 +1762,6 @@ async def main() -> None: _response = await self._client_wrapper.httpx_client.request( "keys", method="POST", - params={ - "workspace_id": workspace_id, - }, request_options=request_options, ) try: @@ -1768,16 +1773,6 @@ async def main() -> None: object_=_response.json(), ), ) - if _response.status_code == 422: - raise UnprocessableEntityError( - typing.cast( - HttpValidationError, - parse_obj_as( - type_=HttpValidationError, # type: ignore - object_=_response.json(), - ), - ) - ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) @@ -2055,6 +2050,9 @@ async def main() -> None: "description": description, "type": type, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2263,6 +2261,9 @@ async def main() -> None: "description": description, "updated_at": updated_at, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2440,6 +2441,9 @@ async def main() -> None: json={ "email": email, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2537,6 +2541,9 @@ async def main() -> None: json={ "token": token, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2621,6 +2628,9 @@ async def main() -> None: "description": description, "type": type, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2708,6 +2718,9 @@ async def main() -> None: "description": description, "updated_at": updated_at, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2929,6 +2942,9 @@ async def main() -> None: "organization_id": organization_id, "role": role, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/configs/client.py b/agenta-cli/agenta/client/backend/configs/client.py index e034ff37b0..ab54844eb9 100644 --- a/agenta-cli/agenta/client/backend/configs/client.py +++ b/agenta-cli/agenta/client/backend/configs/client.py @@ -143,6 +143,9 @@ def save_config( "parameters": parameters, "overwrite": overwrite, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -434,6 +437,9 @@ async def main() -> None: "parameters": parameters, "overwrite": overwrite, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/containers/client.py b/agenta-cli/agenta/client/backend/containers/client.py index c7180c0a4b..0b62a90e86 100644 --- a/agenta-cli/agenta/client/backend/containers/client.py +++ b/agenta-cli/agenta/client/backend/containers/client.py @@ -156,6 +156,9 @@ def restart_container( json={ "variant_id": variant_id, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -468,6 +471,9 @@ async def main() -> None: json={ "variant_id": variant_id, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/core/file.py b/agenta-cli/agenta/client/backend/core/file.py index a9623d336a..3467175cb7 100644 --- a/agenta-cli/agenta/client/backend/core/file.py +++ b/agenta-cli/agenta/client/backend/core/file.py @@ -43,23 +43,28 @@ def convert_file_dict_to_httpx_tuples( return httpx_tuples -def with_content_type(*, file: File, content_type: str) -> File: - """ """ +def with_content_type(*, file: File, default_content_type: str) -> File: + """ + This function resolves to the file's content type, if provided, and defaults + to the default_content_type value if not. + """ if isinstance(file, tuple): if len(file) == 2: filename, content = cast(Tuple[Optional[str], FileContent], file) # type: ignore - return (filename, content, content_type) + return (filename, content, default_content_type) elif len(file) == 3: - filename, content, _ = cast( + filename, content, file_content_type = cast( Tuple[Optional[str], FileContent, Optional[str]], file ) # type: ignore - return (filename, content, content_type) + out_content_type = file_content_type or default_content_type + return (filename, content, out_content_type) elif len(file) == 4: - filename, content, _, headers = cast( # type: ignore + filename, content, file_content_type, headers = cast( # type: ignore Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], file, ) - return (filename, content, content_type, headers) + out_content_type = file_content_type or default_content_type + return (filename, content, out_content_type, headers) else: raise ValueError(f"Unexpected tuple length: {len(file)}") - return (None, file, content_type) + return (None, file, default_content_type) diff --git a/agenta-cli/agenta/client/backend/environments/client.py b/agenta-cli/agenta/client/backend/environments/client.py index 1cfbb07010..f9cc94afa7 100644 --- a/agenta-cli/agenta/client/backend/environments/client.py +++ b/agenta-cli/agenta/client/backend/environments/client.py @@ -70,6 +70,9 @@ def deploy_to_environment( "environment_name": environment_name, "variant_id": variant_id, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -162,6 +165,9 @@ async def main() -> None: "environment_name": environment_name, "variant_id": variant_id, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/evaluations/client.py b/agenta-cli/agenta/client/backend/evaluations/client.py index a8190dd1f2..c8f39d56f2 100644 --- a/agenta-cli/agenta/client/backend/evaluations/client.py +++ b/agenta-cli/agenta/client/backend/evaluations/client.py @@ -34,6 +34,7 @@ def fetch_evaluation_ids( Fetches evaluation ids for a given resource type and id. Arguments: + app_id (str): The ID of the app for which to fetch evaluations. resource_type (str): The type of resource for which to fetch evaluations. resource_ids List[ObjectId]: The IDs of resource for which to fetch evaluations. @@ -250,6 +251,9 @@ def create_evaluation( "lm_providers_keys": lm_providers_keys, "correct_answer_column": correct_answer_column, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -322,6 +326,9 @@ def delete_evaluations( json={ "evaluations_ids": evaluations_ids, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -716,6 +723,7 @@ async def fetch_evaluation_ids( Fetches evaluation ids for a given resource type and id. Arguments: + app_id (str): The ID of the app for which to fetch evaluations. resource_type (str): The type of resource for which to fetch evaluations. resource_ids List[ObjectId]: The IDs of resource for which to fetch evaluations. @@ -727,7 +735,6 @@ async def fetch_evaluation_ids( Parameters ---------- - resource_type : str resource_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] @@ -957,6 +964,9 @@ async def main() -> None: "lm_providers_keys": lm_providers_keys, "correct_answer_column": correct_answer_column, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1037,6 +1047,9 @@ async def main() -> None: json={ "evaluations_ids": evaluations_ids, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/evaluators/client.py b/agenta-cli/agenta/client/backend/evaluators/client.py index 29bafb0305..bad5cab677 100644 --- a/agenta-cli/agenta/client/backend/evaluators/client.py +++ b/agenta-cli/agenta/client/backend/evaluators/client.py @@ -122,6 +122,9 @@ def evaluator_data_map( "inputs": inputs, "mapping": mapping, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -209,6 +212,9 @@ def evaluator_run( "settings": settings, "credentials": credentials, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -364,6 +370,9 @@ def create_new_evaluator_config( "evaluator_key": evaluator_key, "settings_values": settings_values, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -511,6 +520,9 @@ def update_evaluator_config( "evaluator_key": evaluator_key, "settings_values": settings_values, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -726,6 +738,9 @@ async def main() -> None: "inputs": inputs, "mapping": mapping, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -821,6 +836,9 @@ async def main() -> None: "settings": settings, "credentials": credentials, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -992,6 +1010,9 @@ async def main() -> None: "evaluator_key": evaluator_key, "settings_values": settings_values, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1155,6 +1176,9 @@ async def main() -> None: "evaluator_key": evaluator_key, "settings_values": settings_values, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/observability/client.py b/agenta-cli/agenta/client/backend/observability/client.py index aebe134924..dbce982f6b 100644 --- a/agenta-cli/agenta/client/backend/observability/client.py +++ b/agenta-cli/agenta/client/backend/observability/client.py @@ -66,7 +66,7 @@ def dashboard( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/dashboard/", + "observability/dashboard", method="GET", params={ "app_id": app_id, @@ -152,7 +152,7 @@ def create_traces( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/trace/", + "observability/trace", method="POST", json={ "trace": trace, @@ -162,6 +162,9 @@ def create_traces( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -242,7 +245,7 @@ def get_traces( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/traces/", + "observability/traces", method="GET", params={ "app_id": app_id, @@ -312,7 +315,7 @@ def delete_traces_legacy( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/traces/", + "observability/traces", method="DELETE", json=request, request_options=request_options, @@ -371,7 +374,7 @@ def get_trace_detail( ) """ _response = self._client_wrapper.httpx_client.request( - f"observability/traces/{jsonable_encoder(trace_id)}/", + f"observability/traces/{jsonable_encoder(trace_id)}", method="GET", request_options=request_options, ) @@ -452,7 +455,7 @@ def get_spans_of_generation( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/spans/", + "observability/spans", method="GET", params={ "app_id": app_id, @@ -522,7 +525,7 @@ def delete_spans_of_trace( ) """ _response = self._client_wrapper.httpx_client.request( - "observability/spans/", + "observability/spans", method="DELETE", json=request, request_options=request_options, @@ -587,7 +590,7 @@ def get_span_of_generation( ) """ _response = self._client_wrapper.httpx_client.request( - f"observability/spans/{jsonable_encoder(span_id)}/", + f"observability/spans/{jsonable_encoder(span_id)}", method="GET", params={ "type": type, @@ -672,7 +675,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/dashboard/", + "observability/dashboard", method="GET", params={ "app_id": app_id, @@ -765,7 +768,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/trace/", + "observability/trace", method="POST", json={ "trace": trace, @@ -775,6 +778,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -863,7 +869,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/traces/", + "observability/traces", method="GET", params={ "app_id": app_id, @@ -941,7 +947,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/traces/", + "observability/traces", method="DELETE", json=request, request_options=request_options, @@ -1008,7 +1014,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"observability/traces/{jsonable_encoder(trace_id)}/", + f"observability/traces/{jsonable_encoder(trace_id)}", method="GET", request_options=request_options, ) @@ -1097,7 +1103,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/spans/", + "observability/spans", method="GET", params={ "app_id": app_id, @@ -1175,7 +1181,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "observability/spans/", + "observability/spans", method="DELETE", json=request, request_options=request_options, @@ -1248,7 +1254,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"observability/spans/{jsonable_encoder(span_id)}/", + f"observability/spans/{jsonable_encoder(span_id)}", method="GET", params={ "type": type, diff --git a/agenta-cli/agenta/client/backend/observability_v_1/__init__.py b/agenta-cli/agenta/client/backend/observability_v_1/__init__.py index aceeca0c75..780ddec649 100644 --- a/agenta-cli/agenta/client/backend/observability_v_1/__init__.py +++ b/agenta-cli/agenta/client/backend/observability_v_1/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import Format, QueryTracesResponse +from .types import Format, QueryAnalyticsResponse, QueryTracesResponse -__all__ = ["Format", "QueryTracesResponse"] +__all__ = ["Format", "QueryAnalyticsResponse", "QueryTracesResponse"] diff --git a/agenta-cli/agenta/client/backend/observability_v_1/client.py b/agenta-cli/agenta/client/backend/observability_v_1/client.py index 5fa38f8c3c..ce252ea18b 100644 --- a/agenta-cli/agenta/client/backend/observability_v_1/client.py +++ b/agenta-cli/agenta/client/backend/observability_v_1/client.py @@ -11,6 +11,7 @@ from .types.query_traces_response import QueryTracesResponse from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..types.http_validation_error import HttpValidationError +from .types.query_analytics_response import QueryAnalyticsResponse from ..core.client_wrapper import AsyncClientWrapper @@ -270,6 +271,103 @@ def delete_traces( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def query_analytics( + self, + *, + format: typing.Optional[Format] = None, + focus: typing.Optional[str] = None, + oldest: typing.Optional[str] = None, + newest: typing.Optional[str] = None, + window: typing.Optional[int] = None, + filtering: typing.Optional[str] = None, + time_range: typing.Optional[str] = None, + app_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, + variant: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> QueryAnalyticsResponse: + """ + Parameters + ---------- + format : typing.Optional[Format] + + focus : typing.Optional[str] + + oldest : typing.Optional[str] + + newest : typing.Optional[str] + + window : typing.Optional[int] + + filtering : typing.Optional[str] + + time_range : typing.Optional[str] + + app_id : typing.Optional[str] + + environment : typing.Optional[str] + + variant : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + QueryAnalyticsResponse + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.observability_v_1.query_analytics() + """ + _response = self._client_wrapper.httpx_client.request( + "observability/v1/analytics", + method="GET", + params={ + "format": format, + "focus": focus, + "oldest": oldest, + "newest": newest, + "window": window, + "filtering": filtering, + "timeRange": time_range, + "app_id": app_id, + "environment": environment, + "variant": variant, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + QueryAnalyticsResponse, + parse_obj_as( + type_=QueryAnalyticsResponse, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + class AsyncObservabilityV1Client: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -558,3 +656,108 @@ async def main() -> None: except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + + async def query_analytics( + self, + *, + format: typing.Optional[Format] = None, + focus: typing.Optional[str] = None, + oldest: typing.Optional[str] = None, + newest: typing.Optional[str] = None, + window: typing.Optional[int] = None, + filtering: typing.Optional[str] = None, + time_range: typing.Optional[str] = None, + app_id: typing.Optional[str] = None, + environment: typing.Optional[str] = None, + variant: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> QueryAnalyticsResponse: + """ + Parameters + ---------- + format : typing.Optional[Format] + + focus : typing.Optional[str] + + oldest : typing.Optional[str] + + newest : typing.Optional[str] + + window : typing.Optional[int] + + filtering : typing.Optional[str] + + time_range : typing.Optional[str] + + app_id : typing.Optional[str] + + environment : typing.Optional[str] + + variant : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + QueryAnalyticsResponse + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.observability_v_1.query_analytics() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "observability/v1/analytics", + method="GET", + params={ + "format": format, + "focus": focus, + "oldest": oldest, + "newest": newest, + "window": window, + "filtering": filtering, + "timeRange": time_range, + "app_id": app_id, + "environment": environment, + "variant": variant, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + QueryAnalyticsResponse, + parse_obj_as( + type_=QueryAnalyticsResponse, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/agenta-cli/agenta/client/backend/observability_v_1/types/__init__.py b/agenta-cli/agenta/client/backend/observability_v_1/types/__init__.py index 7303a90f08..bf6cbe689d 100644 --- a/agenta-cli/agenta/client/backend/observability_v_1/types/__init__.py +++ b/agenta-cli/agenta/client/backend/observability_v_1/types/__init__.py @@ -1,6 +1,7 @@ # This file was auto-generated by Fern from our API Definition. from .format import Format +from .query_analytics_response import QueryAnalyticsResponse from .query_traces_response import QueryTracesResponse -__all__ = ["Format", "QueryTracesResponse"] +__all__ = ["Format", "QueryAnalyticsResponse", "QueryTracesResponse"] diff --git a/agenta-cli/agenta/client/backend/observability_v_1/types/format.py b/agenta-cli/agenta/client/backend/observability_v_1/types/format.py index ed6f7db216..b3b01bea42 100644 --- a/agenta-cli/agenta/client/backend/observability_v_1/types/format.py +++ b/agenta-cli/agenta/client/backend/observability_v_1/types/format.py @@ -2,4 +2,4 @@ import typing -Format = typing.Union[typing.Literal["opentelemetry", "agenta"], typing.Any] +Format = typing.Union[typing.Literal["legacy", "agenta"], typing.Any] diff --git a/agenta-cli/agenta/client/backend/observability_v_1/types/query_analytics_response.py b/agenta-cli/agenta/client/backend/observability_v_1/types/query_analytics_response.py new file mode 100644 index 0000000000..ada2858ab8 --- /dev/null +++ b/agenta-cli/agenta/client/backend/observability_v_1/types/query_analytics_response.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from ...types.legacy_analytics_response import LegacyAnalyticsResponse +from ...types.analytics_response import AnalyticsResponse + +QueryAnalyticsResponse = typing.Union[LegacyAnalyticsResponse, AnalyticsResponse] diff --git a/agenta-cli/agenta/client/backend/scopes/__init__.py b/agenta-cli/agenta/client/backend/scopes/__init__.py new file mode 100644 index 0000000000..67a41b2742 --- /dev/null +++ b/agenta-cli/agenta/client/backend/scopes/__init__.py @@ -0,0 +1 @@ +# This file was auto-generated by Fern from our API Definition. diff --git a/agenta-cli/agenta/client/backend/scopes/client.py b/agenta-cli/agenta/client/backend/scopes/client.py new file mode 100644 index 0000000000..7c437da103 --- /dev/null +++ b/agenta-cli/agenta/client/backend/scopes/client.py @@ -0,0 +1,114 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.client_wrapper import SyncClientWrapper +import typing +from ..core.request_options import RequestOptions +from ..types.projects_response import ProjectsResponse +from ..core.pydantic_utilities import parse_obj_as +from json.decoder import JSONDecodeError +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper + + +class ScopesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get_projects( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[ProjectsResponse]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[ProjectsResponse] + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.scopes.get_projects() + """ + _response = self._client_wrapper.httpx_client.request( + "projects", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[ProjectsResponse], + parse_obj_as( + type_=typing.List[ProjectsResponse], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncScopesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get_projects( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[ProjectsResponse]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[ProjectsResponse] + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.scopes.get_projects() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "projects", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[ProjectsResponse], + parse_obj_as( + type_=typing.List[ProjectsResponse], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/agenta-cli/agenta/client/backend/testsets/client.py b/agenta-cli/agenta/client/backend/testsets/client.py index fc10205700..091705f1ef 100644 --- a/agenta-cli/agenta/client/backend/testsets/client.py +++ b/agenta-cli/agenta/client/backend/testsets/client.py @@ -10,8 +10,8 @@ from ..types.http_validation_error import HttpValidationError from json.decoder import JSONDecodeError from ..core.api_error import ApiError -from ..core.jsonable_encoder import jsonable_encoder from ..types.test_set_output_response import TestSetOutputResponse +from ..core.jsonable_encoder import jsonable_encoder from ..core.client_wrapper import AsyncClientWrapper # this is used as the default value for optional parameters @@ -106,7 +106,11 @@ def upload_file( raise ApiError(status_code=_response.status_code, body=_response_json) def import_testset( - self, *, request_options: typing.Optional[RequestOptions] = None + self, + *, + endpoint: typing.Optional[str] = OMIT, + testset_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> TestSetSimpleResponse: """ Import JSON testset data from an endpoint and save it to MongoDB. @@ -120,6 +124,10 @@ def import_testset( Parameters ---------- + endpoint : typing.Optional[str] + + testset_name : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -141,7 +149,12 @@ def import_testset( _response = self._client_wrapper.httpx_client.request( "testsets/endpoint", method="POST", + json={ + "endpoint": endpoint, + "testset_name": testset_name, + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: @@ -167,6 +180,59 @@ def import_testset( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def get_testsets( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[TestSetOutputResponse]: + """ + Get all testsets. + + Returns: + + - A list of testset objects. + + Raises: + + - `HTTPException` with status code 404 if no testsets are found. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[TestSetOutputResponse] + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.testsets.get_testsets() + """ + _response = self._client_wrapper.httpx_client.request( + "testsets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[TestSetOutputResponse], + parse_obj_as( + type_=typing.List[TestSetOutputResponse], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + def create_testset( self, *, @@ -245,31 +311,31 @@ def create_testset( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_single_testset( + def delete_testsets( self, - testset_id: str, *, + testset_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.Optional[typing.Any]: + ) -> typing.List[str]: """ - Fetch a specific testset in a MongoDB collection using its \_id. + Delete specific testsets based on their unique IDs. Args: - testset_id (str): The \_id of the testset to fetch. + testset_ids (List[str]): The unique identifiers of the testsets to delete. Returns: - The requested testset if found, else an HTTPException. + A list of the deleted testsets' IDs. Parameters ---------- - testset_id : str + testset_ids : typing.Sequence[str] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.Optional[typing.Any] + typing.List[str] Successful Response Examples @@ -280,21 +346,28 @@ def get_single_testset( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.testsets.get_single_testset( - testset_id="testset_id", + client.testsets.delete_testsets( + testset_ids=["testset_ids"], ) """ _response = self._client_wrapper.httpx_client.request( - f"testsets/{jsonable_encoder(testset_id)}", - method="GET", + "testsets", + method="DELETE", + json={ + "testset_ids": testset_ids, + }, + headers={ + "content-type": "application/json", + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - typing.Optional[typing.Any], + typing.List[str], parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore + type_=typing.List[str], # type: ignore object_=_response.json(), ), ) @@ -313,27 +386,27 @@ def get_single_testset( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def update_testset( + def deprecating_create_testset( self, - testset_id: str, + app_id: str, *, name: str, csvdata: typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.Optional[typing.Any]: + ) -> TestSetSimpleResponse: """ - Update a testset with given id, update the testset in MongoDB. + Create a testset with given name, save the testset to MongoDB. Args: - testset_id (str): id of the test set to be updated. - csvdata (NewTestset): New data to replace the old testset. + name (str): name of the test set. + testset (Dict[str, str]): test set data. Returns: - str: The id of the test set updated. + str: The id of the test set created. Parameters ---------- - testset_id : str + app_id : str name : str @@ -344,7 +417,7 @@ def update_testset( Returns ------- - typing.Optional[typing.Any] + TestSetSimpleResponse Successful Response Examples @@ -355,15 +428,15 @@ def update_testset( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.testsets.update_testset( - testset_id="testset_id", + client.testsets.deprecating_create_testset( + app_id="app_id", name="name", csvdata=[{"key": "value"}], ) """ _response = self._client_wrapper.httpx_client.request( - f"testsets/{jsonable_encoder(testset_id)}", - method="PUT", + f"testsets/{jsonable_encoder(app_id)}", + method="POST", json={ "name": name, "csvdata": csvdata, @@ -374,9 +447,9 @@ def update_testset( try: if 200 <= _response.status_code < 300: return typing.cast( - typing.Optional[typing.Any], + TestSetSimpleResponse, parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore + type_=TestSetSimpleResponse, # type: ignore object_=_response.json(), ), ) @@ -395,28 +468,31 @@ def update_testset( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_testsets( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> typing.List[TestSetOutputResponse]: + def get_single_testset( + self, + testset_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[typing.Any]: """ - Get all testsets. - - Returns: - - - A list of testset objects. + Fetch a specific testset in a MongoDB collection using its \_id. - Raises: + Args: + testset_id (str): The \_id of the testset to fetch. - - `HTTPException` with status code 404 if no testsets are found. + Returns: + The requested testset if found, else an HTTPException. Parameters ---------- + testset_id : str + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[TestSetOutputResponse] + typing.Optional[typing.Any] Successful Response Examples @@ -427,19 +503,21 @@ def get_testsets( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.testsets.get_testsets() + client.testsets.get_single_testset( + testset_id="testset_id", + ) """ _response = self._client_wrapper.httpx_client.request( - "testsets", + f"testsets/{jsonable_encoder(testset_id)}", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - typing.List[TestSetOutputResponse], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.List[TestSetOutputResponse], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ) @@ -458,31 +536,38 @@ def get_testsets( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete_testsets( + def update_testset( self, + testset_id: str, *, - testset_ids: typing.Sequence[str], + name: str, + csvdata: typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[str]: + ) -> typing.Optional[typing.Any]: """ - Delete specific testsets based on their unique IDs. + Update a testset with given id, update the testset in MongoDB. Args: - testset_ids (List[str]): The unique identifiers of the testsets to delete. + testset_id (str): id of the test set to be updated. + csvdata (NewTestset): New data to replace the old testset. Returns: - A list of the deleted testsets' IDs. + str: The id of the test set updated. Parameters ---------- - testset_ids : typing.Sequence[str] + testset_id : str + + name : str + + csvdata : typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[str] + typing.Optional[typing.Any] Successful Response Examples @@ -493,15 +578,18 @@ def delete_testsets( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.testsets.delete_testsets( - testset_ids=["testset_ids"], + client.testsets.update_testset( + testset_id="testset_id", + name="name", + csvdata=[{"key": "value"}], ) """ _response = self._client_wrapper.httpx_client.request( - "testsets", - method="DELETE", + f"testsets/{jsonable_encoder(testset_id)}", + method="PUT", json={ - "testset_ids": testset_ids, + "name": name, + "csvdata": csvdata, }, request_options=request_options, omit=OMIT, @@ -509,9 +597,9 @@ def delete_testsets( try: if 200 <= _response.status_code < 300: return typing.cast( - typing.List[str], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.List[str], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ) @@ -627,7 +715,11 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response_json) async def import_testset( - self, *, request_options: typing.Optional[RequestOptions] = None + self, + *, + endpoint: typing.Optional[str] = OMIT, + testset_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> TestSetSimpleResponse: """ Import JSON testset data from an endpoint and save it to MongoDB. @@ -641,6 +733,10 @@ async def import_testset( Parameters ---------- + endpoint : typing.Optional[str] + + testset_name : typing.Optional[str] + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -670,7 +766,12 @@ async def main() -> None: _response = await self._client_wrapper.httpx_client.request( "testsets/endpoint", method="POST", + json={ + "endpoint": endpoint, + "testset_name": testset_name, + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: @@ -696,6 +797,67 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + async def get_testsets( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[TestSetOutputResponse]: + """ + Get all testsets. + + Returns: + + - A list of testset objects. + + Raises: + + - `HTTPException` with status code 404 if no testsets are found. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[TestSetOutputResponse] + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.testsets.get_testsets() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "testsets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[TestSetOutputResponse], + parse_obj_as( + type_=typing.List[TestSetOutputResponse], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + async def create_testset( self, *, @@ -782,31 +944,31 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_single_testset( + async def delete_testsets( self, - testset_id: str, *, + testset_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.Optional[typing.Any]: + ) -> typing.List[str]: """ - Fetch a specific testset in a MongoDB collection using its \_id. + Delete specific testsets based on their unique IDs. Args: - testset_id (str): The \_id of the testset to fetch. + testset_ids (List[str]): The unique identifiers of the testsets to delete. Returns: - The requested testset if found, else an HTTPException. + A list of the deleted testsets' IDs. Parameters ---------- - testset_id : str + testset_ids : typing.Sequence[str] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.Optional[typing.Any] + typing.List[str] Successful Response Examples @@ -822,24 +984,31 @@ async def get_single_testset( async def main() -> None: - await client.testsets.get_single_testset( - testset_id="testset_id", + await client.testsets.delete_testsets( + testset_ids=["testset_ids"], ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"testsets/{jsonable_encoder(testset_id)}", - method="GET", + "testsets", + method="DELETE", + json={ + "testset_ids": testset_ids, + }, + headers={ + "content-type": "application/json", + }, request_options=request_options, + omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - typing.Optional[typing.Any], + typing.List[str], parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore + type_=typing.List[str], # type: ignore object_=_response.json(), ), ) @@ -858,27 +1027,27 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def update_testset( + async def deprecating_create_testset( self, - testset_id: str, + app_id: str, *, name: str, csvdata: typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.Optional[typing.Any]: + ) -> TestSetSimpleResponse: """ - Update a testset with given id, update the testset in MongoDB. + Create a testset with given name, save the testset to MongoDB. Args: - testset_id (str): id of the test set to be updated. - csvdata (NewTestset): New data to replace the old testset. + name (str): name of the test set. + testset (Dict[str, str]): test set data. Returns: - str: The id of the test set updated. + str: The id of the test set created. Parameters ---------- - testset_id : str + app_id : str name : str @@ -889,7 +1058,7 @@ async def update_testset( Returns ------- - typing.Optional[typing.Any] + TestSetSimpleResponse Successful Response Examples @@ -905,8 +1074,8 @@ async def update_testset( async def main() -> None: - await client.testsets.update_testset( - testset_id="testset_id", + await client.testsets.deprecating_create_testset( + app_id="app_id", name="name", csvdata=[{"key": "value"}], ) @@ -915,8 +1084,8 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"testsets/{jsonable_encoder(testset_id)}", - method="PUT", + f"testsets/{jsonable_encoder(app_id)}", + method="POST", json={ "name": name, "csvdata": csvdata, @@ -927,9 +1096,9 @@ async def main() -> None: try: if 200 <= _response.status_code < 300: return typing.cast( - typing.Optional[typing.Any], + TestSetSimpleResponse, parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore + type_=TestSetSimpleResponse, # type: ignore object_=_response.json(), ), ) @@ -948,28 +1117,31 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_testsets( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> typing.List[TestSetOutputResponse]: + async def get_single_testset( + self, + testset_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[typing.Any]: """ - Get all testsets. - - Returns: - - - A list of testset objects. + Fetch a specific testset in a MongoDB collection using its \_id. - Raises: + Args: + testset_id (str): The \_id of the testset to fetch. - - `HTTPException` with status code 404 if no testsets are found. + Returns: + The requested testset if found, else an HTTPException. Parameters ---------- + testset_id : str + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[TestSetOutputResponse] + typing.Optional[typing.Any] Successful Response Examples @@ -985,22 +1157,24 @@ async def get_testsets( async def main() -> None: - await client.testsets.get_testsets() + await client.testsets.get_single_testset( + testset_id="testset_id", + ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "testsets", + f"testsets/{jsonable_encoder(testset_id)}", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - typing.List[TestSetOutputResponse], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.List[TestSetOutputResponse], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ) @@ -1019,31 +1193,38 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete_testsets( + async def update_testset( self, + testset_id: str, *, - testset_ids: typing.Sequence[str], + name: str, + csvdata: typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]], request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[str]: + ) -> typing.Optional[typing.Any]: """ - Delete specific testsets based on their unique IDs. + Update a testset with given id, update the testset in MongoDB. Args: - testset_ids (List[str]): The unique identifiers of the testsets to delete. + testset_id (str): id of the test set to be updated. + csvdata (NewTestset): New data to replace the old testset. Returns: - A list of the deleted testsets' IDs. + str: The id of the test set updated. Parameters ---------- - testset_ids : typing.Sequence[str] + testset_id : str + + name : str + + csvdata : typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[str] + typing.Optional[typing.Any] Successful Response Examples @@ -1059,18 +1240,21 @@ async def delete_testsets( async def main() -> None: - await client.testsets.delete_testsets( - testset_ids=["testset_ids"], + await client.testsets.update_testset( + testset_id="testset_id", + name="name", + csvdata=[{"key": "value"}], ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - "testsets", - method="DELETE", + f"testsets/{jsonable_encoder(testset_id)}", + method="PUT", json={ - "testset_ids": testset_ids, + "name": name, + "csvdata": csvdata, }, request_options=request_options, omit=OMIT, @@ -1078,9 +1262,9 @@ async def main() -> None: try: if 200 <= _response.status_code < 300: return typing.cast( - typing.List[str], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.List[str], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ) diff --git a/agenta-cli/agenta/client/backend/types/__init__.py b/agenta-cli/agenta/client/backend/types/__init__.py index b10c09c61b..6ef4a84f0a 100644 --- a/agenta-cli/agenta/client/backend/types/__init__.py +++ b/agenta-cli/agenta/client/backend/types/__init__.py @@ -9,11 +9,13 @@ from .agenta_trees_response import AgentaTreesResponse from .aggregated_result import AggregatedResult from .aggregated_result_evaluator_config import AggregatedResultEvaluatorConfig +from .analytics_response import AnalyticsResponse from .app import App from .app_variant_response import AppVariantResponse from .app_variant_revision import AppVariantRevision from .base_output import BaseOutput from .body_import_testset import BodyImportTestset +from .bucket_dto import BucketDto from .collect_status_response import CollectStatusResponse from .config_db import ConfigDb from .config_dto import ConfigDto @@ -41,6 +43,7 @@ from .evaluator_output_interface import EvaluatorOutputInterface from .exception_dto import ExceptionDto from .get_config_response import GetConfigResponse +from .header_dto import HeaderDto from .http_validation_error import HttpValidationError from .human_evaluation import HumanEvaluation from .human_evaluation_scenario import HumanEvaluationScenario @@ -50,12 +53,14 @@ from .human_evaluation_update import HumanEvaluationUpdate from .image import Image from .invite_request import InviteRequest +from .legacy_analytics_response import LegacyAnalyticsResponse +from .legacy_data_point import LegacyDataPoint from .lifecycle_dto import LifecycleDto from .link_dto import LinkDto from .list_api_keys_response import ListApiKeysResponse from .llm_run_rate_limit import LlmRunRateLimit from .llm_tokens import LlmTokens -from .lm_providers_enum import LmProvidersEnum +from .metrics_dto import MetricsDto from .new_human_evaluation import NewHumanEvaluation from .new_testset import NewTestset from .node_dto import NodeDto @@ -73,11 +78,17 @@ from .outputs import Outputs from .parent_dto import ParentDto from .permission import Permission +from .projects_response import ProjectsResponse +from .provider_key_dto import ProviderKeyDto +from .provider_kind import ProviderKind from .reference_dto import ReferenceDto from .reference_request_model import ReferenceRequestModel from .result import Result from .root_dto import RootDto from .score import Score +from .secret_dto import SecretDto +from .secret_kind import SecretKind +from .secret_response_dto import SecretResponseDto from .simple_evaluation_output import SimpleEvaluationOutput from .span import Span from .span_detail import SpanDetail @@ -118,11 +129,13 @@ "AgentaTreesResponse", "AggregatedResult", "AggregatedResultEvaluatorConfig", + "AnalyticsResponse", "App", "AppVariantResponse", "AppVariantRevision", "BaseOutput", "BodyImportTestset", + "BucketDto", "CollectStatusResponse", "ConfigDb", "ConfigDto", @@ -150,6 +163,7 @@ "EvaluatorOutputInterface", "ExceptionDto", "GetConfigResponse", + "HeaderDto", "HttpValidationError", "HumanEvaluation", "HumanEvaluationScenario", @@ -159,12 +173,14 @@ "HumanEvaluationUpdate", "Image", "InviteRequest", + "LegacyAnalyticsResponse", + "LegacyDataPoint", "LifecycleDto", "LinkDto", "ListApiKeysResponse", "LlmRunRateLimit", "LlmTokens", - "LmProvidersEnum", + "MetricsDto", "NewHumanEvaluation", "NewTestset", "NodeDto", @@ -182,11 +198,17 @@ "Outputs", "ParentDto", "Permission", + "ProjectsResponse", + "ProviderKeyDto", + "ProviderKind", "ReferenceDto", "ReferenceRequestModel", "Result", "RootDto", "Score", + "SecretDto", + "SecretKind", + "SecretResponseDto", "SimpleEvaluationOutput", "Span", "SpanDetail", diff --git a/agenta-cli/agenta/client/backend/types/analytics_response.py b/agenta-cli/agenta/client/backend/types/analytics_response.py new file mode 100644 index 0000000000..87195da026 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/analytics_response.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .bucket_dto import BucketDto +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class AnalyticsResponse(UniversalBaseModel): + version: str + count: typing.Optional[int] = None + buckets: typing.List[BucketDto] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/app.py b/agenta-cli/agenta/client/backend/types/app.py index 1a16548531..c98d4e9faf 100644 --- a/agenta-cli/agenta/client/backend/types/app.py +++ b/agenta-cli/agenta/client/backend/types/app.py @@ -1,14 +1,15 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel -from ..core.pydantic_utilities import IS_PYDANTIC_V2 import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 import pydantic class App(UniversalBaseModel): app_id: str app_name: str + app_type: typing.Optional[str] = None updated_at: str if IS_PYDANTIC_V2: diff --git a/agenta-cli/agenta/client/backend/types/body_import_testset.py b/agenta-cli/agenta/client/backend/types/body_import_testset.py index 12f7ad7453..9243142a3e 100644 --- a/agenta-cli/agenta/client/backend/types/body_import_testset.py +++ b/agenta-cli/agenta/client/backend/types/body_import_testset.py @@ -9,7 +9,6 @@ class BodyImportTestset(UniversalBaseModel): endpoint: typing.Optional[str] = None testset_name: typing.Optional[str] = None - app_id: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( diff --git a/agenta-cli/agenta/client/backend/types/bucket_dto.py b/agenta-cli/agenta/client/backend/types/bucket_dto.py new file mode 100644 index 0000000000..fe02e3e5bd --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/bucket_dto.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import datetime as dt +from .metrics_dto import MetricsDto +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class BucketDto(UniversalBaseModel): + timestamp: dt.datetime + window: int + total: MetricsDto + error: MetricsDto + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/header_dto.py b/agenta-cli/agenta/client/backend/types/header_dto.py new file mode 100644 index 0000000000..31f6050a21 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/header_dto.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class HeaderDto(UniversalBaseModel): + name: typing.Optional[str] = None + description: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/legacy_analytics_response.py b/agenta-cli/agenta/client/backend/types/legacy_analytics_response.py new file mode 100644 index 0000000000..8201c64567 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/legacy_analytics_response.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .legacy_data_point import LegacyDataPoint +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class LegacyAnalyticsResponse(UniversalBaseModel): + total_count: int + failure_rate: float + total_cost: float + avg_cost: float + avg_latency: float + total_tokens: int + avg_tokens: float + data: typing.List[LegacyDataPoint] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/legacy_data_point.py b/agenta-cli/agenta/client/backend/types/legacy_data_point.py new file mode 100644 index 0000000000..26c987726a --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/legacy_data_point.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class LegacyDataPoint(UniversalBaseModel): + timestamp: dt.datetime + success_count: int + failure_count: int + cost: float + latency: float + total_tokens: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/lm_providers_enum.py b/agenta-cli/agenta/client/backend/types/lm_providers_enum.py deleted file mode 100644 index 6aa756ba0e..0000000000 --- a/agenta-cli/agenta/client/backend/types/lm_providers_enum.py +++ /dev/null @@ -1,21 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -LmProvidersEnum = typing.Union[ - typing.Literal[ - "OPENAI_API_KEY", - "MISTRAL_API_KEY", - "COHERE_API_KEY", - "ANTHROPIC_API_KEY", - "ANYSCALE_API_KEY", - "PERPLEXITYAI_API_KEY", - "DEEPINFRA_API_KEY", - "TOGETHERAI_API_KEY", - "ALEPHALPHA_API_KEY", - "OPENROUTER_API_KEY", - "GROQ_API_KEY", - "GEMINI_API_KEY", - ], - typing.Any, -] diff --git a/agenta-cli/agenta/client/backend/types/metrics_dto.py b/agenta-cli/agenta/client/backend/types/metrics_dto.py new file mode 100644 index 0000000000..34be8ae995 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/metrics_dto.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class MetricsDto(UniversalBaseModel): + count: typing.Optional[int] = None + duration: typing.Optional[float] = None + cost: typing.Optional[float] = None + tokens: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/permission.py b/agenta-cli/agenta/client/backend/types/permission.py index a32616dd16..59f87e22b4 100644 --- a/agenta-cli/agenta/client/backend/types/permission.py +++ b/agenta-cli/agenta/client/backend/types/permission.py @@ -13,6 +13,7 @@ "delete_app_variant", "modify_variant_configurations", "delete_application_variant", + "run_service", "view_app_environment_deployment", "edit_app_environment_deployment", "create_app_environment_deployment", diff --git a/agenta-cli/agenta/client/backend/types/projects_response.py b/agenta-cli/agenta/client/backend/types/projects_response.py new file mode 100644 index 0000000000..31fd82d4ac --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/projects_response.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ProjectsResponse(UniversalBaseModel): + organization_id: typing.Optional[str] = None + organization_name: typing.Optional[str] = None + workspace_id: typing.Optional[str] = None + workspace_name: typing.Optional[str] = None + project_id: str + project_name: str + user_role: typing.Optional[str] = None + is_demo: typing.Optional[bool] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/provider_key_dto.py b/agenta-cli/agenta/client/backend/types/provider_key_dto.py new file mode 100644 index 0000000000..d22e947f2f --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/provider_key_dto.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from .provider_kind import ProviderKind +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class ProviderKeyDto(UniversalBaseModel): + provider: ProviderKind + key: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/provider_kind.py b/agenta-cli/agenta/client/backend/types/provider_kind.py new file mode 100644 index 0000000000..d469462030 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/provider_kind.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ProviderKind = typing.Union[ + typing.Literal[ + "openai", + "cohere", + "anyscale", + "deepinfra", + "alephalpha", + "groq", + "mistralai", + "anthropic", + "perplexityai", + "togetherai", + "openrouter", + "gemini", + ], + typing.Any, +] diff --git a/agenta-cli/agenta/client/backend/types/secret_dto.py b/agenta-cli/agenta/client/backend/types/secret_dto.py new file mode 100644 index 0000000000..a980b9073d --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/secret_dto.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from .secret_kind import SecretKind +from .provider_key_dto import ProviderKeyDto +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class SecretDto(UniversalBaseModel): + kind: SecretKind = "provider_key" + data: ProviderKeyDto + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/types/secret_kind.py b/agenta-cli/agenta/client/backend/types/secret_kind.py new file mode 100644 index 0000000000..8d44867226 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/secret_kind.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +SecretKind = typing.Literal["provider_key"] diff --git a/agenta-cli/agenta/client/backend/types/secret_response_dto.py b/agenta-cli/agenta/client/backend/types/secret_response_dto.py new file mode 100644 index 0000000000..1c0a850295 --- /dev/null +++ b/agenta-cli/agenta/client/backend/types/secret_response_dto.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .header_dto import HeaderDto +from .secret_dto import SecretDto +from .lifecycle_dto import LifecycleDto +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class SecretResponseDto(UniversalBaseModel): + header: typing.Optional[HeaderDto] = None + secret: SecretDto + id: str + lifecycle: typing.Optional[LifecycleDto] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/agenta-cli/agenta/client/backend/variants/client.py b/agenta-cli/agenta/client/backend/variants/client.py index 389a77f778..c5fa02fa8e 100644 --- a/agenta-cli/agenta/client/backend/variants/client.py +++ b/agenta-cli/agenta/client/backend/variants/client.py @@ -97,6 +97,9 @@ def add_variant_from_base_and_config( "new_config_name": new_config_name, "parameters": parameters, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -249,6 +252,9 @@ def start_variant( object_=env_vars, annotation=DockerEnvVars, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -399,6 +405,9 @@ def update_variant_parameters( json={ "parameters": parameters, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -757,6 +766,9 @@ def configs_add( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -839,6 +851,9 @@ def configs_fetch( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -921,6 +936,9 @@ def configs_fork( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -989,6 +1007,9 @@ def configs_commit( object_=config, annotation=ConfigDto, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1074,6 +1095,9 @@ def configs_deploy( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1150,6 +1174,9 @@ def configs_delete( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1216,6 +1243,9 @@ def configs_list( object_=application_ref, annotation=ReferenceDto, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1292,6 +1322,9 @@ def configs_history( direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1397,6 +1430,9 @@ async def main() -> None: "new_config_name": new_config_name, "parameters": parameters, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1565,6 +1601,9 @@ async def main() -> None: object_=env_vars, annotation=DockerEnvVars, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -1731,6 +1770,9 @@ async def main() -> None: json={ "parameters": parameters, }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2129,6 +2171,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2219,6 +2264,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2309,6 +2357,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2385,6 +2436,9 @@ async def main() -> None: object_=config, annotation=ConfigDto, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2478,6 +2532,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2562,6 +2619,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2636,6 +2696,9 @@ async def main() -> None: object_=application_ref, annotation=ReferenceDto, direction="write" ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) @@ -2720,6 +2783,9 @@ async def main() -> None: direction="write", ), }, + headers={ + "content-type": "application/json", + }, request_options=request_options, omit=OMIT, ) diff --git a/agenta-cli/agenta/client/backend/vault/__init__.py b/agenta-cli/agenta/client/backend/vault/__init__.py new file mode 100644 index 0000000000..67a41b2742 --- /dev/null +++ b/agenta-cli/agenta/client/backend/vault/__init__.py @@ -0,0 +1 @@ +# This file was auto-generated by Fern from our API Definition. diff --git a/agenta-cli/agenta/client/backend/vault/client.py b/agenta-cli/agenta/client/backend/vault/client.py new file mode 100644 index 0000000000..0c2a31100e --- /dev/null +++ b/agenta-cli/agenta/client/backend/vault/client.py @@ -0,0 +1,685 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from ..core.client_wrapper import SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.secret_response_dto import SecretResponseDto +from ..core.pydantic_utilities import parse_obj_as +from json.decoder import JSONDecodeError +from ..core.api_error import ApiError +from ..types.secret_dto import SecretDto +from ..types.header_dto import HeaderDto +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.http_validation_error import HttpValidationError +from ..core.jsonable_encoder import jsonable_encoder +from ..core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class VaultClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_secrets( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[SecretResponseDto]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[SecretResponseDto] + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.vault.list_secrets() + """ + _response = self._client_wrapper.httpx_client.request( + "vault/v1/secrets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[SecretResponseDto], + parse_obj_as( + type_=typing.List[SecretResponseDto], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def create_secret( + self, + *, + secret: SecretDto, + header: typing.Optional[HeaderDto] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret : SecretDto + + header : typing.Optional[HeaderDto] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + from agenta import AgentaApi, ProviderKeyDto, SecretDto + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.vault.create_secret( + secret=SecretDto( + data=ProviderKeyDto( + provider="openai", + key="key", + ), + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "vault/v1/secrets", + method="POST", + json={ + "header": convert_and_respect_annotation_metadata( + object_=header, annotation=HeaderDto, direction="write" + ), + "secret": convert_and_respect_annotation_metadata( + object_=secret, annotation=SecretDto, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def read_secret( + self, secret_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.vault.read_secret( + secret_id="secret_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def update_secret( + self, + secret_id: str, + *, + header: typing.Optional[HeaderDto] = OMIT, + secret: typing.Optional[SecretDto] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret_id : str + + header : typing.Optional[HeaderDto] + + secret : typing.Optional[SecretDto] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.vault.update_secret( + secret_id="secret_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="PUT", + json={ + "header": convert_and_respect_annotation_metadata( + object_=header, annotation=HeaderDto, direction="write" + ), + "secret": convert_and_respect_annotation_metadata( + object_=secret, annotation=SecretDto, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete_secret( + self, secret_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + secret_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from agenta import AgentaApi + + client = AgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.vault.delete_secret( + secret_id="secret_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncVaultClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_secrets( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[SecretResponseDto]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[SecretResponseDto] + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.vault.list_secrets() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "vault/v1/secrets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + typing.List[SecretResponseDto], + parse_obj_as( + type_=typing.List[SecretResponseDto], # type: ignore + object_=_response.json(), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def create_secret( + self, + *, + secret: SecretDto, + header: typing.Optional[HeaderDto] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret : SecretDto + + header : typing.Optional[HeaderDto] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi, ProviderKeyDto, SecretDto + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.vault.create_secret( + secret=SecretDto( + data=ProviderKeyDto( + provider="openai", + key="key", + ), + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "vault/v1/secrets", + method="POST", + json={ + "header": convert_and_respect_annotation_metadata( + object_=header, annotation=HeaderDto, direction="write" + ), + "secret": convert_and_respect_annotation_metadata( + object_=secret, annotation=SecretDto, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def read_secret( + self, secret_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.vault.read_secret( + secret_id="secret_id", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update_secret( + self, + secret_id: str, + *, + header: typing.Optional[HeaderDto] = OMIT, + secret: typing.Optional[SecretDto] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SecretResponseDto: + """ + Parameters + ---------- + secret_id : str + + header : typing.Optional[HeaderDto] + + secret : typing.Optional[SecretDto] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SecretResponseDto + Successful Response + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.vault.update_secret( + secret_id="secret_id", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="PUT", + json={ + "header": convert_and_respect_annotation_metadata( + object_=header, annotation=HeaderDto, direction="write" + ), + "secret": convert_and_respect_annotation_metadata( + object_=secret, annotation=SecretDto, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + SecretResponseDto, + parse_obj_as( + type_=SecretResponseDto, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete_secret( + self, secret_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + secret_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from agenta import AsyncAgentaApi + + client = AsyncAgentaApi( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.vault.delete_secret( + secret_id="secret_id", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"vault/v1/secrets/{jsonable_encoder(secret_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 422: + raise UnprocessableEntityError( + typing.cast( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json)