great-expectations-cloud 20250912.0.dev3__tar.gz → 20250915.0.dev0__tar.gz
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.
Potentially problematic release.
This version of great-expectations-cloud might be problematic. Click here for more details.
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/PKG-INFO +1 -1
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/draft_datasource_config_action.py +12 -6
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/generate_data_quality_check_expectations_action.py +9 -6
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/list_asset_names.py +9 -6
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/run_scheduled_checkpoint.py +2 -4
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/run_window_checkpoint.py +2 -4
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/agent.py +58 -32
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/models.py +1 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/pyproject.toml +1 -1
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/LICENSE +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/README.md +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/__init__.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/__init__.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/__init__.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/agent_action.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/run_checkpoint.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/run_metric_list_action.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/unknown.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/actions/utils.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/agent_warnings.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/cli.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/config.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/constants.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/event_handler.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/exceptions.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/message_service/__init__.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/message_service/asyncio_rabbit_mq_client.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/message_service/subscriber.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/run.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/agent/utils.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/logging/README.md +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/logging/logging_cfg.py +0 -0
- {great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/great_expectations_cloud/py.typed +0 -0
|
@@ -40,7 +40,9 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
|
|
|
40
40
|
def check_draft_datasource_config(
|
|
41
41
|
self, event: DraftDatasourceConfigEvent, id: str
|
|
42
42
|
) -> ActionResult:
|
|
43
|
-
draft_config = self.get_draft_config(
|
|
43
|
+
draft_config = self.get_draft_config(
|
|
44
|
+
config_id=event.config_id, workspace_id=event.workspace_id
|
|
45
|
+
)
|
|
44
46
|
datasource_type = draft_config.get("type", None)
|
|
45
47
|
if datasource_type is None:
|
|
46
48
|
raise TypeError( # noqa: TRY003 # one off error
|
|
@@ -58,7 +60,9 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
|
|
|
58
60
|
|
|
59
61
|
if isinstance(datasource, SQLDatasource):
|
|
60
62
|
asset_names = get_asset_names(datasource)
|
|
61
|
-
self._update_asset_names_list(
|
|
63
|
+
self._update_asset_names_list(
|
|
64
|
+
config_id=event.config_id, workspace_id=event.workspace_id, asset_names=asset_names
|
|
65
|
+
)
|
|
62
66
|
|
|
63
67
|
return ActionResult(
|
|
64
68
|
id=id,
|
|
@@ -66,11 +70,13 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
|
|
|
66
70
|
created_resources=[],
|
|
67
71
|
)
|
|
68
72
|
|
|
69
|
-
def _update_asset_names_list(
|
|
73
|
+
def _update_asset_names_list(
|
|
74
|
+
self, config_id: UUID, workspace_id: UUID, asset_names: list[str]
|
|
75
|
+
) -> None:
|
|
70
76
|
with create_session(access_token=self._auth_key) as session:
|
|
71
77
|
url = urljoin(
|
|
72
78
|
base=self._base_url,
|
|
73
|
-
url=f"/api/v1/organizations/{self._organization_id}/draft-table-names/{config_id}",
|
|
79
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{workspace_id}/draft-table-names/{config_id}",
|
|
74
80
|
)
|
|
75
81
|
response = session.put(
|
|
76
82
|
url=url,
|
|
@@ -84,10 +90,10 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
|
|
|
84
90
|
f"={config_id}.",
|
|
85
91
|
)
|
|
86
92
|
|
|
87
|
-
def get_draft_config(self, config_id: UUID) -> dict[str, Any]:
|
|
93
|
+
def get_draft_config(self, config_id: UUID, workspace_id: UUID) -> dict[str, Any]:
|
|
88
94
|
resource_url = urljoin(
|
|
89
95
|
base=self._base_url,
|
|
90
|
-
url=f"/api/v1/organizations/{self._organization_id}/draft-datasources/{config_id}",
|
|
96
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{workspace_id}/draft-datasources/{config_id}",
|
|
91
97
|
)
|
|
92
98
|
with create_session(access_token=self._auth_key) as session:
|
|
93
99
|
response = session.get(resource_url)
|
|
@@ -10,7 +10,10 @@ from uuid import UUID
|
|
|
10
10
|
|
|
11
11
|
import great_expectations.expectations as gx_expectations
|
|
12
12
|
from great_expectations.core.http import create_session
|
|
13
|
-
from great_expectations.exceptions import
|
|
13
|
+
from great_expectations.exceptions import (
|
|
14
|
+
GXCloudError,
|
|
15
|
+
InvalidExpectationConfigurationError,
|
|
16
|
+
)
|
|
14
17
|
from great_expectations.expectations.metadata_types import (
|
|
15
18
|
DataQualityIssues,
|
|
16
19
|
FailureSeverity,
|
|
@@ -49,9 +52,7 @@ from great_expectations_cloud.agent.utils import (
|
|
|
49
52
|
)
|
|
50
53
|
|
|
51
54
|
if TYPE_CHECKING:
|
|
52
|
-
from great_expectations.core.suite_parameters import
|
|
53
|
-
SuiteParameterDict,
|
|
54
|
-
)
|
|
55
|
+
from great_expectations.core.suite_parameters import SuiteParameterDict
|
|
55
56
|
from great_expectations.data_context import CloudDataContext
|
|
56
57
|
from great_expectations.datasource.fluent import DataAsset
|
|
57
58
|
|
|
@@ -99,6 +100,8 @@ class GenerateDataQualityCheckExpectationsAction(
|
|
|
99
100
|
|
|
100
101
|
@override
|
|
101
102
|
def run(self, event: GenerateDataQualityCheckExpectationsEvent, id: str) -> ActionResult:
|
|
103
|
+
self._workspace_id = event.workspace_id
|
|
104
|
+
|
|
102
105
|
created_resources: list[CreatedResource] = []
|
|
103
106
|
assets_with_errors: list[str] = []
|
|
104
107
|
selected_dqis: Sequence[DataQualityIssues] = event.selected_data_quality_issues or []
|
|
@@ -222,7 +225,7 @@ class GenerateDataQualityCheckExpectationsAction(
|
|
|
222
225
|
"""
|
|
223
226
|
url = urljoin(
|
|
224
227
|
base=self._base_url,
|
|
225
|
-
url=f"/api/v1/organizations/{self._organization_id}/expectations/",
|
|
228
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{self._workspace_id}/expectations/",
|
|
226
229
|
)
|
|
227
230
|
with create_session(access_token=self._auth_key) as session:
|
|
228
231
|
response = session.get(
|
|
@@ -524,7 +527,7 @@ class GenerateDataQualityCheckExpectationsAction(
|
|
|
524
527
|
) -> UUID:
|
|
525
528
|
url = urljoin(
|
|
526
529
|
base=self._base_url,
|
|
527
|
-
url=f"/api/v1/organizations/{self._organization_id}/expectations/{asset_id}",
|
|
530
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{self._workspace_id}/expectations/{asset_id}",
|
|
528
531
|
)
|
|
529
532
|
|
|
530
533
|
expectation_payload = expectation.configuration.to_json_dict()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from urllib.parse import urljoin
|
|
4
|
+
from uuid import UUID
|
|
4
5
|
|
|
5
6
|
from great_expectations.core.http import create_session
|
|
6
7
|
from great_expectations.datasource.fluent import SQLDatasource
|
|
@@ -13,9 +14,7 @@ from great_expectations_cloud.agent.actions.agent_action import (
|
|
|
13
14
|
)
|
|
14
15
|
from great_expectations_cloud.agent.actions.utils import get_asset_names
|
|
15
16
|
from great_expectations_cloud.agent.event_handler import register_event_action
|
|
16
|
-
from great_expectations_cloud.agent.models import
|
|
17
|
-
ListAssetNamesEvent,
|
|
18
|
-
)
|
|
17
|
+
from great_expectations_cloud.agent.models import ListAssetNamesEvent
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
class ListAssetNamesAction(AgentAction[ListAssetNamesEvent]):
|
|
@@ -34,7 +33,9 @@ class ListAssetNamesAction(AgentAction[ListAssetNamesEvent]):
|
|
|
34
33
|
asset_names = get_asset_names(datasource)
|
|
35
34
|
|
|
36
35
|
self._add_or_update_asset_names_list(
|
|
37
|
-
datasource_id=str(datasource.id),
|
|
36
|
+
datasource_id=str(datasource.id),
|
|
37
|
+
workspace_id=event.workspace_id,
|
|
38
|
+
asset_names=asset_names,
|
|
38
39
|
)
|
|
39
40
|
|
|
40
41
|
return ActionResult(
|
|
@@ -43,11 +44,13 @@ class ListAssetNamesAction(AgentAction[ListAssetNamesEvent]):
|
|
|
43
44
|
created_resources=[],
|
|
44
45
|
)
|
|
45
46
|
|
|
46
|
-
def _add_or_update_asset_names_list(
|
|
47
|
+
def _add_or_update_asset_names_list(
|
|
48
|
+
self, datasource_id: str, workspace_id: UUID, asset_names: list[str]
|
|
49
|
+
) -> None:
|
|
47
50
|
with create_session(access_token=self._auth_key) as session:
|
|
48
51
|
url = urljoin(
|
|
49
52
|
base=self._base_url,
|
|
50
|
-
url=f"/api/v1/organizations/{self._organization_id}/table-names/{datasource_id}",
|
|
53
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{workspace_id}/table-names/{datasource_id}",
|
|
51
54
|
)
|
|
52
55
|
response = session.put(
|
|
53
56
|
url=url,
|
|
@@ -13,9 +13,7 @@ from great_expectations_cloud.agent.actions.agent_action import (
|
|
|
13
13
|
)
|
|
14
14
|
from great_expectations_cloud.agent.actions.run_checkpoint import run_checkpoint
|
|
15
15
|
from great_expectations_cloud.agent.event_handler import register_event_action
|
|
16
|
-
from great_expectations_cloud.agent.models import
|
|
17
|
-
RunScheduledCheckpointEvent,
|
|
18
|
-
)
|
|
16
|
+
from great_expectations_cloud.agent.models import RunScheduledCheckpointEvent
|
|
19
17
|
|
|
20
18
|
if TYPE_CHECKING:
|
|
21
19
|
from great_expectations.data_context import CloudDataContext
|
|
@@ -26,7 +24,7 @@ class RunScheduledCheckpointAction(AgentAction[RunScheduledCheckpointEvent]):
|
|
|
26
24
|
def run(self, event: RunScheduledCheckpointEvent, id: str) -> ActionResult:
|
|
27
25
|
expectation_parameters_url = urljoin(
|
|
28
26
|
base=self._base_url,
|
|
29
|
-
url=f"/api/v1/organizations/{self._organization_id}/checkpoints/{event.checkpoint_id}/expectation-parameters",
|
|
27
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{event.workspace_id}/checkpoints/{event.checkpoint_id}/expectation-parameters",
|
|
30
28
|
)
|
|
31
29
|
return run_scheduled_checkpoint(
|
|
32
30
|
context=self._context,
|
|
@@ -13,9 +13,7 @@ from great_expectations_cloud.agent.actions.agent_action import (
|
|
|
13
13
|
)
|
|
14
14
|
from great_expectations_cloud.agent.actions.run_checkpoint import run_checkpoint
|
|
15
15
|
from great_expectations_cloud.agent.event_handler import register_event_action
|
|
16
|
-
from great_expectations_cloud.agent.models import
|
|
17
|
-
RunWindowCheckpointEvent,
|
|
18
|
-
)
|
|
16
|
+
from great_expectations_cloud.agent.models import RunWindowCheckpointEvent
|
|
19
17
|
|
|
20
18
|
if TYPE_CHECKING:
|
|
21
19
|
from great_expectations.data_context import CloudDataContext
|
|
@@ -26,7 +24,7 @@ class RunWindowCheckpointAction(AgentAction[RunWindowCheckpointEvent]):
|
|
|
26
24
|
def run(self, event: RunWindowCheckpointEvent, id: str) -> ActionResult:
|
|
27
25
|
expectation_parameters_url = urljoin(
|
|
28
26
|
base=self._base_url,
|
|
29
|
-
url=f"/api/v1/organizations/{self._organization_id}/checkpoints/{event.checkpoint_id}/expectation-parameters",
|
|
27
|
+
url=f"/api/v1/organizations/{self._organization_id}/workspaces/{event.workspace_id}/checkpoints/{event.checkpoint_id}/expectation-parameters",
|
|
30
28
|
)
|
|
31
29
|
return run_window_checkpoint(
|
|
32
30
|
self._context,
|
|
@@ -17,13 +17,12 @@ from uuid import UUID
|
|
|
17
17
|
|
|
18
18
|
import orjson
|
|
19
19
|
import requests
|
|
20
|
+
from great_expectations import __version__, get_context
|
|
21
|
+
from great_expectations.core import http
|
|
20
22
|
from great_expectations.core.http import create_session
|
|
21
23
|
from great_expectations.data_context.cloud_constants import CLOUD_DEFAULT_BASE_URL
|
|
22
|
-
from great_expectations.data_context.data_context.context_factory import get_context
|
|
23
24
|
from great_expectations.data_context.types.base import ProgressBarsConfig
|
|
24
|
-
from pika.adapters.utils.connection_workflow import
|
|
25
|
-
AMQPConnectorException,
|
|
26
|
-
)
|
|
25
|
+
from pika.adapters.utils.connection_workflow import AMQPConnectorException
|
|
27
26
|
from pika.exceptions import (
|
|
28
27
|
AMQPConnectionError,
|
|
29
28
|
AMQPError,
|
|
@@ -46,9 +45,7 @@ from great_expectations_cloud.agent.config import (
|
|
|
46
45
|
generate_config_validation_error_text,
|
|
47
46
|
)
|
|
48
47
|
from great_expectations_cloud.agent.constants import USER_AGENT_HEADER, HeaderName
|
|
49
|
-
from great_expectations_cloud.agent.event_handler import
|
|
50
|
-
EventHandler,
|
|
51
|
-
)
|
|
48
|
+
from great_expectations_cloud.agent.event_handler import EventHandler
|
|
52
49
|
from great_expectations_cloud.agent.exceptions import (
|
|
53
50
|
GXAgentConfigError,
|
|
54
51
|
GXAgentError,
|
|
@@ -151,19 +148,6 @@ class GXAgent:
|
|
|
151
148
|
"great_expectations_version": great_expectations_version,
|
|
152
149
|
},
|
|
153
150
|
)
|
|
154
|
-
LOGGER.debug("Loading a DataContext - this might take a moment.")
|
|
155
|
-
|
|
156
|
-
with warnings.catch_warnings():
|
|
157
|
-
# suppress warnings about GX version
|
|
158
|
-
warnings.filterwarnings("ignore", message="You are using great_expectations version")
|
|
159
|
-
self._context: CloudDataContext = get_context(
|
|
160
|
-
cloud_mode=True,
|
|
161
|
-
user_agent_str=self.user_agent_str,
|
|
162
|
-
)
|
|
163
|
-
self._configure_progress_bars(data_context=self._context)
|
|
164
|
-
LOGGER.debug("DataContext is ready.")
|
|
165
|
-
|
|
166
|
-
self._set_http_session_headers(data_context=self._context)
|
|
167
151
|
|
|
168
152
|
# Create a thread pool with a single worker, so we can run long-lived
|
|
169
153
|
# GX processes and maintain our connection to the broker. Note that
|
|
@@ -264,6 +248,7 @@ class GXAgent:
|
|
|
264
248
|
"event_type": event_context.event.type,
|
|
265
249
|
"correlation_id": event_context.correlation_id,
|
|
266
250
|
"organization_id": self.get_organization_id(event_context),
|
|
251
|
+
"workspace_id": str(self.get_workspace_id(event_context)),
|
|
267
252
|
"schedule_id": event_context.event.schedule_id
|
|
268
253
|
if isinstance(event_context.event, ScheduledEventBase)
|
|
269
254
|
else None,
|
|
@@ -288,8 +273,23 @@ class GXAgent:
|
|
|
288
273
|
self._current_task.add_done_callback(on_exit_callback)
|
|
289
274
|
|
|
290
275
|
def get_data_context(self, event_context: EventContext) -> CloudDataContext:
|
|
291
|
-
"""
|
|
292
|
-
|
|
276
|
+
"""Create a new CloudDataContext for each job using the event's workspace_id."""
|
|
277
|
+
with warnings.catch_warnings():
|
|
278
|
+
warnings.filterwarnings("ignore", message="You are using great_expectations version")
|
|
279
|
+
workspace_id = self.get_workspace_id(event_context)
|
|
280
|
+
|
|
281
|
+
LOGGER.debug("Loading a DataContext - this might take a moment.")
|
|
282
|
+
|
|
283
|
+
context: CloudDataContext = get_context(
|
|
284
|
+
cloud_mode=True,
|
|
285
|
+
user_agent_str=self.user_agent_str,
|
|
286
|
+
cloud_workspace_id=str(workspace_id),
|
|
287
|
+
)
|
|
288
|
+
self._configure_progress_bars(data_context=context)
|
|
289
|
+
|
|
290
|
+
LOGGER.debug("DataContext is ready.")
|
|
291
|
+
|
|
292
|
+
return context
|
|
293
293
|
|
|
294
294
|
def get_organization_id(self, event_context: EventContext) -> UUID:
|
|
295
295
|
"""Helper method to get the organization ID. Overridden in GX-Runner."""
|
|
@@ -299,6 +299,13 @@ class GXAgent:
|
|
|
299
299
|
"""Helper method to get the auth key. Overridden in GX-Runner."""
|
|
300
300
|
return self._get_config().gx_cloud_access_token
|
|
301
301
|
|
|
302
|
+
def get_workspace_id(self, event_context: EventContext) -> UUID:
|
|
303
|
+
"""Helper method to get the workspace ID from the event."""
|
|
304
|
+
workspace_id: UUID | None = getattr(event_context.event, "workspace_id", None)
|
|
305
|
+
if workspace_id is None:
|
|
306
|
+
raise GXAgentError()
|
|
307
|
+
return workspace_id
|
|
308
|
+
|
|
302
309
|
def _set_sentry_tags(self, even_context: EventContext) -> None:
|
|
303
310
|
"""Used by GX-Runner to set tags for Sentry logging. No-op in the Agent."""
|
|
304
311
|
pass
|
|
@@ -321,14 +328,18 @@ class GXAgent:
|
|
|
321
328
|
)
|
|
322
329
|
|
|
323
330
|
org_id = self.get_organization_id(event_context)
|
|
331
|
+
workspace_id = self.get_workspace_id(event_context)
|
|
324
332
|
base_url = self._get_config().gx_cloud_base_url
|
|
325
333
|
auth_key = self.get_auth_key()
|
|
326
334
|
|
|
327
335
|
if isinstance(event_context.event, ScheduledEventBase):
|
|
328
|
-
self._create_scheduled_job_and_set_started(event_context, org_id)
|
|
336
|
+
self._create_scheduled_job_and_set_started(event_context, org_id, workspace_id)
|
|
329
337
|
else:
|
|
330
338
|
self._update_status(
|
|
331
|
-
correlation_id=event_context.correlation_id,
|
|
339
|
+
correlation_id=event_context.correlation_id,
|
|
340
|
+
status=JobStarted(),
|
|
341
|
+
org_id=org_id,
|
|
342
|
+
workspace_id=workspace_id,
|
|
332
343
|
)
|
|
333
344
|
LOGGER.info(
|
|
334
345
|
"Starting job",
|
|
@@ -336,6 +347,7 @@ class GXAgent:
|
|
|
336
347
|
"event_type": event_context.event.type,
|
|
337
348
|
"correlation_id": event_context.correlation_id,
|
|
338
349
|
"organization_id": str(org_id),
|
|
350
|
+
"workspace_id": str(workspace_id),
|
|
339
351
|
"schedule_id": event_context.event.schedule_id
|
|
340
352
|
if isinstance(event_context.event, ScheduledEventBase)
|
|
341
353
|
else None,
|
|
@@ -367,6 +379,7 @@ class GXAgent:
|
|
|
367
379
|
# warning: this method will not be executed in the main thread
|
|
368
380
|
|
|
369
381
|
org_id = self.get_organization_id(event_context)
|
|
382
|
+
workspace_id = self.get_workspace_id(event_context)
|
|
370
383
|
|
|
371
384
|
# get results or errors from the thread
|
|
372
385
|
error = future.exception()
|
|
@@ -386,6 +399,7 @@ class GXAgent:
|
|
|
386
399
|
"event_type": event_context.event.type,
|
|
387
400
|
"id": event_context.correlation_id,
|
|
388
401
|
"organization_id": str(org_id),
|
|
402
|
+
"workspace_id": str(workspace_id),
|
|
389
403
|
"schedule_id": event_context.event.schedule_id
|
|
390
404
|
if isinstance(event_context.event, ScheduledEventBase)
|
|
391
405
|
else None,
|
|
@@ -406,6 +420,7 @@ class GXAgent:
|
|
|
406
420
|
result.job_duration.total_seconds() if result.job_duration else None
|
|
407
421
|
),
|
|
408
422
|
"organization_id": str(org_id),
|
|
423
|
+
"workspace_id": str(workspace_id),
|
|
409
424
|
"schedule_id": event_context.event.schedule_id
|
|
410
425
|
if isinstance(event_context.event, ScheduledEventBase)
|
|
411
426
|
else None,
|
|
@@ -420,12 +435,16 @@ class GXAgent:
|
|
|
420
435
|
"event_type": event_context.event.type,
|
|
421
436
|
"correlation_id": event_context.correlation_id,
|
|
422
437
|
"organization_id": str(org_id),
|
|
438
|
+
"workspace_id": str(workspace_id),
|
|
423
439
|
},
|
|
424
440
|
)
|
|
425
441
|
|
|
426
442
|
try:
|
|
427
443
|
self._update_status(
|
|
428
|
-
correlation_id=event_context.correlation_id,
|
|
444
|
+
correlation_id=event_context.correlation_id,
|
|
445
|
+
status=status,
|
|
446
|
+
org_id=org_id,
|
|
447
|
+
workspace_id=workspace_id,
|
|
429
448
|
)
|
|
430
449
|
except Exception:
|
|
431
450
|
LOGGER.exception(
|
|
@@ -434,6 +453,7 @@ class GXAgent:
|
|
|
434
453
|
"correlation_id": event_context.correlation_id,
|
|
435
454
|
"status": str(status),
|
|
436
455
|
"organization_id": str(org_id),
|
|
456
|
+
"workspace_id": str(workspace_id),
|
|
437
457
|
},
|
|
438
458
|
)
|
|
439
459
|
# We do not want to cause an infinite loop of errors
|
|
@@ -553,7 +573,9 @@ class GXAgent:
|
|
|
553
573
|
)
|
|
554
574
|
)
|
|
555
575
|
|
|
556
|
-
def _update_status(
|
|
576
|
+
def _update_status(
|
|
577
|
+
self, correlation_id: str, status: JobStatus, org_id: UUID, workspace_id: UUID
|
|
578
|
+
) -> None:
|
|
557
579
|
"""Update GX Cloud on the status of a job.
|
|
558
580
|
|
|
559
581
|
Args:
|
|
@@ -566,11 +588,12 @@ class GXAgent:
|
|
|
566
588
|
"correlation_id": correlation_id,
|
|
567
589
|
"status": str(status),
|
|
568
590
|
"organization_id": str(org_id),
|
|
591
|
+
"workspace_id": str(workspace_id),
|
|
569
592
|
},
|
|
570
593
|
)
|
|
571
594
|
agent_sessions_url = urljoin(
|
|
572
595
|
self._get_config().gx_cloud_base_url,
|
|
573
|
-
f"/api/v1/organizations/{org_id}/agent-jobs/{correlation_id}",
|
|
596
|
+
f"/api/v1/organizations/{org_id}/workspaces/{workspace_id}/agent-jobs/{correlation_id}",
|
|
574
597
|
)
|
|
575
598
|
with create_session(access_token=self.get_auth_key()) as session:
|
|
576
599
|
data = UpdateJobStatusRequest(data=status).json()
|
|
@@ -581,6 +604,7 @@ class GXAgent:
|
|
|
581
604
|
"correlation_id": correlation_id,
|
|
582
605
|
"status": str(status),
|
|
583
606
|
"organization_id": str(org_id),
|
|
607
|
+
"workspace_id": str(workspace_id),
|
|
584
608
|
},
|
|
585
609
|
)
|
|
586
610
|
GXAgent._log_http_error(
|
|
@@ -588,7 +612,7 @@ class GXAgent:
|
|
|
588
612
|
)
|
|
589
613
|
|
|
590
614
|
def _create_scheduled_job_and_set_started(
|
|
591
|
-
self, event_context: EventContext, org_id: UUID
|
|
615
|
+
self, event_context: EventContext, org_id: UUID, workspace_id: UUID
|
|
592
616
|
) -> None:
|
|
593
617
|
"""Create a job in GX Cloud for scheduled events.
|
|
594
618
|
|
|
@@ -610,13 +634,14 @@ class GXAgent:
|
|
|
610
634
|
"correlation_id": str(event_context.correlation_id),
|
|
611
635
|
"event_type": str(event_context.event.type),
|
|
612
636
|
"organization_id": str(org_id),
|
|
637
|
+
"workspace_id": str(workspace_id),
|
|
613
638
|
"schedule_id": str(event_context.event.schedule_id),
|
|
614
639
|
},
|
|
615
640
|
)
|
|
616
641
|
|
|
617
642
|
agent_sessions_url = urljoin(
|
|
618
643
|
self._get_config().gx_cloud_base_url,
|
|
619
|
-
f"/api/v1/organizations/{org_id}/agent-jobs",
|
|
644
|
+
f"/api/v1/organizations/{org_id}/workspaces/{workspace_id}/agent-jobs",
|
|
620
645
|
)
|
|
621
646
|
data = CreateScheduledJobAndSetJobStarted(
|
|
622
647
|
type="run_scheduled_checkpoint.received",
|
|
@@ -637,6 +662,7 @@ class GXAgent:
|
|
|
637
662
|
"event_type": str(event_context.event.type),
|
|
638
663
|
"organization_id": str(org_id),
|
|
639
664
|
"schedule_id": str(event_context.event.schedule_id),
|
|
665
|
+
"workspace_id": str(workspace_id),
|
|
640
666
|
},
|
|
641
667
|
)
|
|
642
668
|
GXAgent._log_http_error(
|
|
@@ -659,7 +685,9 @@ class GXAgent:
|
|
|
659
685
|
"""
|
|
660
686
|
Sets headers on all stores in the data context.
|
|
661
687
|
"""
|
|
662
|
-
from great_expectations.data_context.store.gx_cloud_store_backend import
|
|
688
|
+
from great_expectations.data_context.store.gx_cloud_store_backend import ( # noqa: PLC0415
|
|
689
|
+
GXCloudStoreBackend,
|
|
690
|
+
)
|
|
663
691
|
|
|
664
692
|
# OSS doesn't use the same session for all requests, so we need to set the header for each store
|
|
665
693
|
stores = list(data_context.stores.values())
|
|
@@ -687,8 +715,6 @@ class GXAgent:
|
|
|
687
715
|
Note: the Agent-Job-Id header value will be set for all GX Cloud request until this method is
|
|
688
716
|
called again.
|
|
689
717
|
"""
|
|
690
|
-
from great_expectations import __version__ # noqa: PLC0415
|
|
691
|
-
from great_expectations.core import http # noqa: PLC0415
|
|
692
718
|
|
|
693
719
|
header_name = self.get_header_name()
|
|
694
720
|
user_agent_header_value = self.user_agent_str
|
{great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "great_expectations_cloud"
|
|
3
|
-
version = "
|
|
3
|
+
version = "20250915.0.dev0"
|
|
4
4
|
description = "Great Expectations Cloud"
|
|
5
5
|
authors = ["The Great Expectations Team <team@greatexpectations.io>"]
|
|
6
6
|
repository = "https://github.com/great-expectations/cloud"
|
{great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/LICENSE
RENAMED
|
File without changes
|
{great_expectations_cloud-20250912.0.dev3 → great_expectations_cloud-20250915.0.dev0}/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|