elementary-runtime 0.1.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. elementary_runtime/__init__.py +5 -0
  2. elementary_runtime/common/__init__.py +0 -0
  3. elementary_runtime/common/validators.py +27 -0
  4. elementary_runtime/config/__init__.py +40 -0
  5. elementary_runtime/config/base.py +19 -0
  6. elementary_runtime/config/connections.py +55 -0
  7. elementary_runtime/config/env.py +66 -0
  8. elementary_runtime/config/errors.py +20 -0
  9. elementary_runtime/config/runtime.py +60 -0
  10. elementary_runtime/config/secrets.py +77 -0
  11. elementary_runtime/config/sections.py +98 -0
  12. elementary_runtime/coordinator/__init__.py +0 -0
  13. elementary_runtime/execution/__init__.py +0 -0
  14. elementary_runtime/execution/redaction/__init__.py +0 -0
  15. elementary_runtime/execution/sql/__init__.py +0 -0
  16. elementary_runtime/execution/worker/__init__.py +0 -0
  17. elementary_runtime/protocol/__init__.py +162 -0
  18. elementary_runtime/protocol/base.py +82 -0
  19. elementary_runtime/protocol/enums.py +89 -0
  20. elementary_runtime/protocol/errors.py +28 -0
  21. elementary_runtime/protocol/http.py +15 -0
  22. elementary_runtime/protocol/instances.py +51 -0
  23. elementary_runtime/protocol/limits.py +18 -0
  24. elementary_runtime/protocol/tasks/__init__.py +80 -0
  25. elementary_runtime/protocol/tasks/custom_sql_test.py +35 -0
  26. elementary_runtime/protocol/tasks/envelope.py +20 -0
  27. elementary_runtime/protocol/tasks/heartbeat.py +34 -0
  28. elementary_runtime/protocol/tasks/poll.py +20 -0
  29. elementary_runtime/protocol/tasks/registry.py +35 -0
  30. elementary_runtime/protocol/tasks/results.py +30 -0
  31. elementary_runtime/protocol/tasks/run_sql.py +29 -0
  32. elementary_runtime/protocol/tasks/sql_query.py +102 -0
  33. elementary_runtime/protocol/telemetry.py +99 -0
  34. elementary_runtime/py.typed +0 -0
  35. elementary_runtime/warehouses/__init__.py +0 -0
  36. elementary_runtime-0.1.0rc1.dist-info/METADATA +95 -0
  37. elementary_runtime-0.1.0rc1.dist-info/RECORD +38 -0
  38. elementary_runtime-0.1.0rc1.dist-info/WHEEL +4 -0
@@ -0,0 +1,5 @@
1
+ from importlib.metadata import version
2
+
3
+ __version__ = version("elementary-runtime")
4
+
5
+ __all__ = ["__version__"]
File without changes
@@ -0,0 +1,27 @@
1
+ from collections.abc import Callable, Hashable, Sequence
2
+ from typing import TypeVar
3
+
4
+ T = TypeVar("T")
5
+ H = TypeVar("H", bound=Hashable)
6
+
7
+
8
+ def require_unique(items: Sequence[H]) -> list[H]:
9
+ seen: set[H] = set()
10
+ for item in items:
11
+ if item in seen:
12
+ raise ValueError("values must be unique")
13
+ seen.add(item)
14
+ return list(items)
15
+
16
+
17
+ def require_unique_attr(attr: str) -> Callable[[Sequence[T]], list[T]]:
18
+ def validator(items: Sequence[T]) -> list[T]:
19
+ seen: set[object] = set()
20
+ for item in items:
21
+ value = getattr(item, attr)
22
+ if value in seen:
23
+ raise ValueError(f"duplicate {attr} {value!r}")
24
+ seen.add(value)
25
+ return list(items)
26
+
27
+ return validator
@@ -0,0 +1,40 @@
1
+ from elementary_runtime.config.base import ConfigModel
2
+ from elementary_runtime.config.connections import (
3
+ SnowflakeConnectionConfig,
4
+ WarehouseConnection,
5
+ WarehouseConnectionConfig,
6
+ WarehouseType,
7
+ )
8
+ from elementary_runtime.config.errors import (
9
+ ConfigError,
10
+ InvalidPlaceholderError,
11
+ MissingEnvironmentVariableError,
12
+ )
13
+ from elementary_runtime.config.runtime import RuntimeConfig
14
+ from elementary_runtime.config.secrets import FileBacked, FileBackedSecret
15
+ from elementary_runtime.config.sections import (
16
+ DEFAULT_API_URL,
17
+ CloudConfig,
18
+ ConcurrencyConfig,
19
+ InstanceConfig,
20
+ LimitsConfig,
21
+ )
22
+
23
+ __all__ = [
24
+ "DEFAULT_API_URL",
25
+ "CloudConfig",
26
+ "ConcurrencyConfig",
27
+ "ConfigError",
28
+ "ConfigModel",
29
+ "FileBacked",
30
+ "FileBackedSecret",
31
+ "InstanceConfig",
32
+ "InvalidPlaceholderError",
33
+ "LimitsConfig",
34
+ "MissingEnvironmentVariableError",
35
+ "RuntimeConfig",
36
+ "SnowflakeConnectionConfig",
37
+ "WarehouseConnection",
38
+ "WarehouseConnectionConfig",
39
+ "WarehouseType",
40
+ ]
@@ -0,0 +1,19 @@
1
+ from typing import Any
2
+
3
+ from pydantic import BaseModel, ConfigDict, model_validator
4
+
5
+ from elementary_runtime.config.secrets import resolve_file_backed
6
+
7
+
8
+ class ConfigModel(BaseModel):
9
+ model_config = ConfigDict(
10
+ extra="forbid",
11
+ frozen=True,
12
+ allow_inf_nan=False,
13
+ validate_default=True,
14
+ )
15
+
16
+ @model_validator(mode="before")
17
+ @classmethod
18
+ def _resolve_file_backed(cls, data: Any) -> Any:
19
+ return resolve_file_backed(cls, data)
@@ -0,0 +1,55 @@
1
+ from enum import Enum
2
+ from typing import Annotated, Literal
3
+
4
+ from pydantic import Field, model_validator
5
+ from typing_extensions import Self
6
+
7
+ from elementary_runtime.config.base import ConfigModel
8
+ from elementary_runtime.config.secrets import FileBackedSecret
9
+ from elementary_runtime.protocol import IdStr, NonEmptyStr
10
+
11
+
12
+ class WarehouseType(str, Enum):
13
+ SNOWFLAKE = "snowflake"
14
+
15
+
16
+ class WarehouseConnectionConfig(ConfigModel):
17
+ warehouse_connection_id: Annotated[
18
+ IdStr, Field(description="Elementary Cloud connection id")
19
+ ]
20
+ type: WarehouseType
21
+
22
+
23
+ class SnowflakeConnectionConfig(WarehouseConnectionConfig):
24
+ type: Literal[WarehouseType.SNOWFLAKE] = WarehouseType.SNOWFLAKE
25
+ account: NonEmptyStr
26
+ user: NonEmptyStr
27
+ password: FileBackedSecret | None = None
28
+ private_key: Annotated[
29
+ FileBackedSecret | None, Field(description="key-pair auth")
30
+ ] = None
31
+ private_key_passphrase: FileBackedSecret | None = None
32
+ role: NonEmptyStr | None = None
33
+ warehouse: Annotated[
34
+ NonEmptyStr | None, Field(description="Snowflake compute warehouse")
35
+ ] = None
36
+
37
+ @model_validator(mode="after")
38
+ def _password_or_private_key(self) -> Self:
39
+ if self.password is None and self.private_key is None:
40
+ raise ValueError("password or private_key is required")
41
+ if self.password is not None and self.private_key is not None:
42
+ raise ValueError("password and private_key cannot both be set")
43
+ if self.private_key is not None and self.private_key_passphrase is None:
44
+ raise ValueError(
45
+ "private_key_passphrase is required when private_key is set"
46
+ )
47
+ if self.password is not None and self.private_key_passphrase is not None:
48
+ raise ValueError("private_key_passphrase cannot be set with password")
49
+ return self
50
+
51
+
52
+ WarehouseConnection = Annotated[
53
+ SnowflakeConnectionConfig,
54
+ Field(discriminator="type"),
55
+ ]
@@ -0,0 +1,66 @@
1
+ import os
2
+ from typing import Any
3
+
4
+ from expandvars import (
5
+ ExpandvarsException,
6
+ ParameterNullOrNotSet,
7
+ UnboundVariable,
8
+ expand,
9
+ )
10
+
11
+ from elementary_runtime.config.errors import (
12
+ InvalidPlaceholderError,
13
+ MissingEnvironmentVariableError,
14
+ )
15
+
16
+ # expandvars honors this as a process-wide escape hatch: when set, missing
17
+ # required variables are replaced with its value instead of raising. Strip it
18
+ # so a customer environment cannot silently weaken nounset.
19
+ _RECOVER_NULL = "EXPANDVARS_RECOVER_NULL"
20
+
21
+
22
+ def expand_env(value: Any, environ: dict[str, str] | None = None) -> Any:
23
+ env = dict(os.environ if environ is None else environ)
24
+ env.pop(_RECOVER_NULL, None)
25
+ return _expand(value, env)
26
+
27
+
28
+ def _expand(value: Any, environ: dict[str, str]) -> Any:
29
+ if isinstance(value, str):
30
+ return _expand_string(value, environ)
31
+ if isinstance(value, list):
32
+ return [_expand(item, environ) for item in value]
33
+ if isinstance(value, dict):
34
+ return {key: _expand(item, environ) for key, item in value.items()}
35
+ return value
36
+
37
+
38
+ def _exc_message(exc: BaseException) -> str:
39
+ if exc.args and isinstance(exc.args[0], str):
40
+ return exc.args[0]
41
+ return str(exc)
42
+
43
+
44
+ def _placeholder_name(exc: BaseException) -> tuple[str, str | None]:
45
+ name, sep, detail = _exc_message(exc).partition(": ")
46
+ if not sep or detail in {"unbound variable", "parameter null or not set"}:
47
+ return name, None
48
+ return name, detail
49
+
50
+
51
+ def _expand_string(value: str, environ: dict[str, str]) -> str:
52
+ try:
53
+ expanded = expand(
54
+ value,
55
+ nounset=True,
56
+ environ=environ,
57
+ surrounded_vars_only=True,
58
+ )
59
+ except (UnboundVariable, ParameterNullOrNotSet) as exc:
60
+ name, hint = _placeholder_name(exc)
61
+ raise MissingEnvironmentVariableError(name, hint) from exc
62
+ except ExpandvarsException as exc:
63
+ raise InvalidPlaceholderError(value, _exc_message(exc)) from exc
64
+ if not isinstance(expanded, str):
65
+ raise InvalidPlaceholderError(value, "expansion must produce a string")
66
+ return expanded
@@ -0,0 +1,20 @@
1
+ class ConfigError(Exception):
2
+ def __init__(self, message: str) -> None:
3
+ super().__init__(message)
4
+
5
+
6
+ class MissingEnvironmentVariableError(ConfigError):
7
+ def __init__(self, name: str, hint: str | None = None) -> None:
8
+ self.name = name
9
+ self.hint = hint
10
+ if hint is None:
11
+ super().__init__(f"missing environment variable {name}")
12
+ else:
13
+ super().__init__(f"missing environment variable {name}: {hint}")
14
+
15
+
16
+ class InvalidPlaceholderError(ConfigError):
17
+ def __init__(self, value: str, reason: str) -> None:
18
+ self.value = value
19
+ self.reason = reason
20
+ super().__init__(f"invalid placeholder in {value!r}: {reason}")
@@ -0,0 +1,60 @@
1
+ from collections.abc import Mapping
2
+ from pathlib import Path
3
+ from typing import Annotated, Any, Literal
4
+
5
+ import yaml
6
+ from pydantic import AfterValidator, Field, ValidationError
7
+ from typing_extensions import Self
8
+
9
+ from elementary_runtime.common.validators import require_unique_attr
10
+ from elementary_runtime.config.base import ConfigModel
11
+ from elementary_runtime.config.connections import WarehouseConnection
12
+ from elementary_runtime.config.env import expand_env
13
+ from elementary_runtime.config.errors import ConfigError
14
+ from elementary_runtime.config.sections import (
15
+ CloudConfig,
16
+ ConcurrencyConfig,
17
+ InstanceConfig,
18
+ LimitsConfig,
19
+ )
20
+
21
+
22
+ class RuntimeConfig(ConfigModel):
23
+ version: Literal[1]
24
+ cloud: CloudConfig
25
+ instance: InstanceConfig = Field(default_factory=InstanceConfig)
26
+ limits: LimitsConfig = Field(default_factory=LimitsConfig)
27
+ concurrency: ConcurrencyConfig = Field(default_factory=ConcurrencyConfig)
28
+ connections: Annotated[
29
+ list[WarehouseConnection],
30
+ Field(min_length=1),
31
+ AfterValidator(require_unique_attr("warehouse_connection_id")),
32
+ ]
33
+
34
+ @classmethod
35
+ def from_dict(cls, data: Mapping[str, Any]) -> Self:
36
+ try:
37
+ return cls.model_validate(data)
38
+ except ValidationError as exc:
39
+ raise ConfigError(str(exc)) from exc
40
+
41
+ @classmethod
42
+ def from_yaml(cls, path: str | Path) -> Self:
43
+ config_path = Path(path)
44
+ try:
45
+ raw = config_path.read_text(encoding="utf-8")
46
+ except OSError:
47
+ raise ConfigError(
48
+ f"unable to read configuration file {config_path}"
49
+ ) from None
50
+ try:
51
+ loaded = yaml.safe_load(raw)
52
+ except yaml.YAMLError as exc:
53
+ raise ConfigError(
54
+ f"invalid YAML in configuration file {config_path}: {exc}"
55
+ ) from exc
56
+ if loaded is None:
57
+ loaded = {}
58
+ if not isinstance(loaded, dict):
59
+ raise ConfigError("configuration root must be a mapping")
60
+ return cls.from_dict(expand_env(loaded))
@@ -0,0 +1,77 @@
1
+ from dataclasses import dataclass
2
+ from functools import cache
3
+ from pathlib import Path
4
+ from types import UnionType
5
+ from typing import Annotated, Any, Union, get_args, get_origin
6
+
7
+ from pydantic import AfterValidator, BaseModel, SecretStr
8
+
9
+ FILE_SUFFIX = "_file"
10
+
11
+
12
+ @dataclass(frozen=True, slots=True)
13
+ class FileBacked:
14
+ pass
15
+
16
+
17
+ def _require_non_empty_secret(value: SecretStr) -> SecretStr:
18
+ if not value.get_secret_value():
19
+ raise ValueError("value must not be empty")
20
+ return value
21
+
22
+
23
+ FileBackedSecret = Annotated[
24
+ SecretStr,
25
+ FileBacked(),
26
+ AfterValidator(_require_non_empty_secret),
27
+ ]
28
+
29
+
30
+ def read_secret_file(path: object) -> str:
31
+ if not isinstance(path, str) or not path:
32
+ raise ValueError("secret file path must be a non-empty string")
33
+ try:
34
+ return Path(path).read_text(encoding="utf-8").strip()
35
+ except OSError:
36
+ raise ValueError(f"unable to read secret file {path}") from None
37
+
38
+
39
+ def _has_file_backed(annotation: object) -> bool:
40
+ origin = get_origin(annotation)
41
+ if origin is Annotated:
42
+ args = get_args(annotation)
43
+ return any(isinstance(arg, FileBacked) for arg in args[1:]) or _has_file_backed(
44
+ args[0]
45
+ )
46
+ if origin in {Union, UnionType}:
47
+ return any(_has_file_backed(arg) for arg in get_args(annotation))
48
+ return False
49
+
50
+
51
+ @cache
52
+ def file_backed_field_names(cls: type[BaseModel]) -> tuple[str, ...]:
53
+ return tuple(
54
+ name
55
+ for name, field in cls.model_fields.items()
56
+ if any(isinstance(marker, FileBacked) for marker in field.metadata)
57
+ or _has_file_backed(field.annotation)
58
+ )
59
+
60
+
61
+ def resolve_file_backed(cls: type[BaseModel], data: Any) -> Any:
62
+ if not isinstance(data, dict):
63
+ return data
64
+ names = file_backed_field_names(cls)
65
+ if not names:
66
+ return data
67
+ resolved = dict(data)
68
+ for name in names:
69
+ file_key = f"{name}{FILE_SUFFIX}"
70
+ has_value = name in resolved
71
+ has_file = file_key in resolved
72
+ if has_value and has_file:
73
+ raise ValueError(f"{name} and {file_key} cannot both be set")
74
+ if not has_file:
75
+ continue
76
+ resolved[name] = read_secret_file(resolved.pop(file_key))
77
+ return resolved
@@ -0,0 +1,98 @@
1
+ from typing import Annotated
2
+
3
+ from pydantic import Field, HttpUrl, TypeAdapter, model_validator
4
+ from typing_extensions import Self
5
+
6
+ from elementary_runtime.config.base import ConfigModel
7
+ from elementary_runtime.config.secrets import FileBackedSecret
8
+ from elementary_runtime.protocol import DisplayName, InstanceIdPrefix
9
+ from elementary_runtime.protocol.limits import (
10
+ MAX_POLL_TASKS,
11
+ MAX_QUERY_TIMEOUT_SECONDS,
12
+ MAX_SAMPLE_ROW_LIMIT,
13
+ )
14
+
15
+ DEFAULT_API_URL = "https://app.elementary-data.com/runtime/v1"
16
+ _DEFAULT_API_URL = TypeAdapter(HttpUrl).validate_python(DEFAULT_API_URL)
17
+ DEFAULT_MAX_QUERY_TIMEOUT_SECONDS = 300
18
+ DEFAULT_MAX_RESULT_BYTES = 10_485_760
19
+ DEFAULT_MAX_SAMPLE_ROWS_RETURNED = 1000
20
+ DEFAULT_MAX_CONCURRENT_TASKS = 8
21
+ DEFAULT_POLL_INTERVAL_SECONDS = 10
22
+ DEFAULT_HEARTBEAT_INTERVAL_SECONDS = 30
23
+
24
+ MAX_QUERY_TIMEOUT_SECONDS_LIMIT = MAX_QUERY_TIMEOUT_SECONDS
25
+ MAX_RESULT_BYTES_LIMIT = 1_073_741_824
26
+ MAX_SAMPLE_ROWS_RETURNED_LIMIT = MAX_SAMPLE_ROW_LIMIT
27
+ MAX_CONCURRENT_TASKS_LIMIT = 256
28
+ POLL_INTERVAL_SECONDS_LIMIT = 3_600
29
+ HEARTBEAT_INTERVAL_SECONDS_LIMIT = 3_600
30
+
31
+
32
+ class CloudConfig(ConfigModel):
33
+ api_url: Annotated[HttpUrl, Field(description="Elementary Cloud runtime API")] = (
34
+ _DEFAULT_API_URL
35
+ )
36
+ token: FileBackedSecret
37
+
38
+
39
+ class InstanceConfig(ConfigModel):
40
+ id_prefix: Annotated[
41
+ InstanceIdPrefix | None,
42
+ Field(description="prepended to the generated instance id"),
43
+ ] = None
44
+ display_name: DisplayName | None = None
45
+
46
+
47
+ class LimitsConfig(ConfigModel):
48
+ max_query_timeout_seconds: Annotated[
49
+ int, Field(ge=1, le=MAX_QUERY_TIMEOUT_SECONDS_LIMIT)
50
+ ] = DEFAULT_MAX_QUERY_TIMEOUT_SECONDS
51
+ max_result_bytes: Annotated[
52
+ int,
53
+ Field(
54
+ ge=1,
55
+ le=MAX_RESULT_BYTES_LIMIT,
56
+ description="encoded result payload sent to Cloud",
57
+ ),
58
+ ] = DEFAULT_MAX_RESULT_BYTES
59
+ max_sample_rows_returned: Annotated[
60
+ int,
61
+ Field(
62
+ ge=0,
63
+ le=MAX_SAMPLE_ROWS_RETURNED_LIMIT,
64
+ description="rows included in the result sample",
65
+ ),
66
+ ] = DEFAULT_MAX_SAMPLE_ROWS_RETURNED
67
+
68
+
69
+ class ConcurrencyConfig(ConfigModel):
70
+ max_concurrent_tasks: Annotated[int, Field(ge=1, le=MAX_CONCURRENT_TASKS_LIMIT)] = (
71
+ DEFAULT_MAX_CONCURRENT_TASKS
72
+ )
73
+ prefetch_count: Annotated[
74
+ int, Field(ge=1, le=MAX_POLL_TASKS, description="tasks requested per poll")
75
+ ] = DEFAULT_MAX_CONCURRENT_TASKS
76
+ poll_interval_seconds: Annotated[
77
+ int, Field(ge=1, le=POLL_INTERVAL_SECONDS_LIMIT)
78
+ ] = DEFAULT_POLL_INTERVAL_SECONDS
79
+ heartbeat_interval_seconds: Annotated[
80
+ int, Field(ge=1, le=HEARTBEAT_INTERVAL_SECONDS_LIMIT)
81
+ ] = DEFAULT_HEARTBEAT_INTERVAL_SECONDS
82
+
83
+ @model_validator(mode="before")
84
+ @classmethod
85
+ def _default_prefetch_count(cls, data: object) -> object:
86
+ if not isinstance(data, dict):
87
+ return data
88
+ data = dict(data)
89
+ if data.get("prefetch_count") is None:
90
+ max_tasks = data.get("max_concurrent_tasks", DEFAULT_MAX_CONCURRENT_TASKS)
91
+ data["prefetch_count"] = max_tasks
92
+ return data
93
+
94
+ @model_validator(mode="after")
95
+ def _prefetch_within_capacity(self) -> Self:
96
+ if self.prefetch_count > self.max_concurrent_tasks:
97
+ raise ValueError("prefetch_count cannot exceed max_concurrent_tasks")
98
+ return self
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,162 @@
1
+ from elementary_runtime.protocol.base import (
2
+ DisplayName,
3
+ ErrorMessage,
4
+ IdStr,
5
+ InstanceId,
6
+ InstanceIdPrefix,
7
+ NonEmptyStr,
8
+ ProtocolEnum,
9
+ ProtocolModel,
10
+ UtcDatetime,
11
+ )
12
+ from elementary_runtime.protocol.enums import (
13
+ ConnectionErrorCode,
14
+ ConnectionHealth,
15
+ ErrorCode,
16
+ ExceptionComponent,
17
+ ExceptionOperation,
18
+ HeartbeatStatus,
19
+ RuntimeStopReason,
20
+ SubmittedResultStatus,
21
+ TaskExecutionOutcome,
22
+ TaskType,
23
+ TelemetryEventType,
24
+ TestSourceType,
25
+ )
26
+ from elementary_runtime.protocol.errors import (
27
+ ErrorBody,
28
+ ErrorDetails,
29
+ ErrorResponse,
30
+ TaskErrorDetail,
31
+ )
32
+ from elementary_runtime.protocol.http import Headers, Paths
33
+ from elementary_runtime.protocol.instances import (
34
+ ConnectionReport,
35
+ ObservedWarehouseIdentity,
36
+ RegisterInstanceRequest,
37
+ )
38
+ from elementary_runtime.protocol.tasks import (
39
+ TASK_MODELS,
40
+ CloudTestSource,
41
+ CustomSqlTestResult,
42
+ CustomSqlTestResultPayload,
43
+ CustomSqlTestTask,
44
+ CustomSqlTestTaskPayload,
45
+ HeartbeatTasksRequest,
46
+ HeartbeatTasksResponse,
47
+ PollTasksRequest,
48
+ PollTasksResponse,
49
+ ResultSample,
50
+ RunSqlResult,
51
+ RunSqlResultPayload,
52
+ RunSqlTask,
53
+ RunSqlTaskPayload,
54
+ SampleColumnType,
55
+ SampleHeader,
56
+ SqlExecutionStatus,
57
+ SqlQueryResultPayload,
58
+ SqlQueryTaskPayload,
59
+ SubmitResultsRequest,
60
+ SubmitResultsResponse,
61
+ SubmittedResult,
62
+ Task,
63
+ TaskEnvelope,
64
+ TaskHeartbeat,
65
+ TaskHeartbeatStatus,
66
+ TaskModels,
67
+ TaskResult,
68
+ TaskResultEnvelope,
69
+ WarehouseTaskEnvelope,
70
+ )
71
+ from elementary_runtime.protocol.telemetry import (
72
+ ExceptionFrame,
73
+ RuntimeExceptionEvent,
74
+ RuntimeExceptionFields,
75
+ RuntimeStartedEvent,
76
+ RuntimeStartedFields,
77
+ RuntimeStoppedEvent,
78
+ RuntimeStoppedFields,
79
+ TaskExecutionSummaryEvent,
80
+ TaskExecutionSummaryFields,
81
+ TelemetryEvent,
82
+ TelemetryEventBase,
83
+ TelemetryRequest,
84
+ TelemetryResponse,
85
+ )
86
+
87
+ __all__ = [
88
+ "TASK_MODELS",
89
+ "CloudTestSource",
90
+ "ConnectionErrorCode",
91
+ "ConnectionHealth",
92
+ "ConnectionReport",
93
+ "CustomSqlTestResult",
94
+ "CustomSqlTestResultPayload",
95
+ "CustomSqlTestTask",
96
+ "CustomSqlTestTaskPayload",
97
+ "DisplayName",
98
+ "ErrorBody",
99
+ "ErrorCode",
100
+ "ErrorDetails",
101
+ "ErrorMessage",
102
+ "ErrorResponse",
103
+ "ExceptionComponent",
104
+ "ExceptionFrame",
105
+ "ExceptionOperation",
106
+ "Headers",
107
+ "HeartbeatStatus",
108
+ "HeartbeatTasksRequest",
109
+ "HeartbeatTasksResponse",
110
+ "IdStr",
111
+ "InstanceId",
112
+ "InstanceIdPrefix",
113
+ "NonEmptyStr",
114
+ "ObservedWarehouseIdentity",
115
+ "Paths",
116
+ "PollTasksRequest",
117
+ "PollTasksResponse",
118
+ "ProtocolEnum",
119
+ "ProtocolModel",
120
+ "RegisterInstanceRequest",
121
+ "ResultSample",
122
+ "RunSqlResult",
123
+ "RunSqlResultPayload",
124
+ "RunSqlTask",
125
+ "RunSqlTaskPayload",
126
+ "RuntimeExceptionEvent",
127
+ "RuntimeExceptionFields",
128
+ "RuntimeStartedEvent",
129
+ "RuntimeStartedFields",
130
+ "RuntimeStopReason",
131
+ "RuntimeStoppedEvent",
132
+ "RuntimeStoppedFields",
133
+ "SampleColumnType",
134
+ "SampleHeader",
135
+ "SqlExecutionStatus",
136
+ "SqlQueryResultPayload",
137
+ "SqlQueryTaskPayload",
138
+ "SubmitResultsRequest",
139
+ "SubmitResultsResponse",
140
+ "SubmittedResult",
141
+ "SubmittedResultStatus",
142
+ "Task",
143
+ "TaskEnvelope",
144
+ "TaskErrorDetail",
145
+ "TaskExecutionOutcome",
146
+ "TaskExecutionSummaryEvent",
147
+ "TaskExecutionSummaryFields",
148
+ "TaskHeartbeat",
149
+ "TaskHeartbeatStatus",
150
+ "TaskModels",
151
+ "TaskResult",
152
+ "TaskResultEnvelope",
153
+ "TaskType",
154
+ "TelemetryEvent",
155
+ "TelemetryEventBase",
156
+ "TelemetryEventType",
157
+ "TelemetryRequest",
158
+ "TelemetryResponse",
159
+ "TestSourceType",
160
+ "UtcDatetime",
161
+ "WarehouseTaskEnvelope",
162
+ ]