diff --git a/pyproject.toml b/pyproject.toml index d85badb64..cc2a93f13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,10 +39,7 @@ lambda-worker-otel = [ "opentelemetry-semantic-conventions>=0.40b0,<1", "opentelemetry-sdk-extension-aws>=2.0.0,<3", ] -aioboto3 = [ - "aioboto3>=10.4.0", - "types-aioboto3[s3]>=10.4.0", -] +aioboto3 = ["aioboto3>=10.4.0", "types-aioboto3[s3]>=10.4.0"] [project.urls] Homepage = "https://github.com/temporalio/sdk-python" @@ -86,6 +83,7 @@ dev = [ "opentelemetry-exporter-otlp-proto-grpc>=1.11.1,<2", "opentelemetry-semantic-conventions>=0.40b0,<1", "opentelemetry-sdk-extension-aws>=2.0.0,<3", + "pytest-flakefinder>=1.1.0", "async-timeout>=4.0,<6; python_version < '3.11'", ] @@ -239,7 +237,7 @@ exclude = [ ] [tool.ruff] -target-version = "py39" +target-version = "py310" [build-system] requires = ["maturin>=1.0,<2.0"] diff --git a/temporalio/api/cloud/cloudservice/v1/__init__.py b/temporalio/api/cloud/cloudservice/v1/__init__.py index 022ee05cb..31e4e7753 100644 --- a/temporalio/api/cloud/cloudservice/v1/__init__.py +++ b/temporalio/api/cloud/cloudservice/v1/__init__.py @@ -11,6 +11,8 @@ CreateBillingReportResponse, CreateConnectivityRuleRequest, CreateConnectivityRuleResponse, + CreateCustomRoleRequest, + CreateCustomRoleResponse, CreateNamespaceExportSinkRequest, CreateNamespaceExportSinkResponse, CreateNamespaceRequest, @@ -29,6 +31,8 @@ DeleteApiKeyResponse, DeleteConnectivityRuleRequest, DeleteConnectivityRuleResponse, + DeleteCustomRoleRequest, + DeleteCustomRoleResponse, DeleteNamespaceExportSinkRequest, DeleteNamespaceExportSinkResponse, DeleteNamespaceRegionRequest, @@ -67,6 +71,10 @@ GetConnectivityRulesResponse, GetCurrentIdentityRequest, GetCurrentIdentityResponse, + GetCustomRoleRequest, + GetCustomRoleResponse, + GetCustomRolesRequest, + GetCustomRolesResponse, GetNamespaceCapacityInfoRequest, GetNamespaceCapacityInfoResponse, GetNamespaceExportSinkRequest, @@ -117,6 +125,8 @@ UpdateAccountResponse, UpdateApiKeyRequest, UpdateApiKeyResponse, + UpdateCustomRoleRequest, + UpdateCustomRoleResponse, UpdateNamespaceExportSinkRequest, UpdateNamespaceExportSinkResponse, UpdateNamespaceRequest, @@ -150,6 +160,8 @@ "CreateBillingReportResponse", "CreateConnectivityRuleRequest", "CreateConnectivityRuleResponse", + "CreateCustomRoleRequest", + "CreateCustomRoleResponse", "CreateNamespaceExportSinkRequest", "CreateNamespaceExportSinkResponse", "CreateNamespaceRequest", @@ -168,6 +180,8 @@ "DeleteApiKeyResponse", "DeleteConnectivityRuleRequest", "DeleteConnectivityRuleResponse", + "DeleteCustomRoleRequest", + "DeleteCustomRoleResponse", "DeleteNamespaceExportSinkRequest", "DeleteNamespaceExportSinkResponse", "DeleteNamespaceRegionRequest", @@ -206,6 +220,10 @@ "GetConnectivityRulesResponse", "GetCurrentIdentityRequest", "GetCurrentIdentityResponse", + "GetCustomRoleRequest", + "GetCustomRoleResponse", + "GetCustomRolesRequest", + "GetCustomRolesResponse", "GetNamespaceCapacityInfoRequest", "GetNamespaceCapacityInfoResponse", "GetNamespaceExportSinkRequest", @@ -256,6 +274,8 @@ "UpdateAccountResponse", "UpdateApiKeyRequest", "UpdateApiKeyResponse", + "UpdateCustomRoleRequest", + "UpdateCustomRoleResponse", "UpdateNamespaceExportSinkRequest", "UpdateNamespaceExportSinkResponse", "UpdateNamespaceRequest", diff --git a/temporalio/api/cloud/cloudservice/v1/request_response_pb2.py b/temporalio/api/cloud/cloudservice/v1/request_response_pb2.py index 23f1b7fad..b1874c825 100644 --- a/temporalio/api/cloud/cloudservice/v1/request_response_pb2.py +++ b/temporalio/api/cloud/cloudservice/v1/request_response_pb2.py @@ -48,7 +48,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n9temporal/api/cloud/cloudservice/v1/request_response.proto\x12"temporal.api.cloud.cloudservice.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a-temporal/api/cloud/operation/v1/message.proto\x1a,temporal/api/cloud/identity/v1/message.proto\x1a-temporal/api/cloud/namespace/v1/message.proto\x1a)temporal/api/cloud/nexus/v1/message.proto\x1a*temporal/api/cloud/region/v1/message.proto\x1a+temporal/api/cloud/account/v1/message.proto\x1a)temporal/api/cloud/usage/v1/message.proto\x1a\x34temporal/api/cloud/connectivityrule/v1/message.proto\x1a,temporal/api/cloud/auditlog/v1/message.proto\x1a+temporal/api/cloud/billing/v1/message.proto"\x1b\n\x19GetCurrentIdentityRequest"\xed\x01\n\x1aGetCurrentIdentityResponse\x12\x34\n\x04user\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.identity.v1.UserH\x00\x12I\n\x0fservice_account\x18\x02 \x01(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccountH\x00\x12\x41\n\x11principal_api_key\x18\x03 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKeyB\x0b\n\tprincipal"Z\n\x0fGetUsersRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12\x11\n\tnamespace\x18\x04 \x01(\t"`\n\x10GetUsersResponse\x12\x33\n\x05users\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.identity.v1.User\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"!\n\x0eGetUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t"E\n\x0fGetUserResponse\x12\x32\n\x04user\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.identity.v1.User"g\n\x11\x43reateUserRequest\x12\x36\n\x04spec\x18\x01 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"o\n\x12\x43reateUserResponse\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x92\x01\n\x11UpdateUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x36\n\x04spec\x18\x02 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"^\n\x12UpdateUserResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"Z\n\x11\x44\x65leteUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"^\n\x12\x44\x65leteUserResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xba\x01\n\x1dSetUserNamespaceAccessRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"j\n\x1eSetUserNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"6\n\x18GetAsyncOperationRequest\x12\x1a\n\x12\x61sync_operation_id\x18\x01 \x01(\t"e\n\x19GetAsyncOperationResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xf3\x01\n\x16\x43reateNamespaceRequest\x12<\n\x04spec\x18\x02 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t\x12R\n\x04tags\x18\x04 \x03(\x0b\x32\x44.temporal.api.cloud.cloudservice.v1.CreateNamespaceRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"v\n\x17\x43reateNamespaceResponse\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"K\n\x14GetNamespacesRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t"p\n\x15GetNamespacesResponse\x12>\n\nnamespaces\x18\x01 \x03(\x0b\x32*.temporal.api.cloud.namespace.v1.Namespace\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"(\n\x13GetNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t"U\n\x14GetNamespaceResponse\x12=\n\tnamespace\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.namespace.v1.Namespace"\x9f\x01\n\x16UpdateNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12<\n\x04spec\x18\x02 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"c\n\x17UpdateNamespaceResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xc6\x01\n"RenameCustomSearchAttributeRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12-\n%existing_custom_search_attribute_name\x18\x02 \x01(\t\x12(\n new_custom_search_attribute_name\x18\x03 \x01(\t\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"o\n#RenameCustomSearchAttributeResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"a\n\x16\x44\x65leteNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"c\n\x17\x44\x65leteNamespaceResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"_\n\x1e\x46\x61iloverNamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"k\n\x1f\x46\x61iloverNamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"t\n\x19\x41\x64\x64NamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"f\n\x1a\x41\x64\x64NamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"w\n\x1c\x44\x65leteNamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"i\n\x1d\x44\x65leteNamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x13\n\x11GetRegionsRequest"K\n\x12GetRegionsResponse\x12\x35\n\x07regions\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.region.v1.Region""\n\x10GetRegionRequest\x12\x0e\n\x06region\x18\x01 \x01(\t"I\n\x11GetRegionResponse\x12\x34\n\x06region\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.region.v1.Region"\xae\x01\n\x11GetApiKeysRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x10\n\x08owner_id\x18\x03 \x01(\t\x12!\n\x15owner_type_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12=\n\nowner_type\x18\x05 \x01(\x0e\x32).temporal.api.cloud.identity.v1.OwnerType"g\n\x12GetApiKeysResponse\x12\x38\n\x08\x61pi_keys\x18\x01 \x03(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKey\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t""\n\x10GetApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t"L\n\x11GetApiKeyResponse\x12\x37\n\x07\x61pi_key\x18\x01 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKey"k\n\x13\x43reateApiKeyRequest\x12\x38\n\x04spec\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x7f\n\x14\x43reateApiKeyResponse\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x95\x01\n\x13UpdateApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\x38\n\x04spec\x18\x02 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"`\n\x14UpdateApiKeyResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"[\n\x13\x44\x65leteApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"`\n\x14\x44\x65leteApiKeyResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x87\x01\n\x18GetNexusEndpointsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x1b\n\x13target_namespace_id\x18\x03 \x01(\t\x12\x19\n\x11target_task_queue\x18\x04 \x01(\t\x12\x0c\n\x04name\x18\x05 \x01(\t"n\n\x19GetNexusEndpointsResponse\x12\x38\n\tendpoints\x18\x01 \x03(\x0b\x32%.temporal.api.cloud.nexus.v1.Endpoint\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t".\n\x17GetNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t"S\n\x18GetNexusEndpointResponse\x12\x37\n\x08\x65ndpoint\x18\x01 \x01(\x0b\x32%.temporal.api.cloud.nexus.v1.Endpoint"q\n\x1a\x43reateNexusEndpointRequest\x12\x37\n\x04spec\x18\x01 \x01(\x0b\x32).temporal.api.cloud.nexus.v1.EndpointSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"|\n\x1b\x43reateNexusEndpointResponse\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xa0\x01\n\x1aUpdateNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x37\n\x04spec\x18\x02 \x01(\x0b\x32).temporal.api.cloud.nexus.v1.EndpointSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"g\n\x1bUpdateNexusEndpointResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"g\n\x1a\x44\x65leteNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"g\n\x1b\x44\x65leteNexusEndpointResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xf5\x02\n\x14GetUserGroupsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x11\n\tnamespace\x18\x03 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12`\n\x0cgoogle_group\x18\x05 \x01(\x0b\x32J.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest.GoogleGroupFilter\x12\\\n\nscim_group\x18\x06 \x01(\x0b\x32H.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest.SCIMGroupFilter\x1a*\n\x11GoogleGroupFilter\x12\x15\n\remail_address\x18\x01 \x01(\t\x1a!\n\x0fSCIMGroupFilter\x12\x0e\n\x06idp_id\x18\x01 \x01(\t"k\n\x15GetUserGroupsResponse\x12\x39\n\x06groups\x18\x01 \x03(\x0b\x32).temporal.api.cloud.identity.v1.UserGroup\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\'\n\x13GetUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t"P\n\x14GetUserGroupResponse\x12\x38\n\x05group\x18\x01 \x01(\x0b\x32).temporal.api.cloud.identity.v1.UserGroup"q\n\x16\x43reateUserGroupRequest\x12;\n\x04spec\x18\x01 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"u\n\x17\x43reateUserGroupResponse\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x9d\x01\n\x16UpdateUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12;\n\x04spec\x18\x02 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"c\n\x17UpdateUserGroupResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"`\n\x16\x44\x65leteUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"c\n\x17\x44\x65leteUserGroupResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xc0\x01\n"SetUserGroupNamespaceAccessRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"o\n#SetUserGroupNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x8f\x01\n\x19\x41\x64\x64UserGroupMemberRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x44\n\tmember_id\x18\x02 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"f\n\x1a\x41\x64\x64UserGroupMemberResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x92\x01\n\x1cRemoveUserGroupMemberRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x44\n\tmember_id\x18\x02 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"i\n\x1dRemoveUserGroupMemberResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"U\n\x1aGetUserGroupMembersRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x10\n\x08group_id\x18\x03 \x01(\t"x\n\x1bGetUserGroupMembersResponse\x12@\n\x07members\x18\x01 \x03(\x0b\x32/.temporal.api.cloud.identity.v1.UserGroupMember\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"{\n\x1b\x43reateServiceAccountRequest\x12@\n\x04spec\x18\x01 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x84\x01\n\x1c\x43reateServiceAccountResponse\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"6\n\x18GetServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t"d\n\x19GetServiceAccountResponse\x12G\n\x0fservice_account\x18\x01 \x01(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccount"B\n\x19GetServiceAccountsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t"~\n\x1aGetServiceAccountsResponse\x12G\n\x0fservice_account\x18\x01 \x03(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccount\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\xb1\x01\n\x1bUpdateServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12@\n\x04spec\x18\x02 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"h\n\x1cUpdateServiceAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xcf\x01\n\'SetServiceAccountNamespaceAccessRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"t\n(SetServiceAccountNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"o\n\x1b\x44\x65leteServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"h\n\x1c\x44\x65leteServiceAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xaa\x01\n\x0fGetUsageRequest\x12\x38\n\x14start_time_inclusive\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12\x65nd_time_exclusive\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tpage_size\x18\x03 \x01(\x05\x12\x12\n\npage_token\x18\x04 \x01(\t"d\n\x10GetUsageResponse\x12\x37\n\tsummaries\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.usage.v1.Summary\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\x13\n\x11GetAccountRequest"M\n\x12GetAccountResponse\x12\x37\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32&.temporal.api.cloud.account.v1.Account"\x86\x01\n\x14UpdateAccountRequest\x12\x38\n\x04spec\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.account.v1.AccountSpec\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"a\n\x15UpdateAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x90\x01\n CreateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!CreateNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"@\n\x1dGetNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"[\n\x1eGetNamespaceExportSinkResponse\x12\x39\n\x04sink\x18\x01 \x01(\x0b\x32+.temporal.api.cloud.namespace.v1.ExportSink"Z\n\x1eGetNamespaceExportSinksRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x11\n\tpage_size\x18\x02 \x01(\x05\x12\x12\n\npage_token\x18\x03 \x01(\t"v\n\x1fGetNamespaceExportSinksResponse\x12:\n\x05sinks\x18\x01 \x03(\x0b\x32+.temporal.api.cloud.namespace.v1.ExportSink\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\xaa\x01\n UpdateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"m\n!UpdateNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"y\n DeleteNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"m\n!DeleteNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"v\n"ValidateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec"%\n#ValidateNamespaceExportSinkResponse"\x82\x02\n\x1aUpdateNamespaceTagsRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12h\n\x0etags_to_upsert\x18\x02 \x03(\x0b\x32P.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsRequest.TagsToUpsertEntry\x12\x16\n\x0etags_to_remove\x18\x03 \x03(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t\x1a\x33\n\x11TagsToUpsertEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"g\n\x1bUpdateNamespaceTagsResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x87\x01\n\x1d\x43reateConnectivityRuleRequest\x12J\n\x04spec\x18\x01 \x01(\x0b\x32<.temporal.api.cloud.connectivityrule.v1.ConnectivityRuleSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x88\x01\n\x1e\x43reateConnectivityRuleResponse\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation":\n\x1aGetConnectivityRuleRequest\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t"r\n\x1bGetConnectivityRuleResponse\x12S\n\x11\x63onnectivity_rule\x18\x01 \x01(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule"W\n\x1bGetConnectivityRulesRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x11\n\tnamespace\x18\x03 \x01(\t"\x8d\x01\n\x1cGetConnectivityRulesResponse\x12T\n\x12\x63onnectivity_rules\x18\x01 \x03(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"s\n\x1d\x44\x65leteConnectivityRuleRequest\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"j\n\x1e\x44\x65leteConnectivityRuleResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xae\x01\n\x13GetAuditLogsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x38\n\x14start_time_inclusive\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12\x65nd_time_exclusive\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"h\n\x14GetAuditLogsResponse\x12\x37\n\x04logs\x18\x01 \x03(\x0b\x32).temporal.api.cloud.auditlog.v1.LogRecord\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"c\n"ValidateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec"%\n#ValidateAccountAuditLogSinkResponse"}\n CreateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"m\n!CreateAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"-\n\x1dGetAccountAuditLogSinkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"[\n\x1eGetAccountAuditLogSinkResponse\x12\x39\n\x04sink\x18\x01 \x01(\x0b\x32+.temporal.api.cloud.account.v1.AuditLogSink"G\n\x1eGetAccountAuditLogSinksRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t"v\n\x1fGetAccountAuditLogSinksResponse\x12:\n\x05sinks\x18\x01 \x03(\x0b\x32+.temporal.api.cloud.account.v1.AuditLogSink\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\x97\x01\n UpdateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!UpdateAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"f\n DeleteAccountAuditLogSinkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!DeleteAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"4\n\x1fGetNamespaceCapacityInfoRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t"q\n GetNamespaceCapacityInfoResponse\x12M\n\rcapacity_info\x18\x01 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo"x\n\x1a\x43reateBillingReportRequest\x12>\n\x04spec\x18\x01 \x01(\x0b\x32\x30.temporal.api.cloud.billing.v1.BillingReportSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x82\x01\n\x1b\x43reateBillingReportResponse\x12\x19\n\x11\x62illing_report_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"4\n\x17GetBillingReportRequest\x12\x19\n\x11\x62illing_report_id\x18\x01 \x01(\t"`\n\x18GetBillingReportResponse\x12\x44\n\x0e\x62illing_report\x18\x01 \x01(\x0b\x32,.temporal.api.cloud.billing.v1.BillingReportB\xc8\x01\n%io.temporal.api.cloud.cloudservice.v1B\x14RequestResponseProtoP\x01Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\xaa\x02$Temporalio.Api.Cloud.CloudService.V1\xea\x02(Temporalio::Api::Cloud::CloudService::V1b\x06proto3' + b'\n9temporal/api/cloud/cloudservice/v1/request_response.proto\x12"temporal.api.cloud.cloudservice.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a-temporal/api/cloud/operation/v1/message.proto\x1a,temporal/api/cloud/identity/v1/message.proto\x1a-temporal/api/cloud/namespace/v1/message.proto\x1a)temporal/api/cloud/nexus/v1/message.proto\x1a*temporal/api/cloud/region/v1/message.proto\x1a+temporal/api/cloud/account/v1/message.proto\x1a)temporal/api/cloud/usage/v1/message.proto\x1a\x34temporal/api/cloud/connectivityrule/v1/message.proto\x1a,temporal/api/cloud/auditlog/v1/message.proto\x1a+temporal/api/cloud/billing/v1/message.proto"\x1b\n\x19GetCurrentIdentityRequest"\xed\x01\n\x1aGetCurrentIdentityResponse\x12\x34\n\x04user\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.identity.v1.UserH\x00\x12I\n\x0fservice_account\x18\x02 \x01(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccountH\x00\x12\x41\n\x11principal_api_key\x18\x03 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKeyB\x0b\n\tprincipal"Z\n\x0fGetUsersRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12\x11\n\tnamespace\x18\x04 \x01(\t"`\n\x10GetUsersResponse\x12\x33\n\x05users\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.identity.v1.User\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"!\n\x0eGetUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t"E\n\x0fGetUserResponse\x12\x32\n\x04user\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.identity.v1.User"g\n\x11\x43reateUserRequest\x12\x36\n\x04spec\x18\x01 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"o\n\x12\x43reateUserResponse\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x92\x01\n\x11UpdateUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x36\n\x04spec\x18\x02 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"^\n\x12UpdateUserResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"Z\n\x11\x44\x65leteUserRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"^\n\x12\x44\x65leteUserResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xba\x01\n\x1dSetUserNamespaceAccessRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"j\n\x1eSetUserNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"6\n\x18GetAsyncOperationRequest\x12\x1a\n\x12\x61sync_operation_id\x18\x01 \x01(\t"e\n\x19GetAsyncOperationResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xf3\x01\n\x16\x43reateNamespaceRequest\x12<\n\x04spec\x18\x02 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t\x12R\n\x04tags\x18\x04 \x03(\x0b\x32\x44.temporal.api.cloud.cloudservice.v1.CreateNamespaceRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"v\n\x17\x43reateNamespaceResponse\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"K\n\x14GetNamespacesRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t"p\n\x15GetNamespacesResponse\x12>\n\nnamespaces\x18\x01 \x03(\x0b\x32*.temporal.api.cloud.namespace.v1.Namespace\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"(\n\x13GetNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t"U\n\x14GetNamespaceResponse\x12=\n\tnamespace\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.namespace.v1.Namespace"\x9f\x01\n\x16UpdateNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12<\n\x04spec\x18\x02 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"c\n\x17UpdateNamespaceResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xc6\x01\n"RenameCustomSearchAttributeRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12-\n%existing_custom_search_attribute_name\x18\x02 \x01(\t\x12(\n new_custom_search_attribute_name\x18\x03 \x01(\t\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"o\n#RenameCustomSearchAttributeResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"a\n\x16\x44\x65leteNamespaceRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"c\n\x17\x44\x65leteNamespaceResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"_\n\x1e\x46\x61iloverNamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"k\n\x1f\x46\x61iloverNamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"t\n\x19\x41\x64\x64NamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"f\n\x1a\x41\x64\x64NamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"w\n\x1c\x44\x65leteNamespaceRegionRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0e\n\x06region\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"i\n\x1d\x44\x65leteNamespaceRegionResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x13\n\x11GetRegionsRequest"K\n\x12GetRegionsResponse\x12\x35\n\x07regions\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.region.v1.Region""\n\x10GetRegionRequest\x12\x0e\n\x06region\x18\x01 \x01(\t"I\n\x11GetRegionResponse\x12\x34\n\x06region\x18\x01 \x01(\x0b\x32$.temporal.api.cloud.region.v1.Region"\xae\x01\n\x11GetApiKeysRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x10\n\x08owner_id\x18\x03 \x01(\t\x12!\n\x15owner_type_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12=\n\nowner_type\x18\x05 \x01(\x0e\x32).temporal.api.cloud.identity.v1.OwnerType"g\n\x12GetApiKeysResponse\x12\x38\n\x08\x61pi_keys\x18\x01 \x03(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKey\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t""\n\x10GetApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t"L\n\x11GetApiKeyResponse\x12\x37\n\x07\x61pi_key\x18\x01 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.ApiKey"k\n\x13\x43reateApiKeyRequest\x12\x38\n\x04spec\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x7f\n\x14\x43reateApiKeyResponse\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x95\x01\n\x13UpdateApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\x38\n\x04spec\x18\x02 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"`\n\x14UpdateApiKeyResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"[\n\x13\x44\x65leteApiKeyRequest\x12\x0e\n\x06key_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"`\n\x14\x44\x65leteApiKeyResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x87\x01\n\x18GetNexusEndpointsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x1b\n\x13target_namespace_id\x18\x03 \x01(\t\x12\x19\n\x11target_task_queue\x18\x04 \x01(\t\x12\x0c\n\x04name\x18\x05 \x01(\t"n\n\x19GetNexusEndpointsResponse\x12\x38\n\tendpoints\x18\x01 \x03(\x0b\x32%.temporal.api.cloud.nexus.v1.Endpoint\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t".\n\x17GetNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t"S\n\x18GetNexusEndpointResponse\x12\x37\n\x08\x65ndpoint\x18\x01 \x01(\x0b\x32%.temporal.api.cloud.nexus.v1.Endpoint"q\n\x1a\x43reateNexusEndpointRequest\x12\x37\n\x04spec\x18\x01 \x01(\x0b\x32).temporal.api.cloud.nexus.v1.EndpointSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"|\n\x1b\x43reateNexusEndpointResponse\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xa0\x01\n\x1aUpdateNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x37\n\x04spec\x18\x02 \x01(\x0b\x32).temporal.api.cloud.nexus.v1.EndpointSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"g\n\x1bUpdateNexusEndpointResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"g\n\x1a\x44\x65leteNexusEndpointRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"g\n\x1b\x44\x65leteNexusEndpointResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xf5\x02\n\x14GetUserGroupsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x11\n\tnamespace\x18\x03 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12`\n\x0cgoogle_group\x18\x05 \x01(\x0b\x32J.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest.GoogleGroupFilter\x12\\\n\nscim_group\x18\x06 \x01(\x0b\x32H.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest.SCIMGroupFilter\x1a*\n\x11GoogleGroupFilter\x12\x15\n\remail_address\x18\x01 \x01(\t\x1a!\n\x0fSCIMGroupFilter\x12\x0e\n\x06idp_id\x18\x01 \x01(\t"k\n\x15GetUserGroupsResponse\x12\x39\n\x06groups\x18\x01 \x03(\x0b\x32).temporal.api.cloud.identity.v1.UserGroup\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\'\n\x13GetUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t"P\n\x14GetUserGroupResponse\x12\x38\n\x05group\x18\x01 \x01(\x0b\x32).temporal.api.cloud.identity.v1.UserGroup"q\n\x16\x43reateUserGroupRequest\x12;\n\x04spec\x18\x01 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"u\n\x17\x43reateUserGroupResponse\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x9d\x01\n\x16UpdateUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12;\n\x04spec\x18\x02 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"c\n\x17UpdateUserGroupResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"`\n\x16\x44\x65leteUserGroupRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"c\n\x17\x44\x65leteUserGroupResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xc0\x01\n"SetUserGroupNamespaceAccessRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"o\n#SetUserGroupNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x8f\x01\n\x19\x41\x64\x64UserGroupMemberRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x44\n\tmember_id\x18\x02 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"f\n\x1a\x41\x64\x64UserGroupMemberResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x92\x01\n\x1cRemoveUserGroupMemberRequest\x12\x10\n\x08group_id\x18\x01 \x01(\t\x12\x44\n\tmember_id\x18\x02 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"i\n\x1dRemoveUserGroupMemberResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"U\n\x1aGetUserGroupMembersRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x10\n\x08group_id\x18\x03 \x01(\t"x\n\x1bGetUserGroupMembersResponse\x12@\n\x07members\x18\x01 \x03(\x0b\x32/.temporal.api.cloud.identity.v1.UserGroupMember\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"{\n\x1b\x43reateServiceAccountRequest\x12@\n\x04spec\x18\x01 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x84\x01\n\x1c\x43reateServiceAccountResponse\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"6\n\x18GetServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t"d\n\x19GetServiceAccountResponse\x12G\n\x0fservice_account\x18\x01 \x01(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccount"B\n\x19GetServiceAccountsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t"~\n\x1aGetServiceAccountsResponse\x12G\n\x0fservice_account\x18\x01 \x03(\x0b\x32..temporal.api.cloud.identity.v1.ServiceAccount\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\xb1\x01\n\x1bUpdateServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12@\n\x04spec\x18\x02 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"h\n\x1cUpdateServiceAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xcf\x01\n\'SetServiceAccountNamespaceAccessRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess\x12\x18\n\x10resource_version\x18\x04 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t"t\n(SetServiceAccountNamespaceAccessResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"o\n\x1b\x44\x65leteServiceAccountRequest\x12\x1a\n\x12service_account_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"h\n\x1c\x44\x65leteServiceAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xaa\x01\n\x0fGetUsageRequest\x12\x38\n\x14start_time_inclusive\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12\x65nd_time_exclusive\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tpage_size\x18\x03 \x01(\x05\x12\x12\n\npage_token\x18\x04 \x01(\t"d\n\x10GetUsageResponse\x12\x37\n\tsummaries\x18\x01 \x03(\x0b\x32$.temporal.api.cloud.usage.v1.Summary\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\x13\n\x11GetAccountRequest"M\n\x12GetAccountResponse\x12\x37\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32&.temporal.api.cloud.account.v1.Account"\x86\x01\n\x14UpdateAccountRequest\x12\x38\n\x04spec\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.account.v1.AccountSpec\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"a\n\x15UpdateAccountResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x90\x01\n CreateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!CreateNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"@\n\x1dGetNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"[\n\x1eGetNamespaceExportSinkResponse\x12\x39\n\x04sink\x18\x01 \x01(\x0b\x32+.temporal.api.cloud.namespace.v1.ExportSink"Z\n\x1eGetNamespaceExportSinksRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x11\n\tpage_size\x18\x02 \x01(\x05\x12\x12\n\npage_token\x18\x03 \x01(\t"v\n\x1fGetNamespaceExportSinksResponse\x12:\n\x05sinks\x18\x01 \x03(\x0b\x32+.temporal.api.cloud.namespace.v1.ExportSink\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\xaa\x01\n UpdateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"m\n!UpdateNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"y\n DeleteNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"m\n!DeleteNamespaceExportSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"v\n"ValidateNamespaceExportSinkRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12=\n\x04spec\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec"%\n#ValidateNamespaceExportSinkResponse"\x82\x02\n\x1aUpdateNamespaceTagsRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12h\n\x0etags_to_upsert\x18\x02 \x03(\x0b\x32P.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsRequest.TagsToUpsertEntry\x12\x16\n\x0etags_to_remove\x18\x03 \x03(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t\x1a\x33\n\x11TagsToUpsertEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"g\n\x1bUpdateNamespaceTagsResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x87\x01\n\x1d\x43reateConnectivityRuleRequest\x12J\n\x04spec\x18\x01 \x01(\x0b\x32<.temporal.api.cloud.connectivityrule.v1.ConnectivityRuleSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x88\x01\n\x1e\x43reateConnectivityRuleResponse\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation":\n\x1aGetConnectivityRuleRequest\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t"r\n\x1bGetConnectivityRuleResponse\x12S\n\x11\x63onnectivity_rule\x18\x01 \x01(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule"W\n\x1bGetConnectivityRulesRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x11\n\tnamespace\x18\x03 \x01(\t"\x8d\x01\n\x1cGetConnectivityRulesResponse\x12T\n\x12\x63onnectivity_rules\x18\x01 \x03(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"s\n\x1d\x44\x65leteConnectivityRuleRequest\x12\x1c\n\x14\x63onnectivity_rule_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"j\n\x1e\x44\x65leteConnectivityRuleResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\xae\x01\n\x13GetAuditLogsRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t\x12\x38\n\x14start_time_inclusive\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12\x65nd_time_exclusive\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"h\n\x14GetAuditLogsResponse\x12\x37\n\x04logs\x18\x01 \x03(\x0b\x32).temporal.api.cloud.auditlog.v1.LogRecord\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"c\n"ValidateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec"%\n#ValidateAccountAuditLogSinkResponse"}\n CreateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"m\n!CreateAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"-\n\x1dGetAccountAuditLogSinkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"[\n\x1eGetAccountAuditLogSinkResponse\x12\x39\n\x04sink\x18\x01 \x01(\x0b\x32+.temporal.api.cloud.account.v1.AuditLogSink"G\n\x1eGetAccountAuditLogSinksRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t"v\n\x1fGetAccountAuditLogSinksResponse\x12:\n\x05sinks\x18\x01 \x03(\x0b\x32+.temporal.api.cloud.account.v1.AuditLogSink\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\x97\x01\n UpdateAccountAuditLogSinkRequest\x12=\n\x04spec\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.account.v1.AuditLogSinkSpec\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!UpdateAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"f\n DeleteAccountAuditLogSinkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"m\n!DeleteAccountAuditLogSinkResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"4\n\x1fGetNamespaceCapacityInfoRequest\x12\x11\n\tnamespace\x18\x01 \x01(\t"q\n GetNamespaceCapacityInfoResponse\x12M\n\rcapacity_info\x18\x01 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo"x\n\x1a\x43reateBillingReportRequest\x12>\n\x04spec\x18\x01 \x01(\x0b\x32\x30.temporal.api.cloud.billing.v1.BillingReportSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"\x82\x01\n\x1b\x43reateBillingReportResponse\x12\x19\n\x11\x62illing_report_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"4\n\x17GetBillingReportRequest\x12\x19\n\x11\x62illing_report_id\x18\x01 \x01(\t"`\n\x18GetBillingReportResponse\x12\x44\n\x0e\x62illing_report\x18\x01 \x01(\x0b\x32,.temporal.api.cloud.billing.v1.BillingReport">\n\x15GetCustomRolesRequest\x12\x11\n\tpage_size\x18\x01 \x01(\x05\x12\x12\n\npage_token\x18\x02 \x01(\t"s\n\x16GetCustomRolesResponse\x12@\n\x0c\x63ustom_roles\x18\x01 \x03(\x0b\x32*.temporal.api.cloud.identity.v1.CustomRole\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"\'\n\x14GetCustomRoleRequest\x12\x0f\n\x07role_id\x18\x01 \x01(\t"X\n\x15GetCustomRoleResponse\x12?\n\x0b\x63ustom_role\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.CustomRole"s\n\x17\x43reateCustomRoleRequest\x12<\n\x04spec\x18\x01 \x01(\x0b\x32..temporal.api.cloud.identity.v1.CustomRoleSpec\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"u\n\x18\x43reateCustomRoleResponse\x12\x0f\n\x07role_id\x18\x01 \x01(\t\x12H\n\x0f\x61sync_operation\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"\x9e\x01\n\x17UpdateCustomRoleRequest\x12\x0f\n\x07role_id\x18\x01 \x01(\t\x12<\n\x04spec\x18\x02 \x01(\x0b\x32..temporal.api.cloud.identity.v1.CustomRoleSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t"d\n\x18UpdateCustomRoleResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperation"`\n\x17\x44\x65leteCustomRoleRequest\x12\x0f\n\x07role_id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x1a\n\x12\x61sync_operation_id\x18\x03 \x01(\t"d\n\x18\x44\x65leteCustomRoleResponse\x12H\n\x0f\x61sync_operation\x18\x01 \x01(\x0b\x32/.temporal.api.cloud.operation.v1.AsyncOperationB\xc8\x01\n%io.temporal.api.cloud.cloudservice.v1B\x14RequestResponseProtoP\x01Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\xaa\x02$Temporalio.Api.Cloud.CloudService.V1\xea\x02(Temporalio::Api::Cloud::CloudService::V1b\x06proto3' ) @@ -354,6 +354,16 @@ ] _GETBILLINGREPORTREQUEST = DESCRIPTOR.message_types_by_name["GetBillingReportRequest"] _GETBILLINGREPORTRESPONSE = DESCRIPTOR.message_types_by_name["GetBillingReportResponse"] +_GETCUSTOMROLESREQUEST = DESCRIPTOR.message_types_by_name["GetCustomRolesRequest"] +_GETCUSTOMROLESRESPONSE = DESCRIPTOR.message_types_by_name["GetCustomRolesResponse"] +_GETCUSTOMROLEREQUEST = DESCRIPTOR.message_types_by_name["GetCustomRoleRequest"] +_GETCUSTOMROLERESPONSE = DESCRIPTOR.message_types_by_name["GetCustomRoleResponse"] +_CREATECUSTOMROLEREQUEST = DESCRIPTOR.message_types_by_name["CreateCustomRoleRequest"] +_CREATECUSTOMROLERESPONSE = DESCRIPTOR.message_types_by_name["CreateCustomRoleResponse"] +_UPDATECUSTOMROLEREQUEST = DESCRIPTOR.message_types_by_name["UpdateCustomRoleRequest"] +_UPDATECUSTOMROLERESPONSE = DESCRIPTOR.message_types_by_name["UpdateCustomRoleResponse"] +_DELETECUSTOMROLEREQUEST = DESCRIPTOR.message_types_by_name["DeleteCustomRoleRequest"] +_DELETECUSTOMROLERESPONSE = DESCRIPTOR.message_types_by_name["DeleteCustomRoleResponse"] GetCurrentIdentityRequest = _reflection.GeneratedProtocolMessageType( "GetCurrentIdentityRequest", (_message.Message,), @@ -1890,6 +1900,116 @@ ) _sym_db.RegisterMessage(GetBillingReportResponse) +GetCustomRolesRequest = _reflection.GeneratedProtocolMessageType( + "GetCustomRolesRequest", + (_message.Message,), + { + "DESCRIPTOR": _GETCUSTOMROLESREQUEST, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.GetCustomRolesRequest) + }, +) +_sym_db.RegisterMessage(GetCustomRolesRequest) + +GetCustomRolesResponse = _reflection.GeneratedProtocolMessageType( + "GetCustomRolesResponse", + (_message.Message,), + { + "DESCRIPTOR": _GETCUSTOMROLESRESPONSE, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.GetCustomRolesResponse) + }, +) +_sym_db.RegisterMessage(GetCustomRolesResponse) + +GetCustomRoleRequest = _reflection.GeneratedProtocolMessageType( + "GetCustomRoleRequest", + (_message.Message,), + { + "DESCRIPTOR": _GETCUSTOMROLEREQUEST, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.GetCustomRoleRequest) + }, +) +_sym_db.RegisterMessage(GetCustomRoleRequest) + +GetCustomRoleResponse = _reflection.GeneratedProtocolMessageType( + "GetCustomRoleResponse", + (_message.Message,), + { + "DESCRIPTOR": _GETCUSTOMROLERESPONSE, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.GetCustomRoleResponse) + }, +) +_sym_db.RegisterMessage(GetCustomRoleResponse) + +CreateCustomRoleRequest = _reflection.GeneratedProtocolMessageType( + "CreateCustomRoleRequest", + (_message.Message,), + { + "DESCRIPTOR": _CREATECUSTOMROLEREQUEST, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.CreateCustomRoleRequest) + }, +) +_sym_db.RegisterMessage(CreateCustomRoleRequest) + +CreateCustomRoleResponse = _reflection.GeneratedProtocolMessageType( + "CreateCustomRoleResponse", + (_message.Message,), + { + "DESCRIPTOR": _CREATECUSTOMROLERESPONSE, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.CreateCustomRoleResponse) + }, +) +_sym_db.RegisterMessage(CreateCustomRoleResponse) + +UpdateCustomRoleRequest = _reflection.GeneratedProtocolMessageType( + "UpdateCustomRoleRequest", + (_message.Message,), + { + "DESCRIPTOR": _UPDATECUSTOMROLEREQUEST, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.UpdateCustomRoleRequest) + }, +) +_sym_db.RegisterMessage(UpdateCustomRoleRequest) + +UpdateCustomRoleResponse = _reflection.GeneratedProtocolMessageType( + "UpdateCustomRoleResponse", + (_message.Message,), + { + "DESCRIPTOR": _UPDATECUSTOMROLERESPONSE, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.UpdateCustomRoleResponse) + }, +) +_sym_db.RegisterMessage(UpdateCustomRoleResponse) + +DeleteCustomRoleRequest = _reflection.GeneratedProtocolMessageType( + "DeleteCustomRoleRequest", + (_message.Message,), + { + "DESCRIPTOR": _DELETECUSTOMROLEREQUEST, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.DeleteCustomRoleRequest) + }, +) +_sym_db.RegisterMessage(DeleteCustomRoleRequest) + +DeleteCustomRoleResponse = _reflection.GeneratedProtocolMessageType( + "DeleteCustomRoleResponse", + (_message.Message,), + { + "DESCRIPTOR": _DELETECUSTOMROLERESPONSE, + "__module__": "temporalio.api.cloud.cloudservice.v1.request_response_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.cloudservice.v1.DeleteCustomRoleResponse) + }, +) +_sym_db.RegisterMessage(DeleteCustomRoleResponse) + if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b"\n%io.temporal.api.cloud.cloudservice.v1B\024RequestResponseProtoP\001Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\252\002$Temporalio.Api.Cloud.CloudService.V1\352\002(Temporalio::Api::Cloud::CloudService::V1" @@ -2181,4 +2301,24 @@ _GETBILLINGREPORTREQUEST._serialized_end = 15683 _GETBILLINGREPORTRESPONSE._serialized_start = 15685 _GETBILLINGREPORTRESPONSE._serialized_end = 15781 + _GETCUSTOMROLESREQUEST._serialized_start = 15783 + _GETCUSTOMROLESREQUEST._serialized_end = 15845 + _GETCUSTOMROLESRESPONSE._serialized_start = 15847 + _GETCUSTOMROLESRESPONSE._serialized_end = 15962 + _GETCUSTOMROLEREQUEST._serialized_start = 15964 + _GETCUSTOMROLEREQUEST._serialized_end = 16003 + _GETCUSTOMROLERESPONSE._serialized_start = 16005 + _GETCUSTOMROLERESPONSE._serialized_end = 16093 + _CREATECUSTOMROLEREQUEST._serialized_start = 16095 + _CREATECUSTOMROLEREQUEST._serialized_end = 16210 + _CREATECUSTOMROLERESPONSE._serialized_start = 16212 + _CREATECUSTOMROLERESPONSE._serialized_end = 16329 + _UPDATECUSTOMROLEREQUEST._serialized_start = 16332 + _UPDATECUSTOMROLEREQUEST._serialized_end = 16490 + _UPDATECUSTOMROLERESPONSE._serialized_start = 16492 + _UPDATECUSTOMROLERESPONSE._serialized_end = 16592 + _DELETECUSTOMROLEREQUEST._serialized_start = 16594 + _DELETECUSTOMROLEREQUEST._serialized_end = 16690 + _DELETECUSTOMROLERESPONSE._serialized_start = 16692 + _DELETECUSTOMROLERESPONSE._serialized_end = 16792 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/api/cloud/cloudservice/v1/request_response_pb2.pyi b/temporalio/api/cloud/cloudservice/v1/request_response_pb2.pyi index 9de8a7930..404554099 100644 --- a/temporalio/api/cloud/cloudservice/v1/request_response_pb2.pyi +++ b/temporalio/api/cloud/cloudservice/v1/request_response_pb2.pyi @@ -4298,3 +4298,298 @@ class GetBillingReportResponse(google.protobuf.message.Message): ) -> None: ... global___GetBillingReportResponse = GetBillingReportResponse + +class GetCustomRolesRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAGE_SIZE_FIELD_NUMBER: builtins.int + PAGE_TOKEN_FIELD_NUMBER: builtins.int + page_size: builtins.int + """The requested size of the page to retrieve. + Cannot exceed 1000. Defaults to 100. + """ + page_token: builtins.str + """The page token if this is continuing from another response.""" + def __init__( + self, + *, + page_size: builtins.int = ..., + page_token: builtins.str = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "page_size", b"page_size", "page_token", b"page_token" + ], + ) -> None: ... + +global___GetCustomRolesRequest = GetCustomRolesRequest + +class GetCustomRolesResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CUSTOM_ROLES_FIELD_NUMBER: builtins.int + NEXT_PAGE_TOKEN_FIELD_NUMBER: builtins.int + @property + def custom_roles( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ + temporalio.api.cloud.identity.v1.message_pb2.CustomRole + ]: + """The list of custom roles in ascending ID order.""" + next_page_token: builtins.str + """The next page token.""" + def __init__( + self, + *, + custom_roles: collections.abc.Iterable[ + temporalio.api.cloud.identity.v1.message_pb2.CustomRole + ] + | None = ..., + next_page_token: builtins.str = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "custom_roles", b"custom_roles", "next_page_token", b"next_page_token" + ], + ) -> None: ... + +global___GetCustomRolesResponse = GetCustomRolesResponse + +class GetCustomRoleRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROLE_ID_FIELD_NUMBER: builtins.int + role_id: builtins.str + """The ID of the custom role to retrieve.""" + def __init__( + self, + *, + role_id: builtins.str = ..., + ) -> None: ... + def ClearField( + self, field_name: typing_extensions.Literal["role_id", b"role_id"] + ) -> None: ... + +global___GetCustomRoleRequest = GetCustomRoleRequest + +class GetCustomRoleResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CUSTOM_ROLE_FIELD_NUMBER: builtins.int + @property + def custom_role(self) -> temporalio.api.cloud.identity.v1.message_pb2.CustomRole: + """The custom role retrieved.""" + def __init__( + self, + *, + custom_role: temporalio.api.cloud.identity.v1.message_pb2.CustomRole + | None = ..., + ) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["custom_role", b"custom_role"] + ) -> builtins.bool: ... + def ClearField( + self, field_name: typing_extensions.Literal["custom_role", b"custom_role"] + ) -> None: ... + +global___GetCustomRoleResponse = GetCustomRoleResponse + +class CreateCustomRoleRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SPEC_FIELD_NUMBER: builtins.int + ASYNC_OPERATION_ID_FIELD_NUMBER: builtins.int + @property + def spec(self) -> temporalio.api.cloud.identity.v1.message_pb2.CustomRoleSpec: + """The specification for the custom role to create.""" + async_operation_id: builtins.str + """The ID to use for this async operation. + Optional, if not provided a random ID will be generated. + """ + def __init__( + self, + *, + spec: temporalio.api.cloud.identity.v1.message_pb2.CustomRoleSpec | None = ..., + async_operation_id: builtins.str = ..., + ) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["spec", b"spec"] + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "async_operation_id", b"async_operation_id", "spec", b"spec" + ], + ) -> None: ... + +global___CreateCustomRoleRequest = CreateCustomRoleRequest + +class CreateCustomRoleResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROLE_ID_FIELD_NUMBER: builtins.int + ASYNC_OPERATION_FIELD_NUMBER: builtins.int + role_id: builtins.str + """The ID of the custom role created.""" + @property + def async_operation( + self, + ) -> temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation: + """The async operation.""" + def __init__( + self, + *, + role_id: builtins.str = ..., + async_operation: temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation + | None = ..., + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal["async_operation", b"async_operation"], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "async_operation", b"async_operation", "role_id", b"role_id" + ], + ) -> None: ... + +global___CreateCustomRoleResponse = CreateCustomRoleResponse + +class UpdateCustomRoleRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROLE_ID_FIELD_NUMBER: builtins.int + SPEC_FIELD_NUMBER: builtins.int + RESOURCE_VERSION_FIELD_NUMBER: builtins.int + ASYNC_OPERATION_ID_FIELD_NUMBER: builtins.int + role_id: builtins.str + """The ID of the custom role to update.""" + @property + def spec(self) -> temporalio.api.cloud.identity.v1.message_pb2.CustomRoleSpec: + """The new custom role specification.""" + resource_version: builtins.str + """The version of the custom role for which this update is intended. + The latest version can be found in the GetCustomRole operation response. + """ + async_operation_id: builtins.str + """The ID to use for this async operation. + Optional, if not provided a random ID will be generated. + """ + def __init__( + self, + *, + role_id: builtins.str = ..., + spec: temporalio.api.cloud.identity.v1.message_pb2.CustomRoleSpec | None = ..., + resource_version: builtins.str = ..., + async_operation_id: builtins.str = ..., + ) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["spec", b"spec"] + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "async_operation_id", + b"async_operation_id", + "resource_version", + b"resource_version", + "role_id", + b"role_id", + "spec", + b"spec", + ], + ) -> None: ... + +global___UpdateCustomRoleRequest = UpdateCustomRoleRequest + +class UpdateCustomRoleResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASYNC_OPERATION_FIELD_NUMBER: builtins.int + @property + def async_operation( + self, + ) -> temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation: + """The async operation.""" + def __init__( + self, + *, + async_operation: temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation + | None = ..., + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal["async_operation", b"async_operation"], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal["async_operation", b"async_operation"], + ) -> None: ... + +global___UpdateCustomRoleResponse = UpdateCustomRoleResponse + +class DeleteCustomRoleRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ROLE_ID_FIELD_NUMBER: builtins.int + RESOURCE_VERSION_FIELD_NUMBER: builtins.int + ASYNC_OPERATION_ID_FIELD_NUMBER: builtins.int + role_id: builtins.str + """The ID of the custom role to delete.""" + resource_version: builtins.str + """The version of the custom role for which this delete is intended. + The latest version can be found in the GetCustomRole operation response. + """ + async_operation_id: builtins.str + """The ID to use for this async operation. + Optional, if not provided a random ID will be generated. + """ + def __init__( + self, + *, + role_id: builtins.str = ..., + resource_version: builtins.str = ..., + async_operation_id: builtins.str = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "async_operation_id", + b"async_operation_id", + "resource_version", + b"resource_version", + "role_id", + b"role_id", + ], + ) -> None: ... + +global___DeleteCustomRoleRequest = DeleteCustomRoleRequest + +class DeleteCustomRoleResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ASYNC_OPERATION_FIELD_NUMBER: builtins.int + @property + def async_operation( + self, + ) -> temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation: + """The async operation.""" + def __init__( + self, + *, + async_operation: temporalio.api.cloud.operation.v1.message_pb2.AsyncOperation + | None = ..., + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal["async_operation", b"async_operation"], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal["async_operation", b"async_operation"], + ) -> None: ... + +global___DeleteCustomRoleResponse = DeleteCustomRoleResponse diff --git a/temporalio/api/cloud/cloudservice/v1/service_pb2.py b/temporalio/api/cloud/cloudservice/v1/service_pb2.py index c7c772860..4223fb03d 100644 --- a/temporalio/api/cloud/cloudservice/v1/service_pb2.py +++ b/temporalio/api/cloud/cloudservice/v1/service_pb2.py @@ -24,14 +24,14 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n0temporal/api/cloud/cloudservice/v1/service.proto\x12"temporal.api.cloud.cloudservice.v1\x1a\x39temporal/api/cloud/cloudservice/v1/request_response.proto\x1a\x1cgoogle/api/annotations.proto\x1a.protoc-gen-openapiv2/options/annotations.proto2\xb6\xbe\x01\n\x0c\x43loudService\x12\xb0\x02\n\x12GetCurrentIdentity\x12=.temporal.api.cloud.cloudservice.v1.GetCurrentIdentityRequest\x1a>.temporal.api.cloud.cloudservice.v1.GetCurrentIdentityResponse"\x9a\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/current-identity\x92\x41x\n\x07\x41\x63\x63ount\x12\x14Get current identity\x1aWReturns information about the currently authenticated user or service account principal\x12\xa5\x02\n\x08GetUsers\x12\x33.temporal.api.cloud.cloudservice.v1.GetUsersRequest\x1a\x34.temporal.api.cloud.cloudservice.v1.GetUsersResponse"\xad\x01\x82\xd3\xe4\x93\x02\x0e\x12\x0c/cloud/users\x92\x41\x95\x01\n\x05Users\x12\x0eList all users\x1a*Returns a list of all users in the account"E\n\x1dUser management documentation\x12$https://docs.temporal.io/cloud/users*\tlistUsers\x12\x9c\x02\n\x07GetUser\x12\x32.temporal.api.cloud.cloudservice.v1.GetUserRequest\x1a\x33.temporal.api.cloud.cloudservice.v1.GetUserResponse"\xa7\x01\x82\xd3\xe4\x93\x02\x18\x12\x16/cloud/users/{user_id}\x92\x41\x85\x01\n\x05Users\x12\x0eGet user by ID\x1a%Takes a user ID, returns user details"E\n\x1dUser management documentation\x12$https://docs.temporal.io/cloud/users\x12\xd0\x01\n\nCreateUser\x12\x35.temporal.api.cloud.cloudservice.v1.CreateUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.CreateUserResponse"S\x82\xd3\xe4\x93\x02\x11"\x0c/cloud/users:\x01*\x92\x41\x39\n\x05Users\x12\rCreate a user\x1a!Creates a new user in the account\x12\xdb\x01\n\nUpdateUser\x12\x35.temporal.api.cloud.cloudservice.v1.UpdateUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.UpdateUserResponse"^\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/users/{user_id}:\x01*\x92\x41:\n\x05Users\x12\rUpdate a user\x1a"Updates an existing user\'s details\x12\xd5\x01\n\nDeleteUser\x12\x35.temporal.api.cloud.cloudservice.v1.DeleteUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.DeleteUserResponse"X\x82\xd3\xe4\x93\x02\x18*\x16/cloud/users/{user_id}\x92\x41\x37\n\x05Users\x12\rDelete a user\x1a\x1fRemoves a user from the account\x12\xaa\x03\n\x16SetUserNamespaceAccess\x12\x41.temporal.api.cloud.cloudservice.v1.SetUserNamespaceAccessRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.SetUserNamespaceAccessResponse"\x88\x02\x82\xd3\xe4\x93\x02\x39"4/cloud/namespaces/{namespace}/users/{user_id}/access:\x01*\x92\x41\xc5\x01\n\x05Users\x12\x19Set user namespace access\x1a\x38\x43onfigures a user\'s permissions for a specific namespace"g\n#Namespace permissions documentation\x12@https://docs.temporal.io/cloud/users-namespace-level-permissions\x12\xb1\x02\n\x11GetAsyncOperation\x12<.temporal.api.cloud.cloudservice.v1.GetAsyncOperationRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetAsyncOperationResponse"\x9e\x01\x82\xd3\xe4\x93\x02(\x12&/cloud/operations/{async_operation_id}\x92\x41m\n\nOperations\x12\x1aGet async operation status\x1a\x43Returns the current status and details of an asynchronous operation\x12\xc6\x02\n\x0f\x43reateNamespace\x12:.temporal.api.cloud.cloudservice.v1.CreateNamespaceRequest\x1a;.temporal.api.cloud.cloudservice.v1.CreateNamespaceResponse"\xb9\x01\x82\xd3\xe4\x93\x02\x16"\x11/cloud/namespaces:\x01*\x92\x41\x99\x01\n\nNamespaces\x12\x12\x43reate a namespace\x1a&Creates a new namespace in the account"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xc7\x02\n\rGetNamespaces\x12\x38.temporal.api.cloud.cloudservice.v1.GetNamespacesRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.GetNamespacesResponse"\xc0\x01\x82\xd3\xe4\x93\x02\x13\x12\x11/cloud/namespaces\x92\x41\xa3\x01\n\nNamespaces\x12\x13List all namespaces\x1a/Returns a list of all namespaces in the account"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xda\x02\n\x0cGetNamespace\x12\x37.temporal.api.cloud.cloudservice.v1.GetNamespaceRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetNamespaceResponse"\xd6\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/namespaces/{namespace}\x92\x41\xad\x01\n\nNamespaces\x12\x15Get namespace details\x1a\x37Returns detailed information about a specific namespace"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xdb\x02\n\x0fUpdateNamespace\x12:.temporal.api.cloud.cloudservice.v1.UpdateNamespaceRequest\x1a;.temporal.api.cloud.cloudservice.v1.UpdateNamespaceResponse"\xce\x01\x82\xd3\xe4\x93\x02""\x1d/cloud/namespaces/{namespace}:\x01*\x92\x41\xa2\x01\n\nNamespaces\x12\x12Update a namespace\x1a/Updates configuration for an existing namespace"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xc7\x03\n\x1bRenameCustomSearchAttribute\x12\x46.temporal.api.cloud.cloudservice.v1.RenameCustomSearchAttributeRequest\x1aG.temporal.api.cloud.cloudservice.v1.RenameCustomSearchAttributeResponse"\x96\x02\x82\xd3\xe4\x93\x02\x41".temporal.api.cloud.cloudservice.v1.AddNamespaceRegionResponse"\xed\x01\x82\xd3\xe4\x93\x02-"(/cloud/namespaces/{namespace}/add-region:\x01*\x92\x41\xb6\x01\n\x11High Availability\x12\x15\x41\x64\x64 namespace replica\x1a+Adds a new replica to an existing namespace"]\n)High availability namespace documentation\x12\x30https://docs.temporal.io/cloud/high-availability\x12\x9b\x03\n\x15\x44\x65leteNamespaceRegion\x12@.temporal.api.cloud.cloudservice.v1.DeleteNamespaceRegionRequest\x1a\x41.temporal.api.cloud.cloudservice.v1.DeleteNamespaceRegionResponse"\xfc\x01\x82\xd3\xe4\x93\x02\x30*./cloud/namespaces/{namespace}/regions/{region}\x92\x41\xc2\x01\n\x11High Availability\x12\x18Remove namespace replica\x1a\x34Removes a replica from a high availability namespace"]\n)High availability namespace documentation\x12\x30https://docs.temporal.io/cloud/high-availability\x12\xa3\x02\n\nGetRegions\x12\x35.temporal.api.cloud.cloudservice.v1.GetRegionsRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetRegionsResponse"\xa5\x01\x82\xd3\xe4\x93\x02\x10\x12\x0e/cloud/regions\x92\x41\x8b\x01\n\x07Regions\x12\x10List all regions\x1a-Returns a list of all available cloud regions"?\n\x15Regions documentation\x12&https://docs.temporal.io/cloud/regions\x12\xb2\x02\n\tGetRegion\x12\x34.temporal.api.cloud.cloudservice.v1.GetRegionRequest\x1a\x35.temporal.api.cloud.cloudservice.v1.GetRegionResponse"\xb7\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/regions/{region}\x92\x41\x94\x01\n\x07Regions\x12\x12Get region details\x1a\x34Returns detailed information about a specific region"?\n\x15Regions documentation\x12&https://docs.temporal.io/cloud/regions\x12\xa8\x02\n\nGetApiKeys\x12\x35.temporal.api.cloud.cloudservice.v1.GetApiKeysRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetApiKeysResponse"\xaa\x01\x82\xd3\xe4\x93\x02\x11\x12\x0f/cloud/api-keys\x92\x41\x8f\x01\n\x08\x41PI Keys\x12\x11List all API keys\x1a-Returns a list of all API keys in the account"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb8\x02\n\tGetApiKey\x12\x34.temporal.api.cloud.cloudservice.v1.GetApiKeyRequest\x1a\x35.temporal.api.cloud.cloudservice.v1.GetApiKeyResponse"\xbd\x01\x82\xd3\xe4\x93\x02\x1a\x12\x18/cloud/api-keys/{key_id}\x92\x41\x99\x01\n\x08\x41PI Keys\x12\x13Get API key details\x1a\x35Returns detailed information about a specific API key"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb1\x02\n\x0c\x43reateApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.CreateApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.CreateApiKeyResponse"\xad\x01\x82\xd3\xe4\x93\x02\x14"\x0f/cloud/api-keys:\x01*\x92\x41\x8f\x01\n\x08\x41PI Keys\x12\x11\x43reate an API key\x1a-Creates a new API key for programmatic access"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb5\x02\n\x0cUpdateApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.UpdateApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.UpdateApiKeyResponse"\xb1\x01\x82\xd3\xe4\x93\x02\x1d"\x18/cloud/api-keys/{key_id}:\x01*\x92\x41\x8a\x01\n\x08\x41PI Keys\x12\x11Update an API key\x1a(Updates an existing API key\'s properties"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xa8\x02\n\x0c\x44\x65leteApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.DeleteApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.DeleteApiKeyResponse"\xa4\x01\x82\xd3\xe4\x93\x02\x1a*\x18/cloud/api-keys/{key_id}\x92\x41\x80\x01\n\x08\x41PI Keys\x12\x11\x44\x65lete an API key\x1a\x1eRevokes and deletes an API key"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xc3\x02\n\x11GetNexusEndpoints\x12<.temporal.api.cloud.cloudservice.v1.GetNexusEndpointsRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetNexusEndpointsResponse"\xb0\x01\x82\xd3\xe4\x93\x02\x18\x12\x16/cloud/nexus/endpoints\x92\x41\x8e\x01\n\x05Nexus\x12\x18List all Nexus endpoints\x1a\x34Returns a list of all Nexus endpoints in the account"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xd8\x02\n\x10GetNexusEndpoint\x12;.temporal.api.cloud.cloudservice.v1.GetNexusEndpointRequest\x1a<.temporal.api.cloud.cloudservice.v1.GetNexusEndpointResponse"\xc8\x01\x82\xd3\xe4\x93\x02&\x12$/cloud/nexus/endpoints/{endpoint_id}\x92\x41\x98\x01\n\x05Nexus\x12\x1aGet Nexus endpoint details\x1a.temporal.api.cloud.cloudservice.v1.CreateNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.CreateNexusEndpointResponse"\xbc\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/nexus/endpoints:\x01*\x92\x41\x97\x01\n\x05Nexus\x12\x17\x43reate a Nexus endpoint\x1a>Creates a new Nexus endpoint for cross-namespace communication"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xd7\x02\n\x13UpdateNexusEndpoint\x12>.temporal.api.cloud.cloudservice.v1.UpdateNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.UpdateNexusEndpointResponse"\xbe\x01\x82\xd3\xe4\x93\x02)"$/cloud/nexus/endpoints/{endpoint_id}:\x01*\x92\x41\x8b\x01\n\x05Nexus\x12\x17Update a Nexus endpoint\x1a\x32Updates an existing Nexus endpoint\'s configuration"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xcb\x02\n\x13\x44\x65leteNexusEndpoint\x12>.temporal.api.cloud.cloudservice.v1.DeleteNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.DeleteNexusEndpointResponse"\xb2\x01\x82\xd3\xe4\x93\x02&*$/cloud/nexus/endpoints/{endpoint_id}\x92\x41\x82\x01\n\x05Nexus\x12\x17\x44\x65lete a Nexus endpoint\x1a)Removes a Nexus endpoint from the account"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xcc\x02\n\rGetUserGroups\x12\x38.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.GetUserGroupsResponse"\xc5\x01\x82\xd3\xe4\x93\x02\x14\x12\x12/cloud/user-groups\x92\x41\xa7\x01\n\x06Groups\x12\x14List all user groups\x1a\x30Returns a list of all user groups in the account"U\n\x19User groups documentation\x12\x38https://docs.temporal.io/cloud/users-account-level-roles\x12\xd0\x02\n\x0cGetUserGroup\x12\x37.temporal.api.cloud.cloudservice.v1.GetUserGroupRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetUserGroupResponse"\xcc\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/user-groups/{group_id}\x92\x41\xa3\x01\n\x06Groups\x12\x16Get user group details\x1a\x38Returns detailed information about a specific user group"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xc7\x02\n\x0f\x43reateUserGroup\x12:.temporal.api.cloud.cloudservice.v1.CreateUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.CreateUserGroupResponse"\xba\x01\x82\xd3\xe4\x93\x02\x17"\x12/cloud/user-groups:\x01*\x92\x41\x99\x01\n\x06Groups\x12\x13\x43reate a user group\x1a\x31\x43reates a new user group for managing permissions"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xcc\x02\n\x0fUpdateUserGroup\x12:.temporal.api.cloud.cloudservice.v1.UpdateUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.UpdateUserGroupResponse"\xbf\x01\x82\xd3\xe4\x93\x02""\x1d/cloud/user-groups/{group_id}:\x01*\x92\x41\x93\x01\n\x06Groups\x12\x13Update a user group\x1a+Updates an existing user group\'s properties"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xc3\x02\n\x0f\x44\x65leteUserGroup\x12:.temporal.api.cloud.cloudservice.v1.DeleteUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.DeleteUserGroupResponse"\xb6\x01\x82\xd3\xe4\x93\x02\x1f*\x1d/cloud/user-groups/{group_id}\x92\x41\x8d\x01\n\x06Groups\x12\x13\x44\x65lete a user group\x1a%Removes a user group from the account"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xad\x03\n\x1bSetUserGroupNamespaceAccess\x12\x46.temporal.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessRequest\x1aG.temporal.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessResponse"\xfc\x01\x82\xd3\xe4\x93\x02@";/cloud/namespaces/{namespace}/user-groups/{group_id}/access:\x01*\x92\x41\xb2\x01\n\x06Groups\x12\x1fSet user group namespace access\x1a>Configures a user group\'s permissions for a specific namespace"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xdf\x02\n\x12\x41\x64\x64UserGroupMember\x12=.temporal.api.cloud.cloudservice.v1.AddUserGroupMemberRequest\x1a>.temporal.api.cloud.cloudservice.v1.AddUserGroupMemberResponse"\xc9\x01\x82\xd3\xe4\x93\x02*"%/cloud/user-groups/{group_id}/members:\x01*\x92\x41\x95\x01\n\x06Groups\x12\x11\x41\x64\x64 user to group\x1a/Adds a user to a user group (Cloud groups only)"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xf8\x02\n\x15RemoveUserGroupMember\x12@.temporal.api.cloud.cloudservice.v1.RemoveUserGroupMemberRequest\x1a\x41.temporal.api.cloud.cloudservice.v1.RemoveUserGroupMemberResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x30"+/cloud/user-groups/{group_id}/remove-member:\x01*\x92\x41\x9f\x01\n\x06Groups\x12\x16Remove user from group\x1a\x34Removes a user from a user group (Cloud groups only)"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xdf\x02\n\x13GetUserGroupMembers\x12>.temporal.api.cloud.cloudservice.v1.GetUserGroupMembersRequest\x1a?.temporal.api.cloud.cloudservice.v1.GetUserGroupMembersResponse"\xc6\x01\x82\xd3\xe4\x93\x02\'\x12%/cloud/user-groups/{group_id}/members\x92\x41\x95\x01\n\x06Groups\x12\x15List users in a group\x1a+Returns a list of all users in a user group"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xf5\x02\n\x14\x43reateServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.CreateServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.CreateServiceAccountResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x1c"\x17/cloud/service-accounts:\x01*\x92\x41\xb3\x01\n\x10Service Accounts\x12\x18\x43reate a service account\x1a\x32\x43reates a new service account for automated access"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\x8c\x03\n\x11GetServiceAccount\x12<.temporal.api.cloud.cloudservice.v1.GetServiceAccountRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetServiceAccountResponse"\xf9\x01\x82\xd3\xe4\x93\x02.\x12,/cloud/service-accounts/{service_account_id}\x92\x41\xc1\x01\n\x10Service Accounts\x12\x1bGet service account details\x1a=Returns detailed information about a specific service account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xf0\x02\n\x12GetServiceAccounts\x12=.temporal.api.cloud.cloudservice.v1.GetServiceAccountsRequest\x1a>.temporal.api.cloud.cloudservice.v1.GetServiceAccountsResponse"\xda\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/service-accounts\x92\x41\xb7\x01\n\x10Service Accounts\x12\x19List all service accounts\x1a\x35Returns a list of all service accounts in the account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\x88\x03\n\x14UpdateServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.UpdateServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.UpdateServiceAccountResponse"\xec\x01\x82\xd3\xe4\x93\x02\x31",/cloud/service-accounts/{service_account_id}:\x01*\x92\x41\xb1\x01\n\x10Service Accounts\x12\x18Update a service account\x1a\x30Updates an existing service account\'s properties"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xe9\x03\n SetServiceAccountNamespaceAccess\x12K.temporal.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessRequest\x1aL.temporal.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessResponse"\xa9\x02\x82\xd3\xe4\x93\x02O"J/cloud/namespaces/{namespace}/service-accounts/{service_account_id}/access:\x01*\x92\x41\xd0\x01\n\x10Service Accounts\x12$Set service account namespace access\x1a\x43\x43onfigures a service account\'s permissions for a specific namespace"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xff\x02\n\x14\x44\x65leteServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.DeleteServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.DeleteServiceAccountResponse"\xe3\x01\x82\xd3\xe4\x93\x02.*,/cloud/service-accounts/{service_account_id}\x92\x41\xab\x01\n\x10Service Accounts\x12\x18\x44\x65lete a service account\x1a*Removes a service account from the account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xcb\x01\n\x08GetUsage\x12\x33.temporal.api.cloud.cloudservice.v1.GetUsageRequest\x1a\x34.temporal.api.cloud.cloudservice.v1.GetUsageResponse"T\x82\xd3\xe4\x93\x02\x0e\x12\x0c/cloud/usage\x92\x41=\n\x07\x41\x63\x63ount\x12\x0eGet usage data\x1a Get usage data across namespacesX\x01\x12\xb0\x02\n\nGetAccount\x12\x35.temporal.api.cloud.cloudservice.v1.GetAccountRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetAccountResponse"\xb2\x01\x82\xd3\xe4\x93\x02\x10\x12\x0e/cloud/account\x92\x41\x98\x01\n\x07\x41\x63\x63ount\x12\x13Get account details\x1a.Returns detailed information about the account"H\n\x15\x42illing documentation\x12/https://docs.temporal.io/cloud/billing-and-cost\x12\xbb\x02\n\rUpdateAccount\x12\x38.temporal.api.cloud.cloudservice.v1.UpdateAccountRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.UpdateAccountResponse"\xb4\x01\x82\xd3\xe4\x93\x02\x13"\x0e/cloud/account:\x01*\x92\x41\x97\x01\n\x07\x41\x63\x63ount\x12\x16Update account details\x1a*Updates account configuration and settings"H\n\x15\x42illing documentation\x12/https://docs.temporal.io/cloud/billing-and-cost\x12\xf3\x02\n\x19\x43reateNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.CreateNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.CreateNamespaceExportSinkResponse"\xc8\x01\x82\xd3\xe4\x93\x02/"*/cloud/namespaces/{namespace}/export-sinks:\x01*\x92\x41\x8f\x01\n\x06\x45xport\x12\x1a\x43reate history export sink\x1a*Creates a new workflow history export sink"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x8c\x03\n\x16GetNamespaceExportSink\x12\x41.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinkRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinkResponse"\xea\x01\x82\xd3\xe4\x93\x02\x33\x12\x31/cloud/namespaces/{namespace}/export-sinks/{name}\x92\x41\xad\x01\n\x06\x45xport\x12\x18Get history sink details\x1aJReturns detailed information about a specific workflow history export sink"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x82\x03\n\x17GetNamespaceExportSinks\x12\x42.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinksRequest\x1a\x43.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinksResponse"\xdd\x01\x82\xd3\xe4\x93\x02,\x12*/cloud/namespaces/{namespace}/export-sinks\x92\x41\xa7\x01\n\x06\x45xport\x12\x19List history export sinks\x1a\x43Returns a list of all workflow history export sinks for a namespace"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x95\x03\n\x19UpdateNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkResponse"\xea\x01\x82\xd3\xe4\x93\x02;"6/cloud/namespaces/{namespace}/export-sinks/{spec.name}:\x01*\x92\x41\xa5\x01\n\x06\x45xport\x12\x1aUpdate history export sink\x1a@Updates an existing workflow history export sink\'s configuration"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x84\x03\n\x19\x44\x65leteNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x33*1/cloud/namespaces/{namespace}/export-sinks/{name}\x92\x41\x9c\x01\n\x06\x45xport\x12\x1a\x44\x65lete history export sink\x1a\x37Removes a workflow history export sink from a namespace"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\xc9\x03\n\x1bValidateNamespaceExportSink\x12\x46.temporal.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkRequest\x1aG.temporal.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkResponse"\x98\x02\x82\xd3\xe4\x93\x02\x37"2/cloud/namespaces/{namespace}/export-sink-validate:\x01*\x92\x41\xd7\x01\n\x06\x45xport\x12*Validate history export sink configuration\x1a\x62Tests workflow history export sink configuration by delivering a test file to verify accessibility"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\xfc\x02\n\x13UpdateNamespaceTags\x12>.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsRequest\x1a?.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsResponse"\xe3\x01\x82\xd3\xe4\x93\x02.")/cloud/namespaces/{namespace}/update-tags:\x01*\x92\x41\xab\x01\n\nNamespaces\x12\x15Update namespace tags\x1a,Updates the tags associated with a namespace"X\n\x1bNamespace tag documentation\x12\x39https://docs.temporal.io/cloud/namespaces#tag-a-namespace\x12\xff\x02\n\x16\x43reateConnectivityRule\x12\x41.temporal.api.cloud.cloudservice.v1.CreateConnectivityRuleRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.CreateConnectivityRuleResponse"\xdd\x01\x82\xd3\xe4\x93\x02\x1e"\x19/cloud/connectivity-rules:\x01*\x92\x41\xb5\x01\n\x12\x43onnectivity Rules\x12\x18\x43reate connectivity rule\x1a:Creates a new connectivity rule for network access control"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\x94\x03\n\x13GetConnectivityRule\x12>.temporal.api.cloud.cloudservice.v1.GetConnectivityRuleRequest\x1a?.temporal.api.cloud.cloudservice.v1.GetConnectivityRuleResponse"\xfb\x01\x82\xd3\xe4\x93\x02\x32\x12\x30/cloud/connectivity-rules/{connectivity_rule_id}\x92\x41\xbf\x01\n\x12\x43onnectivity Rules\x12\x1dGet connectivity rule details\x1a?Returns detailed information about a specific connectivity rule"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\xf6\x02\n\x14GetConnectivityRules\x12?.temporal.api.cloud.cloudservice.v1.GetConnectivityRulesRequest\x1a@.temporal.api.cloud.cloudservice.v1.GetConnectivityRulesResponse"\xda\x01\x82\xd3\xe4\x93\x02\x1b\x12\x19/cloud/connectivity-rules\x92\x41\xb5\x01\n\x12\x43onnectivity Rules\x12\x1bList all connectivity rules\x1a\x37Returns a list of all connectivity rules in the account"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\x85\x03\n\x16\x44\x65leteConnectivityRule\x12\x41.temporal.api.cloud.cloudservice.v1.DeleteConnectivityRuleRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.DeleteConnectivityRuleResponse"\xe3\x01\x82\xd3\xe4\x93\x02\x32*0/cloud/connectivity-rules/{connectivity_rule_id}\x92\x41\xa7\x01\n\x12\x43onnectivity Rules\x12\x18\x44\x65lete connectivity rule\x1a,Removes a connectivity rule from the account"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\xe2\x02\n\x0cGetAuditLogs\x12\x37.temporal.api.cloud.cloudservice.v1.GetAuditLogsRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetAuditLogsResponse"\xde\x01\x82\xd3\xe4\x93\x02\x13\x12\x11/cloud/audit-logs\x92\x41\xc1\x01\n\x07\x41\x63\x63ount\x12\x0eGet audit logs\x1aYReturns a paginated list of audit logs for the account, optionally filtered by time range"K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xb4\x04\n\x1bValidateAccountAuditLogSink\x12\x46.temporal.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkRequest\x1aG.temporal.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkResponse"\x83\x03\x82\xd3\xe4\x93\x02#"\x1e/cloud/audit-log-sink-validate:\x01*\x92\x41\xd6\x02\n\x07\x41\x63\x63ount\x12\x17Validate audit log sink\x1a\xe4\x01Validate customer audit log sink is accessible from Temporal\'s workflow by delivering an empty file to the specified sink. The operation verifies that the sink is correctly configured, accessible and ready to receive audit logs."K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xf4\x02\n\x19\x43reateAccountAuditLogSink\x12\x44.temporal.api.cloud.cloudservice.v1.CreateAccountAuditLogSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.CreateAccountAuditLogSinkResponse"\xc9\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/audit-log-sinks:\x01*\x92\x41\xa4\x01\n\x07\x41\x63\x63ount\x12\x15\x43reate audit log sink\x1a\x35\x43reates a new audit log sink for exporting audit logs"K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xfb\x02\n\x16GetAccountAuditLogSink\x12\x41.temporal.api.cloud.cloudservice.v1.GetAccountAuditLogSinkRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.GetAccountAuditLogSinkResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/audit-log-sinks/{name}\x92\x41\xb0\x01\n\x07\x41\x63\x63ount\x12\x1aGet audit log sink details\x1a.temporal.api.cloud.cloudservice.v1.CreateBillingReportRequest\x1a?.temporal.api.cloud.cloudservice.v1.CreateBillingReportResponse"\xc1\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/billing-reports:\x01*\x92\x41\x9c\x01\n\x07\x41\x63\x63ount\x12\x17\x43reate a billing report\x1a(Creates a billing report for the account"N\n\x1c\x42illing report documentation\x12.https://docs.temporal.io/cloud/billing-reports\x12\xe6\x02\n\x10GetBillingReport\x12;.temporal.api.cloud.cloudservice.v1.GetBillingReportRequest\x1a<.temporal.api.cloud.cloudservice.v1.GetBillingReportResponse"\xd6\x01\x82\xd3\xe4\x93\x02,\x12*/cloud/billing-reports/{billing_report_id}\x92\x41\xa0\x01\n\x07\x41\x63\x63ount\x12\x14Get a billing report\x1a/Gets an existing billing report for the account"N\n\x1c\x42illing report documentation\x12.https://docs.temporal.io/cloud/billing-reportsB\x86\x15\n%io.temporal.api.cloud.cloudservice.v1B\x0cServiceProtoP\x01Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\xaa\x02$Temporalio.Api.Cloud.CloudService.V1\xea\x02(Temporalio::Api::Cloud::CloudService::V1\x92\x41\xc2\x13\x12\xe0\r\n\x16Temporal Cloud Ops API\x12\x96\x0cProgrammatic access to manage Temporal Cloud control plane resources including namespaces, users, service accounts, and more.\n\n## Authentication\n\nAll API requests require authentication using an API Key. Include your API key in the `Authorization` header using the Bearer scheme:\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\nAPI keys can be created and managed through the [API Keys endpoints](#tag/API-Keys) or via the Temporal Cloud UI. For more information, see [API Keys Documentation](https://docs.temporal.io/cloud/api-keys).\n\n## Authorization\n\nThe API uses Role-Based Access Control (RBAC) to manage permissions. Each operation requires specific role-based permissions in addition to a valid API key.\n\n### Account-Level Roles\n\n- **Account Owner** - Full account administration access\n- **Account Admin** - Manage namespaces, users, and service accounts \n- **Account Developer** - Create namespaces and manage Nexus endpoints\n- **Finance Admin** - View usage and billing information\n- **Account Read** - Read-only access to account resources\n\n### Namespace-Level Roles\n\n- **Namespace Admin** - Full access to namespace configuration and data\n- **Namespace Write** - Execute workflows and modify workflow data\n- **Namespace Read** - Read-only access to namespace data\n\nNamespace-level permissions are scoped to specific namespaces. A user or service account may have different permission levels across different namespaces.\n\nFor detailed information about roles and permissions, see [Access Control Documentation](https://docs.temporal.io/cloud/users).2\x03\x31.0:\xa7\x01\n\x06x-logo\x12\x9c\x01*\x99\x01\n\x96\x01\n\x03url\x12\x8e\x01\x1a\x8b\x01https://images.ctfassets.net/0uuz8ydxyd9p/4YGUnEoCaH9SyoUDhlJkau/e1600205d17eeee3033d926ef06664a9/Temporal_LogoLockup_Horizontal_dark_1.svgj.\n\nNamespaces\x12 Manage Temporal Cloud namespacesj0\n\x05Users\x12\'Manage users and their namespace accessjF\n\x10Service Accounts\x12\x32Manage service accounts and their namespace accessj.\n\x08\x41PI Keys\x12"Manage API keys for authenticationj1\n\x06Groups\x12\'Manage user groups and group membershipj\x1f\n\x05Nexus\x12\x16Manage Nexus endpointsj\x7f\n\x11High Availability\x12jManage high availability (multi-region, multi-cloud, and same-region replication) namespace configurationsj7\n\x06\x45xport\x12-Manage workflow history export configurationsj7\n\x12\x43onnectivity Rules\x12!Manage network connectivity rulesj"\n\x07Regions\x12\x17Query available regionsj,\n\x07\x41\x63\x63ount\x12!Manage account settings and usagej*\n\nOperations\x12\x1cQuery async operation statusr>\n\x1cTemporal Cloud Documentation\x12\x1ehttps://docs.temporal.io/cloudb\x06proto3' + b'\n0temporal/api/cloud/cloudservice/v1/service.proto\x12"temporal.api.cloud.cloudservice.v1\x1a\x39temporal/api/cloud/cloudservice/v1/request_response.proto\x1a\x1cgoogle/api/annotations.proto\x1a.protoc-gen-openapiv2/options/annotations.proto2\xc2\xcb\x01\n\x0c\x43loudService\x12\xb0\x02\n\x12GetCurrentIdentity\x12=.temporal.api.cloud.cloudservice.v1.GetCurrentIdentityRequest\x1a>.temporal.api.cloud.cloudservice.v1.GetCurrentIdentityResponse"\x9a\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/current-identity\x92\x41x\n\x07\x41\x63\x63ount\x12\x14Get current identity\x1aWReturns information about the currently authenticated user or service account principal\x12\xa5\x02\n\x08GetUsers\x12\x33.temporal.api.cloud.cloudservice.v1.GetUsersRequest\x1a\x34.temporal.api.cloud.cloudservice.v1.GetUsersResponse"\xad\x01\x82\xd3\xe4\x93\x02\x0e\x12\x0c/cloud/users\x92\x41\x95\x01\n\x05Users\x12\x0eList all users\x1a*Returns a list of all users in the account"E\n\x1dUser management documentation\x12$https://docs.temporal.io/cloud/users*\tlistUsers\x12\x9c\x02\n\x07GetUser\x12\x32.temporal.api.cloud.cloudservice.v1.GetUserRequest\x1a\x33.temporal.api.cloud.cloudservice.v1.GetUserResponse"\xa7\x01\x82\xd3\xe4\x93\x02\x18\x12\x16/cloud/users/{user_id}\x92\x41\x85\x01\n\x05Users\x12\x0eGet user by ID\x1a%Takes a user ID, returns user details"E\n\x1dUser management documentation\x12$https://docs.temporal.io/cloud/users\x12\xd0\x01\n\nCreateUser\x12\x35.temporal.api.cloud.cloudservice.v1.CreateUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.CreateUserResponse"S\x82\xd3\xe4\x93\x02\x11"\x0c/cloud/users:\x01*\x92\x41\x39\n\x05Users\x12\rCreate a user\x1a!Creates a new user in the account\x12\xdb\x01\n\nUpdateUser\x12\x35.temporal.api.cloud.cloudservice.v1.UpdateUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.UpdateUserResponse"^\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/users/{user_id}:\x01*\x92\x41:\n\x05Users\x12\rUpdate a user\x1a"Updates an existing user\'s details\x12\xd5\x01\n\nDeleteUser\x12\x35.temporal.api.cloud.cloudservice.v1.DeleteUserRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.DeleteUserResponse"X\x82\xd3\xe4\x93\x02\x18*\x16/cloud/users/{user_id}\x92\x41\x37\n\x05Users\x12\rDelete a user\x1a\x1fRemoves a user from the account\x12\xaa\x03\n\x16SetUserNamespaceAccess\x12\x41.temporal.api.cloud.cloudservice.v1.SetUserNamespaceAccessRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.SetUserNamespaceAccessResponse"\x88\x02\x82\xd3\xe4\x93\x02\x39"4/cloud/namespaces/{namespace}/users/{user_id}/access:\x01*\x92\x41\xc5\x01\n\x05Users\x12\x19Set user namespace access\x1a\x38\x43onfigures a user\'s permissions for a specific namespace"g\n#Namespace permissions documentation\x12@https://docs.temporal.io/cloud/users-namespace-level-permissions\x12\xb1\x02\n\x11GetAsyncOperation\x12<.temporal.api.cloud.cloudservice.v1.GetAsyncOperationRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetAsyncOperationResponse"\x9e\x01\x82\xd3\xe4\x93\x02(\x12&/cloud/operations/{async_operation_id}\x92\x41m\n\nOperations\x12\x1aGet async operation status\x1a\x43Returns the current status and details of an asynchronous operation\x12\xc6\x02\n\x0f\x43reateNamespace\x12:.temporal.api.cloud.cloudservice.v1.CreateNamespaceRequest\x1a;.temporal.api.cloud.cloudservice.v1.CreateNamespaceResponse"\xb9\x01\x82\xd3\xe4\x93\x02\x16"\x11/cloud/namespaces:\x01*\x92\x41\x99\x01\n\nNamespaces\x12\x12\x43reate a namespace\x1a&Creates a new namespace in the account"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xc7\x02\n\rGetNamespaces\x12\x38.temporal.api.cloud.cloudservice.v1.GetNamespacesRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.GetNamespacesResponse"\xc0\x01\x82\xd3\xe4\x93\x02\x13\x12\x11/cloud/namespaces\x92\x41\xa3\x01\n\nNamespaces\x12\x13List all namespaces\x1a/Returns a list of all namespaces in the account"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xda\x02\n\x0cGetNamespace\x12\x37.temporal.api.cloud.cloudservice.v1.GetNamespaceRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetNamespaceResponse"\xd6\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/namespaces/{namespace}\x92\x41\xad\x01\n\nNamespaces\x12\x15Get namespace details\x1a\x37Returns detailed information about a specific namespace"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xdb\x02\n\x0fUpdateNamespace\x12:.temporal.api.cloud.cloudservice.v1.UpdateNamespaceRequest\x1a;.temporal.api.cloud.cloudservice.v1.UpdateNamespaceResponse"\xce\x01\x82\xd3\xe4\x93\x02""\x1d/cloud/namespaces/{namespace}:\x01*\x92\x41\xa2\x01\n\nNamespaces\x12\x12Update a namespace\x1a/Updates configuration for an existing namespace"O\n"Namespace management documentation\x12)https://docs.temporal.io/cloud/namespaces\x12\xc7\x03\n\x1bRenameCustomSearchAttribute\x12\x46.temporal.api.cloud.cloudservice.v1.RenameCustomSearchAttributeRequest\x1aG.temporal.api.cloud.cloudservice.v1.RenameCustomSearchAttributeResponse"\x96\x02\x82\xd3\xe4\x93\x02\x41".temporal.api.cloud.cloudservice.v1.AddNamespaceRegionResponse"\xf0\x01\x88\x02\x01\x82\xd3\xe4\x93\x02-"(/cloud/namespaces/{namespace}/add-region:\x01*\x92\x41\xb6\x01\n\x11High Availability\x12\x15\x41\x64\x64 namespace replica\x1a+Adds a new replica to an existing namespace"]\n)High availability namespace documentation\x12\x30https://docs.temporal.io/cloud/high-availability\x12\x9e\x03\n\x15\x44\x65leteNamespaceRegion\x12@.temporal.api.cloud.cloudservice.v1.DeleteNamespaceRegionRequest\x1a\x41.temporal.api.cloud.cloudservice.v1.DeleteNamespaceRegionResponse"\xff\x01\x88\x02\x01\x82\xd3\xe4\x93\x02\x30*./cloud/namespaces/{namespace}/regions/{region}\x92\x41\xc2\x01\n\x11High Availability\x12\x18Remove namespace replica\x1a\x34Removes a replica from a high availability namespace"]\n)High availability namespace documentation\x12\x30https://docs.temporal.io/cloud/high-availability\x12\xa3\x02\n\nGetRegions\x12\x35.temporal.api.cloud.cloudservice.v1.GetRegionsRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetRegionsResponse"\xa5\x01\x82\xd3\xe4\x93\x02\x10\x12\x0e/cloud/regions\x92\x41\x8b\x01\n\x07Regions\x12\x10List all regions\x1a-Returns a list of all available cloud regions"?\n\x15Regions documentation\x12&https://docs.temporal.io/cloud/regions\x12\xb2\x02\n\tGetRegion\x12\x34.temporal.api.cloud.cloudservice.v1.GetRegionRequest\x1a\x35.temporal.api.cloud.cloudservice.v1.GetRegionResponse"\xb7\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/regions/{region}\x92\x41\x94\x01\n\x07Regions\x12\x12Get region details\x1a\x34Returns detailed information about a specific region"?\n\x15Regions documentation\x12&https://docs.temporal.io/cloud/regions\x12\xa8\x02\n\nGetApiKeys\x12\x35.temporal.api.cloud.cloudservice.v1.GetApiKeysRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetApiKeysResponse"\xaa\x01\x82\xd3\xe4\x93\x02\x11\x12\x0f/cloud/api-keys\x92\x41\x8f\x01\n\x08\x41PI Keys\x12\x11List all API keys\x1a-Returns a list of all API keys in the account"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb8\x02\n\tGetApiKey\x12\x34.temporal.api.cloud.cloudservice.v1.GetApiKeyRequest\x1a\x35.temporal.api.cloud.cloudservice.v1.GetApiKeyResponse"\xbd\x01\x82\xd3\xe4\x93\x02\x1a\x12\x18/cloud/api-keys/{key_id}\x92\x41\x99\x01\n\x08\x41PI Keys\x12\x13Get API key details\x1a\x35Returns detailed information about a specific API key"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb1\x02\n\x0c\x43reateApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.CreateApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.CreateApiKeyResponse"\xad\x01\x82\xd3\xe4\x93\x02\x14"\x0f/cloud/api-keys:\x01*\x92\x41\x8f\x01\n\x08\x41PI Keys\x12\x11\x43reate an API key\x1a-Creates a new API key for programmatic access"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xb5\x02\n\x0cUpdateApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.UpdateApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.UpdateApiKeyResponse"\xb1\x01\x82\xd3\xe4\x93\x02\x1d"\x18/cloud/api-keys/{key_id}:\x01*\x92\x41\x8a\x01\n\x08\x41PI Keys\x12\x11Update an API key\x1a(Updates an existing API key\'s properties"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xa8\x02\n\x0c\x44\x65leteApiKey\x12\x37.temporal.api.cloud.cloudservice.v1.DeleteApiKeyRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.DeleteApiKeyResponse"\xa4\x01\x82\xd3\xe4\x93\x02\x1a*\x18/cloud/api-keys/{key_id}\x92\x41\x80\x01\n\x08\x41PI Keys\x12\x11\x44\x65lete an API key\x1a\x1eRevokes and deletes an API key"A\n\x16\x41PI Keys documentation\x12\'https://docs.temporal.io/cloud/api-keys\x12\xc3\x02\n\x11GetNexusEndpoints\x12<.temporal.api.cloud.cloudservice.v1.GetNexusEndpointsRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetNexusEndpointsResponse"\xb0\x01\x82\xd3\xe4\x93\x02\x18\x12\x16/cloud/nexus/endpoints\x92\x41\x8e\x01\n\x05Nexus\x12\x18List all Nexus endpoints\x1a\x34Returns a list of all Nexus endpoints in the account"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xd8\x02\n\x10GetNexusEndpoint\x12;.temporal.api.cloud.cloudservice.v1.GetNexusEndpointRequest\x1a<.temporal.api.cloud.cloudservice.v1.GetNexusEndpointResponse"\xc8\x01\x82\xd3\xe4\x93\x02&\x12$/cloud/nexus/endpoints/{endpoint_id}\x92\x41\x98\x01\n\x05Nexus\x12\x1aGet Nexus endpoint details\x1a.temporal.api.cloud.cloudservice.v1.CreateNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.CreateNexusEndpointResponse"\xbc\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/nexus/endpoints:\x01*\x92\x41\x97\x01\n\x05Nexus\x12\x17\x43reate a Nexus endpoint\x1a>Creates a new Nexus endpoint for cross-namespace communication"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xd7\x02\n\x13UpdateNexusEndpoint\x12>.temporal.api.cloud.cloudservice.v1.UpdateNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.UpdateNexusEndpointResponse"\xbe\x01\x82\xd3\xe4\x93\x02)"$/cloud/nexus/endpoints/{endpoint_id}:\x01*\x92\x41\x8b\x01\n\x05Nexus\x12\x17Update a Nexus endpoint\x1a\x32Updates an existing Nexus endpoint\'s configuration"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xcb\x02\n\x13\x44\x65leteNexusEndpoint\x12>.temporal.api.cloud.cloudservice.v1.DeleteNexusEndpointRequest\x1a?.temporal.api.cloud.cloudservice.v1.DeleteNexusEndpointResponse"\xb2\x01\x82\xd3\xe4\x93\x02&*$/cloud/nexus/endpoints/{endpoint_id}\x92\x41\x82\x01\n\x05Nexus\x12\x17\x44\x65lete a Nexus endpoint\x1a)Removes a Nexus endpoint from the account"5\n\x13Nexus documentation\x12\x1ehttps://docs.temporal.io/nexus\x12\xcc\x02\n\rGetUserGroups\x12\x38.temporal.api.cloud.cloudservice.v1.GetUserGroupsRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.GetUserGroupsResponse"\xc5\x01\x82\xd3\xe4\x93\x02\x14\x12\x12/cloud/user-groups\x92\x41\xa7\x01\n\x06Groups\x12\x14List all user groups\x1a\x30Returns a list of all user groups in the account"U\n\x19User groups documentation\x12\x38https://docs.temporal.io/cloud/users-account-level-roles\x12\xd0\x02\n\x0cGetUserGroup\x12\x37.temporal.api.cloud.cloudservice.v1.GetUserGroupRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetUserGroupResponse"\xcc\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/user-groups/{group_id}\x92\x41\xa3\x01\n\x06Groups\x12\x16Get user group details\x1a\x38Returns detailed information about a specific user group"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xc7\x02\n\x0f\x43reateUserGroup\x12:.temporal.api.cloud.cloudservice.v1.CreateUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.CreateUserGroupResponse"\xba\x01\x82\xd3\xe4\x93\x02\x17"\x12/cloud/user-groups:\x01*\x92\x41\x99\x01\n\x06Groups\x12\x13\x43reate a user group\x1a\x31\x43reates a new user group for managing permissions"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xcc\x02\n\x0fUpdateUserGroup\x12:.temporal.api.cloud.cloudservice.v1.UpdateUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.UpdateUserGroupResponse"\xbf\x01\x82\xd3\xe4\x93\x02""\x1d/cloud/user-groups/{group_id}:\x01*\x92\x41\x93\x01\n\x06Groups\x12\x13Update a user group\x1a+Updates an existing user group\'s properties"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xc3\x02\n\x0f\x44\x65leteUserGroup\x12:.temporal.api.cloud.cloudservice.v1.DeleteUserGroupRequest\x1a;.temporal.api.cloud.cloudservice.v1.DeleteUserGroupResponse"\xb6\x01\x82\xd3\xe4\x93\x02\x1f*\x1d/cloud/user-groups/{group_id}\x92\x41\x8d\x01\n\x06Groups\x12\x13\x44\x65lete a user group\x1a%Removes a user group from the account"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xad\x03\n\x1bSetUserGroupNamespaceAccess\x12\x46.temporal.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessRequest\x1aG.temporal.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessResponse"\xfc\x01\x82\xd3\xe4\x93\x02@";/cloud/namespaces/{namespace}/user-groups/{group_id}/access:\x01*\x92\x41\xb2\x01\n\x06Groups\x12\x1fSet user group namespace access\x1a>Configures a user group\'s permissions for a specific namespace"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xdf\x02\n\x12\x41\x64\x64UserGroupMember\x12=.temporal.api.cloud.cloudservice.v1.AddUserGroupMemberRequest\x1a>.temporal.api.cloud.cloudservice.v1.AddUserGroupMemberResponse"\xc9\x01\x82\xd3\xe4\x93\x02*"%/cloud/user-groups/{group_id}/members:\x01*\x92\x41\x95\x01\n\x06Groups\x12\x11\x41\x64\x64 user to group\x1a/Adds a user to a user group (Cloud groups only)"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xf8\x02\n\x15RemoveUserGroupMember\x12@.temporal.api.cloud.cloudservice.v1.RemoveUserGroupMemberRequest\x1a\x41.temporal.api.cloud.cloudservice.v1.RemoveUserGroupMemberResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x30"+/cloud/user-groups/{group_id}/remove-member:\x01*\x92\x41\x9f\x01\n\x06Groups\x12\x16Remove user from group\x1a\x34Removes a user from a user group (Cloud groups only)"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xdf\x02\n\x13GetUserGroupMembers\x12>.temporal.api.cloud.cloudservice.v1.GetUserGroupMembersRequest\x1a?.temporal.api.cloud.cloudservice.v1.GetUserGroupMembersResponse"\xc6\x01\x82\xd3\xe4\x93\x02\'\x12%/cloud/user-groups/{group_id}/members\x92\x41\x95\x01\n\x06Groups\x12\x15List users in a group\x1a+Returns a list of all users in a user group"G\n\x19User groups documentation\x12*https://docs.temporal.io/cloud/user-groups\x12\xf5\x02\n\x14\x43reateServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.CreateServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.CreateServiceAccountResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x1c"\x17/cloud/service-accounts:\x01*\x92\x41\xb3\x01\n\x10Service Accounts\x12\x18\x43reate a service account\x1a\x32\x43reates a new service account for automated access"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\x8c\x03\n\x11GetServiceAccount\x12<.temporal.api.cloud.cloudservice.v1.GetServiceAccountRequest\x1a=.temporal.api.cloud.cloudservice.v1.GetServiceAccountResponse"\xf9\x01\x82\xd3\xe4\x93\x02.\x12,/cloud/service-accounts/{service_account_id}\x92\x41\xc1\x01\n\x10Service Accounts\x12\x1bGet service account details\x1a=Returns detailed information about a specific service account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xf0\x02\n\x12GetServiceAccounts\x12=.temporal.api.cloud.cloudservice.v1.GetServiceAccountsRequest\x1a>.temporal.api.cloud.cloudservice.v1.GetServiceAccountsResponse"\xda\x01\x82\xd3\xe4\x93\x02\x19\x12\x17/cloud/service-accounts\x92\x41\xb7\x01\n\x10Service Accounts\x12\x19List all service accounts\x1a\x35Returns a list of all service accounts in the account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\x88\x03\n\x14UpdateServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.UpdateServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.UpdateServiceAccountResponse"\xec\x01\x82\xd3\xe4\x93\x02\x31",/cloud/service-accounts/{service_account_id}:\x01*\x92\x41\xb1\x01\n\x10Service Accounts\x12\x18Update a service account\x1a\x30Updates an existing service account\'s properties"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xe9\x03\n SetServiceAccountNamespaceAccess\x12K.temporal.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessRequest\x1aL.temporal.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessResponse"\xa9\x02\x82\xd3\xe4\x93\x02O"J/cloud/namespaces/{namespace}/service-accounts/{service_account_id}/access:\x01*\x92\x41\xd0\x01\n\x10Service Accounts\x12$Set service account namespace access\x1a\x43\x43onfigures a service account\'s permissions for a specific namespace"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xff\x02\n\x14\x44\x65leteServiceAccount\x12?.temporal.api.cloud.cloudservice.v1.DeleteServiceAccountRequest\x1a@.temporal.api.cloud.cloudservice.v1.DeleteServiceAccountResponse"\xe3\x01\x82\xd3\xe4\x93\x02.*,/cloud/service-accounts/{service_account_id}\x92\x41\xab\x01\n\x10Service Accounts\x12\x18\x44\x65lete a service account\x1a*Removes a service account from the account"Q\n\x1eService Accounts documentation\x12/https://docs.temporal.io/cloud/service-accounts\x12\xcb\x01\n\x08GetUsage\x12\x33.temporal.api.cloud.cloudservice.v1.GetUsageRequest\x1a\x34.temporal.api.cloud.cloudservice.v1.GetUsageResponse"T\x82\xd3\xe4\x93\x02\x0e\x12\x0c/cloud/usage\x92\x41=\n\x07\x41\x63\x63ount\x12\x0eGet usage data\x1a Get usage data across namespacesX\x01\x12\xb0\x02\n\nGetAccount\x12\x35.temporal.api.cloud.cloudservice.v1.GetAccountRequest\x1a\x36.temporal.api.cloud.cloudservice.v1.GetAccountResponse"\xb2\x01\x82\xd3\xe4\x93\x02\x10\x12\x0e/cloud/account\x92\x41\x98\x01\n\x07\x41\x63\x63ount\x12\x13Get account details\x1a.Returns detailed information about the account"H\n\x15\x42illing documentation\x12/https://docs.temporal.io/cloud/billing-and-cost\x12\xbb\x02\n\rUpdateAccount\x12\x38.temporal.api.cloud.cloudservice.v1.UpdateAccountRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.UpdateAccountResponse"\xb4\x01\x82\xd3\xe4\x93\x02\x13"\x0e/cloud/account:\x01*\x92\x41\x97\x01\n\x07\x41\x63\x63ount\x12\x16Update account details\x1a*Updates account configuration and settings"H\n\x15\x42illing documentation\x12/https://docs.temporal.io/cloud/billing-and-cost\x12\xf3\x02\n\x19\x43reateNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.CreateNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.CreateNamespaceExportSinkResponse"\xc8\x01\x82\xd3\xe4\x93\x02/"*/cloud/namespaces/{namespace}/export-sinks:\x01*\x92\x41\x8f\x01\n\x06\x45xport\x12\x1a\x43reate history export sink\x1a*Creates a new workflow history export sink"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x8c\x03\n\x16GetNamespaceExportSink\x12\x41.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinkRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinkResponse"\xea\x01\x82\xd3\xe4\x93\x02\x33\x12\x31/cloud/namespaces/{namespace}/export-sinks/{name}\x92\x41\xad\x01\n\x06\x45xport\x12\x18Get history sink details\x1aJReturns detailed information about a specific workflow history export sink"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x82\x03\n\x17GetNamespaceExportSinks\x12\x42.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinksRequest\x1a\x43.temporal.api.cloud.cloudservice.v1.GetNamespaceExportSinksResponse"\xdd\x01\x82\xd3\xe4\x93\x02,\x12*/cloud/namespaces/{namespace}/export-sinks\x92\x41\xa7\x01\n\x06\x45xport\x12\x19List history export sinks\x1a\x43Returns a list of all workflow history export sinks for a namespace"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x95\x03\n\x19UpdateNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkResponse"\xea\x01\x82\xd3\xe4\x93\x02;"6/cloud/namespaces/{namespace}/export-sinks/{spec.name}:\x01*\x92\x41\xa5\x01\n\x06\x45xport\x12\x1aUpdate history export sink\x1a@Updates an existing workflow history export sink\'s configuration"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\x84\x03\n\x19\x44\x65leteNamespaceExportSink\x12\x44.temporal.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x33*1/cloud/namespaces/{namespace}/export-sinks/{name}\x92\x41\x9c\x01\n\x06\x45xport\x12\x1a\x44\x65lete history export sink\x1a\x37Removes a workflow history export sink from a namespace"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\xc9\x03\n\x1bValidateNamespaceExportSink\x12\x46.temporal.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkRequest\x1aG.temporal.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkResponse"\x98\x02\x82\xd3\xe4\x93\x02\x37"2/cloud/namespaces/{namespace}/export-sink-validate:\x01*\x92\x41\xd7\x01\n\x06\x45xport\x12*Validate history export sink configuration\x1a\x62Tests workflow history export sink configuration by delivering a test file to verify accessibility"=\n\x14\x45xport documentation\x12%https://docs.temporal.io/cloud/export\x12\xfc\x02\n\x13UpdateNamespaceTags\x12>.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsRequest\x1a?.temporal.api.cloud.cloudservice.v1.UpdateNamespaceTagsResponse"\xe3\x01\x82\xd3\xe4\x93\x02.")/cloud/namespaces/{namespace}/update-tags:\x01*\x92\x41\xab\x01\n\nNamespaces\x12\x15Update namespace tags\x1a,Updates the tags associated with a namespace"X\n\x1bNamespace tag documentation\x12\x39https://docs.temporal.io/cloud/namespaces#tag-a-namespace\x12\xff\x02\n\x16\x43reateConnectivityRule\x12\x41.temporal.api.cloud.cloudservice.v1.CreateConnectivityRuleRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.CreateConnectivityRuleResponse"\xdd\x01\x82\xd3\xe4\x93\x02\x1e"\x19/cloud/connectivity-rules:\x01*\x92\x41\xb5\x01\n\x12\x43onnectivity Rules\x12\x18\x43reate connectivity rule\x1a:Creates a new connectivity rule for network access control"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\x94\x03\n\x13GetConnectivityRule\x12>.temporal.api.cloud.cloudservice.v1.GetConnectivityRuleRequest\x1a?.temporal.api.cloud.cloudservice.v1.GetConnectivityRuleResponse"\xfb\x01\x82\xd3\xe4\x93\x02\x32\x12\x30/cloud/connectivity-rules/{connectivity_rule_id}\x92\x41\xbf\x01\n\x12\x43onnectivity Rules\x12\x1dGet connectivity rule details\x1a?Returns detailed information about a specific connectivity rule"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\xf6\x02\n\x14GetConnectivityRules\x12?.temporal.api.cloud.cloudservice.v1.GetConnectivityRulesRequest\x1a@.temporal.api.cloud.cloudservice.v1.GetConnectivityRulesResponse"\xda\x01\x82\xd3\xe4\x93\x02\x1b\x12\x19/cloud/connectivity-rules\x92\x41\xb5\x01\n\x12\x43onnectivity Rules\x12\x1bList all connectivity rules\x1a\x37Returns a list of all connectivity rules in the account"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\x85\x03\n\x16\x44\x65leteConnectivityRule\x12\x41.temporal.api.cloud.cloudservice.v1.DeleteConnectivityRuleRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.DeleteConnectivityRuleResponse"\xe3\x01\x82\xd3\xe4\x93\x02\x32*0/cloud/connectivity-rules/{connectivity_rule_id}\x92\x41\xa7\x01\n\x12\x43onnectivity Rules\x12\x18\x44\x65lete connectivity rule\x1a,Removes a connectivity rule from the account"I\n\x1a\x43onnectivity documentation\x12+https://docs.temporal.io/cloud/connectivity\x12\xe2\x02\n\x0cGetAuditLogs\x12\x37.temporal.api.cloud.cloudservice.v1.GetAuditLogsRequest\x1a\x38.temporal.api.cloud.cloudservice.v1.GetAuditLogsResponse"\xde\x01\x82\xd3\xe4\x93\x02\x13\x12\x11/cloud/audit-logs\x92\x41\xc1\x01\n\x07\x41\x63\x63ount\x12\x0eGet audit logs\x1aYReturns a paginated list of audit logs for the account, optionally filtered by time range"K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xb4\x04\n\x1bValidateAccountAuditLogSink\x12\x46.temporal.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkRequest\x1aG.temporal.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkResponse"\x83\x03\x82\xd3\xe4\x93\x02#"\x1e/cloud/audit-log-sink-validate:\x01*\x92\x41\xd6\x02\n\x07\x41\x63\x63ount\x12\x17Validate audit log sink\x1a\xe4\x01Validate customer audit log sink is accessible from Temporal\'s workflow by delivering an empty file to the specified sink. The operation verifies that the sink is correctly configured, accessible and ready to receive audit logs."K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xf4\x02\n\x19\x43reateAccountAuditLogSink\x12\x44.temporal.api.cloud.cloudservice.v1.CreateAccountAuditLogSinkRequest\x1a\x45.temporal.api.cloud.cloudservice.v1.CreateAccountAuditLogSinkResponse"\xc9\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/audit-log-sinks:\x01*\x92\x41\xa4\x01\n\x07\x41\x63\x63ount\x12\x15\x43reate audit log sink\x1a\x35\x43reates a new audit log sink for exporting audit logs"K\n\x1b\x41udit logging documentation\x12,https://docs.temporal.io/cloud/audit-logging\x12\xfb\x02\n\x16GetAccountAuditLogSink\x12\x41.temporal.api.cloud.cloudservice.v1.GetAccountAuditLogSinkRequest\x1a\x42.temporal.api.cloud.cloudservice.v1.GetAccountAuditLogSinkResponse"\xd9\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/audit-log-sinks/{name}\x92\x41\xb0\x01\n\x07\x41\x63\x63ount\x12\x1aGet audit log sink details\x1a.temporal.api.cloud.cloudservice.v1.CreateBillingReportRequest\x1a?.temporal.api.cloud.cloudservice.v1.CreateBillingReportResponse"\xc1\x01\x82\xd3\xe4\x93\x02\x1b"\x16/cloud/billing-reports:\x01*\x92\x41\x9c\x01\n\x07\x41\x63\x63ount\x12\x17\x43reate a billing report\x1a(Creates a billing report for the account"N\n\x1c\x42illing report documentation\x12.https://docs.temporal.io/cloud/billing-reports\x12\xe6\x02\n\x10GetBillingReport\x12;.temporal.api.cloud.cloudservice.v1.GetBillingReportRequest\x1a<.temporal.api.cloud.cloudservice.v1.GetBillingReportResponse"\xd6\x01\x82\xd3\xe4\x93\x02,\x12*/cloud/billing-reports/{billing_report_id}\x92\x41\xa0\x01\n\x07\x41\x63\x63ount\x12\x14Get a billing report\x1a/Gets an existing billing report for the account"N\n\x1c\x42illing report documentation\x12.https://docs.temporal.io/cloud/billing-reports\x12\xc4\x02\n\x0eGetCustomRoles\x12\x39.temporal.api.cloud.cloudservice.v1.GetCustomRolesRequest\x1a:.temporal.api.cloud.cloudservice.v1.GetCustomRolesResponse"\xba\x01\x82\xd3\xe4\x93\x02\x15\x12\x13/cloud/custom-roles\x92\x41\x9b\x01\n\x0c\x43ustom Roles\x12\x11List custom roles\x1a-Returns a list of custom roles in the account"I\n\x1a\x43ustom roles documentation\x12+https://docs.temporal.io/cloud/custom-roles\x12\xcc\x02\n\rGetCustomRole\x12\x38.temporal.api.cloud.cloudservice.v1.GetCustomRoleRequest\x1a\x39.temporal.api.cloud.cloudservice.v1.GetCustomRoleResponse"\xc5\x01\x82\xd3\xe4\x93\x02\x1f\x12\x1d/cloud/custom-roles/{role_id}\x92\x41\x9c\x01\n\x0c\x43ustom Roles\x12\x15Get custom role by ID\x1a*Returns details for a specific custom role"I\n\x1a\x43ustom roles documentation\x12+https://docs.temporal.io/cloud/custom-roles\x12\xcb\x02\n\x10\x43reateCustomRole\x12;.temporal.api.cloud.cloudservice.v1.CreateCustomRoleRequest\x1a<.temporal.api.cloud.cloudservice.v1.CreateCustomRoleResponse"\xbb\x01\x82\xd3\xe4\x93\x02\x18"\x13/cloud/custom-roles:\x01*\x92\x41\x99\x01\n\x0c\x43ustom Roles\x12\x14\x43reate a custom role\x1a(Creates a new custom role in the account"I\n\x1a\x43ustom roles documentation\x12+https://docs.temporal.io/cloud/custom-roles\x12\xcc\x02\n\x10UpdateCustomRole\x12;.temporal.api.cloud.cloudservice.v1.UpdateCustomRoleRequest\x1a<.temporal.api.cloud.cloudservice.v1.UpdateCustomRoleResponse"\xbc\x01\x82\xd3\xe4\x93\x02""\x1d/cloud/custom-roles/{role_id}:\x01*\x92\x41\x90\x01\n\x0c\x43ustom Roles\x12\x14Update a custom role\x1a\x1fUpdates an existing custom role"I\n\x1a\x43ustom roles documentation\x12+https://docs.temporal.io/cloud/custom-roles\x12\xd0\x02\n\x10\x44\x65leteCustomRole\x12;.temporal.api.cloud.cloudservice.v1.DeleteCustomRoleRequest\x1a<.temporal.api.cloud.cloudservice.v1.DeleteCustomRoleResponse"\xc0\x01\x82\xd3\xe4\x93\x02\x1f*\x1d/cloud/custom-roles/{role_id}\x92\x41\x97\x01\n\x0c\x43ustom Roles\x12\x14\x44\x65lete a custom role\x1a&Deletes a custom role from the account"I\n\x1a\x43ustom roles documentation\x12+https://docs.temporal.io/cloud/custom-rolesB\xc1\x15\n%io.temporal.api.cloud.cloudservice.v1B\x0cServiceProtoP\x01Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\xaa\x02$Temporalio.Api.Cloud.CloudService.V1\xea\x02(Temporalio::Api::Cloud::CloudService::V1\x92\x41\xfd\x13\x12\xe0\r\n\x16Temporal Cloud Ops API\x12\x96\x0cProgrammatic access to manage Temporal Cloud control plane resources including namespaces, users, service accounts, and more.\n\n## Authentication\n\nAll API requests require authentication using an API Key. Include your API key in the `Authorization` header using the Bearer scheme:\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\nAPI keys can be created and managed through the [API Keys endpoints](#tag/API-Keys) or via the Temporal Cloud UI. For more information, see [API Keys Documentation](https://docs.temporal.io/cloud/api-keys).\n\n## Authorization\n\nThe API uses Role-Based Access Control (RBAC) to manage permissions. Each operation requires specific role-based permissions in addition to a valid API key.\n\n### Account-Level Roles\n\n- **Account Owner** - Full account administration access\n- **Account Admin** - Manage namespaces, users, and service accounts \n- **Account Developer** - Create namespaces and manage Nexus endpoints\n- **Finance Admin** - View usage and billing information\n- **Account Read** - Read-only access to account resources\n\n### Namespace-Level Roles\n\n- **Namespace Admin** - Full access to namespace configuration and data\n- **Namespace Write** - Execute workflows and modify workflow data\n- **Namespace Read** - Read-only access to namespace data\n\nNamespace-level permissions are scoped to specific namespaces. A user or service account may have different permission levels across different namespaces.\n\nFor detailed information about roles and permissions, see [Access Control Documentation](https://docs.temporal.io/cloud/users).2\x03\x31.0:\xa7\x01\n\x06x-logo\x12\x9c\x01*\x99\x01\n\x96\x01\n\x03url\x12\x8e\x01\x1a\x8b\x01https://images.ctfassets.net/0uuz8ydxyd9p/4YGUnEoCaH9SyoUDhlJkau/e1600205d17eeee3033d926ef06664a9/Temporal_LogoLockup_Horizontal_dark_1.svgj.\n\nNamespaces\x12 Manage Temporal Cloud namespacesj0\n\x05Users\x12\'Manage users and their namespace accessjF\n\x10Service Accounts\x12\x32Manage service accounts and their namespace accessj.\n\x08\x41PI Keys\x12"Manage API keys for authenticationj1\n\x06Groups\x12\'Manage user groups and group membershipj\x1f\n\x05Nexus\x12\x16Manage Nexus endpointsj\x7f\n\x11High Availability\x12jManage high availability (multi-region, multi-cloud, and same-region replication) namespace configurationsj7\n\x06\x45xport\x12-Manage workflow history export configurationsj7\n\x12\x43onnectivity Rules\x12!Manage network connectivity rulesj"\n\x07Regions\x12\x17Query available regionsj,\n\x07\x41\x63\x63ount\x12!Manage account settings and usagej9\n\x0c\x43ustom Roles\x12)Manage custom roles and their permissionsj*\n\nOperations\x12\x1cQuery async operation statusr>\n\x1cTemporal Cloud Documentation\x12\x1ehttps://docs.temporal.io/cloudb\x06proto3' ) _CLOUDSERVICE = DESCRIPTOR.services_by_name["CloudService"] if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b"\n%io.temporal.api.cloud.cloudservice.v1B\014ServiceProtoP\001Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\252\002$Temporalio.Api.Cloud.CloudService.V1\352\002(Temporalio::Api::Cloud::CloudService::V1\222A\302\023\022\340\r\n\026Temporal Cloud Ops API\022\226\014Programmatic access to manage Temporal Cloud control plane resources including namespaces, users, service accounts, and more.\n\n## Authentication\n\nAll API requests require authentication using an API Key. Include your API key in the `Authorization` header using the Bearer scheme:\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\nAPI keys can be created and managed through the [API Keys endpoints](#tag/API-Keys) or via the Temporal Cloud UI. For more information, see [API Keys Documentation](https://docs.temporal.io/cloud/api-keys).\n\n## Authorization\n\nThe API uses Role-Based Access Control (RBAC) to manage permissions. Each operation requires specific role-based permissions in addition to a valid API key.\n\n### Account-Level Roles\n\n- **Account Owner** - Full account administration access\n- **Account Admin** - Manage namespaces, users, and service accounts \n- **Account Developer** - Create namespaces and manage Nexus endpoints\n- **Finance Admin** - View usage and billing information\n- **Account Read** - Read-only access to account resources\n\n### Namespace-Level Roles\n\n- **Namespace Admin** - Full access to namespace configuration and data\n- **Namespace Write** - Execute workflows and modify workflow data\n- **Namespace Read** - Read-only access to namespace data\n\nNamespace-level permissions are scoped to specific namespaces. A user or service account may have different permission levels across different namespaces.\n\nFor detailed information about roles and permissions, see [Access Control Documentation](https://docs.temporal.io/cloud/users).2\0031.0:\247\001\n\006x-logo\022\234\001*\231\001\n\226\001\n\003url\022\216\001\032\213\001https://images.ctfassets.net/0uuz8ydxyd9p/4YGUnEoCaH9SyoUDhlJkau/e1600205d17eeee3033d926ef06664a9/Temporal_LogoLockup_Horizontal_dark_1.svgj.\n\nNamespaces\022 Manage Temporal Cloud namespacesj0\n\005Users\022'Manage users and their namespace accessjF\n\020Service Accounts\0222Manage service accounts and their namespace accessj.\n\010API Keys\022\"Manage API keys for authenticationj1\n\006Groups\022'Manage user groups and group membershipj\037\n\005Nexus\022\026Manage Nexus endpointsj\177\n\021High Availability\022jManage high availability (multi-region, multi-cloud, and same-region replication) namespace configurationsj7\n\006Export\022-Manage workflow history export configurationsj7\n\022Connectivity Rules\022!Manage network connectivity rulesj\"\n\007Regions\022\027Query available regionsj,\n\007Account\022!Manage account settings and usagej*\n\nOperations\022\034Query async operation statusr>\n\034Temporal Cloud Documentation\022\036https://docs.temporal.io/cloud" + DESCRIPTOR._serialized_options = b"\n%io.temporal.api.cloud.cloudservice.v1B\014ServiceProtoP\001Z5go.temporal.io/api/cloud/cloudservice/v1;cloudservice\252\002$Temporalio.Api.Cloud.CloudService.V1\352\002(Temporalio::Api::Cloud::CloudService::V1\222A\375\023\022\340\r\n\026Temporal Cloud Ops API\022\226\014Programmatic access to manage Temporal Cloud control plane resources including namespaces, users, service accounts, and more.\n\n## Authentication\n\nAll API requests require authentication using an API Key. Include your API key in the `Authorization` header using the Bearer scheme:\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\nAPI keys can be created and managed through the [API Keys endpoints](#tag/API-Keys) or via the Temporal Cloud UI. For more information, see [API Keys Documentation](https://docs.temporal.io/cloud/api-keys).\n\n## Authorization\n\nThe API uses Role-Based Access Control (RBAC) to manage permissions. Each operation requires specific role-based permissions in addition to a valid API key.\n\n### Account-Level Roles\n\n- **Account Owner** - Full account administration access\n- **Account Admin** - Manage namespaces, users, and service accounts \n- **Account Developer** - Create namespaces and manage Nexus endpoints\n- **Finance Admin** - View usage and billing information\n- **Account Read** - Read-only access to account resources\n\n### Namespace-Level Roles\n\n- **Namespace Admin** - Full access to namespace configuration and data\n- **Namespace Write** - Execute workflows and modify workflow data\n- **Namespace Read** - Read-only access to namespace data\n\nNamespace-level permissions are scoped to specific namespaces. A user or service account may have different permission levels across different namespaces.\n\nFor detailed information about roles and permissions, see [Access Control Documentation](https://docs.temporal.io/cloud/users).2\0031.0:\247\001\n\006x-logo\022\234\001*\231\001\n\226\001\n\003url\022\216\001\032\213\001https://images.ctfassets.net/0uuz8ydxyd9p/4YGUnEoCaH9SyoUDhlJkau/e1600205d17eeee3033d926ef06664a9/Temporal_LogoLockup_Horizontal_dark_1.svgj.\n\nNamespaces\022 Manage Temporal Cloud namespacesj0\n\005Users\022'Manage users and their namespace accessjF\n\020Service Accounts\0222Manage service accounts and their namespace accessj.\n\010API Keys\022\"Manage API keys for authenticationj1\n\006Groups\022'Manage user groups and group membershipj\037\n\005Nexus\022\026Manage Nexus endpointsj\177\n\021High Availability\022jManage high availability (multi-region, multi-cloud, and same-region replication) namespace configurationsj7\n\006Export\022-Manage workflow history export configurationsj7\n\022Connectivity Rules\022!Manage network connectivity rulesj\"\n\007Regions\022\027Query available regionsj,\n\007Account\022!Manage account settings and usagej9\n\014Custom Roles\022)Manage custom roles and their permissionsj*\n\nOperations\022\034Query async operation statusr>\n\034Temporal Cloud Documentation\022\036https://docs.temporal.io/cloud" _CLOUDSERVICE.methods_by_name["GetCurrentIdentity"]._options = None _CLOUDSERVICE.methods_by_name[ "GetCurrentIdentity" @@ -95,11 +95,11 @@ _CLOUDSERVICE.methods_by_name["AddNamespaceRegion"]._options = None _CLOUDSERVICE.methods_by_name[ "AddNamespaceRegion" - ]._serialized_options = b'\202\323\344\223\002-"(/cloud/namespaces/{namespace}/add-region:\001*\222A\266\001\n\021High Availability\022\025Add namespace replica\032+Adds a new replica to an existing namespace"]\n)High availability namespace documentation\0220https://docs.temporal.io/cloud/high-availability' + ]._serialized_options = b'\210\002\001\202\323\344\223\002-"(/cloud/namespaces/{namespace}/add-region:\001*\222A\266\001\n\021High Availability\022\025Add namespace replica\032+Adds a new replica to an existing namespace"]\n)High availability namespace documentation\0220https://docs.temporal.io/cloud/high-availability' _CLOUDSERVICE.methods_by_name["DeleteNamespaceRegion"]._options = None _CLOUDSERVICE.methods_by_name[ "DeleteNamespaceRegion" - ]._serialized_options = b'\202\323\344\223\0020*./cloud/namespaces/{namespace}/regions/{region}\222A\302\001\n\021High Availability\022\030Remove namespace replica\0324Removes a replica from a high availability namespace"]\n)High availability namespace documentation\0220https://docs.temporal.io/cloud/high-availability' + ]._serialized_options = b'\210\002\001\202\323\344\223\0020*./cloud/namespaces/{namespace}/regions/{region}\222A\302\001\n\021High Availability\022\030Remove namespace replica\0324Removes a replica from a high availability namespace"]\n)High availability namespace documentation\0220https://docs.temporal.io/cloud/high-availability' _CLOUDSERVICE.methods_by_name["GetRegions"]._options = None _CLOUDSERVICE.methods_by_name[ "GetRegions" @@ -304,6 +304,26 @@ _CLOUDSERVICE.methods_by_name[ "GetBillingReport" ]._serialized_options = b'\202\323\344\223\002,\022*/cloud/billing-reports/{billing_report_id}\222A\240\001\n\007Account\022\024Get a billing report\032/Gets an existing billing report for the account"N\n\034Billing report documentation\022.https://docs.temporal.io/cloud/billing-reports' + _CLOUDSERVICE.methods_by_name["GetCustomRoles"]._options = None + _CLOUDSERVICE.methods_by_name[ + "GetCustomRoles" + ]._serialized_options = b'\202\323\344\223\002\025\022\023/cloud/custom-roles\222A\233\001\n\014Custom Roles\022\021List custom roles\032-Returns a list of custom roles in the account"I\n\032Custom roles documentation\022+https://docs.temporal.io/cloud/custom-roles' + _CLOUDSERVICE.methods_by_name["GetCustomRole"]._options = None + _CLOUDSERVICE.methods_by_name[ + "GetCustomRole" + ]._serialized_options = b'\202\323\344\223\002\037\022\035/cloud/custom-roles/{role_id}\222A\234\001\n\014Custom Roles\022\025Get custom role by ID\032*Returns details for a specific custom role"I\n\032Custom roles documentation\022+https://docs.temporal.io/cloud/custom-roles' + _CLOUDSERVICE.methods_by_name["CreateCustomRole"]._options = None + _CLOUDSERVICE.methods_by_name[ + "CreateCustomRole" + ]._serialized_options = b'\202\323\344\223\002\030"\023/cloud/custom-roles:\001*\222A\231\001\n\014Custom Roles\022\024Create a custom role\032(Creates a new custom role in the account"I\n\032Custom roles documentation\022+https://docs.temporal.io/cloud/custom-roles' + _CLOUDSERVICE.methods_by_name["UpdateCustomRole"]._options = None + _CLOUDSERVICE.methods_by_name[ + "UpdateCustomRole" + ]._serialized_options = b'\202\323\344\223\002""\035/cloud/custom-roles/{role_id}:\001*\222A\220\001\n\014Custom Roles\022\024Update a custom role\032\037Updates an existing custom role"I\n\032Custom roles documentation\022+https://docs.temporal.io/cloud/custom-roles' + _CLOUDSERVICE.methods_by_name["DeleteCustomRole"]._options = None + _CLOUDSERVICE.methods_by_name[ + "DeleteCustomRole" + ]._serialized_options = b'\202\323\344\223\002\037*\035/cloud/custom-roles/{role_id}\222A\227\001\n\014Custom Roles\022\024Delete a custom role\032&Deletes a custom role from the account"I\n\032Custom roles documentation\022+https://docs.temporal.io/cloud/custom-roles' _CLOUDSERVICE._serialized_start = 227 - _CLOUDSERVICE._serialized_end = 24601 + _CLOUDSERVICE._serialized_end = 26277 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.py b/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.py index cf2755c84..4888d7186 100644 --- a/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.py +++ b/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.py @@ -359,6 +359,31 @@ def __init__(self, channel): request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetBillingReportRequest.SerializeToString, response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetBillingReportResponse.FromString, ) + self.GetCustomRoles = channel.unary_unary( + "/temporal.api.cloud.cloudservice.v1.CloudService/GetCustomRoles", + request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesRequest.SerializeToString, + response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesResponse.FromString, + ) + self.GetCustomRole = channel.unary_unary( + "/temporal.api.cloud.cloudservice.v1.CloudService/GetCustomRole", + request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleRequest.SerializeToString, + response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleResponse.FromString, + ) + self.CreateCustomRole = channel.unary_unary( + "/temporal.api.cloud.cloudservice.v1.CloudService/CreateCustomRole", + request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleRequest.SerializeToString, + response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleResponse.FromString, + ) + self.UpdateCustomRole = channel.unary_unary( + "/temporal.api.cloud.cloudservice.v1.CloudService/UpdateCustomRole", + request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleRequest.SerializeToString, + response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleResponse.FromString, + ) + self.DeleteCustomRole = channel.unary_unary( + "/temporal.api.cloud.cloudservice.v1.CloudService/DeleteCustomRole", + request_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleRequest.SerializeToString, + response_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleResponse.FromString, + ) class CloudServiceServicer(object): @@ -457,13 +482,17 @@ def FailoverNamespaceRegion(self, request, context): raise NotImplementedError("Method not implemented!") def AddNamespaceRegion(self, request, context): - """Add a new region to a namespace""" + """Add a new region to a namespace + Deprecated: Use the UpdateNamespace() to add new replica in the namespace spec instead. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def DeleteNamespaceRegion(self, request, context): - """Delete a region from a namespace""" + """Delete a region from a namespace + Deprecated: Use the UpdateNamespace() to delete a replica in the namespace spec instead. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -780,6 +809,36 @@ def GetBillingReport(self, request, context): context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") + def GetCustomRoles(self, request, context): + """Get custom roles""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def GetCustomRole(self, request, context): + """Get a custom role""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def CreateCustomRole(self, request, context): + """Create a custom role""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def UpdateCustomRole(self, request, context): + """Update a custom role""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DeleteCustomRole(self, request, context): + """Delete a custom role""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + def add_CloudServiceServicer_to_server(servicer, server): rpc_method_handlers = { @@ -1123,6 +1182,31 @@ def add_CloudServiceServicer_to_server(servicer, server): request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetBillingReportRequest.FromString, response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetBillingReportResponse.SerializeToString, ), + "GetCustomRoles": grpc.unary_unary_rpc_method_handler( + servicer.GetCustomRoles, + request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesRequest.FromString, + response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesResponse.SerializeToString, + ), + "GetCustomRole": grpc.unary_unary_rpc_method_handler( + servicer.GetCustomRole, + request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleRequest.FromString, + response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleResponse.SerializeToString, + ), + "CreateCustomRole": grpc.unary_unary_rpc_method_handler( + servicer.CreateCustomRole, + request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleRequest.FromString, + response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleResponse.SerializeToString, + ), + "UpdateCustomRole": grpc.unary_unary_rpc_method_handler( + servicer.UpdateCustomRole, + request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleRequest.FromString, + response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleResponse.SerializeToString, + ), + "DeleteCustomRole": grpc.unary_unary_rpc_method_handler( + servicer.DeleteCustomRole, + request_deserializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleRequest.FromString, + response_serializer=temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( "temporal.api.cloud.cloudservice.v1.CloudService", rpc_method_handlers @@ -3107,3 +3191,148 @@ def GetBillingReport( timeout, metadata, ) + + @staticmethod + def GetCustomRoles( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/temporal.api.cloud.cloudservice.v1.CloudService/GetCustomRoles", + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesRequest.SerializeToString, + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRolesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetCustomRole( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/temporal.api.cloud.cloudservice.v1.CloudService/GetCustomRole", + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleRequest.SerializeToString, + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.GetCustomRoleResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateCustomRole( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/temporal.api.cloud.cloudservice.v1.CloudService/CreateCustomRole", + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleRequest.SerializeToString, + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.CreateCustomRoleResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def UpdateCustomRole( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/temporal.api.cloud.cloudservice.v1.CloudService/UpdateCustomRole", + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleRequest.SerializeToString, + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.UpdateCustomRoleResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DeleteCustomRole( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/temporal.api.cloud.cloudservice.v1.CloudService/DeleteCustomRole", + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleRequest.SerializeToString, + temporal_dot_api_dot_cloud_dot_cloudservice_dot_v1_dot_request__response__pb2.DeleteCustomRoleResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.pyi b/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.pyi index 5cd60b88a..0d8e642f4 100644 --- a/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.pyi +++ b/temporalio/api/cloud/cloudservice/v1/service_pb2_grpc.pyi @@ -94,12 +94,16 @@ class CloudServiceStub: temporalio.api.cloud.cloudservice.v1.request_response_pb2.AddNamespaceRegionRequest, temporalio.api.cloud.cloudservice.v1.request_response_pb2.AddNamespaceRegionResponse, ] - """Add a new region to a namespace""" + """Add a new region to a namespace + Deprecated: Use the UpdateNamespace() to add new replica in the namespace spec instead. + """ DeleteNamespaceRegion: grpc.UnaryUnaryMultiCallable[ temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteNamespaceRegionRequest, temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteNamespaceRegionResponse, ] - """Delete a region from a namespace""" + """Delete a region from a namespace + Deprecated: Use the UpdateNamespace() to delete a replica in the namespace spec instead. + """ GetRegions: grpc.UnaryUnaryMultiCallable[ temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetRegionsRequest, temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetRegionsResponse, @@ -360,6 +364,31 @@ class CloudServiceStub: temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetBillingReportResponse, ] """Get a billing report""" + GetCustomRoles: grpc.UnaryUnaryMultiCallable[ + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRolesRequest, + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRolesResponse, + ] + """Get custom roles""" + GetCustomRole: grpc.UnaryUnaryMultiCallable[ + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRoleRequest, + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRoleResponse, + ] + """Get a custom role""" + CreateCustomRole: grpc.UnaryUnaryMultiCallable[ + temporalio.api.cloud.cloudservice.v1.request_response_pb2.CreateCustomRoleRequest, + temporalio.api.cloud.cloudservice.v1.request_response_pb2.CreateCustomRoleResponse, + ] + """Create a custom role""" + UpdateCustomRole: grpc.UnaryUnaryMultiCallable[ + temporalio.api.cloud.cloudservice.v1.request_response_pb2.UpdateCustomRoleRequest, + temporalio.api.cloud.cloudservice.v1.request_response_pb2.UpdateCustomRoleResponse, + ] + """Update a custom role""" + DeleteCustomRole: grpc.UnaryUnaryMultiCallable[ + temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteCustomRoleRequest, + temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteCustomRoleResponse, + ] + """Delete a custom role""" class CloudServiceServicer(metaclass=abc.ABCMeta): """WARNING: This service is currently experimental and may change in @@ -479,14 +508,18 @@ class CloudServiceServicer(metaclass=abc.ABCMeta): request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.AddNamespaceRegionRequest, context: grpc.ServicerContext, ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.AddNamespaceRegionResponse: - """Add a new region to a namespace""" + """Add a new region to a namespace + Deprecated: Use the UpdateNamespace() to add new replica in the namespace spec instead. + """ @abc.abstractmethod def DeleteNamespaceRegion( self, request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteNamespaceRegionRequest, context: grpc.ServicerContext, ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteNamespaceRegionResponse: - """Delete a region from a namespace""" + """Delete a region from a namespace + Deprecated: Use the UpdateNamespace() to delete a replica in the namespace spec instead. + """ @abc.abstractmethod def GetRegions( self, @@ -853,6 +886,45 @@ class CloudServiceServicer(metaclass=abc.ABCMeta): context: grpc.ServicerContext, ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetBillingReportResponse: """Get a billing report""" + @abc.abstractmethod + def GetCustomRoles( + self, + request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRolesRequest, + context: grpc.ServicerContext, + ) -> ( + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRolesResponse + ): + """Get custom roles""" + @abc.abstractmethod + def GetCustomRole( + self, + request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRoleRequest, + context: grpc.ServicerContext, + ) -> ( + temporalio.api.cloud.cloudservice.v1.request_response_pb2.GetCustomRoleResponse + ): + """Get a custom role""" + @abc.abstractmethod + def CreateCustomRole( + self, + request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.CreateCustomRoleRequest, + context: grpc.ServicerContext, + ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.CreateCustomRoleResponse: + """Create a custom role""" + @abc.abstractmethod + def UpdateCustomRole( + self, + request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.UpdateCustomRoleRequest, + context: grpc.ServicerContext, + ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.UpdateCustomRoleResponse: + """Update a custom role""" + @abc.abstractmethod + def DeleteCustomRole( + self, + request: temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteCustomRoleRequest, + context: grpc.ServicerContext, + ) -> temporalio.api.cloud.cloudservice.v1.request_response_pb2.DeleteCustomRoleResponse: + """Delete a custom role""" def add_CloudServiceServicer_to_server( servicer: CloudServiceServicer, server: grpc.Server diff --git a/temporalio/api/cloud/identity/v1/__init__.py b/temporalio/api/cloud/identity/v1/__init__.py index 6b477fbef..38954f384 100644 --- a/temporalio/api/cloud/identity/v1/__init__.py +++ b/temporalio/api/cloud/identity/v1/__init__.py @@ -4,6 +4,8 @@ ApiKey, ApiKeySpec, CloudGroupSpec, + CustomRole, + CustomRoleSpec, GoogleGroupSpec, Invitation, NamespaceAccess, @@ -26,6 +28,8 @@ "ApiKey", "ApiKeySpec", "CloudGroupSpec", + "CustomRole", + "CustomRoleSpec", "GoogleGroupSpec", "Invitation", "NamespaceAccess", diff --git a/temporalio/api/cloud/identity/v1/message_pb2.py b/temporalio/api/cloud/identity/v1/message_pb2.py index 892468506..b7036cd3f 100644 --- a/temporalio/api/cloud/identity/v1/message_pb2.py +++ b/temporalio/api/cloud/identity/v1/message_pb2.py @@ -22,7 +22,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n,temporal/api/cloud/identity/v1/message.proto\x12\x1etemporal.api.cloud.identity.v1\x1a,temporal/api/cloud/resource/v1/message.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\xff\x01\n\rAccountAccess\x12\x1b\n\x0frole_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12@\n\x04role\x18\x02 \x01(\x0e\x32\x32.temporal.api.cloud.identity.v1.AccountAccess.Role"\x8e\x01\n\x04Role\x12\x14\n\x10ROLE_UNSPECIFIED\x10\x00\x12\x0e\n\nROLE_OWNER\x10\x01\x12\x0e\n\nROLE_ADMIN\x10\x02\x12\x12\n\x0eROLE_DEVELOPER\x10\x03\x12\x16\n\x12ROLE_FINANCE_ADMIN\x10\x04\x12\r\n\tROLE_READ\x10\x05\x12\x15\n\x11ROLE_METRICS_READ\x10\x06"\xef\x01\n\x0fNamespaceAccess\x12!\n\x15permission_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12N\n\npermission\x18\x02 \x01(\x0e\x32:.temporal.api.cloud.identity.v1.NamespaceAccess.Permission"i\n\nPermission\x12\x1a\n\x16PERMISSION_UNSPECIFIED\x10\x00\x12\x14\n\x10PERMISSION_ADMIN\x10\x01\x12\x14\n\x10PERMISSION_WRITE\x10\x02\x12\x13\n\x0fPERMISSION_READ\x10\x03"\x95\x02\n\x06\x41\x63\x63\x65ss\x12\x45\n\x0e\x61\x63\x63ount_access\x18\x01 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.AccountAccess\x12Y\n\x12namespace_accesses\x18\x02 \x03(\x0b\x32=.temporal.api.cloud.identity.v1.Access.NamespaceAccessesEntry\x1ai\n\x16NamespaceAccessesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12>\n\x05value\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess:\x02\x38\x01"k\n\x15NamespaceScopedAccess\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess"Q\n\x08UserSpec\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access"p\n\nInvitation\x12\x30\n\x0c\x63reated_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x65xpired_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x86\x03\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x36\n\x04spec\x18\x03 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\t \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12>\n\ninvitation\x18\x06 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.Invitation\x12\x30\n\x0c\x63reated_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"(\n\x0fGoogleGroupSpec\x12\x15\n\remail_address\x18\x01 \x01(\t"\x1f\n\rSCIMGroupSpec\x12\x0e\n\x06idp_id\x18\x01 \x01(\t"\x10\n\x0e\x43loudGroupSpec"\xc0\x02\n\rUserGroupSpec\x12\x14\n\x0c\x64isplay_name\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access\x12G\n\x0cgoogle_group\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.GoogleGroupSpecH\x00\x12\x43\n\nscim_group\x18\x04 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.SCIMGroupSpecH\x00\x12\x45\n\x0b\x63loud_group\x18\x05 \x01(\x0b\x32..temporal.api.cloud.identity.v1.CloudGroupSpecH\x00\x42\x0c\n\ngroup_type"\xd0\x02\n\tUserGroup\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12;\n\x04spec\x18\x03 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"5\n\x11UserGroupMemberId\x12\x11\n\x07user_id\x18\x01 \x01(\tH\x00\x42\r\n\x0bmember_type"\x89\x01\n\x0fUserGroupMember\x12\x44\n\tmember_id\x18\x01 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x30\n\x0c\x63reated_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xda\x02\n\x0eServiceAccount\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12@\n\x04spec\x18\x03 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xc7\x01\n\x12ServiceAccountSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access\x12V\n\x17namespace_scoped_access\x18\x04 \x01(\x0b\x32\x35.temporal.api.cloud.identity.v1.NamespaceScopedAccess\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xca\x02\n\x06\x41piKey\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x38\n\x04spec\x18\x03 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xee\x01\n\nApiKeySpec\x12\x10\n\x08owner_id\x18\x01 \x01(\t\x12!\n\x15owner_type_deprecated\x18\x02 \x01(\tB\x02\x18\x01\x12=\n\nowner_type\x18\x07 \x01(\x0e\x32).temporal.api.cloud.identity.v1.OwnerType\x12\x14\n\x0c\x64isplay_name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12/\n\x0b\x65xpiry_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08\x64isabled\x18\x06 \x01(\x08*\\\n\tOwnerType\x12\x1a\n\x16OWNER_TYPE_UNSPECIFIED\x10\x00\x12\x13\n\x0fOWNER_TYPE_USER\x10\x01\x12\x1e\n\x1aOWNER_TYPE_SERVICE_ACCOUNT\x10\x02\x42\xac\x01\n!io.temporal.api.cloud.identity.v1B\x0cMessageProtoP\x01Z-go.temporal.io/api/cloud/identity/v1;identity\xaa\x02 Temporalio.Api.Cloud.Identity.V1\xea\x02$Temporalio::Api::Cloud::Identity::V1b\x06proto3' + b'\n,temporal/api/cloud/identity/v1/message.proto\x12\x1etemporal.api.cloud.identity.v1\x1a,temporal/api/cloud/resource/v1/message.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\x95\x02\n\rAccountAccess\x12\x1b\n\x0frole_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12@\n\x04role\x18\x02 \x01(\x0e\x32\x32.temporal.api.cloud.identity.v1.AccountAccess.Role\x12\x14\n\x0c\x63ustom_roles\x18\x03 \x03(\t"\x8e\x01\n\x04Role\x12\x14\n\x10ROLE_UNSPECIFIED\x10\x00\x12\x0e\n\nROLE_OWNER\x10\x01\x12\x0e\n\nROLE_ADMIN\x10\x02\x12\x12\n\x0eROLE_DEVELOPER\x10\x03\x12\x16\n\x12ROLE_FINANCE_ADMIN\x10\x04\x12\r\n\tROLE_READ\x10\x05\x12\x15\n\x11ROLE_METRICS_READ\x10\x06"\xef\x01\n\x0fNamespaceAccess\x12!\n\x15permission_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12N\n\npermission\x18\x02 \x01(\x0e\x32:.temporal.api.cloud.identity.v1.NamespaceAccess.Permission"i\n\nPermission\x12\x1a\n\x16PERMISSION_UNSPECIFIED\x10\x00\x12\x14\n\x10PERMISSION_ADMIN\x10\x01\x12\x14\n\x10PERMISSION_WRITE\x10\x02\x12\x13\n\x0fPERMISSION_READ\x10\x03"\xba\x02\n\x06\x41\x63\x63\x65ss\x12\x45\n\x0e\x61\x63\x63ount_access\x18\x01 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.AccountAccess\x12Y\n\x12namespace_accesses\x18\x02 \x03(\x0b\x32=.temporal.api.cloud.identity.v1.Access.NamespaceAccessesEntry\x12#\n\x17\x63ustom_roles_deprecated\x18\x04 \x03(\tB\x02\x18\x01\x1ai\n\x16NamespaceAccessesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12>\n\x05value\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess:\x02\x38\x01"k\n\x15NamespaceScopedAccess\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12?\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.NamespaceAccess"Q\n\x08UserSpec\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access"p\n\nInvitation\x12\x30\n\x0c\x63reated_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x65xpired_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x86\x03\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x36\n\x04spec\x18\x03 \x01(\x0b\x32(.temporal.api.cloud.identity.v1.UserSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\t \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12>\n\ninvitation\x18\x06 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.Invitation\x12\x30\n\x0c\x63reated_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"(\n\x0fGoogleGroupSpec\x12\x15\n\remail_address\x18\x01 \x01(\t"\x1f\n\rSCIMGroupSpec\x12\x0e\n\x06idp_id\x18\x01 \x01(\t"\x10\n\x0e\x43loudGroupSpec"\xc0\x02\n\rUserGroupSpec\x12\x14\n\x0c\x64isplay_name\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access\x12G\n\x0cgoogle_group\x18\x03 \x01(\x0b\x32/.temporal.api.cloud.identity.v1.GoogleGroupSpecH\x00\x12\x43\n\nscim_group\x18\x04 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.SCIMGroupSpecH\x00\x12\x45\n\x0b\x63loud_group\x18\x05 \x01(\x0b\x32..temporal.api.cloud.identity.v1.CloudGroupSpecH\x00\x42\x0c\n\ngroup_type"\xd0\x02\n\tUserGroup\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12;\n\x04spec\x18\x03 \x01(\x0b\x32-.temporal.api.cloud.identity.v1.UserGroupSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"5\n\x11UserGroupMemberId\x12\x11\n\x07user_id\x18\x01 \x01(\tH\x00\x42\r\n\x0bmember_type"\x89\x01\n\x0fUserGroupMember\x12\x44\n\tmember_id\x18\x01 \x01(\x0b\x32\x31.temporal.api.cloud.identity.v1.UserGroupMemberId\x12\x30\n\x0c\x63reated_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xda\x02\n\x0eServiceAccount\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12@\n\x04spec\x18\x03 \x01(\x0b\x32\x32.temporal.api.cloud.identity.v1.ServiceAccountSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xc7\x01\n\x12ServiceAccountSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32&.temporal.api.cloud.identity.v1.Access\x12V\n\x17namespace_scoped_access\x18\x04 \x01(\x0b\x32\x35.temporal.api.cloud.identity.v1.NamespaceScopedAccess\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xca\x02\n\x06\x41piKey\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12\x38\n\x04spec\x18\x03 \x01(\x0b\x32*.temporal.api.cloud.identity.v1.ApiKeySpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\x08 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xee\x01\n\nApiKeySpec\x12\x10\n\x08owner_id\x18\x01 \x01(\t\x12!\n\x15owner_type_deprecated\x18\x02 \x01(\tB\x02\x18\x01\x12=\n\nowner_type\x18\x07 \x01(\x0e\x32).temporal.api.cloud.identity.v1.OwnerType\x12\x14\n\x0c\x64isplay_name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12/\n\x0b\x65xpiry_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x10\n\x08\x64isabled\x18\x06 \x01(\x08"\xbc\x02\n\x0e\x43ustomRoleSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12N\n\x0bpermissions\x18\x03 \x03(\x0b\x32\x39.temporal.api.cloud.identity.v1.CustomRoleSpec.Permission\x1aK\n\tResources\x12\x15\n\rresource_type\x18\x01 \x01(\t\x12\x14\n\x0cresource_ids\x18\x02 \x03(\t\x12\x11\n\tallow_all\x18\x03 \x01(\x08\x1aj\n\nPermission\x12K\n\tresources\x18\x01 \x01(\x0b\x32\x38.temporal.api.cloud.identity.v1.CustomRoleSpec.Resources\x12\x0f\n\x07\x61\x63tions\x18\x02 \x03(\t"\xb4\x02\n\nCustomRole\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12<\n\x04spec\x18\x03 \x01(\x0b\x32..temporal.api.cloud.identity.v1.CustomRoleSpec\x12<\n\x05state\x18\x04 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x30\n\x0c\x63reated_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp*\\\n\tOwnerType\x12\x1a\n\x16OWNER_TYPE_UNSPECIFIED\x10\x00\x12\x13\n\x0fOWNER_TYPE_USER\x10\x01\x12\x1e\n\x1aOWNER_TYPE_SERVICE_ACCOUNT\x10\x02\x42\xac\x01\n!io.temporal.api.cloud.identity.v1B\x0cMessageProtoP\x01Z-go.temporal.io/api/cloud/identity/v1;identity\xaa\x02 Temporalio.Api.Cloud.Identity.V1\xea\x02$Temporalio::Api::Cloud::Identity::V1b\x06proto3' ) _OWNERTYPE = DESCRIPTOR.enum_types_by_name["OwnerType"] @@ -51,6 +51,10 @@ _SERVICEACCOUNTSPEC = DESCRIPTOR.message_types_by_name["ServiceAccountSpec"] _APIKEY = DESCRIPTOR.message_types_by_name["ApiKey"] _APIKEYSPEC = DESCRIPTOR.message_types_by_name["ApiKeySpec"] +_CUSTOMROLESPEC = DESCRIPTOR.message_types_by_name["CustomRoleSpec"] +_CUSTOMROLESPEC_RESOURCES = _CUSTOMROLESPEC.nested_types_by_name["Resources"] +_CUSTOMROLESPEC_PERMISSION = _CUSTOMROLESPEC.nested_types_by_name["Permission"] +_CUSTOMROLE = DESCRIPTOR.message_types_by_name["CustomRole"] _ACCOUNTACCESS_ROLE = _ACCOUNTACCESS.enum_types_by_name["Role"] _NAMESPACEACCESS_PERMISSION = _NAMESPACEACCESS.enum_types_by_name["Permission"] AccountAccess = _reflection.GeneratedProtocolMessageType( @@ -261,6 +265,48 @@ ) _sym_db.RegisterMessage(ApiKeySpec) +CustomRoleSpec = _reflection.GeneratedProtocolMessageType( + "CustomRoleSpec", + (_message.Message,), + { + "Resources": _reflection.GeneratedProtocolMessageType( + "Resources", + (_message.Message,), + { + "DESCRIPTOR": _CUSTOMROLESPEC_RESOURCES, + "__module__": "temporalio.api.cloud.identity.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.identity.v1.CustomRoleSpec.Resources) + }, + ), + "Permission": _reflection.GeneratedProtocolMessageType( + "Permission", + (_message.Message,), + { + "DESCRIPTOR": _CUSTOMROLESPEC_PERMISSION, + "__module__": "temporalio.api.cloud.identity.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.identity.v1.CustomRoleSpec.Permission) + }, + ), + "DESCRIPTOR": _CUSTOMROLESPEC, + "__module__": "temporalio.api.cloud.identity.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.identity.v1.CustomRoleSpec) + }, +) +_sym_db.RegisterMessage(CustomRoleSpec) +_sym_db.RegisterMessage(CustomRoleSpec.Resources) +_sym_db.RegisterMessage(CustomRoleSpec.Permission) + +CustomRole = _reflection.GeneratedProtocolMessageType( + "CustomRole", + (_message.Message,), + { + "DESCRIPTOR": _CUSTOMROLE, + "__module__": "temporalio.api.cloud.identity.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.identity.v1.CustomRole) + }, +) +_sym_db.RegisterMessage(CustomRole) + if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b"\n!io.temporal.api.cloud.identity.v1B\014MessageProtoP\001Z-go.temporal.io/api/cloud/identity/v1;identity\252\002 Temporalio.Api.Cloud.Identity.V1\352\002$Temporalio::Api::Cloud::Identity::V1" @@ -272,6 +318,8 @@ ]._serialized_options = b"\030\001" _ACCESS_NAMESPACEACCESSESENTRY._options = None _ACCESS_NAMESPACEACCESSESENTRY._serialized_options = b"8\001" + _ACCESS.fields_by_name["custom_roles_deprecated"]._options = None + _ACCESS.fields_by_name["custom_roles_deprecated"]._serialized_options = b"\030\001" _USER.fields_by_name["state_deprecated"]._options = None _USER.fields_by_name["state_deprecated"]._serialized_options = b"\030\001" _USERGROUP.fields_by_name["state_deprecated"]._options = None @@ -284,48 +332,56 @@ _APIKEYSPEC.fields_by_name[ "owner_type_deprecated" ]._serialized_options = b"\030\001" - _OWNERTYPE._serialized_start = 3713 - _OWNERTYPE._serialized_end = 3805 + _OWNERTYPE._serialized_start = 4402 + _OWNERTYPE._serialized_end = 4494 _ACCOUNTACCESS._serialized_start = 160 - _ACCOUNTACCESS._serialized_end = 415 - _ACCOUNTACCESS_ROLE._serialized_start = 273 - _ACCOUNTACCESS_ROLE._serialized_end = 415 - _NAMESPACEACCESS._serialized_start = 418 - _NAMESPACEACCESS._serialized_end = 657 - _NAMESPACEACCESS_PERMISSION._serialized_start = 552 - _NAMESPACEACCESS_PERMISSION._serialized_end = 657 - _ACCESS._serialized_start = 660 - _ACCESS._serialized_end = 937 - _ACCESS_NAMESPACEACCESSESENTRY._serialized_start = 832 - _ACCESS_NAMESPACEACCESSESENTRY._serialized_end = 937 - _NAMESPACESCOPEDACCESS._serialized_start = 939 - _NAMESPACESCOPEDACCESS._serialized_end = 1046 - _USERSPEC._serialized_start = 1048 - _USERSPEC._serialized_end = 1129 - _INVITATION._serialized_start = 1131 - _INVITATION._serialized_end = 1243 - _USER._serialized_start = 1246 - _USER._serialized_end = 1636 - _GOOGLEGROUPSPEC._serialized_start = 1638 - _GOOGLEGROUPSPEC._serialized_end = 1678 - _SCIMGROUPSPEC._serialized_start = 1680 - _SCIMGROUPSPEC._serialized_end = 1711 - _CLOUDGROUPSPEC._serialized_start = 1713 - _CLOUDGROUPSPEC._serialized_end = 1729 - _USERGROUPSPEC._serialized_start = 1732 - _USERGROUPSPEC._serialized_end = 2052 - _USERGROUP._serialized_start = 2055 - _USERGROUP._serialized_end = 2391 - _USERGROUPMEMBERID._serialized_start = 2393 - _USERGROUPMEMBERID._serialized_end = 2446 - _USERGROUPMEMBER._serialized_start = 2449 - _USERGROUPMEMBER._serialized_end = 2586 - _SERVICEACCOUNT._serialized_start = 2589 - _SERVICEACCOUNT._serialized_end = 2935 - _SERVICEACCOUNTSPEC._serialized_start = 2938 - _SERVICEACCOUNTSPEC._serialized_end = 3137 - _APIKEY._serialized_start = 3140 - _APIKEY._serialized_end = 3470 - _APIKEYSPEC._serialized_start = 3473 - _APIKEYSPEC._serialized_end = 3711 + _ACCOUNTACCESS._serialized_end = 437 + _ACCOUNTACCESS_ROLE._serialized_start = 295 + _ACCOUNTACCESS_ROLE._serialized_end = 437 + _NAMESPACEACCESS._serialized_start = 440 + _NAMESPACEACCESS._serialized_end = 679 + _NAMESPACEACCESS_PERMISSION._serialized_start = 574 + _NAMESPACEACCESS_PERMISSION._serialized_end = 679 + _ACCESS._serialized_start = 682 + _ACCESS._serialized_end = 996 + _ACCESS_NAMESPACEACCESSESENTRY._serialized_start = 891 + _ACCESS_NAMESPACEACCESSESENTRY._serialized_end = 996 + _NAMESPACESCOPEDACCESS._serialized_start = 998 + _NAMESPACESCOPEDACCESS._serialized_end = 1105 + _USERSPEC._serialized_start = 1107 + _USERSPEC._serialized_end = 1188 + _INVITATION._serialized_start = 1190 + _INVITATION._serialized_end = 1302 + _USER._serialized_start = 1305 + _USER._serialized_end = 1695 + _GOOGLEGROUPSPEC._serialized_start = 1697 + _GOOGLEGROUPSPEC._serialized_end = 1737 + _SCIMGROUPSPEC._serialized_start = 1739 + _SCIMGROUPSPEC._serialized_end = 1770 + _CLOUDGROUPSPEC._serialized_start = 1772 + _CLOUDGROUPSPEC._serialized_end = 1788 + _USERGROUPSPEC._serialized_start = 1791 + _USERGROUPSPEC._serialized_end = 2111 + _USERGROUP._serialized_start = 2114 + _USERGROUP._serialized_end = 2450 + _USERGROUPMEMBERID._serialized_start = 2452 + _USERGROUPMEMBERID._serialized_end = 2505 + _USERGROUPMEMBER._serialized_start = 2508 + _USERGROUPMEMBER._serialized_end = 2645 + _SERVICEACCOUNT._serialized_start = 2648 + _SERVICEACCOUNT._serialized_end = 2994 + _SERVICEACCOUNTSPEC._serialized_start = 2997 + _SERVICEACCOUNTSPEC._serialized_end = 3196 + _APIKEY._serialized_start = 3199 + _APIKEY._serialized_end = 3529 + _APIKEYSPEC._serialized_start = 3532 + _APIKEYSPEC._serialized_end = 3770 + _CUSTOMROLESPEC._serialized_start = 3773 + _CUSTOMROLESPEC._serialized_end = 4089 + _CUSTOMROLESPEC_RESOURCES._serialized_start = 3906 + _CUSTOMROLESPEC_RESOURCES._serialized_end = 3981 + _CUSTOMROLESPEC_PERMISSION._serialized_start = 3983 + _CUSTOMROLESPEC_PERMISSION._serialized_end = 4089 + _CUSTOMROLE._serialized_start = 4092 + _CUSTOMROLE._serialized_end = 4400 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/api/cloud/identity/v1/message_pb2.pyi b/temporalio/api/cloud/identity/v1/message_pb2.pyi index ced77ff78..0427542bf 100644 --- a/temporalio/api/cloud/identity/v1/message_pb2.pyi +++ b/temporalio/api/cloud/identity/v1/message_pb2.pyi @@ -92,6 +92,7 @@ class AccountAccess(google.protobuf.message.Message): ROLE_DEPRECATED_FIELD_NUMBER: builtins.int ROLE_FIELD_NUMBER: builtins.int + CUSTOM_ROLES_FIELD_NUMBER: builtins.int role_deprecated: builtins.str """The role on the account, should be one of [owner, admin, developer, financeadmin, read, metricsread] owner - gives full access to the account, including users, namespaces, and billing @@ -108,16 +109,29 @@ class AccountAccess(google.protobuf.message.Message): temporal:versioning:min_version=v0.3.0 temporal:enums:replaces=role_deprecated """ + @property + def custom_roles( + self, + ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """List of custom role IDs assigned to the user or service account. + temporal:versioning:min_version=v0.13.0 + """ def __init__( self, *, role_deprecated: builtins.str = ..., role: global___AccountAccess.Role.ValueType = ..., + custom_roles: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... def ClearField( self, field_name: typing_extensions.Literal[ - "role", b"role", "role_deprecated", b"role_deprecated" + "custom_roles", + b"custom_roles", + "role", + b"role", + "role_deprecated", + b"role_deprecated", ], ) -> None: ... @@ -214,6 +228,7 @@ class Access(google.protobuf.message.Message): ACCOUNT_ACCESS_FIELD_NUMBER: builtins.int NAMESPACE_ACCESSES_FIELD_NUMBER: builtins.int + CUSTOM_ROLES_DEPRECATED_FIELD_NUMBER: builtins.int @property def account_access(self) -> global___AccountAccess: """The account access""" @@ -226,6 +241,14 @@ class Access(google.protobuf.message.Message): """The map of namespace accesses The key is the namespace name and the value is the access to the namespace """ + @property + def custom_roles_deprecated( + self, + ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """List of custom role IDs assigned to the user or service account. + Deprecated: Not supported after v0.12.0 api version. Use account_access.custom_roles instead. + temporal:versioning:max_version=v0.12.0 + """ def __init__( self, *, @@ -234,6 +257,7 @@ class Access(google.protobuf.message.Message): builtins.str, global___NamespaceAccess ] | None = ..., + custom_roles_deprecated: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... def HasField( self, field_name: typing_extensions.Literal["account_access", b"account_access"] @@ -243,6 +267,8 @@ class Access(google.protobuf.message.Message): field_name: typing_extensions.Literal[ "account_access", b"account_access", + "custom_roles_deprecated", + b"custom_roles_deprecated", "namespace_accesses", b"namespace_accesses", ], @@ -1009,3 +1035,186 @@ class ApiKeySpec(google.protobuf.message.Message): ) -> None: ... global___ApiKeySpec = ApiKeySpec + +class CustomRoleSpec(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class Resources(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_TYPE_FIELD_NUMBER: builtins.int + RESOURCE_IDS_FIELD_NUMBER: builtins.int + ALLOW_ALL_FIELD_NUMBER: builtins.int + resource_type: builtins.str + """The resource type the permission applies to.""" + @property + def resource_ids( + self, + ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[ + builtins.str + ]: + """The resource IDs the permission applies to. Can be empty if allow_all is true.""" + allow_all: builtins.bool + """Whether the permission applies to all resources of the given type.""" + def __init__( + self, + *, + resource_type: builtins.str = ..., + resource_ids: collections.abc.Iterable[builtins.str] | None = ..., + allow_all: builtins.bool = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "allow_all", + b"allow_all", + "resource_ids", + b"resource_ids", + "resource_type", + b"resource_type", + ], + ) -> None: ... + + class Permission(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCES_FIELD_NUMBER: builtins.int + ACTIONS_FIELD_NUMBER: builtins.int + @property + def resources(self) -> global___CustomRoleSpec.Resources: + """The resources the permission applies to.""" + @property + def actions( + self, + ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[ + builtins.str + ]: + """The actions allowed by the permission.""" + def __init__( + self, + *, + resources: global___CustomRoleSpec.Resources | None = ..., + actions: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["resources", b"resources"] + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "actions", b"actions", "resources", b"resources" + ], + ) -> None: ... + + NAME_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + PERMISSIONS_FIELD_NUMBER: builtins.int + name: builtins.str + """The name of the custom role.""" + description: builtins.str + """The description of the custom role.""" + @property + def permissions( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ + global___CustomRoleSpec.Permission + ]: + """The permissions assigned to the custom role.""" + def __init__( + self, + *, + name: builtins.str = ..., + description: builtins.str = ..., + permissions: collections.abc.Iterable[global___CustomRoleSpec.Permission] + | None = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "description", + b"description", + "name", + b"name", + "permissions", + b"permissions", + ], + ) -> None: ... + +global___CustomRoleSpec = CustomRoleSpec + +class CustomRole(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + RESOURCE_VERSION_FIELD_NUMBER: builtins.int + SPEC_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + ASYNC_OPERATION_ID_FIELD_NUMBER: builtins.int + CREATED_TIME_FIELD_NUMBER: builtins.int + LAST_MODIFIED_TIME_FIELD_NUMBER: builtins.int + id: builtins.str + """The id of the custom role.""" + resource_version: builtins.str + """The current version of the custom role specification. + The next update operation will have to include this version. + """ + @property + def spec(self) -> global___CustomRoleSpec: + """The custom role specification.""" + state: temporalio.api.cloud.resource.v1.message_pb2.ResourceState.ValueType + """The current state of the custom role. + For any failed state, reach out to Temporal Cloud support for remediation. + """ + async_operation_id: builtins.str + """The id of the async operation that is creating/updating/deleting the custom role, if any.""" + @property + def created_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """The date and time when the custom role was created.""" + @property + def last_modified_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """The date and time when the custom role was last modified. + Will not be set if the custom role has never been modified. + """ + def __init__( + self, + *, + id: builtins.str = ..., + resource_version: builtins.str = ..., + spec: global___CustomRoleSpec | None = ..., + state: temporalio.api.cloud.resource.v1.message_pb2.ResourceState.ValueType = ..., + async_operation_id: builtins.str = ..., + created_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_modified_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal[ + "created_time", + b"created_time", + "last_modified_time", + b"last_modified_time", + "spec", + b"spec", + ], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "async_operation_id", + b"async_operation_id", + "created_time", + b"created_time", + "id", + b"id", + "last_modified_time", + b"last_modified_time", + "resource_version", + b"resource_version", + "spec", + b"spec", + "state", + b"state", + ], + ) -> None: ... + +global___CustomRole = CustomRole diff --git a/temporalio/api/cloud/namespace/v1/__init__.py b/temporalio/api/cloud/namespace/v1/__init__.py index 7bf5d0446..04e5e98f8 100644 --- a/temporalio/api/cloud/namespace/v1/__init__.py +++ b/temporalio/api/cloud/namespace/v1/__init__.py @@ -8,6 +8,7 @@ Endpoints, ExportSink, ExportSinkSpec, + FairnessSpec, HighAvailabilitySpec, LifecycleSpec, Limits, @@ -17,6 +18,8 @@ NamespaceRegionStatus, NamespaceSpec, PrivateConnectivity, + Replica, + ReplicaSpec, ) __all__ = [ @@ -29,6 +32,7 @@ "Endpoints", "ExportSink", "ExportSinkSpec", + "FairnessSpec", "HighAvailabilitySpec", "LifecycleSpec", "Limits", @@ -38,4 +42,6 @@ "NamespaceRegionStatus", "NamespaceSpec", "PrivateConnectivity", + "Replica", + "ReplicaSpec", ] diff --git a/temporalio/api/cloud/namespace/v1/message_pb2.py b/temporalio/api/cloud/namespace/v1/message_pb2.py index 5cd6c00c2..33eb2f789 100644 --- a/temporalio/api/cloud/namespace/v1/message_pb2.py +++ b/temporalio/api/cloud/namespace/v1/message_pb2.py @@ -27,7 +27,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n-temporal/api/cloud/namespace/v1/message.proto\x12\x1ftemporal.api.cloud.namespace.v1\x1a,temporal/api/cloud/resource/v1/message.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a(temporal/api/cloud/sink/v1/message.proto\x1a\x34temporal/api/cloud/connectivityrule/v1/message.proto"\x81\x01\n\x15\x43\x65rtificateFilterSpec\x12\x13\n\x0b\x63ommon_name\x18\x01 \x01(\t\x12\x14\n\x0corganization\x18\x02 \x01(\t\x12\x1b\n\x13organizational_unit\x18\x03 \x01(\t\x12 \n\x18subject_alternative_name\x18\x04 \x01(\t"\xbb\x01\n\x0cMtlsAuthSpec\x12)\n\x1d\x61\x63\x63\x65pted_client_ca_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12\x1a\n\x12\x61\x63\x63\x65pted_client_ca\x18\x04 \x01(\x0c\x12S\n\x13\x63\x65rtificate_filters\x18\x02 \x03(\x0b\x32\x36.temporal.api.cloud.namespace.v1.CertificateFilterSpec\x12\x0f\n\x07\x65nabled\x18\x03 \x01(\x08"!\n\x0e\x41piKeyAuthSpec\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08"1\n\rLifecycleSpec\x12 \n\x18\x65nable_delete_protection\x18\x01 \x01(\x08"\xf4\x02\n\x0f\x43odecServerSpec\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x19\n\x11pass_access_token\x18\x02 \x01(\x08\x12(\n include_cross_origin_credentials\x18\x03 \x01(\x08\x12\x61\n\x14\x63ustom_error_message\x18\x04 \x01(\x0b\x32\x43.temporal.api.cloud.namespace.v1.CodecServerSpec.CustomErrorMessage\x1a\xa6\x01\n\x12\x43ustomErrorMessage\x12\x61\n\x07\x64\x65\x66\x61ult\x18\x01 \x01(\x0b\x32P.temporal.api.cloud.namespace.v1.CodecServerSpec.CustomErrorMessage.ErrorMessage\x1a-\n\x0c\x45rrorMessage\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04link\x18\x02 \x01(\t"8\n\x14HighAvailabilitySpec\x12 \n\x18\x64isable_managed_failover\x18\x01 \x01(\x08"\xdf\x01\n\x0c\x43\x61pacitySpec\x12K\n\ton_demand\x18\x01 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.CapacitySpec.OnDemandH\x00\x12P\n\x0bprovisioned\x18\x02 \x01(\x0b\x32\x39.temporal.api.cloud.namespace.v1.CapacitySpec.ProvisionedH\x00\x1a\n\n\x08OnDemand\x1a\x1c\n\x0bProvisioned\x12\r\n\x05value\x18\x01 \x01(\x01\x42\x06\n\x04spec"\xdc\x05\n\x08\x43\x61pacity\x12G\n\ton_demand\x18\x01 \x01(\x0b\x32\x32.temporal.api.cloud.namespace.v1.Capacity.OnDemandH\x00\x12L\n\x0bprovisioned\x18\x02 \x01(\x0b\x32\x35.temporal.api.cloud.namespace.v1.Capacity.ProvisionedH\x00\x12I\n\x0elatest_request\x18\x03 \x01(\x0b\x32\x31.temporal.api.cloud.namespace.v1.Capacity.Request\x1a\n\n\x08OnDemand\x1a$\n\x0bProvisioned\x12\x15\n\rcurrent_value\x18\x01 \x01(\x01\x1a\xab\x03\n\x07Request\x12\x46\n\x05state\x18\x01 \x01(\x0e\x32\x37.temporal.api.cloud.namespace.v1.Capacity.Request.State\x12.\n\nstart_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t\x12;\n\x04spec\x18\x05 \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.CapacitySpec"\xa0\x01\n\x05State\x12&\n"STATE_CAPACITY_REQUEST_UNSPECIFIED\x10\x00\x12$\n STATE_CAPACITY_REQUEST_COMPLETED\x10\x01\x12&\n"STATE_CAPACITY_REQUEST_IN_PROGRESS\x10\x02\x12!\n\x1dSTATE_CAPACITY_REQUEST_FAILED\x10\x03\x42\x0e\n\x0c\x63urrent_mode"\xcf\t\n\rNamespaceSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07regions\x18\x02 \x03(\t\x12\x16\n\x0eretention_days\x18\x03 \x01(\x05\x12@\n\tmtls_auth\x18\x04 \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.MtlsAuthSpec\x12\x45\n\x0c\x61pi_key_auth\x18\x07 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ApiKeyAuthSpec\x12p\n\x18\x63ustom_search_attributes\x18\x05 \x03(\x0b\x32J.temporal.api.cloud.namespace.v1.NamespaceSpec.CustomSearchAttributesEntryB\x02\x18\x01\x12_\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x44.temporal.api.cloud.namespace.v1.NamespaceSpec.SearchAttributesEntry\x12\x46\n\x0c\x63odec_server\x18\x06 \x01(\x0b\x32\x30.temporal.api.cloud.namespace.v1.CodecServerSpec\x12\x41\n\tlifecycle\x18\t \x01(\x0b\x32..temporal.api.cloud.namespace.v1.LifecycleSpec\x12P\n\x11high_availability\x18\n \x01(\x0b\x32\x35.temporal.api.cloud.namespace.v1.HighAvailabilitySpec\x12\x1d\n\x15\x63onnectivity_rule_ids\x18\x0b \x03(\t\x12\x44\n\rcapacity_spec\x18\x0c \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.CapacitySpec\x1a=\n\x1b\x43ustomSearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a{\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12Q\n\x05value\x18\x02 \x01(\x0e\x32\x42.temporal.api.cloud.namespace.v1.NamespaceSpec.SearchAttributeType:\x02\x38\x01"\xac\x02\n\x13SearchAttributeType\x12%\n!SEARCH_ATTRIBUTE_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aSEARCH_ATTRIBUTE_TYPE_TEXT\x10\x01\x12!\n\x1dSEARCH_ATTRIBUTE_TYPE_KEYWORD\x10\x02\x12\x1d\n\x19SEARCH_ATTRIBUTE_TYPE_INT\x10\x03\x12 \n\x1cSEARCH_ATTRIBUTE_TYPE_DOUBLE\x10\x04\x12\x1e\n\x1aSEARCH_ATTRIBUTE_TYPE_BOOL\x10\x05\x12"\n\x1eSEARCH_ATTRIBUTE_TYPE_DATETIME\x10\x06\x12&\n"SEARCH_ATTRIBUTE_TYPE_KEYWORD_LIST\x10\x07"Q\n\tEndpoints\x12\x13\n\x0bweb_address\x18\x01 \x01(\t\x12\x19\n\x11mtls_grpc_address\x18\x02 \x01(\t\x12\x14\n\x0cgrpc_address\x18\x03 \x01(\t"*\n\x06Limits\x12 \n\x18\x61\x63tions_per_second_limit\x18\x01 \x01(\x05"X\n\x12\x41WSPrivateLinkInfo\x12\x1e\n\x16\x61llowed_principal_arns\x18\x01 \x03(\t\x12"\n\x1avpc_endpoint_service_names\x18\x02 \x03(\t"t\n\x13PrivateConnectivity\x12\x0e\n\x06region\x18\x01 \x01(\t\x12M\n\x10\x61ws_private_link\x18\x02 \x01(\x0b\x32\x33.temporal.api.cloud.namespace.v1.AWSPrivateLinkInfo"\x83\x08\n\tNamespace\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12<\n\x04spec\x18\x03 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\r \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12=\n\tendpoints\x18\x06 \x01(\x0b\x32*.temporal.api.cloud.namespace.v1.Endpoints\x12\x15\n\ractive_region\x18\x07 \x01(\t\x12\x37\n\x06limits\x18\x08 \x01(\x0b\x32\'.temporal.api.cloud.namespace.v1.Limits\x12T\n\x16private_connectivities\x18\t \x03(\x0b\x32\x34.temporal.api.cloud.namespace.v1.PrivateConnectivity\x12\x30\n\x0c\x63reated_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12S\n\rregion_status\x18\x0c \x03(\x0b\x32<.temporal.api.cloud.namespace.v1.Namespace.RegionStatusEntry\x12T\n\x12\x63onnectivity_rules\x18\x0e \x03(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule\x12\x42\n\x04tags\x18\x0f \x03(\x0b\x32\x34.temporal.api.cloud.namespace.v1.Namespace.TagsEntry\x12;\n\x08\x63\x61pacity\x18\x10 \x01(\x0b\x32).temporal.api.cloud.namespace.v1.Capacity\x1ak\n\x11RegionStatusEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x45\n\x05value\x18\x02 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.NamespaceRegionStatus:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\x9b\x02\n\x15NamespaceRegionStatus\x12\x1c\n\x10state_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12K\n\x05state\x18\x03 \x01(\x0e\x32<.temporal.api.cloud.namespace.v1.NamespaceRegionStatus.State\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"{\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSTATE_ADDING\x10\x01\x12\x10\n\x0cSTATE_ACTIVE\x10\x02\x12\x11\n\rSTATE_PASSIVE\x10\x03\x12\x12\n\x0eSTATE_REMOVING\x10\x04\x12\x10\n\x0cSTATE_FAILED\x10\x05"\x91\x01\n\x0e\x45xportSinkSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x65nabled\x18\x02 \x01(\x08\x12.\n\x02s3\x18\x03 \x01(\x0b\x32".temporal.api.cloud.sink.v1.S3Spec\x12\x30\n\x03gcs\x18\x04 \x01(\x0b\x32#.temporal.api.cloud.sink.v1.GCSSpec"\xf6\x03\n\nExportSink\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12<\n\x05state\x18\x03 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12=\n\x04spec\x18\x04 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x42\n\x06health\x18\x05 \x01(\x0e\x32\x32.temporal.api.cloud.namespace.v1.ExportSink.Health\x12\x15\n\rerror_message\x18\x06 \x01(\t\x12;\n\x17latest_data_export_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_health_check_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"o\n\x06Health\x12\x16\n\x12HEALTH_UNSPECIFIED\x10\x00\x12\r\n\tHEALTH_OK\x10\x01\x12\x19\n\x15HEALTH_ERROR_INTERNAL\x10\x02\x12#\n\x1fHEALTH_ERROR_USER_CONFIGURATION\x10\x03"\x9f\x06\n\x15NamespaceCapacityInfo\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x19\n\x11has_legacy_limits\x18\x02 \x01(\x08\x12\x43\n\x10\x63urrent_capacity\x18\x03 \x01(\x0b\x32).temporal.api.cloud.namespace.v1.Capacity\x12`\n\x0cmode_options\x18\x04 \x01(\x0b\x32J.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions\x12K\n\x05stats\x18\x05 \x01(\x0b\x32<.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.Stats\x1a\xd3\x02\n\x13\x43\x61pacityModeOptions\x12k\n\x0bprovisioned\x18\x01 \x01(\x0b\x32V.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions.Provisioned\x12\x66\n\ton_demand\x18\x02 \x01(\x0b\x32S.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions.OnDemand\x1aH\n\x0bProvisioned\x12\x18\n\x10valid_tru_values\x18\x01 \x03(\x01\x12\x1f\n\x17max_available_tru_value\x18\x02 \x01(\x01\x1a\x1d\n\x08OnDemand\x12\x11\n\taps_limit\x18\x01 \x01(\x01\x1a\x8d\x01\n\x05Stats\x12Q\n\x03\x61ps\x18\x01 \x01(\x0b\x32\x44.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.Stats.Summary\x1a\x31\n\x07Summary\x12\x0c\n\x04mean\x18\x01 \x01(\x01\x12\x0b\n\x03p90\x18\x02 \x01(\x01\x12\x0b\n\x03p99\x18\x03 \x01(\x01\x42\xb1\x01\n"io.temporal.api.cloud.namespace.v1B\x0cMessageProtoP\x01Z/go.temporal.io/api/cloud/namespace/v1;namespace\xaa\x02!Temporalio.Api.Cloud.Namespace.V1\xea\x02%Temporalio::Api::Cloud::Namespace::V1b\x06proto3' + b'\n-temporal/api/cloud/namespace/v1/message.proto\x12\x1ftemporal.api.cloud.namespace.v1\x1a,temporal/api/cloud/resource/v1/message.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a(temporal/api/cloud/sink/v1/message.proto\x1a\x34temporal/api/cloud/connectivityrule/v1/message.proto"\x81\x01\n\x15\x43\x65rtificateFilterSpec\x12\x13\n\x0b\x63ommon_name\x18\x01 \x01(\t\x12\x14\n\x0corganization\x18\x02 \x01(\t\x12\x1b\n\x13organizational_unit\x18\x03 \x01(\t\x12 \n\x18subject_alternative_name\x18\x04 \x01(\t"\xbb\x01\n\x0cMtlsAuthSpec\x12)\n\x1d\x61\x63\x63\x65pted_client_ca_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12\x1a\n\x12\x61\x63\x63\x65pted_client_ca\x18\x04 \x01(\x0c\x12S\n\x13\x63\x65rtificate_filters\x18\x02 \x03(\x0b\x32\x36.temporal.api.cloud.namespace.v1.CertificateFilterSpec\x12\x0f\n\x07\x65nabled\x18\x03 \x01(\x08"!\n\x0e\x41piKeyAuthSpec\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08"1\n\rLifecycleSpec\x12 \n\x18\x65nable_delete_protection\x18\x01 \x01(\x08"\xf4\x02\n\x0f\x43odecServerSpec\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x19\n\x11pass_access_token\x18\x02 \x01(\x08\x12(\n include_cross_origin_credentials\x18\x03 \x01(\x08\x12\x61\n\x14\x63ustom_error_message\x18\x04 \x01(\x0b\x32\x43.temporal.api.cloud.namespace.v1.CodecServerSpec.CustomErrorMessage\x1a\xa6\x01\n\x12\x43ustomErrorMessage\x12\x61\n\x07\x64\x65\x66\x61ult\x18\x01 \x01(\x0b\x32P.temporal.api.cloud.namespace.v1.CodecServerSpec.CustomErrorMessage.ErrorMessage\x1a-\n\x0c\x45rrorMessage\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04link\x18\x02 \x01(\t"c\n\x14HighAvailabilitySpec\x12 \n\x18\x64isable_managed_failover\x18\x01 \x01(\x08\x12)\n!disable_passive_poller_forwarding\x18\x02 \x01(\x08"\x1d\n\x0bReplicaSpec\x12\x0e\n\x06region\x18\x01 \x01(\t"\x99\x02\n\x07Replica\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nis_primary\x18\x02 \x01(\x08\x12\x44\n\x05state\x18\x03 \x01(\x0e\x32\x35.temporal.api.cloud.namespace.v1.Replica.ReplicaState\x12\x0e\n\x06region\x18\x04 \x01(\t"\x97\x01\n\x0cReplicaState\x12\x1d\n\x19REPLICA_STATE_UNSPECIFIED\x10\x00\x12\x18\n\x14REPLICA_STATE_ADDING\x10\x01\x12\x18\n\x14REPLICA_STATE_ACTIVE\x10\x02\x12\x1a\n\x16REPLICA_STATE_REMOVING\x10\x03\x12\x18\n\x14REPLICA_STATE_FAILED\x10\x05"\xdf\x01\n\x0c\x43\x61pacitySpec\x12K\n\ton_demand\x18\x01 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.CapacitySpec.OnDemandH\x00\x12P\n\x0bprovisioned\x18\x02 \x01(\x0b\x32\x39.temporal.api.cloud.namespace.v1.CapacitySpec.ProvisionedH\x00\x1a\n\n\x08OnDemand\x1a\x1c\n\x0bProvisioned\x12\r\n\x05value\x18\x01 \x01(\x01\x42\x06\n\x04spec"\xdc\x05\n\x08\x43\x61pacity\x12G\n\ton_demand\x18\x01 \x01(\x0b\x32\x32.temporal.api.cloud.namespace.v1.Capacity.OnDemandH\x00\x12L\n\x0bprovisioned\x18\x02 \x01(\x0b\x32\x35.temporal.api.cloud.namespace.v1.Capacity.ProvisionedH\x00\x12I\n\x0elatest_request\x18\x03 \x01(\x0b\x32\x31.temporal.api.cloud.namespace.v1.Capacity.Request\x1a\n\n\x08OnDemand\x1a$\n\x0bProvisioned\x12\x15\n\rcurrent_value\x18\x01 \x01(\x01\x1a\xab\x03\n\x07Request\x12\x46\n\x05state\x18\x01 \x01(\x0e\x32\x37.temporal.api.cloud.namespace.v1.Capacity.Request.State\x12.\n\nstart_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1a\n\x12\x61sync_operation_id\x18\x04 \x01(\t\x12;\n\x04spec\x18\x05 \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.CapacitySpec"\xa0\x01\n\x05State\x12&\n"STATE_CAPACITY_REQUEST_UNSPECIFIED\x10\x00\x12$\n STATE_CAPACITY_REQUEST_COMPLETED\x10\x01\x12&\n"STATE_CAPACITY_REQUEST_IN_PROGRESS\x10\x02\x12!\n\x1dSTATE_CAPACITY_REQUEST_FAILED\x10\x03\x42\x0e\n\x0c\x63urrent_mode"3\n\x0c\x46\x61irnessSpec\x12#\n\x1btask_queue_fairness_enabled\x18\x01 \x01(\x08"\xd4\n\n\rNamespaceSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07regions\x18\x02 \x03(\tB\x02\x18\x01\x12\x16\n\x0eretention_days\x18\x03 \x01(\x05\x12@\n\tmtls_auth\x18\x04 \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.MtlsAuthSpec\x12\x45\n\x0c\x61pi_key_auth\x18\x07 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ApiKeyAuthSpec\x12p\n\x18\x63ustom_search_attributes\x18\x05 \x03(\x0b\x32J.temporal.api.cloud.namespace.v1.NamespaceSpec.CustomSearchAttributesEntryB\x02\x18\x01\x12_\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x44.temporal.api.cloud.namespace.v1.NamespaceSpec.SearchAttributesEntry\x12\x46\n\x0c\x63odec_server\x18\x06 \x01(\x0b\x32\x30.temporal.api.cloud.namespace.v1.CodecServerSpec\x12\x41\n\tlifecycle\x18\t \x01(\x0b\x32..temporal.api.cloud.namespace.v1.LifecycleSpec\x12P\n\x11high_availability\x18\n \x01(\x0b\x32\x35.temporal.api.cloud.namespace.v1.HighAvailabilitySpec\x12\x1d\n\x15\x63onnectivity_rule_ids\x18\x0b \x03(\t\x12\x44\n\rcapacity_spec\x18\x0c \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.CapacitySpec\x12>\n\x08replicas\x18\r \x03(\x0b\x32,.temporal.api.cloud.namespace.v1.ReplicaSpec\x12?\n\x08\x66\x61irness\x18\x0e \x01(\x0b\x32-.temporal.api.cloud.namespace.v1.FairnessSpec\x1a=\n\x1b\x43ustomSearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a{\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12Q\n\x05value\x18\x02 \x01(\x0e\x32\x42.temporal.api.cloud.namespace.v1.NamespaceSpec.SearchAttributeType:\x02\x38\x01"\xac\x02\n\x13SearchAttributeType\x12%\n!SEARCH_ATTRIBUTE_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aSEARCH_ATTRIBUTE_TYPE_TEXT\x10\x01\x12!\n\x1dSEARCH_ATTRIBUTE_TYPE_KEYWORD\x10\x02\x12\x1d\n\x19SEARCH_ATTRIBUTE_TYPE_INT\x10\x03\x12 \n\x1cSEARCH_ATTRIBUTE_TYPE_DOUBLE\x10\x04\x12\x1e\n\x1aSEARCH_ATTRIBUTE_TYPE_BOOL\x10\x05\x12"\n\x1eSEARCH_ATTRIBUTE_TYPE_DATETIME\x10\x06\x12&\n"SEARCH_ATTRIBUTE_TYPE_KEYWORD_LIST\x10\x07"Q\n\tEndpoints\x12\x13\n\x0bweb_address\x18\x01 \x01(\t\x12\x19\n\x11mtls_grpc_address\x18\x02 \x01(\t\x12\x14\n\x0cgrpc_address\x18\x03 \x01(\t"*\n\x06Limits\x12 \n\x18\x61\x63tions_per_second_limit\x18\x01 \x01(\x05"X\n\x12\x41WSPrivateLinkInfo\x12\x1e\n\x16\x61llowed_principal_arns\x18\x01 \x03(\t\x12"\n\x1avpc_endpoint_service_names\x18\x02 \x03(\t"t\n\x13PrivateConnectivity\x12\x0e\n\x06region\x18\x01 \x01(\t\x12M\n\x10\x61ws_private_link\x18\x02 \x01(\x0b\x32\x33.temporal.api.cloud.namespace.v1.AWSPrivateLinkInfo"\xc3\x08\n\tNamespace\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12<\n\x04spec\x18\x03 \x01(\x0b\x32..temporal.api.cloud.namespace.v1.NamespaceSpec\x12\x1c\n\x10state_deprecated\x18\x04 \x01(\tB\x02\x18\x01\x12<\n\x05state\x18\r \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12=\n\tendpoints\x18\x06 \x01(\x0b\x32*.temporal.api.cloud.namespace.v1.Endpoints\x12\x15\n\ractive_region\x18\x07 \x01(\t\x12\x37\n\x06limits\x18\x08 \x01(\x0b\x32\'.temporal.api.cloud.namespace.v1.Limits\x12T\n\x16private_connectivities\x18\t \x03(\x0b\x32\x34.temporal.api.cloud.namespace.v1.PrivateConnectivity\x12\x30\n\x0c\x63reated_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x12last_modified_time\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12W\n\rregion_status\x18\x0c \x03(\x0b\x32<.temporal.api.cloud.namespace.v1.Namespace.RegionStatusEntryB\x02\x18\x01\x12T\n\x12\x63onnectivity_rules\x18\x0e \x03(\x0b\x32\x38.temporal.api.cloud.connectivityrule.v1.ConnectivityRule\x12\x42\n\x04tags\x18\x0f \x03(\x0b\x32\x34.temporal.api.cloud.namespace.v1.Namespace.TagsEntry\x12;\n\x08\x63\x61pacity\x18\x10 \x01(\x0b\x32).temporal.api.cloud.namespace.v1.Capacity\x12:\n\x08replicas\x18\x12 \x03(\x0b\x32(.temporal.api.cloud.namespace.v1.Replica\x1ak\n\x11RegionStatusEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x45\n\x05value\x18\x02 \x01(\x0b\x32\x36.temporal.api.cloud.namespace.v1.NamespaceRegionStatus:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\x9b\x02\n\x15NamespaceRegionStatus\x12\x1c\n\x10state_deprecated\x18\x01 \x01(\tB\x02\x18\x01\x12K\n\x05state\x18\x03 \x01(\x0e\x32<.temporal.api.cloud.namespace.v1.NamespaceRegionStatus.State\x12\x1a\n\x12\x61sync_operation_id\x18\x02 \x01(\t"{\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSTATE_ADDING\x10\x01\x12\x10\n\x0cSTATE_ACTIVE\x10\x02\x12\x11\n\rSTATE_PASSIVE\x10\x03\x12\x12\n\x0eSTATE_REMOVING\x10\x04\x12\x10\n\x0cSTATE_FAILED\x10\x05"\x91\x01\n\x0e\x45xportSinkSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x65nabled\x18\x02 \x01(\x08\x12.\n\x02s3\x18\x03 \x01(\x0b\x32".temporal.api.cloud.sink.v1.S3Spec\x12\x30\n\x03gcs\x18\x04 \x01(\x0b\x32#.temporal.api.cloud.sink.v1.GCSSpec"\xf6\x03\n\nExportSink\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10resource_version\x18\x02 \x01(\t\x12<\n\x05state\x18\x03 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12=\n\x04spec\x18\x04 \x01(\x0b\x32/.temporal.api.cloud.namespace.v1.ExportSinkSpec\x12\x42\n\x06health\x18\x05 \x01(\x0e\x32\x32.temporal.api.cloud.namespace.v1.ExportSink.Health\x12\x15\n\rerror_message\x18\x06 \x01(\t\x12;\n\x17latest_data_export_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_health_check_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"o\n\x06Health\x12\x16\n\x12HEALTH_UNSPECIFIED\x10\x00\x12\r\n\tHEALTH_OK\x10\x01\x12\x19\n\x15HEALTH_ERROR_INTERNAL\x10\x02\x12#\n\x1fHEALTH_ERROR_USER_CONFIGURATION\x10\x03"\x9f\x06\n\x15NamespaceCapacityInfo\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x19\n\x11has_legacy_limits\x18\x02 \x01(\x08\x12\x43\n\x10\x63urrent_capacity\x18\x03 \x01(\x0b\x32).temporal.api.cloud.namespace.v1.Capacity\x12`\n\x0cmode_options\x18\x04 \x01(\x0b\x32J.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions\x12K\n\x05stats\x18\x05 \x01(\x0b\x32<.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.Stats\x1a\xd3\x02\n\x13\x43\x61pacityModeOptions\x12k\n\x0bprovisioned\x18\x01 \x01(\x0b\x32V.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions.Provisioned\x12\x66\n\ton_demand\x18\x02 \x01(\x0b\x32S.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.CapacityModeOptions.OnDemand\x1aH\n\x0bProvisioned\x12\x18\n\x10valid_tru_values\x18\x01 \x03(\x01\x12\x1f\n\x17max_available_tru_value\x18\x02 \x01(\x01\x1a\x1d\n\x08OnDemand\x12\x11\n\taps_limit\x18\x01 \x01(\x01\x1a\x8d\x01\n\x05Stats\x12Q\n\x03\x61ps\x18\x01 \x01(\x0b\x32\x44.temporal.api.cloud.namespace.v1.NamespaceCapacityInfo.Stats.Summary\x1a\x31\n\x07Summary\x12\x0c\n\x04mean\x18\x01 \x01(\x01\x12\x0b\n\x03p90\x18\x02 \x01(\x01\x12\x0b\n\x03p99\x18\x03 \x01(\x01\x42\xb1\x01\n"io.temporal.api.cloud.namespace.v1B\x0cMessageProtoP\x01Z/go.temporal.io/api/cloud/namespace/v1;namespace\xaa\x02!Temporalio.Api.Cloud.Namespace.V1\xea\x02%Temporalio::Api::Cloud::Namespace::V1b\x06proto3' ) @@ -43,6 +43,8 @@ _CODECSERVERSPEC_CUSTOMERRORMESSAGE.nested_types_by_name["ErrorMessage"] ) _HIGHAVAILABILITYSPEC = DESCRIPTOR.message_types_by_name["HighAvailabilitySpec"] +_REPLICASPEC = DESCRIPTOR.message_types_by_name["ReplicaSpec"] +_REPLICA = DESCRIPTOR.message_types_by_name["Replica"] _CAPACITYSPEC = DESCRIPTOR.message_types_by_name["CapacitySpec"] _CAPACITYSPEC_ONDEMAND = _CAPACITYSPEC.nested_types_by_name["OnDemand"] _CAPACITYSPEC_PROVISIONED = _CAPACITYSPEC.nested_types_by_name["Provisioned"] @@ -50,6 +52,7 @@ _CAPACITY_ONDEMAND = _CAPACITY.nested_types_by_name["OnDemand"] _CAPACITY_PROVISIONED = _CAPACITY.nested_types_by_name["Provisioned"] _CAPACITY_REQUEST = _CAPACITY.nested_types_by_name["Request"] +_FAIRNESSSPEC = DESCRIPTOR.message_types_by_name["FairnessSpec"] _NAMESPACESPEC = DESCRIPTOR.message_types_by_name["NamespaceSpec"] _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY = _NAMESPACESPEC.nested_types_by_name[ "CustomSearchAttributesEntry" @@ -81,6 +84,7 @@ _NAMESPACECAPACITYINFO_STATS_SUMMARY = ( _NAMESPACECAPACITYINFO_STATS.nested_types_by_name["Summary"] ) +_REPLICA_REPLICASTATE = _REPLICA.enum_types_by_name["ReplicaState"] _CAPACITY_REQUEST_STATE = _CAPACITY_REQUEST.enum_types_by_name["State"] _NAMESPACESPEC_SEARCHATTRIBUTETYPE = _NAMESPACESPEC.enum_types_by_name[ "SearchAttributeType" @@ -173,6 +177,28 @@ ) _sym_db.RegisterMessage(HighAvailabilitySpec) +ReplicaSpec = _reflection.GeneratedProtocolMessageType( + "ReplicaSpec", + (_message.Message,), + { + "DESCRIPTOR": _REPLICASPEC, + "__module__": "temporalio.api.cloud.namespace.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.namespace.v1.ReplicaSpec) + }, +) +_sym_db.RegisterMessage(ReplicaSpec) + +Replica = _reflection.GeneratedProtocolMessageType( + "Replica", + (_message.Message,), + { + "DESCRIPTOR": _REPLICA, + "__module__": "temporalio.api.cloud.namespace.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.namespace.v1.Replica) + }, +) +_sym_db.RegisterMessage(Replica) + CapacitySpec = _reflection.GeneratedProtocolMessageType( "CapacitySpec", (_message.Message,), @@ -245,6 +271,17 @@ _sym_db.RegisterMessage(Capacity.Provisioned) _sym_db.RegisterMessage(Capacity.Request) +FairnessSpec = _reflection.GeneratedProtocolMessageType( + "FairnessSpec", + (_message.Message,), + { + "DESCRIPTOR": _FAIRNESSSPEC, + "__module__": "temporalio.api.cloud.namespace.v1.message_pb2", + # @@protoc_insertion_point(class_scope:temporal.api.cloud.namespace.v1.FairnessSpec) + }, +) +_sym_db.RegisterMessage(FairnessSpec) + NamespaceSpec = _reflection.GeneratedProtocolMessageType( "NamespaceSpec", (_message.Message,), @@ -456,6 +493,8 @@ _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY._serialized_options = b"8\001" _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._options = None _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._serialized_options = b"8\001" + _NAMESPACESPEC.fields_by_name["regions"]._options = None + _NAMESPACESPEC.fields_by_name["regions"]._serialized_options = b"\030\001" _NAMESPACESPEC.fields_by_name["custom_search_attributes"]._options = None _NAMESPACESPEC.fields_by_name[ "custom_search_attributes" @@ -466,6 +505,8 @@ _NAMESPACE_TAGSENTRY._serialized_options = b"8\001" _NAMESPACE.fields_by_name["state_deprecated"]._options = None _NAMESPACE.fields_by_name["state_deprecated"]._serialized_options = b"\030\001" + _NAMESPACE.fields_by_name["region_status"]._options = None + _NAMESPACE.fields_by_name["region_status"]._serialized_options = b"\030\001" _NAMESPACEREGIONSTATUS.fields_by_name["state_deprecated"]._options = None _NAMESPACEREGIONSTATUS.fields_by_name[ "state_deprecated" @@ -485,65 +526,73 @@ _CODECSERVERSPEC_CUSTOMERRORMESSAGE_ERRORMESSAGE._serialized_start = 993 _CODECSERVERSPEC_CUSTOMERRORMESSAGE_ERRORMESSAGE._serialized_end = 1038 _HIGHAVAILABILITYSPEC._serialized_start = 1040 - _HIGHAVAILABILITYSPEC._serialized_end = 1096 - _CAPACITYSPEC._serialized_start = 1099 - _CAPACITYSPEC._serialized_end = 1322 - _CAPACITYSPEC_ONDEMAND._serialized_start = 1274 - _CAPACITYSPEC_ONDEMAND._serialized_end = 1284 - _CAPACITYSPEC_PROVISIONED._serialized_start = 1286 - _CAPACITYSPEC_PROVISIONED._serialized_end = 1314 - _CAPACITY._serialized_start = 1325 - _CAPACITY._serialized_end = 2057 - _CAPACITY_ONDEMAND._serialized_start = 1274 - _CAPACITY_ONDEMAND._serialized_end = 1284 - _CAPACITY_PROVISIONED._serialized_start = 1575 - _CAPACITY_PROVISIONED._serialized_end = 1611 - _CAPACITY_REQUEST._serialized_start = 1614 - _CAPACITY_REQUEST._serialized_end = 2041 - _CAPACITY_REQUEST_STATE._serialized_start = 1881 - _CAPACITY_REQUEST_STATE._serialized_end = 2041 - _NAMESPACESPEC._serialized_start = 2060 - _NAMESPACESPEC._serialized_end = 3291 - _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY._serialized_start = 2802 - _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY._serialized_end = 2863 - _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._serialized_start = 2865 - _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._serialized_end = 2988 - _NAMESPACESPEC_SEARCHATTRIBUTETYPE._serialized_start = 2991 - _NAMESPACESPEC_SEARCHATTRIBUTETYPE._serialized_end = 3291 - _ENDPOINTS._serialized_start = 3293 - _ENDPOINTS._serialized_end = 3374 - _LIMITS._serialized_start = 3376 - _LIMITS._serialized_end = 3418 - _AWSPRIVATELINKINFO._serialized_start = 3420 - _AWSPRIVATELINKINFO._serialized_end = 3508 - _PRIVATECONNECTIVITY._serialized_start = 3510 - _PRIVATECONNECTIVITY._serialized_end = 3626 - _NAMESPACE._serialized_start = 3629 - _NAMESPACE._serialized_end = 4656 - _NAMESPACE_REGIONSTATUSENTRY._serialized_start = 4504 - _NAMESPACE_REGIONSTATUSENTRY._serialized_end = 4611 - _NAMESPACE_TAGSENTRY._serialized_start = 4613 - _NAMESPACE_TAGSENTRY._serialized_end = 4656 - _NAMESPACEREGIONSTATUS._serialized_start = 4659 - _NAMESPACEREGIONSTATUS._serialized_end = 4942 - _NAMESPACEREGIONSTATUS_STATE._serialized_start = 4819 - _NAMESPACEREGIONSTATUS_STATE._serialized_end = 4942 - _EXPORTSINKSPEC._serialized_start = 4945 - _EXPORTSINKSPEC._serialized_end = 5090 - _EXPORTSINK._serialized_start = 5093 - _EXPORTSINK._serialized_end = 5595 - _EXPORTSINK_HEALTH._serialized_start = 5484 - _EXPORTSINK_HEALTH._serialized_end = 5595 - _NAMESPACECAPACITYINFO._serialized_start = 5598 - _NAMESPACECAPACITYINFO._serialized_end = 6397 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS._serialized_start = 5914 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS._serialized_end = 6253 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_PROVISIONED._serialized_start = 6150 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_PROVISIONED._serialized_end = 6222 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_ONDEMAND._serialized_start = 6224 - _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_ONDEMAND._serialized_end = 6253 - _NAMESPACECAPACITYINFO_STATS._serialized_start = 6256 - _NAMESPACECAPACITYINFO_STATS._serialized_end = 6397 - _NAMESPACECAPACITYINFO_STATS_SUMMARY._serialized_start = 6348 - _NAMESPACECAPACITYINFO_STATS_SUMMARY._serialized_end = 6397 + _HIGHAVAILABILITYSPEC._serialized_end = 1139 + _REPLICASPEC._serialized_start = 1141 + _REPLICASPEC._serialized_end = 1170 + _REPLICA._serialized_start = 1173 + _REPLICA._serialized_end = 1454 + _REPLICA_REPLICASTATE._serialized_start = 1303 + _REPLICA_REPLICASTATE._serialized_end = 1454 + _CAPACITYSPEC._serialized_start = 1457 + _CAPACITYSPEC._serialized_end = 1680 + _CAPACITYSPEC_ONDEMAND._serialized_start = 1632 + _CAPACITYSPEC_ONDEMAND._serialized_end = 1642 + _CAPACITYSPEC_PROVISIONED._serialized_start = 1644 + _CAPACITYSPEC_PROVISIONED._serialized_end = 1672 + _CAPACITY._serialized_start = 1683 + _CAPACITY._serialized_end = 2415 + _CAPACITY_ONDEMAND._serialized_start = 1632 + _CAPACITY_ONDEMAND._serialized_end = 1642 + _CAPACITY_PROVISIONED._serialized_start = 1933 + _CAPACITY_PROVISIONED._serialized_end = 1969 + _CAPACITY_REQUEST._serialized_start = 1972 + _CAPACITY_REQUEST._serialized_end = 2399 + _CAPACITY_REQUEST_STATE._serialized_start = 2239 + _CAPACITY_REQUEST_STATE._serialized_end = 2399 + _FAIRNESSSPEC._serialized_start = 2417 + _FAIRNESSSPEC._serialized_end = 2468 + _NAMESPACESPEC._serialized_start = 2471 + _NAMESPACESPEC._serialized_end = 3835 + _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY._serialized_start = 3346 + _NAMESPACESPEC_CUSTOMSEARCHATTRIBUTESENTRY._serialized_end = 3407 + _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._serialized_start = 3409 + _NAMESPACESPEC_SEARCHATTRIBUTESENTRY._serialized_end = 3532 + _NAMESPACESPEC_SEARCHATTRIBUTETYPE._serialized_start = 3535 + _NAMESPACESPEC_SEARCHATTRIBUTETYPE._serialized_end = 3835 + _ENDPOINTS._serialized_start = 3837 + _ENDPOINTS._serialized_end = 3918 + _LIMITS._serialized_start = 3920 + _LIMITS._serialized_end = 3962 + _AWSPRIVATELINKINFO._serialized_start = 3964 + _AWSPRIVATELINKINFO._serialized_end = 4052 + _PRIVATECONNECTIVITY._serialized_start = 4054 + _PRIVATECONNECTIVITY._serialized_end = 4170 + _NAMESPACE._serialized_start = 4173 + _NAMESPACE._serialized_end = 5264 + _NAMESPACE_REGIONSTATUSENTRY._serialized_start = 5112 + _NAMESPACE_REGIONSTATUSENTRY._serialized_end = 5219 + _NAMESPACE_TAGSENTRY._serialized_start = 5221 + _NAMESPACE_TAGSENTRY._serialized_end = 5264 + _NAMESPACEREGIONSTATUS._serialized_start = 5267 + _NAMESPACEREGIONSTATUS._serialized_end = 5550 + _NAMESPACEREGIONSTATUS_STATE._serialized_start = 5427 + _NAMESPACEREGIONSTATUS_STATE._serialized_end = 5550 + _EXPORTSINKSPEC._serialized_start = 5553 + _EXPORTSINKSPEC._serialized_end = 5698 + _EXPORTSINK._serialized_start = 5701 + _EXPORTSINK._serialized_end = 6203 + _EXPORTSINK_HEALTH._serialized_start = 6092 + _EXPORTSINK_HEALTH._serialized_end = 6203 + _NAMESPACECAPACITYINFO._serialized_start = 6206 + _NAMESPACECAPACITYINFO._serialized_end = 7005 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS._serialized_start = 6522 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS._serialized_end = 6861 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_PROVISIONED._serialized_start = 6758 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_PROVISIONED._serialized_end = 6830 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_ONDEMAND._serialized_start = 6832 + _NAMESPACECAPACITYINFO_CAPACITYMODEOPTIONS_ONDEMAND._serialized_end = 6861 + _NAMESPACECAPACITYINFO_STATS._serialized_start = 6864 + _NAMESPACECAPACITYINFO_STATS._serialized_end = 7005 + _NAMESPACECAPACITYINFO_STATS_SUMMARY._serialized_start = 6956 + _NAMESPACECAPACITYINFO_STATS_SUMMARY._serialized_end = 7005 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/api/cloud/namespace/v1/message_pb2.pyi b/temporalio/api/cloud/namespace/v1/message_pb2.pyi index 147e50616..b2cbe49d8 100644 --- a/temporalio/api/cloud/namespace/v1/message_pb2.pyi +++ b/temporalio/api/cloud/namespace/v1/message_pb2.pyi @@ -265,22 +265,128 @@ class HighAvailabilitySpec(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor DISABLE_MANAGED_FAILOVER_FIELD_NUMBER: builtins.int + DISABLE_PASSIVE_POLLER_FORWARDING_FIELD_NUMBER: builtins.int disable_managed_failover: builtins.bool """Flag to disable managed failover for the namespace.""" + disable_passive_poller_forwarding: builtins.bool + """Flag to disable passive poller forwarding for this namespace. + temporal:versioning:min_version=v0.13.0 + """ def __init__( self, *, disable_managed_failover: builtins.bool = ..., + disable_passive_poller_forwarding: builtins.bool = ..., ) -> None: ... def ClearField( self, field_name: typing_extensions.Literal[ - "disable_managed_failover", b"disable_managed_failover" + "disable_managed_failover", + b"disable_managed_failover", + "disable_passive_poller_forwarding", + b"disable_passive_poller_forwarding", ], ) -> None: ... global___HighAvailabilitySpec = HighAvailabilitySpec +class ReplicaSpec(google.protobuf.message.Message): + """temporal:versioning:min_version=v0.13.0""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REGION_FIELD_NUMBER: builtins.int + region: builtins.str + """The id of the region where the replica should be placed. + The GetRegions API can be used to get the list of valid region ids. + All the replicas must adhere to the region's max_in_region_replicas limit and connectable_region_ids. + Required. Immutable. + Example: "aws-us-west-2". + """ + def __init__( + self, + *, + region: builtins.str = ..., + ) -> None: ... + def ClearField( + self, field_name: typing_extensions.Literal["region", b"region"] + ) -> None: ... + +global___ReplicaSpec = ReplicaSpec + +class Replica(google.protobuf.message.Message): + """temporal:versioning:min_version=v0.13.0""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _ReplicaState: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ReplicaStateEnumTypeWrapper( + google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ + Replica._ReplicaState.ValueType + ], + builtins.type, + ): # noqa: F821 + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + REPLICA_STATE_UNSPECIFIED: Replica._ReplicaState.ValueType # 0 + REPLICA_STATE_ADDING: Replica._ReplicaState.ValueType # 1 + """This replica is currently being added to the namespace.""" + REPLICA_STATE_ACTIVE: Replica._ReplicaState.ValueType # 2 + """This replica is healthy and active.""" + REPLICA_STATE_REMOVING: Replica._ReplicaState.ValueType # 3 + """This replica is currently being removed from the namespace.""" + REPLICA_STATE_FAILED: Replica._ReplicaState.ValueType # 5 + """This replica is in a failed state, reach out to Temporal Cloud support for remediation.""" + + class ReplicaState(_ReplicaState, metaclass=_ReplicaStateEnumTypeWrapper): ... + REPLICA_STATE_UNSPECIFIED: Replica.ReplicaState.ValueType # 0 + REPLICA_STATE_ADDING: Replica.ReplicaState.ValueType # 1 + """This replica is currently being added to the namespace.""" + REPLICA_STATE_ACTIVE: Replica.ReplicaState.ValueType # 2 + """This replica is healthy and active.""" + REPLICA_STATE_REMOVING: Replica.ReplicaState.ValueType # 3 + """This replica is currently being removed from the namespace.""" + REPLICA_STATE_FAILED: Replica.ReplicaState.ValueType # 5 + """This replica is in a failed state, reach out to Temporal Cloud support for remediation.""" + + ID_FIELD_NUMBER: builtins.int + IS_PRIMARY_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int + REGION_FIELD_NUMBER: builtins.int + id: builtins.str + """The id of the replica. This is generated by Temporal after a replica is created.""" + is_primary: builtins.bool + """Whether this replica is currently the primary one.""" + state: global___Replica.ReplicaState.ValueType + """The current state of this replica.""" + region: builtins.str + """The cloud provider and region of this replica.""" + def __init__( + self, + *, + id: builtins.str = ..., + is_primary: builtins.bool = ..., + state: global___Replica.ReplicaState.ValueType = ..., + region: builtins.str = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "id", + b"id", + "is_primary", + b"is_primary", + "region", + b"region", + "state", + b"state", + ], + ) -> None: ... + +global___Replica = Replica + class CapacitySpec(google.protobuf.message.Message): """temporal:versioning:min_version=v0.10.0""" @@ -495,6 +601,26 @@ class Capacity(google.protobuf.message.Message): global___Capacity = Capacity +class FairnessSpec(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TASK_QUEUE_FAIRNESS_ENABLED_FIELD_NUMBER: builtins.int + task_queue_fairness_enabled: builtins.bool + """Flag to enable task queue fairness for the namespace (default: disabled).""" + def __init__( + self, + *, + task_queue_fairness_enabled: builtins.bool = ..., + ) -> None: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "task_queue_fairness_enabled", b"task_queue_fairness_enabled" + ], + ) -> None: ... + +global___FairnessSpec = FairnessSpec + class NamespaceSpec(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -584,6 +710,8 @@ class NamespaceSpec(google.protobuf.message.Message): HIGH_AVAILABILITY_FIELD_NUMBER: builtins.int CONNECTIVITY_RULE_IDS_FIELD_NUMBER: builtins.int CAPACITY_SPEC_FIELD_NUMBER: builtins.int + REPLICAS_FIELD_NUMBER: builtins.int + FAIRNESS_FIELD_NUMBER: builtins.int name: builtins.str """The name to use for the namespace. This will create a namespace that's available at '..tmprl.cloud:7233'. @@ -601,6 +729,8 @@ class NamespaceSpec(google.protobuf.message.Message): Number of supported regions is 2. The regions is immutable. Once set, it cannot be changed. Example: ["aws-us-west-2"]. + Deprecated: Use replicas field instead. + temporal:versioning:max_version=v0.15.0 """ retention_days: builtins.int """The number of days the workflows data will be retained for. @@ -675,6 +805,26 @@ class NamespaceSpec(google.protobuf.message.Message): Can be changed only when the last capacity request is not in progress. temporal:versioning:min_version=v0.10.0 """ + @property + def replicas( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ + global___ReplicaSpec + ]: + """The replication configuration for the namespace. + At least one replica must be specified. + Only one replica can be marked to be the desired active one. + The status of each replica is available in the Namespace.replicas field. + Use HighAvailabilitySpec to set the preferred primary replica ID. + If the preferred primary replica ID is not set, the first replica in this replicas list will be the preferred primary. + temporal:versioning:min_version=v0.13.0 + """ + @property + def fairness(self) -> global___FairnessSpec: + """The fairness configuration for the namespace. + If unspecified, fairness features will be disabled. + temporal:versioning:min_version=v0.14.0 + """ def __init__( self, *, @@ -694,6 +844,8 @@ class NamespaceSpec(google.protobuf.message.Message): high_availability: global___HighAvailabilitySpec | None = ..., connectivity_rule_ids: collections.abc.Iterable[builtins.str] | None = ..., capacity_spec: global___CapacitySpec | None = ..., + replicas: collections.abc.Iterable[global___ReplicaSpec] | None = ..., + fairness: global___FairnessSpec | None = ..., ) -> None: ... def HasField( self, @@ -704,6 +856,8 @@ class NamespaceSpec(google.protobuf.message.Message): b"capacity_spec", "codec_server", b"codec_server", + "fairness", + b"fairness", "high_availability", b"high_availability", "lifecycle", @@ -725,6 +879,8 @@ class NamespaceSpec(google.protobuf.message.Message): b"connectivity_rule_ids", "custom_search_attributes", b"custom_search_attributes", + "fairness", + b"fairness", "high_availability", b"high_availability", "lifecycle", @@ -735,6 +891,8 @@ class NamespaceSpec(google.protobuf.message.Message): b"name", "regions", b"regions", + "replicas", + b"replicas", "retention_days", b"retention_days", "search_attributes", @@ -922,6 +1080,7 @@ class Namespace(google.protobuf.message.Message): CONNECTIVITY_RULES_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int CAPACITY_FIELD_NUMBER: builtins.int + REPLICAS_FIELD_NUMBER: builtins.int namespace: builtins.str """The namespace identifier.""" resource_version: builtins.str @@ -975,6 +1134,8 @@ class Namespace(google.protobuf.message.Message): ]: """The status of each region where the namespace is available. The id of the region is the key and the status is the value of the map. + deprecated: Use replicas field instead. + temporal:versioning:max_version=v0.15.0 """ @property def connectivity_rules( @@ -991,6 +1152,15 @@ class Namespace(google.protobuf.message.Message): @property def capacity(self) -> global___Capacity: """The status of namespace's capacity, if any.""" + @property + def replicas( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ + global___Replica + ]: + """The status of each replica where the namespace is available. + temporal:versioning:min_version=v0.13.0 + """ def __init__( self, *, @@ -1017,6 +1187,7 @@ class Namespace(google.protobuf.message.Message): | None = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., capacity: global___Capacity | None = ..., + replicas: collections.abc.Iterable[global___Replica] | None = ..., ) -> None: ... def HasField( self, @@ -1060,6 +1231,8 @@ class Namespace(google.protobuf.message.Message): b"private_connectivities", "region_status", b"region_status", + "replicas", + b"replicas", "resource_version", b"resource_version", "spec", diff --git a/temporalio/bridge/Cargo.lock b/temporalio/bridge/Cargo.lock index 39403b364..6d8749bca 100644 --- a/temporalio/bridge/Cargo.lock +++ b/temporalio/bridge/Cargo.lock @@ -2635,7 +2635,7 @@ dependencies = [ [[package]] name = "temporalio-client" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "async-trait", @@ -2665,7 +2665,7 @@ dependencies = [ [[package]] name = "temporalio-common" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "async-trait", @@ -2691,7 +2691,6 @@ dependencies = [ "prost-types", "prost-wkt", "prost-wkt-types", - "rand 0.10.0", "ringbuf", "serde", "serde_json", @@ -2710,7 +2709,7 @@ dependencies = [ [[package]] name = "temporalio-macros" -version = "0.3.0" +version = "0.4.0" dependencies = [ "proc-macro2", "quote", @@ -2719,7 +2718,7 @@ dependencies = [ [[package]] name = "temporalio-sdk-core" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "async-trait", diff --git a/temporalio/bridge/Cargo.toml b/temporalio/bridge/Cargo.toml index 31e8ee633..587ff9a8c 100644 --- a/temporalio/bridge/Cargo.toml +++ b/temporalio/bridge/Cargo.toml @@ -28,11 +28,11 @@ pyo3 = { version = "0.25", features = [ ] } pyo3-async-runtimes = { version = "0.25", features = ["tokio-runtime"] } pythonize = "0.25" -temporalio-client = { version = "0.3.0", path = "./sdk-core/crates/client" } -temporalio-common = { version = "0.3.0", path = "./sdk-core/crates/common", features = [ +temporalio-client = { version = "0.4.0", path = "./sdk-core/crates/client" } +temporalio-common = { version = "0.4.0", path = "./sdk-core/crates/common", features = [ "envconfig", "otel" ]} -temporalio-sdk-core = { version = "0.3.0", path = "./sdk-core/crates/sdk-core", features = [ +temporalio-sdk-core = { version = "0.4.0", path = "./sdk-core/crates/sdk-core", features = [ "ephemeral-server", ] } tokio = "1.26" diff --git a/temporalio/bridge/sdk-core b/temporalio/bridge/sdk-core index 2872b5363..a9481aaec 160000 --- a/temporalio/bridge/sdk-core +++ b/temporalio/bridge/sdk-core @@ -1 +1 @@ -Subproject commit 2872b5363e1b745cfb90313ebc7a507c5d25c398 +Subproject commit a9481aaec2b78aba39f15868e1fb12bc007f61da diff --git a/temporalio/bridge/services_generated.py b/temporalio/bridge/services_generated.py index f483c318a..837fa1c2e 100644 --- a/temporalio/bridge/services_generated.py +++ b/temporalio/bridge/services_generated.py @@ -2477,6 +2477,24 @@ async def create_connectivity_rule( timeout=timeout, ) + async def create_custom_role( + self, + req: temporalio.api.cloud.cloudservice.v1.CreateCustomRoleRequest, + retry: bool = False, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, + ) -> temporalio.api.cloud.cloudservice.v1.CreateCustomRoleResponse: + """Invokes the CloudService.create_custom_role rpc method.""" + return await self._client._rpc_call( + rpc="create_custom_role", + req=req, + service=self._service, + resp_type=temporalio.api.cloud.cloudservice.v1.CreateCustomRoleResponse, + retry=retry, + metadata=metadata, + timeout=timeout, + ) + async def create_namespace( self, req: temporalio.api.cloud.cloudservice.v1.CreateNamespaceRequest, @@ -2639,6 +2657,24 @@ async def delete_connectivity_rule( timeout=timeout, ) + async def delete_custom_role( + self, + req: temporalio.api.cloud.cloudservice.v1.DeleteCustomRoleRequest, + retry: bool = False, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, + ) -> temporalio.api.cloud.cloudservice.v1.DeleteCustomRoleResponse: + """Invokes the CloudService.delete_custom_role rpc method.""" + return await self._client._rpc_call( + rpc="delete_custom_role", + req=req, + service=self._service, + resp_type=temporalio.api.cloud.cloudservice.v1.DeleteCustomRoleResponse, + retry=retry, + metadata=metadata, + timeout=timeout, + ) + async def delete_namespace( self, req: temporalio.api.cloud.cloudservice.v1.DeleteNamespaceRequest, @@ -2981,6 +3017,42 @@ async def get_current_identity( timeout=timeout, ) + async def get_custom_role( + self, + req: temporalio.api.cloud.cloudservice.v1.GetCustomRoleRequest, + retry: bool = False, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, + ) -> temporalio.api.cloud.cloudservice.v1.GetCustomRoleResponse: + """Invokes the CloudService.get_custom_role rpc method.""" + return await self._client._rpc_call( + rpc="get_custom_role", + req=req, + service=self._service, + resp_type=temporalio.api.cloud.cloudservice.v1.GetCustomRoleResponse, + retry=retry, + metadata=metadata, + timeout=timeout, + ) + + async def get_custom_roles( + self, + req: temporalio.api.cloud.cloudservice.v1.GetCustomRolesRequest, + retry: bool = False, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, + ) -> temporalio.api.cloud.cloudservice.v1.GetCustomRolesResponse: + """Invokes the CloudService.get_custom_roles rpc method.""" + return await self._client._rpc_call( + rpc="get_custom_roles", + req=req, + service=self._service, + resp_type=temporalio.api.cloud.cloudservice.v1.GetCustomRolesResponse, + retry=retry, + metadata=metadata, + timeout=timeout, + ) + async def get_namespace( self, req: temporalio.api.cloud.cloudservice.v1.GetNamespaceRequest, @@ -3431,6 +3503,24 @@ async def update_api_key( timeout=timeout, ) + async def update_custom_role( + self, + req: temporalio.api.cloud.cloudservice.v1.UpdateCustomRoleRequest, + retry: bool = False, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, + ) -> temporalio.api.cloud.cloudservice.v1.UpdateCustomRoleResponse: + """Invokes the CloudService.update_custom_role rpc method.""" + return await self._client._rpc_call( + rpc="update_custom_role", + req=req, + service=self._service, + resp_type=temporalio.api.cloud.cloudservice.v1.UpdateCustomRoleResponse, + retry=retry, + metadata=metadata, + timeout=timeout, + ) + async def update_namespace( self, req: temporalio.api.cloud.cloudservice.v1.UpdateNamespaceRequest, diff --git a/temporalio/bridge/src/client_rpc_generated.rs b/temporalio/bridge/src/client_rpc_generated.rs index 85c537225..1c274c57d 100644 --- a/temporalio/bridge/src/client_rpc_generated.rs +++ b/temporalio/bridge/src/client_rpc_generated.rs @@ -1273,6 +1273,15 @@ impl ClientRef { create_connectivity_rule ) } + "create_custom_role" => { + rpc_call!( + connection, + call, + CloudService, + cloud_service, + create_custom_role + ) + } "create_namespace" => { rpc_call!( connection, @@ -1348,6 +1357,15 @@ impl ClientRef { delete_connectivity_rule ) } + "delete_custom_role" => { + rpc_call!( + connection, + call, + CloudService, + cloud_service, + delete_custom_role + ) + } "delete_namespace" => { rpc_call!( connection, @@ -1495,6 +1513,24 @@ impl ClientRef { get_current_identity ) } + "get_custom_role" => { + rpc_call!( + connection, + call, + CloudService, + cloud_service, + get_custom_role + ) + } + "get_custom_roles" => { + rpc_call!( + connection, + call, + CloudService, + cloud_service, + get_custom_roles + ) + } "get_namespace" => { rpc_call!(connection, call, CloudService, cloud_service, get_namespace) } @@ -1684,6 +1720,15 @@ impl ClientRef { update_api_key ) } + "update_custom_role" => { + rpc_call!( + connection, + call, + CloudService, + cloud_service, + update_custom_role + ) + } "update_namespace" => { rpc_call!( connection, diff --git a/temporalio/client.py b/temporalio/client.py index 1ae8de106..be7ad61bd 100644 --- a/temporalio/client.py +++ b/temporalio/client.py @@ -22,7 +22,7 @@ Mapping, Sequence, ) -from dataclasses import dataclass +from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone from enum import Enum, IntEnum from typing import ( @@ -36,7 +36,9 @@ import google.protobuf.duration_pb2 import google.protobuf.json_format import google.protobuf.timestamp_pb2 +import nexusrpc from google.protobuf.internal.containers import MessageMap +from nexusrpc import InputT, OutputT from typing_extensions import Required, Self, TypedDict import temporalio.activity @@ -46,6 +48,7 @@ import temporalio.api.errordetails.v1 import temporalio.api.failure.v1 import temporalio.api.history.v1 +import temporalio.api.nexus.v1 import temporalio.api.schedule.v1 import temporalio.api.sdk.v1 import temporalio.api.taskqueue.v1 @@ -58,6 +61,7 @@ import temporalio.exceptions import temporalio.nexus import temporalio.nexus._operation_context +import temporalio.nexus._util import temporalio.runtime import temporalio.service import temporalio.workflow @@ -99,6 +103,7 @@ ParamType, ReturnType, SelfType, + ServiceType, ) @@ -2518,6 +2523,158 @@ async def count_activities( ) ) + def create_nexus_client( + self, + service: type[ServiceType] | str, + *, + endpoint: str, + ) -> NexusClient[ServiceType]: + """Create a client for starting standalone Nexus operations. + + .. warning:: + This API is experimental and unstable. + + Args: + service: The Nexus service type or service name string. + endpoint: Endpoint name, resolved to a URL via the cluster's + endpoint registry. + + Returns: + A Nexus client for the given service and endpoint. + """ + return _NexusClient(client=self, service=service, endpoint=endpoint) + + def list_nexus_operations( + self, + query: str, + *, + limit: int | None = None, + page_size: int = 1000, + next_page_token: bytes | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationExecutionAsyncIterator: + """List standalone Nexus operations. + + .. warning:: + This API is experimental and unstable. + + This does not make a request until the first iteration is attempted. + Therefore any errors will not occur until then. + + Args: + query: A Temporal visibility list filter for nexus operations. Required. + limit: Maximum number of operations to return. If unset, all + operations are returned. Only applies if using the + returned :py:class:`NexusOperationExecutionAsyncIterator` + as an async iterator. + page_size: Maximum number of results for each page. + next_page_token: A previously obtained next page token if doing + pagination. Usually not needed as the iterator automatically + starts from the beginning. + rpc_metadata: Headers used on each RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for each RPC call. + + Returns: + An async iterator that can be used with ``async for``. + """ + return self._impl.list_nexus_operations( + ListNexusOperationsInput( + query=query, + page_size=page_size, + next_page_token=next_page_token, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + limit=limit, + ) + ) + + async def count_nexus_operations( + self, + query: str | None = None, + *, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationExecutionCount: + """Count standalone Nexus operations. + + .. warning:: + This API is experimental and unstable. + + Args: + query: A Temporal visibility filter for nexus operations. + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for the RPC call. + + Returns: + Count of nexus operations. + """ + return await self._impl.count_nexus_operations( + CountNexusOperationsInput( + query=query, rpc_metadata=rpc_metadata, rpc_timeout=rpc_timeout + ) + ) + + @overload + def get_nexus_operation_handle( + self, + operation_id: str, + *, + run_id: str | None = None, + ) -> NexusOperationHandle[Any]: ... + + @overload + def get_nexus_operation_handle( + self, + operation_id: str, + *, + run_id: str | None = None, + result_type: type[ReturnType], + ) -> NexusOperationHandle[ReturnType]: ... + + @overload + def get_nexus_operation_handle( + self, + operation_id: str, + *, + operation: nexusrpc.Operation[Any, OutputT], + run_id: str | None = None, + ) -> NexusOperationHandle[OutputT]: ... + + def get_nexus_operation_handle( + self, + operation_id: str, + *, + operation: nexusrpc.Operation[Any, Any] | None = None, + run_id: str | None = None, + result_type: type | None = None, + ) -> NexusOperationHandle[Any]: + """Get a handle to an existing standalone Nexus operation. + + .. warning:: + This API is experimental and unstable. + + Args: + operation_id: The operation ID. + operation: A ``nexusrpc.Operation`` from which the result type + is extracted. If both ``operation`` and ``result_type`` are + provided, the ``result_type`` takes precedence. + run_id: The operation run ID. If not provided, targets the latest run. + result_type: The result type to deserialize into. + + Returns: + A handle to the operation. + """ + result_type = result_type or (operation.output_type if operation else None) + return NexusOperationHandle( + self, + operation_id, + run_id=run_id, + result_type=result_type, + ) + @overload def get_activity_handle( self, @@ -4516,388 +4673,1559 @@ def _from_raw( ) -@dataclass(frozen=True) -class AsyncActivityIDReference: - """Reference to an async activity by its qualified ID.""" +@dataclass +class NexusOperationExecution: + """Info for a standalone Nexus operation execution, from list response. - workflow_id: str | None - run_id: str | None - activity_id: str + .. warning:: + This API is experimental and unstable. + """ + operation_id: str + """Unique identifier of this operation.""" -class AsyncActivityHandle(WithSerializationContext): - """Handle representing an external activity for completion and heartbeat.""" + run_id: str + """Run ID of the standalone Nexus operation.""" - def __init__( - self, - client: Client, - id_or_token: AsyncActivityIDReference | bytes, - data_converter_override: DataConverter | None = None, - ) -> None: - """Create an async activity handle.""" - self._client = client - self._id_or_token = id_or_token - self._data_converter_override = data_converter_override + endpoint: str + """Endpoint name.""" - async def heartbeat( - self, - *details: Any, - rpc_metadata: Mapping[str, str | bytes] = {}, - rpc_timeout: timedelta | None = None, - ) -> None: - """Record a heartbeat for the activity. + service: str + """Service name.""" - Args: - details: Details of the heartbeat. - rpc_metadata: Headers used on the RPC call. Keys here override - client-level RPC metadata keys. - rpc_timeout: Optional RPC deadline to set for the RPC call. - """ - await self._client._impl.heartbeat_async_activity( - HeartbeatAsyncActivityInput( - id_or_token=self._id_or_token, - details=details, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, - data_converter_override=self._data_converter_override, - ), - ) + operation: str + """Operation name.""" - async def complete( - self, - result: Any | None = temporalio.common._arg_unset, - *, - rpc_metadata: Mapping[str, str | bytes] = {}, - rpc_timeout: timedelta | None = None, - ) -> None: - """Complete the activity. + schedule_time: datetime | None + """Time the operation was originally scheduled.""" - Args: - result: Result of the activity if any. - rpc_metadata: Headers used on the RPC call. Keys here override - client-level RPC metadata keys. - rpc_timeout: Optional RPC deadline to set for the RPC call. - """ - await self._client._impl.complete_async_activity( - CompleteAsyncActivityInput( - id_or_token=self._id_or_token, - result=result, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, - data_converter_override=self._data_converter_override, - ), - ) + close_time: datetime | None + """Time the operation reached a terminal status, if closed.""" - async def fail( - self, - error: Exception, - *, - last_heartbeat_details: Sequence[Any] = [], - rpc_metadata: Mapping[str, str | bytes] = {}, - rpc_timeout: timedelta | None = None, - ) -> None: - """Fail the activity. + status: temporalio.common.NexusOperationExecutionStatus + """Current status of the operation.""" - Args: - error: Error for the activity. - last_heartbeat_details: Last heartbeat details for the activity. - rpc_metadata: Headers used on the RPC call. Keys here override - client-level RPC metadata keys. - rpc_timeout: Optional RPC deadline to set for the RPC call. - """ - await self._client._impl.fail_async_activity( - FailAsyncActivityInput( - id_or_token=self._id_or_token, - error=error, - last_heartbeat_details=last_heartbeat_details, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, - data_converter_override=self._data_converter_override, - ), - ) + search_attributes: temporalio.common.TypedSearchAttributes + """Current set of search attributes if any.""" - async def report_cancellation( - self, - *details: Any, - rpc_metadata: Mapping[str, str | bytes] = {}, - rpc_timeout: timedelta | None = None, - ) -> None: - """Report the activity as cancelled. + state_transition_count: int + """Number of state transitions.""" - Args: - details: Cancellation details. - rpc_metadata: Headers used on the RPC call. Keys here override - client-level RPC metadata keys. - rpc_timeout: Optional RPC deadline to set for the RPC call. - """ - await self._client._impl.report_cancellation_async_activity( - ReportCancellationAsyncActivityInput( - id_or_token=self._id_or_token, - details=details, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, - data_converter_override=self._data_converter_override, + execution_duration: timedelta | None + """Duration from scheduled to close time, only populated if closed.""" + + raw_info: ( + temporalio.api.nexus.v1.NexusOperationExecutionListInfo + | temporalio.api.nexus.v1.NexusOperationExecutionInfo + ) + """Underlying protobuf info.""" + + @classmethod + def _from_raw_info( + cls, info: temporalio.api.nexus.v1.NexusOperationExecutionListInfo + ) -> Self: + """Create from raw proto nexus operation list info.""" + return cls( + operation_id=info.operation_id, + run_id=info.run_id, + endpoint=info.endpoint, + service=info.service, + operation=info.operation, + schedule_time=( + info.schedule_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("schedule_time") + else None + ), + close_time=( + info.close_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("close_time") + else None + ), + status=( + temporalio.common.NexusOperationExecutionStatus(info.status) + if info.status + else temporalio.common.NexusOperationExecutionStatus.UNSPECIFIED + ), + search_attributes=temporalio.converter.decode_typed_search_attributes( + info.search_attributes + ), + state_transition_count=info.state_transition_count, + execution_duration=( + info.execution_duration.ToTimedelta() + if info.HasField("execution_duration") + else None ), + raw_info=info, ) - def with_context(self, context: SerializationContext) -> Self: - """Create a new AsyncActivityHandle with a different serialization context. - Payloads received by the activity will be decoded and deserialized using a data converter - with :py:class:`ActivitySerializationContext` set as context. If you are using a custom data - converter that makes use of this context then you can use this method to supply matching - context data to the data converter used to serialize and encode the outbound payloads. - """ - data_converter = self._client.data_converter.with_context(context) - if data_converter is self._client.data_converter: - return self - cls = type(self) - if cls.__init__ is not AsyncActivityHandle.__init__: - raise TypeError( - "If you have subclassed AsyncActivityHandle and overridden the __init__ method " +@dataclass +class NexusOperationExecutionDescription(NexusOperationExecution): + """Detailed information about a standalone Nexus operation execution. + + .. warning:: + This API is experimental and unstable. + """ + + raw_description: temporalio.api.nexus.v1.NexusOperationExecutionInfo + """Underlying protobuf description info.""" + + state: temporalio.common.PendingNexusOperationExecutionState + """More detailed breakdown if status is :py:attr:`NexusOperationExecutionStatus.RUNNING`.""" + + schedule_to_close_timeout: timedelta | None + """Schedule-to-close timeout for this operation.""" + + schedule_to_start_timeout: timedelta | None + """Schedule-to-start timeout for this operation.""" + + start_to_close_timeout: timedelta | None + """Start-to-close timeout for this operation.""" + + attempt: int + """Current attempt number.""" + + expiration_time: datetime | None + """Scheduled time plus schedule_to_close_timeout.""" + + last_attempt_complete_time: datetime | None + """Time when the last attempt completed.""" + + next_attempt_schedule_time: datetime | None + """Time when the next attempt will be scheduled.""" + + last_attempt_failure: BaseException | None + """Failure from the last failed attempt, if any.""" + + blocked_reason: str | None + """Reason the operation is blocked, if any.""" + + request_id: str + """Server-generated request ID used as an idempotency token.""" + + operation_token: str | None + """operation_token is only set for asynchronous operations after a successful start_operation call.""" + + identity: str + """Identity of the client that started this operation.""" + + cancellation_info: NexusOperationExecutionCancellationInfo | None + """Cancellation info if cancellation was requested.""" + + long_poll_token: bytes | None + """Token for follow-on long-poll requests. None if the operation is complete.""" + + _data_converter: DataConverter = field(kw_only=True, compare=False, repr=False) + _static_summary: str | None = field( + kw_only=True, default=None, compare=False, repr=False + ) + _static_details: str | None = field( + kw_only=True, default=None, compare=False, repr=False + ) + _metadata_decoded: bool = field( + kw_only=True, default=False, compare=False, repr=False + ) + + async def static_summary(self) -> str | None: + """Gets the single-line fixed summary for this Nexus operation execution that may appear in + UI/CLI. This can be in single-line Temporal markdown format. + """ + if not self._metadata_decoded: + await self._decode_metadata() + return self._static_summary + + async def static_details(self) -> str | None: + """Gets the general fixed details for this Nexus operation execution that may appear in UI/CLI. + This can be in Temporal markdown format and can span multiple lines. + """ + if not self._metadata_decoded: + await self._decode_metadata() + return self._static_details + + async def _decode_metadata(self) -> None: + """Internal method to decode metadata lazily.""" + self._static_summary, self._static_details = await _decode_user_metadata( + self._data_converter, self.raw_description.user_metadata + ) + self._metadata_decoded = True + + @classmethod + async def _from_execution_info( + cls, + info: temporalio.api.nexus.v1.NexusOperationExecutionInfo, + data_converter: temporalio.converter.DataConverter, + *, + long_poll_token: bytes | None, + ) -> Self: + """Create from raw proto nexus operation execution info.""" + return cls( + _data_converter=data_converter, + operation_id=info.operation_id, + run_id=info.run_id, + endpoint=info.endpoint, + service=info.service, + operation=info.operation, + schedule_time=( + info.schedule_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("schedule_time") + else None + ), + close_time=( + info.close_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("close_time") + else None + ), + status=( + temporalio.common.NexusOperationExecutionStatus(info.status) + if info.status + else temporalio.common.NexusOperationExecutionStatus.UNSPECIFIED + ), + search_attributes=temporalio.converter.decode_typed_search_attributes( + info.search_attributes + ), + state_transition_count=info.state_transition_count, + execution_duration=( + info.execution_duration.ToTimedelta() + if info.HasField("execution_duration") + else None + ), + raw_info=info, + raw_description=info, + state=( + temporalio.common.PendingNexusOperationExecutionState(info.state) + if info.state + else temporalio.common.PendingNexusOperationExecutionState.UNSPECIFIED + ), + schedule_to_close_timeout=( + info.schedule_to_close_timeout.ToTimedelta() + if info.HasField("schedule_to_close_timeout") + else None + ), + schedule_to_start_timeout=( + info.schedule_to_start_timeout.ToTimedelta() + if info.HasField("schedule_to_start_timeout") + else None + ), + start_to_close_timeout=( + info.start_to_close_timeout.ToTimedelta() + if info.HasField("start_to_close_timeout") + else None + ), + attempt=info.attempt, + expiration_time=( + info.expiration_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("expiration_time") + else None + ), + last_attempt_complete_time=( + info.last_attempt_complete_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("last_attempt_complete_time") + else None + ), + last_attempt_failure=( + cast( + BaseException | None, + await data_converter.decode_failure(info.last_attempt_failure), + ) + if info.HasField("last_attempt_failure") + else None + ), + next_attempt_schedule_time=( + info.next_attempt_schedule_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("next_attempt_schedule_time") + else None + ), + blocked_reason=info.blocked_reason if info.blocked_reason else None, + request_id=info.request_id, + operation_token=info.operation_token if info.operation_token else None, + identity=info.identity, + cancellation_info=( + await NexusOperationExecutionCancellationInfo._from_cancellation_info( + info.cancellation_info, data_converter + ) + if info.HasField("cancellation_info") + else None + ), + long_poll_token=long_poll_token, + ) + + +@dataclass +class NexusOperationExecutionCancellationInfo: + """Cancellation information for a Nexus Operation. + + .. warning:: + This API is experimental and unstable. + """ + + raw: temporalio.api.nexus.v1.NexusOperationExecutionCancellationInfo + """Underlying protobuf cancellation info.""" + + requested_time: datetime | None + """The time when cancellation was requested.""" + + state: temporalio.common.NexusOperationCancellationState + """The current state of the cancellation request.""" + + attempt: int + """The number of attempts made to deliver the cancel operation request.""" + + last_attempt_complete_time: datetime | None + """The time when the last attempt completed.""" + + next_attempt_schedule_time: datetime | None + """The time when the next attempt is scheduled.""" + + last_attempt_failure: BaseException | None + """The last attempt's failure, if any.""" + + blocked_reason: str + """Blocked reason provides additional information if the cancellation state is BLOCKED.""" + + reason: str + """The reason specified in the cancellation request.""" + + @classmethod + async def _from_cancellation_info( + cls, + info: temporalio.api.nexus.v1.NexusOperationExecutionCancellationInfo, + data_converter: DataConverter, + ) -> Self: + """Create from raw proto nexus operation cancellation info.""" + return cls( + raw=info, + requested_time=( + info.requested_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("requested_time") + else None + ), + state=( + temporalio.common.NexusOperationCancellationState(info.state) + if info.state + else temporalio.common.NexusOperationCancellationState.UNSPECIFIED + ), + attempt=info.attempt, + last_attempt_complete_time=( + info.last_attempt_complete_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("last_attempt_complete_time") + else None + ), + next_attempt_schedule_time=( + info.next_attempt_schedule_time.ToDatetime(tzinfo=timezone.utc) + if info.HasField("next_attempt_schedule_time") + else None + ), + last_attempt_failure=( + cast( + BaseException | None, + await data_converter.decode_failure(info.last_attempt_failure), + ) + if info.HasField("last_attempt_failure") + else None + ), + blocked_reason=info.blocked_reason, + reason=info.reason, + ) + + +@dataclass +class NexusOperationExecutionCount: + """Representation of a count from a count nexus operations call. + + .. warning:: + This API is experimental and unstable. + """ + + count: int + """Approximate number of operations matching the original query. + + If the query had a group-by clause, this is simply the sum of all the counts + in :py:attr:`groups`. + """ + + groups: Sequence[NexusOperationExecutionCountAggregationGroup] + """Groups if the query had a group-by clause, or empty if not.""" + + @staticmethod + def _from_raw( + resp: temporalio.api.workflowservice.v1.CountNexusOperationExecutionsResponse, + ) -> NexusOperationExecutionCount: + """Create from raw proto response.""" + return NexusOperationExecutionCount( + count=resp.count, + groups=[ + NexusOperationExecutionCountAggregationGroup._from_raw(g) + for g in resp.groups + ], + ) + + +@dataclass(frozen=True) +class NexusOperationExecutionCountAggregationGroup: + """A single aggregation group from a count nexus operations call. + + .. warning:: + This API is experimental and unstable. + """ + + count: int + """Count for this group.""" + + group_values: Sequence[temporalio.common.SearchAttributeValue] + """Values that define this group.""" + + @staticmethod + def _from_raw( + raw: temporalio.api.workflowservice.v1.CountNexusOperationExecutionsResponse.AggregationGroup, + ) -> NexusOperationExecutionCountAggregationGroup: + return NexusOperationExecutionCountAggregationGroup( + count=raw.count, + group_values=[ + temporalio.converter._search_attributes._decode_search_attribute_value( + v + ) + for v in raw.group_values + ], + ) + + +class NexusOperationFailureError(temporalio.exceptions.TemporalError): + """Error that occurs when a Nexus operation is unsuccessful. + + .. warning:: + This API is experimental and unstable. + """ + + def __init__(self, *, cause: BaseException) -> None: + """Create nexus operation failure error.""" + super().__init__("Nexus operation execution failed") + self.__cause__ = cause + + @property + def cause(self) -> BaseException: + """Cause of the nexus operation failure.""" + assert self.__cause__ + return self.__cause__ + + +@dataclass(frozen=True) +class AsyncActivityIDReference: + """Reference to an async activity by its qualified ID.""" + + workflow_id: str | None + run_id: str | None + activity_id: str + + +class AsyncActivityHandle(WithSerializationContext): + """Handle representing an external activity for completion and heartbeat.""" + + def __init__( + self, + client: Client, + id_or_token: AsyncActivityIDReference | bytes, + data_converter_override: DataConverter | None = None, + ) -> None: + """Create an async activity handle.""" + self._client = client + self._id_or_token = id_or_token + self._data_converter_override = data_converter_override + + async def heartbeat( + self, + *details: Any, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Record a heartbeat for the activity. + + Args: + details: Details of the heartbeat. + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.heartbeat_async_activity( + HeartbeatAsyncActivityInput( + id_or_token=self._id_or_token, + details=details, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + data_converter_override=self._data_converter_override, + ), + ) + + async def complete( + self, + result: Any | None = temporalio.common._arg_unset, + *, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Complete the activity. + + Args: + result: Result of the activity if any. + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.complete_async_activity( + CompleteAsyncActivityInput( + id_or_token=self._id_or_token, + result=result, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + data_converter_override=self._data_converter_override, + ), + ) + + async def fail( + self, + error: Exception, + *, + last_heartbeat_details: Sequence[Any] = [], + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Fail the activity. + + Args: + error: Error for the activity. + last_heartbeat_details: Last heartbeat details for the activity. + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.fail_async_activity( + FailAsyncActivityInput( + id_or_token=self._id_or_token, + error=error, + last_heartbeat_details=last_heartbeat_details, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + data_converter_override=self._data_converter_override, + ), + ) + + async def report_cancellation( + self, + *details: Any, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Report the activity as cancelled. + + Args: + details: Cancellation details. + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.report_cancellation_async_activity( + ReportCancellationAsyncActivityInput( + id_or_token=self._id_or_token, + details=details, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + data_converter_override=self._data_converter_override, + ), + ) + + def with_context(self, context: SerializationContext) -> Self: + """Create a new AsyncActivityHandle with a different serialization context. + + Payloads received by the activity will be decoded and deserialized using a data converter + with :py:class:`ActivitySerializationContext` set as context. If you are using a custom data + converter that makes use of this context then you can use this method to supply matching + context data to the data converter used to serialize and encode the outbound payloads. + """ + data_converter = self._client.data_converter.with_context(context) + if data_converter is self._client.data_converter: + return self + cls = type(self) + if cls.__init__ is not AsyncActivityHandle.__init__: + raise TypeError( + "If you have subclassed AsyncActivityHandle and overridden the __init__ method " "then you must override with_context to return an instance of your class." ) - return cls( - self._client, - self._id_or_token, - data_converter, + return cls( + self._client, + self._id_or_token, + data_converter, + ) + + +class ActivityHandle(Generic[ReturnType]): + """Handle representing an activity execution not started by a workflow. + + .. warning:: + This API is experimental. + """ + + def __init__( + self, + client: Client, + id: str, + *, + run_id: str | None = None, + result_type: type | None = None, + ) -> None: + """Create activity handle.""" + self._client = client + self._id = id + self._run_id = run_id + self._result_type = result_type + self._known_outcome: ( + temporalio.api.activity.v1.ActivityExecutionOutcome | None + ) = None + + @functools.cached_property + def _data_converter(self) -> temporalio.converter.DataConverter: + return self._client.data_converter.with_context( + ActivitySerializationContext( + namespace=self._client.namespace, + activity_id=self._id, + activity_type=None, + activity_task_queue=None, + is_local=False, + workflow_id=None, + workflow_type=None, + ) + ) + + @property + def id(self) -> str: + """ID of the activity.""" + return self._id + + @property + def run_id(self) -> str | None: + """Run ID of the activity.""" + return self._run_id + + async def result( + self, + *, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> ReturnType: + """Wait for result of the activity. + + .. warning:: + This API is experimental. + + The result may already be known if this method has been called before, + in which case no network call is made. Otherwise the result will be + polled for until it is available. + + Args: + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for each RPC call. Note: + this is the timeout for each RPC call while polling, not a + timeout for the function as a whole. If an individual RPC + times out, it will be retried until the result is available. + + Returns: + The result of the activity. + + Raises: + ActivityFailureError: If the activity completed with a failure. + RPCError: Activity result could not be fetched for some reason. + """ + await self._poll_until_outcome( + rpc_metadata=rpc_metadata, rpc_timeout=rpc_timeout + ) + + # Convert outcome to failure or value + assert self._known_outcome + if self._known_outcome.HasField("failure"): + raise ActivityFailureError( + cause=await self._data_converter.decode_failure( + self._known_outcome.failure + ), + ) + if not self._known_outcome.result.payloads: + return None # type: ignore + type_hints = [self._result_type] if self._result_type else None + results = await self._data_converter.decode( + self._known_outcome.result.payloads, type_hints + ) + if not results: + return None # type: ignore + elif len(results) > 1: + warnings.warn(f"Expected single activity result, got {len(results)}") + return results[0] + + async def _poll_until_outcome( + self, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Poll for activity result until it's available.""" + if self._known_outcome: + return + + req = temporalio.api.workflowservice.v1.PollActivityExecutionRequest( + namespace=self._client.namespace, + activity_id=self._id, + run_id=self._run_id or "", + ) + + # Continue polling as long as we have no outcome + while True: + try: + res = await self._client.workflow_service.poll_activity_execution( + req, + retry=True, + metadata=rpc_metadata, + timeout=rpc_timeout, + ) + if res.HasField("outcome"): + self._known_outcome = res.outcome + return + except RPCError as err: + if err.status == RPCStatusCode.DEADLINE_EXCEEDED: + # Deadline exceeded is expected with long polling; retry + continue + elif err.status == RPCStatusCode.CANCELLED: + raise asyncio.CancelledError() from err + else: + raise + except asyncio.CancelledError: + raise + + async def cancel( + self, + *, + reason: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Request cancellation of the activity. + + .. warning:: + This API is experimental. + + Requesting cancellation of an activity does not automatically transition the activity to + canceled status. If the activity is heartbeating, a :py:class:`exceptions.CancelledError` + exception will be raised when receiving the heartbeat response; if the activity allows this + exception to bubble out, the activity will transition to canceled status. If the activity it + is not heartbeating, this method will have no effect on activity status. + + Args: + reason: Reason for the cancellation. Recorded and available via describe. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.cancel_activity( + CancelActivityInput( + activity_id=self._id, + activity_run_id=self._run_id, + reason=reason, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + + async def terminate( + self, + *, + reason: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Terminate the activity execution immediately. + + .. warning:: + This API is experimental. + + Termination does not reach the worker and the activity code cannot react to it. + A terminated activity may have a running attempt and will be requested to be + canceled by the server when it heartbeats. + + Args: + reason: Reason for the termination. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.terminate_activity( + TerminateActivityInput( + activity_id=self._id, + activity_run_id=self._run_id, + reason=reason, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + + async def describe( + self, + *, + long_poll_token: bytes | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> ActivityExecutionDescription: + """Describe the activity execution. + + .. warning:: + This API is experimental. + + Args: + long_poll_token: Token from a previous describe response. If provided, + the request will long-poll until the activity state changes. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + + Returns: + Activity execution description. + """ + return await self._client._impl.describe_activity( + DescribeActivityInput( + activity_id=self._id, + activity_run_id=self._run_id, + long_poll_token=long_poll_token, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + + +class NexusOperationHandle(Generic[ReturnType]): + """Handle representing a standalone Nexus operation execution. + + .. warning:: + This API is experimental and unstable. + """ + + def __init__( + self, + client: Client, + operation_id: str, + *, + run_id: str | None = None, + result_type: type | None = None, + endpoint: str = "", + service: str = "", + ) -> None: + """Create nexus operation handle.""" + self._client = client + self._operation_id = operation_id + self._run_id = run_id + self._result_type = result_type + self._endpoint = endpoint + self._service = service + # the default value is `_arg_unset` because ReturnType could be None + self._known_outcome: ReturnType | NexusOperationFailureError | object = ( + temporalio.common._arg_unset + ) + + @property + def operation_id(self) -> str: + """ID of the operation.""" + return self._operation_id + + @property + def run_id(self) -> str | None: + """Run ID of the operation.""" + return self._run_id + + @property + def endpoint(self) -> str: + """Endpoint name.""" + return self._endpoint + + @property + def service(self) -> str: + """Service name.""" + return self._service + + async def result( + self, + *, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> ReturnType: + """Wait for result of the Nexus operation. + + .. warning:: + This API is experimental and unstable. + + The result may already be known if this method has been called before, + in which case no network call is made. Otherwise the result will be + polled for until it is available. + + Args: + rpc_metadata: Headers used on the RPC call. Keys here override + client-level RPC metadata keys. + rpc_timeout: Optional RPC deadline to set for each RPC call. Note: + this is the timeout for each RPC call while polling, not a + timeout for the function as a whole. If an individual RPC + times out, it will be retried until the result is available. + + Returns: + The result of the operation. + + Raises: + NexusOperationFailureError: If the operation completed with a failure. + RPCError: Operation result could not be fetched for some reason. + """ + if self._known_outcome is temporalio.common._arg_unset: + try: + self._known_outcome = ( + await self._client._impl.get_nexus_operation_result( + GetNexusOperationResultInput( + operation_id=self._operation_id, + run_id=self._run_id, + result_type=self._result_type, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + ) + return cast(ReturnType, self._known_outcome) + except NexusOperationFailureError as failure: + self._known_outcome = failure + raise + elif isinstance(self._known_outcome, NexusOperationFailureError): + raise self._known_outcome + else: + return cast(ReturnType, self._known_outcome) + + async def describe( + self, + *, + long_poll_token: bytes | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationExecutionDescription: + """Describe the Nexus operation execution. + + .. warning:: + This API is experimental and unstable. + + Args: + long_poll_token: Token from a previous describe response. If provided, + the request will long-poll until the Nexus Operation state changes. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + + Returns: + Nexus operation execution description. + """ + return await self._client._impl.describe_nexus_operation( + DescribeNexusOperationInput( + operation_id=self._operation_id, + run_id=self._run_id, + long_poll_token=long_poll_token, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) ) + async def cancel( + self, + *, + reason: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Request cancellation of the Nexus operation. -class ActivityHandle(Generic[ReturnType]): - """Handle representing an activity execution not started by a workflow. + .. warning:: + This API is experimental and unstable. + + Args: + reason: Reason for the cancellation. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.cancel_nexus_operation( + CancelNexusOperationInput( + operation_id=self._operation_id, + run_id=self._run_id, + reason=reason, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + + async def terminate( + self, + *, + reason: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> None: + """Terminate the Nexus operation execution immediately. + + .. warning:: + This API is experimental and unstable. + + Args: + reason: Reason for the termination. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. + """ + await self._client._impl.terminate_nexus_operation( + TerminateNexusOperationInput( + operation_id=self._operation_id, + run_id=self._run_id, + reason=reason, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, + ) + ) + + +class NexusOperationExecutionAsyncIterator: + """Asynchronous iterator for Nexus operation execution values. + + You should typically use ``async for`` on this iterator and not call any of its methods. .. warning:: - This API is experimental. + This API is experimental and unstable. """ def __init__( self, client: Client, - id: str, - *, - run_id: str | None = None, - result_type: type | None = None, + input: ListNexusOperationsInput, ) -> None: - """Create activity handle.""" + """Create an asynchronous iterator for the given input. + + Users should not create this directly, but rather use + :py:meth:`Client.list_nexus_operations`. + """ self._client = client - self._id = id - self._run_id = run_id - self._result_type = result_type - self._known_outcome: ( - temporalio.api.activity.v1.ActivityExecutionOutcome | None - ) = None + self._input = input + self._next_page_token = input.next_page_token + self._current_page: Sequence[NexusOperationExecution] | None = None + self._current_page_index = 0 + self._limit = input.limit + self._yielded = 0 - @functools.cached_property - def _data_converter(self) -> temporalio.converter.DataConverter: - return self._client.data_converter.with_context( - ActivitySerializationContext( + @property + def current_page_index(self) -> int: + """Index of the entry in the current page that will be returned from + the next :py:meth:`__anext__` call. + """ + return self._current_page_index + + @property + def current_page(self) -> Sequence[NexusOperationExecution] | None: + """Current page, if it has been fetched yet.""" + return self._current_page + + @property + def next_page_token(self) -> bytes | None: + """Token for the next page request if any.""" + return self._next_page_token + + async def fetch_next_page(self, *, page_size: int | None = None) -> None: + """Fetch the next page of results. + + Args: + page_size: Override the page size this iterator was originally + created with. + """ + page_size = page_size or self._input.page_size + if self._limit is not None and self._limit - self._yielded < page_size: + page_size = self._limit - self._yielded + + resp = await self._client.workflow_service.list_nexus_operation_executions( + temporalio.api.workflowservice.v1.ListNexusOperationExecutionsRequest( namespace=self._client.namespace, - activity_id=self._id, - activity_type=None, - activity_task_queue=None, - is_local=False, - workflow_id=None, - workflow_type=None, - ) + page_size=page_size, + next_page_token=self._next_page_token or b"", + query=self._input.query or "", + ), + retry=True, + metadata=self._input.rpc_metadata, + timeout=self._input.rpc_timeout, ) - @property - def id(self) -> str: - """ID of the activity.""" - return self._id + self._current_page = [ + NexusOperationExecution._from_raw_info(v) for v in resp.operations + ] + self._current_page_index = 0 + self._next_page_token = resp.next_page_token or None + + def __aiter__(self) -> NexusOperationExecutionAsyncIterator: + """Return self as the iterator.""" + return self + + async def __anext__(self) -> NexusOperationExecution: + """Get the next execution on this iterator, fetching next page if + necessary. + """ + if self._limit is not None and self._yielded >= self._limit: + raise StopAsyncIteration + while True: + # No page? fetch and continue + if self._current_page is None: + await self.fetch_next_page() + continue + # No more left in page? + if self._current_page_index >= len(self._current_page): + # If there is a next page token, try to get another page and try + # again + if self._next_page_token is not None: + await self.fetch_next_page() + continue + # No more pages means we're done + raise StopAsyncIteration + # Get current, increment page index, and return + ret = self._current_page[self._current_page_index] + self._current_page_index += 1 + self._yielded += 1 + return ret + + +class NexusClient(ABC, Generic[ServiceType]): + """Client for starting standalone Nexus operations. + + .. warning:: + This API is experimental and unstable. + + Use :py:meth:`Client.create_nexus_client` to create a client. + """ + + # Overload for nexusrpc.Operation with input + @overload + @abstractmethod + async def start_operation( + self, + operation: nexusrpc.Operation[InputT, OutputT], + arg: InputT, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[OutputT]: ... + + # Overload for nexusrpc.Operation with no input + @overload + @abstractmethod + async def start_operation( + self, + operation: nexusrpc.Operation[None, OutputT], + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[OutputT]: ... + + # Overload for Callable with result_type + @overload + @abstractmethod + async def start_operation( + self, + operation: Callable[..., Any], + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type[OutputT], + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[OutputT]: ... + + # Overload for Callable without result_type + @overload + @abstractmethod + async def start_operation( + self, + operation: Callable[..., Any], + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[Any]: ... + + # Overload for str with result_type + @overload + @abstractmethod + async def start_operation( + self, + operation: str, + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type[OutputT], + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[OutputT]: ... - @property - def run_id(self) -> str | None: - """Run ID of the activity.""" - return self._run_id + # Overload for str without result_type + @overload + @abstractmethod + async def start_operation( + self, + operation: str, + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> NexusOperationHandle[Any]: ... - async def result( + @abstractmethod + async def start_operation( self, + operation: nexusrpc.Operation[Any, Any] | str | Callable[..., Any], + arg: Any = temporalio.common._arg_unset, *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, - ) -> ReturnType: - """Wait for result of the activity. + ) -> NexusOperationHandle[Any]: + """Start a Nexus operation and return a handle. .. warning:: - This API is experimental. - - The result may already be known if this method has been called before, - in which case no network call is made. Otherwise the result will be - polled for until it is available. + This API is experimental and unstable. Args: - rpc_metadata: Headers used on the RPC call. Keys here override - client-level RPC metadata keys. - rpc_timeout: Optional RPC deadline to set for each RPC call. Note: - this is the timeout for each RPC call while polling, not a - timeout for the function as a whole. If an individual RPC - times out, it will be retried until the result is available. + operation: The operation to start. Can be a ``nexusrpc.Operation``, + a callable operation method, or a string name. + arg: Input argument for the operation. + id: Unique identifier for this operation. + id_reuse_policy: Policy for reusing operation IDs. + id_conflict_policy: Policy for handling ID conflicts. + result_type: The result type to deserialize into. + schedule_to_close_timeout: Timeout for the operation. + search_attributes: Search attributes for the operation. + summary: Summary for the operation. + headers: Headers to attach to the Nexus request. + rpc_metadata: Headers used on the RPC call. + rpc_timeout: Optional RPC deadline to set for the RPC call. Returns: - The result of the activity. - - Raises: - ActivityFailureError: If the activity completed with a failure. - RPCError: Activity result could not be fetched for some reason. + A handle to the started operation. """ - await self._poll_until_outcome( - rpc_metadata=rpc_metadata, rpc_timeout=rpc_timeout - ) + ... - # Convert outcome to failure or value - assert self._known_outcome - if self._known_outcome.HasField("failure"): - raise ActivityFailureError( - cause=await self._data_converter.decode_failure( - self._known_outcome.failure - ), - ) - if not self._known_outcome.result.payloads: - return None # type: ignore - type_hints = [self._result_type] if self._result_type else None - results = await self._data_converter.decode( - self._known_outcome.result.payloads, type_hints - ) - if not results: - return None # type: ignore - elif len(results) > 1: - warnings.warn(f"Expected single activity result, got {len(results)}") - return results[0] + # Overload for nexusrpc.Operation with input + @overload + @abstractmethod + async def execute_operation( + self, + operation: nexusrpc.Operation[InputT, OutputT], + arg: InputT, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> OutputT: ... - async def _poll_until_outcome( + # Overload for nexusrpc.Operation with no input + @overload + @abstractmethod + async def execute_operation( self, + operation: nexusrpc.Operation[None, OutputT], + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, - ) -> None: - """Poll for activity result until it's available.""" - if self._known_outcome: - return + ) -> OutputT: ... - req = temporalio.api.workflowservice.v1.PollActivityExecutionRequest( - namespace=self._client.namespace, - activity_id=self._id, - run_id=self._run_id or "", - ) + # Overload for Callable with result_type + @overload + @abstractmethod + async def execute_operation( + self, + operation: Callable[..., Any], + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type[OutputT], + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> OutputT: ... - # Continue polling as long as we have no outcome - while True: - try: - res = await self._client.workflow_service.poll_activity_execution( - req, - retry=True, - metadata=rpc_metadata, - timeout=rpc_timeout, - ) - if res.HasField("outcome"): - self._known_outcome = res.outcome - return - except RPCError as err: - if err.status == RPCStatusCode.DEADLINE_EXCEEDED: - # Deadline exceeded is expected with long polling; retry - continue - elif err.status == RPCStatusCode.CANCELLED: - raise asyncio.CancelledError() from err - else: - raise - except asyncio.CancelledError: - raise + # Overload for Callable without result_type + @overload + @abstractmethod + async def execute_operation( + self, + operation: Callable[..., Any], + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> Any: ... - async def cancel( + # Overload for str with result_type + @overload + @abstractmethod + async def execute_operation( self, + operation: str, + arg: Any = temporalio.common._arg_unset, *, - reason: str | None = None, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type[OutputT], + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, - ) -> None: - """Request cancellation of the activity. + ) -> OutputT: ... + + # Overload for str without result_type + @overload + @abstractmethod + async def execute_operation( + self, + operation: str, + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> Any: ... + + @abstractmethod + async def execute_operation( + self, + operation: nexusrpc.Operation[Any, Any] | str | Callable[..., Any], + arg: Any = temporalio.common._arg_unset, + *, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, + ) -> Any: + """Start a Nexus operation and wait for its result. .. warning:: - This API is experimental. + This API is experimental and unstable. - Requesting cancellation of an activity does not automatically transition the activity to - canceled status. If the activity is heartbeating, a :py:class:`exceptions.CancelledError` - exception will be raised when receiving the heartbeat response; if the activity allows this - exception to bubble out, the activity will transition to canceled status. If the activity it - is not heartbeating, this method will have no effect on activity status. + This is a shortcut for ``await (await nexus_client.start_operation(...)).result()``. Args: - reason: Reason for the cancellation. Recorded and available via describe. + operation: The operation to execute. Can be a ``nexusrpc.Operation``, + a callable operation method, or a string name. + arg: Input argument for the operation. + id: Unique identifier for this operation. + id_reuse_policy: Policy for reusing operation IDs. + id_conflict_policy: Policy for handling ID conflicts. + result_type: The result type to deserialize into. + schedule_to_close_timeout: Timeout for the operation. + search_attributes: Search attributes for the operation. + summary: Summary for the operation. + headers: Headers to attach to the Nexus request. rpc_metadata: Headers used on the RPC call. rpc_timeout: Optional RPC deadline to set for the RPC call. + + Returns: + The result of the operation. """ - await self._client._impl.cancel_activity( - CancelActivityInput( - activity_id=self._id, - activity_run_id=self._run_id, - reason=reason, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, + ... + + +class _NexusClient(NexusClient[ServiceType]): + """Concrete implementation of NexusClient.""" + + def __init__( + self, + client: Client, + service: type[ServiceType] | str, + endpoint: str, + ) -> None: + self._client = client + if isinstance(service, str): + self._service_name = service + else: + self._service_name = service.__name__ + self._endpoint = endpoint + + def _resolve_operation( + self, + operation: nexusrpc.Operation[Any, Any] | str | Callable[..., Any], + ) -> tuple[str, type | None]: + """Resolve an operation to its name and output type.""" + if isinstance(operation, str): + return operation, None + elif isinstance(operation, nexusrpc.Operation): + return operation.name, operation.output_type + elif callable(operation): + _, op = temporalio.nexus._util.get_operation_factory(operation) + if isinstance(op, nexusrpc.Operation): + return op.name, op.output_type + else: + raise ValueError( + f"Operation callable is not a Nexus operation: {operation}" + ) + else: + raise ValueError( # pyright: ignore[reportUnreachable] + f"Operation is not resolvable as a Nexus operation: {operation}" ) - ) - async def terminate( + async def start_operation( self, + operation: nexusrpc.Operation[Any, Any] | str | Callable[..., Any], + arg: Any = temporalio.common._arg_unset, *, - reason: str | None = None, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, - ) -> None: - """Terminate the activity execution immediately. + ) -> NexusOperationHandle[Any]: + """Start a Nexus operation and return a handle. .. warning:: - This API is experimental. - - Termination does not reach the worker and the activity code cannot react to it. - A terminated activity may have a running attempt and will be requested to be - canceled by the server when it heartbeats. - - Args: - reason: Reason for the termination. - rpc_metadata: Headers used on the RPC call. - rpc_timeout: Optional RPC deadline to set for the RPC call. + This API is experimental and unstable. """ - await self._client._impl.terminate_activity( - TerminateActivityInput( - activity_id=self._id, - activity_run_id=self._run_id, - reason=reason, + op_name, output_type = self._resolve_operation(operation) + final_result_type: type | None = result_type or output_type + + return await self._client._impl.start_nexus_operation( + StartNexusOperationInput( + operation=op_name, + arg=arg, + id=id, + endpoint=self._endpoint, + service=self._service_name, + result_type=final_result_type, + schedule_to_close_timeout=schedule_to_close_timeout, + id_reuse_policy=id_reuse_policy, + id_conflict_policy=id_conflict_policy, + search_attributes=search_attributes, + summary=summary, + headers=dict(headers) if headers else {}, rpc_metadata=rpc_metadata, rpc_timeout=rpc_timeout, ) ) - async def describe( + async def execute_operation( self, + operation: nexusrpc.Operation[Any, Any] | str | Callable[..., Any], + arg: Any = temporalio.common._arg_unset, *, - long_poll_token: bytes | None = None, + id: str, + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy = temporalio.common.NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy = temporalio.common.NexusOperationIDConflictPolicy.FAIL, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + search_attributes: temporalio.common.TypedSearchAttributes | None = None, + summary: str | None = None, + headers: Mapping[str, str] | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, - ) -> ActivityExecutionDescription: - """Describe the activity execution. + ) -> Any: + """Start a Nexus operation and wait for its result. .. warning:: - This API is experimental. - - Args: - long_poll_token: Token from a previous describe response. If provided, - the request will long-poll until the activity state changes. - rpc_metadata: Headers used on the RPC call. - rpc_timeout: Optional RPC deadline to set for the RPC call. - - Returns: - Activity execution description. + This API is experimental and unstable. """ - return await self._client._impl.describe_activity( - DescribeActivityInput( - activity_id=self._id, - activity_run_id=self._run_id, - long_poll_token=long_poll_token, - rpc_metadata=rpc_metadata, - rpc_timeout=rpc_timeout, - ) + handle = await self.start_operation( + operation, + arg, + id=id, + id_reuse_policy=id_reuse_policy, + id_conflict_policy=id_conflict_policy, + result_type=result_type, + schedule_to_close_timeout=schedule_to_close_timeout, + search_attributes=search_attributes, + summary=summary, + headers=headers, + rpc_metadata=rpc_metadata, + rpc_timeout=rpc_timeout, ) + return await handle.result() @dataclass @@ -7569,6 +8897,119 @@ class CountActivitiesInput: rpc_timeout: timedelta | None +@dataclass +class StartNexusOperationInput: + """Input for :py:meth:`OutboundInterceptor.start_nexus_operation`. + + .. warning:: + This API is experimental and unstable. + """ + + operation: str + arg: Any + id: str + endpoint: str + service: str + result_type: type | None + schedule_to_close_timeout: timedelta | None + id_reuse_policy: temporalio.common.NexusOperationIDReusePolicy + id_conflict_policy: temporalio.common.NexusOperationIDConflictPolicy + search_attributes: temporalio.common.TypedSearchAttributes | None + summary: str | None + headers: Mapping[str, str] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + + +@dataclass +class DescribeNexusOperationInput: + """Input for :py:meth:`OutboundInterceptor.describe_nexus_operation`. + + .. warning:: + This API is experimental and unstable. + """ + + operation_id: str + run_id: str | None + long_poll_token: bytes | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + + +@dataclass +class GetNexusOperationResultInput: + """Input for :py:meth:`OutbountInterceptor.get_nexus_operation_result`. + + .. warning:: + This API is experimental and unstable. + """ + + operation_id: str + run_id: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + result_type: type[Any] | None + + +@dataclass +class CancelNexusOperationInput: + """Input for :py:meth:`OutboundInterceptor.cancel_nexus_operation`. + + .. warning:: + This API is experimental and unstable. + """ + + operation_id: str + run_id: str | None + reason: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + + +@dataclass +class TerminateNexusOperationInput: + """Input for :py:meth:`OutboundInterceptor.terminate_nexus_operation`. + + .. warning:: + This API is experimental and unstable. + """ + + operation_id: str + run_id: str | None + reason: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + + +@dataclass +class ListNexusOperationsInput: + """Input for :py:meth:`OutboundInterceptor.list_nexus_operations`. + + .. warning:: + This API is experimental and unstable. + """ + + query: str | None + page_size: int + next_page_token: bytes | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + limit: int | None + + +@dataclass +class CountNexusOperationsInput: + """Input for :py:meth:`OutboundInterceptor.count_nexus_operations`. + + .. warning:: + This API is experimental and unstable. + """ + + query: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + + @dataclass class StartWorkflowUpdateInput: """Input for :py:meth:`OutboundInterceptor.start_workflow_update`.""" @@ -7959,6 +9400,76 @@ async def count_activities( """ return await self.next.count_activities(input) + ### Nexus operation calls + + async def start_nexus_operation( + self, input: StartNexusOperationInput + ) -> NexusOperationHandle[Any]: + """Called for every :py:meth:`NexusClient.start_operation` call. + + .. warning:: + This API is experimental and unstable. + """ + return await self.next.start_nexus_operation(input) + + async def describe_nexus_operation( + self, input: DescribeNexusOperationInput + ) -> NexusOperationExecutionDescription: + """Called for every :py:meth:`NexusOperationHandle.describe` call. + + .. warning:: + This API is experimental and unstable. + """ + return await self.next.describe_nexus_operation(input) + + async def get_nexus_operation_result( + self, input: GetNexusOperationResultInput + ) -> Any: + """Called for every :py:meth:`NexusOperationHandle.result` call. + + .. warning:: + This API is experimental and unstable. + """ + return await self.next.get_nexus_operation_result(input) + + async def cancel_nexus_operation(self, input: CancelNexusOperationInput) -> None: + """Called for every :py:meth:`NexusOperationHandle.cancel` call. + + .. warning:: + This API is experimental and unstable. + """ + await self.next.cancel_nexus_operation(input) + + async def terminate_nexus_operation( + self, input: TerminateNexusOperationInput + ) -> None: + """Called for every :py:meth:`NexusOperationHandle.terminate` call. + + .. warning:: + This API is experimental and unstable. + """ + await self.next.terminate_nexus_operation(input) + + def list_nexus_operations( + self, input: ListNexusOperationsInput + ) -> NexusOperationExecutionAsyncIterator: + """Called for every :py:meth:`Client.list_nexus_operations` call. + + .. warning:: + This API is experimental and unstable. + """ + return self.next.list_nexus_operations(input) + + async def count_nexus_operations( + self, input: CountNexusOperationsInput + ) -> NexusOperationExecutionCount: + """Called for every :py:meth:`Client.count_nexus_operations` call. + + .. warning:: + This API is experimental and unstable. + """ + return await self.next.count_nexus_operations(input) + async def start_workflow_update( self, input: StartWorkflowUpdateInput ) -> WorkflowUpdateHandle[Any]: @@ -8634,6 +10145,206 @@ async def count_activities( ) ) + ### Nexus operation calls + + async def start_nexus_operation( + self, input: StartNexusOperationInput + ) -> NexusOperationHandle[Any]: + """Start a nexus operation and return a handle to it.""" + req = temporalio.api.workflowservice.v1.StartNexusOperationExecutionRequest( + namespace=self._client.namespace, + identity=self._client.identity, + request_id=str(uuid.uuid4()), + operation_id=input.id, + endpoint=input.endpoint, + service=input.service, + operation=input.operation, + id_reuse_policy=cast( + "temporalio.api.enums.v1.NexusOperationIdReusePolicy.ValueType", + int(input.id_reuse_policy), + ), + id_conflict_policy=cast( + "temporalio.api.enums.v1.NexusOperationIdConflictPolicy.ValueType", + int(input.id_conflict_policy), + ), + ) + + if input.schedule_to_close_timeout is not None: + req.schedule_to_close_timeout.FromTimedelta(input.schedule_to_close_timeout) + + # Set input payload + if input.arg is not temporalio.common._arg_unset: + encoded = await self._client.data_converter.encode([input.arg]) + if encoded: + req.input.CopyFrom(encoded[0]) + + # Set search attributes + if input.search_attributes is not None: + temporalio.converter.encode_search_attributes( + input.search_attributes, req.search_attributes + ) + + # Set user metadata + metadata = await _encode_user_metadata( + self._client.data_converter, input.summary, None + ) + if metadata is not None: + req.user_metadata.CopyFrom(metadata) + + # Set nexus headers + if input.headers: + for k, v in input.headers.items(): + req.nexus_header[k] = v + + resp: temporalio.api.workflowservice.v1.StartNexusOperationExecutionResponse + try: + resp = await self._client.workflow_service.start_nexus_operation_execution( + req, + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + except RPCError as err: + if err.status == RPCStatusCode.ALREADY_EXISTS and err.grpc_status.details: + details = temporalio.api.errordetails.v1.NexusOperationExecutionAlreadyStartedFailure() + if err.grpc_status.details[0].Unpack(details): + raise temporalio.exceptions.NexusOperationAlreadyStartedError( + input.id, run_id=details.run_id + ) + raise + return NexusOperationHandle( + self._client, + input.id, + run_id=resp.run_id or None, + result_type=input.result_type, + endpoint=input.endpoint, + service=input.service, + ) + + async def describe_nexus_operation( + self, input: DescribeNexusOperationInput + ) -> NexusOperationExecutionDescription: + """Describe a nexus operation.""" + resp = await self._client.workflow_service.describe_nexus_operation_execution( + temporalio.api.workflowservice.v1.DescribeNexusOperationExecutionRequest( + namespace=self._client.namespace, + operation_id=input.operation_id, + run_id=input.run_id or "", + ), + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + return await NexusOperationExecutionDescription._from_execution_info( + info=resp.info, + data_converter=self._client.data_converter, + long_poll_token=resp.long_poll_token or None, + ) + + async def get_nexus_operation_result( + self, input: GetNexusOperationResultInput + ) -> Any: + """Poll for nexus operation result until it's available.""" + req = temporalio.api.workflowservice.v1.PollNexusOperationExecutionRequest( + namespace=self._client.namespace, + operation_id=input.operation_id, + run_id=input.run_id or "", + wait_stage=temporalio.api.enums.v1.NexusOperationWaitStage.NEXUS_OPERATION_WAIT_STAGE_CLOSED, + ) + + # Continue polling as long as we have no outcome + while True: + try: + res = ( + await self._client.workflow_service.poll_nexus_operation_execution( + req, + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + ) + match res.WhichOneof("outcome"): + case "result": + type_hints = [input.result_type] if input.result_type else None + [result] = await self._client.data_converter.decode( + [res.result], type_hints + ) + return result + + case "failure": + raise NexusOperationFailureError( + cause=await self._client.data_converter.decode_failure( + res.failure + ) + ) + + case None: + # poll again + pass + except RPCError as err: + match err.status: + case RPCStatusCode.DEADLINE_EXCEEDED: + # Deadline exceeded is expected with long polling; retry + continue + case RPCStatusCode.CANCELLED: + raise asyncio.CancelledError() from err + case _: + raise + + async def cancel_nexus_operation(self, input: CancelNexusOperationInput) -> None: + """Cancel a nexus operation.""" + await self._client.workflow_service.request_cancel_nexus_operation_execution( + temporalio.api.workflowservice.v1.RequestCancelNexusOperationExecutionRequest( + namespace=self._client.namespace, + operation_id=input.operation_id, + run_id=input.run_id or "", + identity=self._client.identity, + request_id=str(uuid.uuid4()), + reason=input.reason or "", + ), + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + + async def terminate_nexus_operation( + self, input: TerminateNexusOperationInput + ) -> None: + """Terminate a nexus operation.""" + await self._client.workflow_service.terminate_nexus_operation_execution( + temporalio.api.workflowservice.v1.TerminateNexusOperationExecutionRequest( + namespace=self._client.namespace, + operation_id=input.operation_id, + run_id=input.run_id or "", + reason=input.reason or "", + identity=self._client.identity, + request_id=str(uuid.uuid4()), + ), + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + + def list_nexus_operations( + self, input: ListNexusOperationsInput + ) -> NexusOperationExecutionAsyncIterator: + return NexusOperationExecutionAsyncIterator(self._client, input) + + async def count_nexus_operations( + self, input: CountNexusOperationsInput + ) -> NexusOperationExecutionCount: + return NexusOperationExecutionCount._from_raw( + await self._client.workflow_service.count_nexus_operation_executions( + temporalio.api.workflowservice.v1.CountNexusOperationExecutionsRequest( + namespace=self._client.namespace, + query=input.query or "", + ), + retry=True, + metadata=input.rpc_metadata, + timeout=input.rpc_timeout, + ) + ) + async def start_workflow_update( self, input: StartWorkflowUpdateInput ) -> WorkflowUpdateHandle[Any]: diff --git a/temporalio/common.py b/temporalio/common.py index 2f34c6387..731a1fc38 100644 --- a/temporalio/common.py +++ b/temporalio/common.py @@ -191,6 +191,150 @@ class ActivityIDConflictPolicy(IntEnum): ) +class NexusOperationIDReusePolicy(IntEnum): + """How already-closed Nexus operation IDs are handled on start. + + .. warning:: + This API is experimental and unstable. + + See :py:class:`temporalio.api.enums.v1.NexusOperationIdReusePolicy`. + """ + + UNSPECIFIED = int( + temporalio.api.enums.v1.NexusOperationIdReusePolicy.NEXUS_OPERATION_ID_REUSE_POLICY_UNSPECIFIED + ) + ALLOW_DUPLICATE = int( + temporalio.api.enums.v1.NexusOperationIdReusePolicy.NEXUS_OPERATION_ID_REUSE_POLICY_ALLOW_DUPLICATE + ) + ALLOW_DUPLICATE_FAILED_ONLY = int( + temporalio.api.enums.v1.NexusOperationIdReusePolicy.NEXUS_OPERATION_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY + ) + REJECT_DUPLICATE = int( + temporalio.api.enums.v1.NexusOperationIdReusePolicy.NEXUS_OPERATION_ID_REUSE_POLICY_REJECT_DUPLICATE + ) + + +class NexusOperationIDConflictPolicy(IntEnum): + """How already-running Nexus operation IDs are handled on start. + + .. warning:: + This API is experimental and unstable. + + See :py:class:`temporalio.api.enums.v1.NexusOperationIdConflictPolicy`. + """ + + UNSPECIFIED = int( + temporalio.api.enums.v1.NexusOperationIdConflictPolicy.NEXUS_OPERATION_ID_CONFLICT_POLICY_UNSPECIFIED + ) + FAIL = int( + temporalio.api.enums.v1.NexusOperationIdConflictPolicy.NEXUS_OPERATION_ID_CONFLICT_POLICY_FAIL + ) + USE_EXISTING = int( + temporalio.api.enums.v1.NexusOperationIdConflictPolicy.NEXUS_OPERATION_ID_CONFLICT_POLICY_USE_EXISTING + ) + + +class NexusOperationExecutionStatus(IntEnum): + """Status of a standalone Nexus operation execution. + + .. warning:: + This API is experimental and unstable. + + See :py:class:`temporalio.api.enums.v1.NexusOperationExecutionStatus`. + """ + + UNSPECIFIED = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_UNSPECIFIED + ) + RUNNING = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_RUNNING + ) + COMPLETED = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_COMPLETED + ) + FAILED = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_FAILED + ) + CANCELED = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_CANCELED + ) + TERMINATED = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_TERMINATED + ) + TIMED_OUT = int( + temporalio.api.enums.v1.NexusOperationExecutionStatus.NEXUS_OPERATION_EXECUTION_STATUS_TIMED_OUT + ) + + +class PendingNexusOperationExecutionState(IntEnum): + """More detailed breakdown of :py:attr:`NexusOperationExecutionStatus.RUNNING`. + + .. warning:: + This API is experimental and unstable. + + See :py:class:`temporalio.api.enums.v1.PendingNexusOperationState`. + """ + + UNSPECIFIED = int( + temporalio.api.enums.v1.PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_UNSPECIFIED + ) + SCHEDULED = int( + temporalio.api.enums.v1.PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_SCHEDULED + ) + BACKING_OFF = int( + temporalio.api.enums.v1.PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_BACKING_OFF + ) + STARTED = int( + temporalio.api.enums.v1.PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_STARTED + ) + BLOCKED = int( + temporalio.api.enums.v1.PendingNexusOperationState.PENDING_NEXUS_OPERATION_STATE_BLOCKED + ) + + +class NexusOperationCancellationState(IntEnum): + """State of a Nexus operation cancellation. + + .. warning:: + This API is experimental and unstable. + """ + + UNSPECIFIED = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_UNSPECIFIED + ) + """Default value, unspecified state.""" + + SCHEDULED = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_SCHEDULED + ) + """Cancellation request is in the queue waiting to be executed or is currently executing.""" + + BACKING_OFF = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_BACKING_OFF + ) + """Cancellation request has failed with a retryable error and is backing off before the next attempt.""" + + SUCCEEDED = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_SUCCEEDED + ) + """Cancellation request succeeded.""" + + FAILED = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_FAILED + ) + """Cancellation request failed with a non-retryable error.""" + + TIMED_OUT = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_TIMED_OUT + ) + """The associated operation timed out - exceeded the user supplied schedule-to-close timeout.""" + + BLOCKED = int( + temporalio.api.enums.v1.NexusOperationCancellationState.NEXUS_OPERATION_CANCELLATION_STATE_BLOCKED + ) + """Cancellation request is blocked (eg: by circuit breaker).""" + + class QueryRejectCondition(IntEnum): """Whether a query should be rejected in certain conditions. diff --git a/temporalio/converter/_failure_converter.py b/temporalio/converter/_failure_converter.py index 5b2bf2fdb..b1511b0b0 100644 --- a/temporalio/converter/_failure_converter.py +++ b/temporalio/converter/_failure_converter.py @@ -236,7 +236,7 @@ def _nexus_handler_error_to_failure( ) -> None: if error.original_failure: self._nexus_failure_to_temporal_failure( - error.original_failure, True, failure + error.original_failure, error.retryable, failure ) else: failure.message = error.message diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index d386d4327..43a2e1bad 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -90,6 +90,24 @@ def __init__( self.run_id = run_id +class NexusOperationAlreadyStartedError(FailureError): + """Thrown by a client when a Nexus operation execution has already started. + + .. warning:: + This API is experimental and unstable. + + Attributes: + operation_id: ID of the already-started operation. + run_id: Run ID of the already-started operation if available. + """ + + def __init__(self, operation_id: str, *, run_id: str | None = None) -> None: + """Initialize a Nexus operation already started error.""" + super().__init__("Nexus operation execution already started") + self.operation_id = operation_id + self.run_id = run_id + + class ApplicationErrorCategory(IntEnum): """Severity category for your application error. Maps to corresponding client-side logging/metrics behaviors""" diff --git a/temporalio/nexus/_link_conversion.py b/temporalio/nexus/_link_conversion.py index a47c002a9..1d707abb1 100644 --- a/temporalio/nexus/_link_conversion.py +++ b/temporalio/nexus/_link_conversion.py @@ -18,9 +18,10 @@ logger = logging.getLogger(__name__) -_LINK_URL_PATH_REGEX = re.compile( +_WORFKLOW_LINK_URL_PATH_REGEX = re.compile( r"^/namespaces/(?P[^/]+)/workflows/(?P[^/]+)/(?P[^/]+)/history$" ) + LINK_EVENT_ID_PARAM_NAME = "eventID" LINK_EVENT_TYPE_PARAM_NAME = "eventType" LINK_REQUEST_ID_PARAM_NAME = "requestID" @@ -94,10 +95,10 @@ def nexus_link_to_workflow_event( StartWorklow request. """ url = urllib.parse.urlparse(link.url) - match = _LINK_URL_PATH_REGEX.match(url.path) + match = _WORFKLOW_LINK_URL_PATH_REGEX.match(url.path) if not match: logger.warning( - f"Invalid Nexus link: {link}. Expected path to match {_LINK_URL_PATH_REGEX.pattern}" + f"Invalid Nexus link: {link}. Expected path to match {_WORFKLOW_LINK_URL_PATH_REGEX.pattern}" ) return None try: diff --git a/temporalio/nexus/_operation_context.py b/temporalio/nexus/_operation_context.py index 04462c900..e3d4b432b 100644 --- a/temporalio/nexus/_operation_context.py +++ b/temporalio/nexus/_operation_context.py @@ -71,6 +71,10 @@ "temporal-nexus-backing-workflow-start-context" ) +_WORKFLOW_EVENT_LINK_TYPE = ( + temporalio.api.common.v1.Link.WorkflowEvent.DESCRIPTOR.full_name +) + @dataclass(frozen=True) class Info: @@ -244,6 +248,8 @@ def _get_workflow_event_links( ) -> list[temporalio.api.common.v1.Link.WorkflowEvent]: event_links = [] for inbound_link in self.nexus_context.inbound_links: + if inbound_link.type != _WORKFLOW_EVENT_LINK_TYPE: + continue if link := nexus_link_to_workflow_event(inbound_link): event_links.append(link) return event_links diff --git a/temporalio/types.py b/temporalio/types.py index 4b217ea23..25b1cbba3 100644 --- a/temporalio/types.py +++ b/temporalio/types.py @@ -28,6 +28,8 @@ ProtocolReturnType = TypeVar("ProtocolReturnType", covariant=True) ProtocolSelfType = TypeVar("ProtocolSelfType", contravariant=True) +ServiceType = TypeVar("ServiceType") + class CallableAsyncNoParam(Protocol[ProtocolReturnType]): """Generic callable type.""" diff --git a/temporalio/worker/_nexus.py b/temporalio/worker/_nexus.py index a189278b8..f35d10fd5 100644 --- a/temporalio/worker/_nexus.py +++ b/temporalio/worker/_nexus.py @@ -216,6 +216,14 @@ async def wait_all_completed(self) -> None: ] await asyncio.gather(*running_tasks, return_exceptions=True) + # Task completion should never be dropped in case of cancellation. + # The Rust future in core must complete for shutdown to happen without + # hanging. + async def _complete_task( + self, completion: temporalio.bridge.proto.nexus.NexusTaskCompletion + ): + await asyncio.shield(self._bridge_worker().complete_nexus_task(completion)) + # TODO(nexus-preview): stack trace pruning. See sdk-typescript NexusHandler.execute # "Any call up to this function and including this one will be trimmed out of stack traces."" @@ -281,8 +289,7 @@ async def _handle_cancel_operation_task( cancel_operation=temporalio.api.nexus.v1.CancelOperationResponse() ), ) - - await self._bridge_worker().complete_nexus_task(completion) + await self._complete_task(completion) except Exception: logger.exception("Failed to send Nexus task completion") finally: @@ -341,7 +348,7 @@ async def _handle_start_operation_task( ), ) - await self._bridge_worker().complete_nexus_task(completion) + await self._complete_task(completion) except Exception: logger.exception("Failed to send Nexus task completion") finally: diff --git a/tests/__init__.py b/tests/__init__.py index 5af71def3..d62129b39 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1 @@ -DEV_SERVER_DOWNLOAD_VERSION = "v1.6.1-server-1.31.0-151.0" +DEV_SERVER_DOWNLOAD_VERSION = "v1.7.1-standalone-nexus-operations" diff --git a/tests/conftest.py b/tests/conftest.py index 303af2e3b..aeb0bc26e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -123,9 +123,19 @@ async def env(env_type: str) -> AsyncGenerator[WorkflowEnvironment, None]: "--dynamic-config-value", "activity.enableStandalone=true", "--dynamic-config-value", + "activity.startDelayEnabled=true", + "--dynamic-config-value", "history.enableChasm=true", "--dynamic-config-value", "history.enableTransitionHistory=true", + "--dynamic-config-value", + "history.enableChasmCallbacks=true", + "--dynamic-config-value", + "nexusoperation.enableStandalone=true", + "--dynamic-config-value", + "nexusoperation.enableChasm=true", + "--dynamic-config-value", + 'system.system.refreshNexusEndpointsMinWait="0s"', ], dev_server_download_version=DEV_SERVER_DOWNLOAD_VERSION, ) diff --git a/tests/nexus/test_type_errors.py b/tests/nexus/test_nexus_type_errors.py similarity index 58% rename from tests/nexus/test_type_errors.py rename to tests/nexus/test_nexus_type_errors.py index 1f5d3e2a7..a8edcb264 100644 --- a/tests/nexus/test_type_errors.py +++ b/tests/nexus/test_nexus_type_errors.py @@ -4,11 +4,15 @@ """ from dataclasses import dataclass +from typing import Any +from unittest.mock import Mock import nexusrpc import temporalio.nexus from temporalio import workflow +from temporalio.client import Client, NexusOperationHandle +from temporalio.service import ServiceClient @dataclass @@ -205,3 +209,118 @@ async def test_invoke_by_operation_handler_method_on_wrong_service(self) -> None MyServiceHandler2.my_sync_operation, # type: ignore MyInput(), ) + + +# ── Standalone Nexus Operation type tests ── +async def standalone_operation_type_tests(): + client = Client(service_client=Mock(spec=ServiceClient)) + nexus_client = client.create_nexus_client( + MyService, + endpoint="fake-endpoint", + ) + + # execute with an operation definition infers output type + _op_defn_output: MyOutput = await nexus_client.execute_operation( + MyService.my_sync_operation, MyInput(), id="op-1" + ) + + # result_type overrides output type from operation definition + # conflicting result_type and annotation on variable cause type error + # assert-type-error-pyright: 'Type "str" is not assignable to declared type "MyOutput"' + _bad_result_type_output: MyOutput = await nexus_client.execute_operation( # type: ignore + MyServiceHandler.my_sync_operation, + MyInput(), + id="op-1", + result_type=str, # type: ignore + ) + + # string operation name and result_type infers output type + _str_op_result_type_output: MyOutput = await nexus_client.execute_operation( + "my_sync_operation", MyInput(), id="op-1", result_type=MyOutput + ) + + # execute with an operation definition and a wrong input type produces a type error + # assert-type-error-pyright: 'No overloads for "execute_operation" match' + await nexus_client.execute_operation( # type: ignore + MyService.my_sync_operation, + # assert-type-error-pyright: 'Argument of type .+ cannot be assigned to parameter "arg"' + "wrong-input-type", # type: ignore + id="op-1", + ) + + # start with an operation definition and a wrong input type produces a type error + # assert-type-error-pyright: 'No overloads for "start_operation" match' + await nexus_client.start_operation( # type: ignore + MyService.my_sync_operation, + # assert-type-error-pyright: 'Argument of type .+ cannot be assigned to parameter "arg"' + "wrong-input-type", # type: ignore + id="op-1", + ) + + # starting with an operation definition infers output type on the handle and + # result from handle + _defn_handle: NexusOperationHandle[MyOutput] = await nexus_client.start_operation( + MyService.my_sync_operation, MyInput(), id="op-1" + ) + _defn_handle_output: MyOutput = await _defn_handle.result() + + # result_type overrides output type from operation definition + # conflicting result_type and annotation on variable cause type error + _result_type_handle: NexusOperationHandle[ + MyOutput + # assert-type-error-pyright: 'Type "NexusOperationHandle\[str\]" is not assignable to declared type "NexusOperationHandle\[MyOutput\]"' + ] = await nexus_client.start_operation( # type: ignore + MyServiceHandler.my_sync_operation, + MyInput(), + id="op-1", + result_type=str, # type: ignore + ) + # handle still respects type declaration on the variable + _result_type_handle_output: MyOutput = await _result_type_handle.result() + + # starting with string operation name and result_type infers output type on the handle + # and result from the handle + _str_op_result_type_handle: NexusOperationHandle[ + MyOutput + ] = await nexus_client.start_operation( + "my_sync_operation", MyInput(), id="op-1", result_type=MyOutput + ) + _str_op_result_type_handle_output: MyOutput = ( + await _str_op_result_type_handle.result() + ) + + # getting a handle with a string produces a handle to Any + _str_op_handle: NexusOperationHandle[Any] = client.get_nexus_operation_handle( + "op-1" + ) + + # getting a handle with an explicit type produces handle of that type + _result_type_get_handle: NexusOperationHandle[MyOutput] = ( + client.get_nexus_operation_handle("op-1", result_type=MyOutput) + ) + + # getting a handle with an operation defintion produces a handle of the operation + # output type + _op_defn_get_handle: NexusOperationHandle[MyOutput] = ( + client.get_nexus_operation_handle("op-1", operation=MyService.my_sync_operation) + ) + + # providing both operation and result_type to get_nexus_operation_handle + # produces a no overload found error + # assert-type-error-pyright: 'No overloads for "get_nexus_operation_handle" match' + _result_type_op_defn_get_handle: NexusOperationHandle[MyOutput] = ( + client.get_nexus_operation_handle( # type: ignore + "op-1", + operation=MyService.my_sync_operation, + result_type=str, + ) + ) + + # mismatched types on get_nexus_operation_handle produces type error + # assert-type-error-pyright: 'Type "NexusOperationHandle\[str\]" is not assignable to declared type "NexusOperationHandle\[MyOutput\]"' + _mismatch_handle: NexusOperationHandle[MyOutput] = ( + client.get_nexus_operation_handle( # type: ignore + "op-1", + result_type=str, # type: ignore + ) + ) diff --git a/tests/nexus/test_standalone_operations.py b/tests/nexus/test_standalone_operations.py new file mode 100644 index 000000000..b1dcfe774 --- /dev/null +++ b/tests/nexus/test_standalone_operations.py @@ -0,0 +1,910 @@ +"""Integration tests for standalone Nexus operations (client-side). + +Tests the client-side Nexus operation API: start, result, describe, cancel, +terminate, list, count, get_nexus_operation_handle, ID conflict policies, +and interceptor integration. +""" + +from __future__ import annotations + +import asyncio +import uuid +from dataclasses import dataclass +from datetime import timedelta +from typing import Any, Literal + +import nexusrpc +import pytest +from nexusrpc.handler import ( + StartOperationContext, + service_handler, + sync_operation, +) + +from temporalio import nexus, workflow +from temporalio.client import ( + CancelNexusOperationInput, + Client, + CountNexusOperationsInput, + DescribeNexusOperationInput, + GetNexusOperationResultInput, + Interceptor, + ListNexusOperationsInput, + NexusOperationExecutionDescription, + NexusOperationFailureError, + NexusOperationHandle, + OutboundInterceptor, + StartNexusOperationInput, + TerminateNexusOperationInput, + WorkflowUpdateStage, +) +from temporalio.common import ( + NexusOperationExecutionStatus, + NexusOperationIDConflictPolicy, + NexusOperationIDReusePolicy, + WorkflowIDConflictPolicy, + WorkflowIDReusePolicy, +) +from temporalio.exceptions import ( + ApplicationError, + CancelledError, + NexusOperationAlreadyStartedError, + TerminatedError, +) +from temporalio.nexus import WorkflowRunOperationContext, workflow_run_operation +from temporalio.testing import WorkflowEnvironment +from temporalio.worker import Worker +from tests.helpers import assert_eventually +from tests.helpers.nexus import make_nexus_endpoint_name + +# --------------------------------------------------------------------------- +# Data types +# --------------------------------------------------------------------------- + + +@dataclass +class EchoInput: + value: str + + +@dataclass +class EchoOutput: + value: str + + +@dataclass +class RaiseErrInput: + err_type: Literal["handler_err", "application_err"] + + +# --------------------------------------------------------------------------- +# Service definition +# --------------------------------------------------------------------------- + + +@nexusrpc.service +class StandaloneTestService: + echo_sync: nexusrpc.Operation[EchoInput, EchoOutput] + echo_async: nexusrpc.Operation[EchoInput, EchoOutput] + blocking_async: nexusrpc.Operation[EchoInput, EchoOutput] + raise_err: nexusrpc.Operation[RaiseErrInput, None] + + +# --------------------------------------------------------------------------- +# Handler workflows +# --------------------------------------------------------------------------- + + +@workflow.defn +class EchoHandlerWorkflow: + @workflow.run + async def run(self, input: EchoInput) -> EchoOutput: + return EchoOutput(value=input.value) + + +@workflow.defn +class BlockingHandlerWorkflow: + """A workflow that blocks until it receives a signal or is cancelled/terminated.""" + + def __init__(self) -> None: + self._proceed = False + + @workflow.run + async def run(self, input: EchoInput) -> EchoOutput: + await workflow.wait_condition(lambda: self._proceed) + return EchoOutput(value=input.value) + + @workflow.update + def unblock(self) -> None: + self._proceed = True + + +# --------------------------------------------------------------------------- +# Service handler +# --------------------------------------------------------------------------- + + +@service_handler(service=StandaloneTestService) +class StandaloneTestServiceHandler: + def __init__(self) -> None: + self.started_blocking = asyncio.Event() + + @sync_operation + async def echo_sync( + self, _ctx: StartOperationContext, input: EchoInput + ) -> EchoOutput: + return EchoOutput(value=input.value) + + @workflow_run_operation + async def echo_async( + self, ctx: WorkflowRunOperationContext, input: EchoInput + ) -> nexus.WorkflowHandle[EchoOutput]: + return await ctx.start_workflow( + EchoHandlerWorkflow.run, + input, + id=str(uuid.uuid4()), + ) + + @workflow_run_operation + async def blocking_async( + self, ctx: WorkflowRunOperationContext, input: EchoInput + ) -> nexus.WorkflowHandle[EchoOutput]: + handle = await ctx.start_workflow( + BlockingHandlerWorkflow.run, + input, + id=f"blocking_async-{input.value}", + id_reuse_policy=WorkflowIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy=WorkflowIDConflictPolicy.FAIL, + ) + self.started_blocking.set() + return handle + + @sync_operation + async def raise_err( + self, _ctx: StartOperationContext, input: RaiseErrInput + ) -> None: + match input.err_type: + case "handler_err": + raise nexusrpc.HandlerError( + "test handler error", + type=nexusrpc.HandlerErrorType.INTERNAL, + retryable_override=False, + ) + case "application_err": + raise ApplicationError("test application error", non_retryable=True) + + +# --------------------------------------------------------------------------- +# Tests +# --------------------------------------------------------------------------- + + +async def test_start_sync_operation_and_get_result( + client: Client, env: WorkflowEnvironment +): + """Start a sync nexus operation, call handle.result(), verify return value.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + # Use execute_with_retry to retry the full start+result cycle + # (endpoint propagation may cause the first attempt to time out) + handle = await nexus_client.start_operation( + StandaloneTestService.echo_sync, + EchoInput(value="hello"), + id=str(uuid.uuid4()), + schedule_to_close_timeout=timedelta(seconds=10), + ) + result = await handle.result() + assert isinstance(result, EchoOutput) + assert result.value == "hello" + + # test value is cached + second_result = await handle.result() + assert result is second_result + + +async def test_start_async_operation_and_poll_result( + client: Client, env: WorkflowEnvironment +): + """Start a workflow_run operation, poll result, verify.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + handle = await nexus_client.start_operation( + StandaloneTestService.echo_async, + EchoInput(value="async-hello"), + id=str(uuid.uuid4()), + schedule_to_close_timeout=timedelta(seconds=30), + ) + result = await handle.result() + assert isinstance(result, EchoOutput) + assert result.value == "async-hello" + + +async def test_execute_operation(client: Client, env: WorkflowEnvironment): + """Use execute_operation convenience method, verify it returns result directly.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + result = await nexus_client.execute_operation( + StandaloneTestService.echo_sync, + EchoInput(value="execute"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=10), + ) + assert isinstance(result, EchoOutput) + assert result.value == "execute" + + +async def test_errors(client: Client, env: WorkflowEnvironment): + """Execute operations that raise errors""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + handle = await nexus_client.start_operation( + StandaloneTestService.raise_err, + RaiseErrInput("handler_err"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + with pytest.raises(NexusOperationFailureError) as err: + await handle.result() + + assert err.value.__cause__ + assert isinstance(err.value.__cause__, nexusrpc.HandlerError) + + # test that the error is cached + with pytest.raises(NexusOperationFailureError) as second_err: + await handle.result() + assert err.value is second_err.value + + handle = await nexus_client.start_operation( + StandaloneTestService.raise_err, + RaiseErrInput("application_err"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + with pytest.raises(NexusOperationFailureError) as err: + await handle.result() + + assert err.value.__cause__ + assert isinstance(err.value.__cause__, nexusrpc.HandlerError) + assert err.value.__cause__.__cause__ + assert isinstance(err.value.__cause__.__cause__, ApplicationError) + + +async def test_describe_operation(client: Client, env: WorkflowEnvironment): + """Start op, get result first, then describe, verify fields populated.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + # Start an async operation and get its result first, then describe + handle = await nexus_client.start_operation( + StandaloneTestService.echo_async, + EchoInput(value="describe-me"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + summary=StandaloneTestService.echo_async.name, + ) + await handle.result() + + desc = await handle.describe() + assert isinstance(desc, NexusOperationExecutionDescription) + assert desc.operation_id == handle.operation_id + assert desc.endpoint == endpoint_name + assert desc.service == "StandaloneTestService" + assert desc.operation == "echo_async" + assert desc.status in ( + NexusOperationExecutionStatus.RUNNING, + NexusOperationExecutionStatus.COMPLETED, + ) + assert isinstance(desc.state, int) + assert isinstance(desc.attempt, int) + assert desc.blocked_reason is None or isinstance(desc.blocked_reason, str) + assert desc.last_attempt_failure is None or isinstance( + desc.last_attempt_failure, BaseException + ) + summary = await desc.static_summary() + assert summary == StandaloneTestService.echo_async.name + + +async def test_cancel_operation(client: Client, env: WorkflowEnvironment): + """Start blocking async op, cancel it, verify awaiting result raises NexusOperationFailureError + from a CancelledError. + """ + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + handle = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value="cancel-me"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Cancel the operation + await handle.cancel() + + with pytest.raises(NexusOperationFailureError) as err: + await handle.result() + + assert err.value.__cause__ + assert isinstance(err.value.__cause__, CancelledError) + + +async def test_terminate_operation(client: Client, env: WorkflowEnvironment): + """Start blocking async op, terminate it, verify awaiting the result raises NexusOperationFailureError + from a TerminatedError. + """ + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + handle = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value="terminate-me"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Terminate the operation + await handle.terminate(reason="test termination") + + with pytest.raises(NexusOperationFailureError) as err: + await handle.result() + + assert err.value.__cause__ + assert isinstance(err.value.__cause__, TerminatedError) + + +async def test_list_operations(client: Client, env: WorkflowEnvironment): + """Start multiple ops, list them, verify iteration yields correct results.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + # Start several blocking operations so they remain visible + op_ids: list[str] = [] + for i in range(3): + op_id = str(uuid.uuid4()) + op_ids.append(op_id) + await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value=f"list-{i}"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Poll until all 3 operations appear (visibility is eventually consistent) + query = f'Endpoint = "{endpoint_name}"' + + async def check_ids() -> None: + found_ids: set[str] = set() + async for op_exec in client.list_nexus_operations(query): + found_ids.add(op_exec.operation_id) + assert all(op_id in found_ids for op_id in op_ids) + + await assert_eventually(check_ids) + + +async def test_count_operations(client: Client, env: WorkflowEnvironment): + """Start ops, count, verify count.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + # Start some blocking operations + for i in range(2): + await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value=f"count-{i}"), + id=str(uuid.uuid4()), + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Poll until count >= 2 (visibility is eventually consistent) + query = f'Endpoint = "{endpoint_name}"' + + async def check_count() -> None: + count_result = await client.count_nexus_operations(query) + assert count_result.count >= 2 + + await assert_eventually(check_count) + + +async def test_get_nexus_operation_handle(client: Client, env: WorkflowEnvironment): + """Start op, get result, then get handle by ID and get result again.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + op_id = str(uuid.uuid4()) + original_handle = await nexus_client.start_operation( + StandaloneTestService.echo_async, + EchoInput(value="handle-test"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + # Get result from the original handle first + original_result = await original_handle.result() + assert isinstance(original_result, EchoOutput) + assert original_result.value == "handle-test" + + # Get a fresh handle by ID and get result again + handle = client.get_nexus_operation_handle( + op_id, operation=StandaloneTestService.echo_async + ) + result = await handle.result() + assert isinstance(result, EchoOutput) + assert result.value == "handle-test" + + +async def test_id_conflict_policy_use_existing( + client: Client, env: WorkflowEnvironment +): + """Start op, re-start with USE_EXISTING, verify same op/run ID and expected result""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + service_handler = StandaloneTestServiceHandler() + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[service_handler], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + op_id = str(uuid.uuid4()) + + # First start + handle = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value=task_queue), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.USE_EXISTING, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Second start with same ID and USE_EXISTING + handle2 = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value="second"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.ALLOW_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.USE_EXISTING, + schedule_to_close_timeout=timedelta(seconds=30), + ) + assert handle.operation_id == handle2.operation_id + assert handle.run_id == handle2.run_id + + # Let the nexus operation run and start the blocking workflow + await service_handler.started_blocking.wait() + + expected_wf_id = f"blocking_async-{task_queue}" + wf_handle = env.client.get_workflow_handle(expected_wf_id) + + await wf_handle.start_update( + BlockingHandlerWorkflow.unblock, + wait_for_stage=WorkflowUpdateStage.COMPLETED, + ) + + first_result = await handle.result() + second_result = await handle2.result() + assert first_result.value == task_queue + assert first_result.value == second_result.value + + +async def test_id_conflict_policy_fail(client: Client, env: WorkflowEnvironment): + """Start op, re-start with FAIL, verify raises NexusOperationAlreadyStartedError.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + op_id = str(uuid.uuid4()) + + # First start + await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value="first"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + # Second start with same ID and FAIL should raise + with pytest.raises(NexusOperationAlreadyStartedError): + await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value="second"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + + +# --------------------------------------------------------------------------- +# Interceptor test +# --------------------------------------------------------------------------- + + +class _RecordingOutboundInterceptor(OutboundInterceptor): + """Outbound interceptor that records calls to nexus operation methods.""" + + def __init__( + self, next: OutboundInterceptor, parent: _RecordingInterceptor + ) -> None: + super().__init__(next) + self._parent = parent + + async def start_nexus_operation( + self, input: StartNexusOperationInput + ) -> NexusOperationHandle[Any]: + self._parent.start_calls.append(input) + return await super().start_nexus_operation(input) + + async def describe_nexus_operation( + self, input: DescribeNexusOperationInput + ) -> NexusOperationExecutionDescription: + self._parent.describe_calls.append(input) + return await super().describe_nexus_operation(input) + + async def get_nexus_operation_result( + self, input: GetNexusOperationResultInput + ) -> Any: + self._parent.result_calls.append(input) + return await super().get_nexus_operation_result(input) + + async def cancel_nexus_operation(self, input: CancelNexusOperationInput) -> None: + self._parent.cancel_calls.append(input) + return await super().cancel_nexus_operation(input) + + async def terminate_nexus_operation( + self, input: TerminateNexusOperationInput + ) -> None: + self._parent.terminate_calls.append(input) + return await super().terminate_nexus_operation(input) + + def list_nexus_operations(self, input: ListNexusOperationsInput): + self._parent.list_calls.append(input) + return super().list_nexus_operations(input) + + async def count_nexus_operations(self, input: CountNexusOperationsInput): + self._parent.count_calls.append(input) + return await super().count_nexus_operations(input) + + +class _RecordingInterceptor(Interceptor): + """Client interceptor that records nexus operation calls.""" + + def __init__(self) -> None: + super().__init__() + self.start_calls: list[StartNexusOperationInput] = [] + self.describe_calls: list[DescribeNexusOperationInput] = [] + self.result_calls: list[GetNexusOperationResultInput] = [] + self.cancel_calls: list[CancelNexusOperationInput] = [] + self.terminate_calls: list[TerminateNexusOperationInput] = [] + self.list_calls: list[ListNexusOperationsInput] = [] + self.count_calls: list[CountNexusOperationsInput] = [] + + def intercept_client(self, next: OutboundInterceptor) -> OutboundInterceptor: + return _RecordingOutboundInterceptor(next, self) + + +async def test_interceptor_receives_inputs(client: Client, env: WorkflowEnvironment): + """Custom OutboundInterceptor records calls, verify correct input types.""" + if env.supports_time_skipping: + pytest.skip( + "Standalone Nexus Operation tests don't work with time-skipping server" + ) + + task_queue = str(uuid.uuid4()) + endpoint_name = make_nexus_endpoint_name(task_queue) + + interceptor = _RecordingInterceptor() + intercepted_client = Client( + service_client=client.service_client, + namespace=client.namespace, + interceptors=[interceptor], + ) + + async with Worker( + client, + task_queue=task_queue, + nexus_service_handlers=[StandaloneTestServiceHandler()], + workflows=[EchoHandlerWorkflow, BlockingHandlerWorkflow], + ): + await env.create_nexus_endpoint(endpoint_name, task_queue) + + nexus_client = intercepted_client.create_nexus_client( + service=StandaloneTestService, endpoint=endpoint_name + ) + + op_id = str(uuid.uuid4()) + + # Start operation -- should trigger start interceptor (with retry) + handle = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value=f"interceptor-test-{op_id}"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + assert len(interceptor.start_calls) >= 1 + start_input = interceptor.start_calls[-1] + assert isinstance(start_input, StartNexusOperationInput) + assert start_input.id == op_id + assert start_input.operation == "blocking_async" + assert start_input.endpoint == endpoint_name + assert start_input.service == "StandaloneTestService" + + # Describe + await handle.describe() + assert len(interceptor.describe_calls) == 1 + desc_input = interceptor.describe_calls[0] + assert isinstance(desc_input, DescribeNexusOperationInput) + assert desc_input.operation_id == op_id + + # Cancel + await handle.cancel() + assert len(interceptor.cancel_calls) == 1 + cancel_input = interceptor.cancel_calls[0] + assert isinstance(cancel_input, CancelNexusOperationInput) + assert cancel_input.operation_id == op_id + + # GetResult + with pytest.raises(NexusOperationFailureError): + await handle.result() + assert len(interceptor.result_calls) == 1 + result_input = interceptor.result_calls[0] + assert isinstance(result_input, GetNexusOperationResultInput) + assert result_input.operation_id == op_id + assert result_input.result_type == EchoOutput + + # Start another so we can terminate it + previous_start_count = len(interceptor.start_calls) + op_id = str(uuid.uuid4()) + handle = await nexus_client.start_operation( + StandaloneTestService.blocking_async, + EchoInput(value=f"interceptor-test-{op_id}"), + id=op_id, + id_reuse_policy=NexusOperationIDReusePolicy.REJECT_DUPLICATE, + id_conflict_policy=NexusOperationIDConflictPolicy.FAIL, + schedule_to_close_timeout=timedelta(seconds=30), + ) + assert len(interceptor.start_calls) > previous_start_count + + # Terminate + await handle.terminate() + assert len(interceptor.terminate_calls) == 1 + terminate_input = interceptor.terminate_calls[0] + assert isinstance(terminate_input, TerminateNexusOperationInput) + assert terminate_input.operation_id == op_id + + query = f'`OperationId`="{op_id}"' + + # List Operations + # Iterate over list to ensure call is made + async for _ in intercepted_client.list_nexus_operations(query): + pass + assert len(interceptor.list_calls) >= 1 + list_input = interceptor.list_calls[-1] + assert isinstance(list_input, ListNexusOperationsInput) + assert list_input.query == query + + # Count Operations + await intercepted_client.count_nexus_operations(query) + assert len(interceptor.count_calls) >= 1 + count_input = interceptor.count_calls[-1] + assert isinstance(count_input, CountNexusOperationsInput) + assert count_input.query == query diff --git a/uv.lock b/uv.lock index c78ab196c..619081b7f 100644 --- a/uv.lock +++ b/uv.lock @@ -4407,6 +4407,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] +[[package]] +name = "pytest-flakefinder" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/53/69c56a93ea057895b5761c5318455804873a6cd9d796d7c55d41c2358125/pytest-flakefinder-1.1.0.tar.gz", hash = "sha256:e2412a1920bdb8e7908783b20b3d57e9dad590cc39a93e8596ffdd493b403e0e", size = 6795, upload-time = "2022-10-26T18:27:54.243Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/8b/06787150d0fd0cbd3a8054262b56f91631c7778c1bc91bf4637e47f909ad/pytest_flakefinder-1.1.0-py2.py3-none-any.whl", hash = "sha256:741e0e8eea427052f5b8c89c2b3c3019a50c39a59ce4df6a305a2c2d9ba2bd13", size = 4644, upload-time = "2022-10-26T18:27:52.128Z" }, +] + [[package]] name = "pytest-pretty" version = "1.3.0" @@ -5222,6 +5234,7 @@ dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, + { name = "pytest-flakefinder" }, { name = "pytest-pretty" }, { name = "pytest-rerunfailures" }, { name = "pytest-timeout" }, @@ -5287,6 +5300,7 @@ dev = [ { name = "pytest", specifier = "~=9.0" }, { name = "pytest-asyncio", specifier = ">=0.21,<0.22" }, { name = "pytest-cov", specifier = ">=6.1.1" }, + { name = "pytest-flakefinder", specifier = ">=1.1.0" }, { name = "pytest-pretty", specifier = ">=1.3.0" }, { name = "pytest-rerunfailures", specifier = ">=16.1" }, { name = "pytest-timeout", specifier = "~=2.2" },