great-expectations-cloud 20250902.0.dev1__py3-none-any.whl → 20250903.0.dev0__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.
- great_expectations_cloud/agent/agent.py +50 -24
- great_expectations_cloud/agent/models.py +1 -0
- {great_expectations_cloud-20250902.0.dev1.dist-info → great_expectations_cloud-20250903.0.dev0.dist-info}/METADATA +1 -1
- {great_expectations_cloud-20250902.0.dev1.dist-info → great_expectations_cloud-20250903.0.dev0.dist-info}/RECORD +7 -7
- {great_expectations_cloud-20250902.0.dev1.dist-info → great_expectations_cloud-20250903.0.dev0.dist-info}/LICENSE +0 -0
- {great_expectations_cloud-20250902.0.dev1.dist-info → great_expectations_cloud-20250903.0.dev0.dist-info}/WHEEL +0 -0
- {great_expectations_cloud-20250902.0.dev1.dist-info → great_expectations_cloud-20250903.0.dev0.dist-info}/entry_points.txt +0 -0
@@ -16,6 +16,8 @@ from uuid import UUID
|
|
16
16
|
|
17
17
|
import orjson
|
18
18
|
import requests
|
19
|
+
from great_expectations import __version__
|
20
|
+
from great_expectations.core import http
|
19
21
|
from great_expectations.core.http import create_session
|
20
22
|
from great_expectations.data_context.cloud_constants import CLOUD_DEFAULT_BASE_URL
|
21
23
|
from great_expectations.data_context.data_context.context_factory import get_context
|
@@ -150,19 +152,7 @@ class GXAgent:
|
|
150
152
|
"great_expectations_version": great_expectations_version,
|
151
153
|
},
|
152
154
|
)
|
153
|
-
|
154
|
-
|
155
|
-
with warnings.catch_warnings():
|
156
|
-
# suppress warnings about GX version
|
157
|
-
warnings.filterwarnings("ignore", message="You are using great_expectations version")
|
158
|
-
self._context: CloudDataContext = get_context(
|
159
|
-
cloud_mode=True,
|
160
|
-
user_agent_str=self.user_agent_str,
|
161
|
-
)
|
162
|
-
self._configure_progress_bars(data_context=self._context)
|
163
|
-
LOGGER.debug("DataContext is ready.")
|
164
|
-
|
165
|
-
self._set_http_session_headers(data_context=self._context)
|
155
|
+
# DataContext is created per job in get_data_context
|
166
156
|
|
167
157
|
# Create a thread pool with a single worker, so we can run long-lived
|
168
158
|
# GX processes and maintain our connection to the broker. Note that
|
@@ -263,6 +253,7 @@ class GXAgent:
|
|
263
253
|
"event_type": event_context.event.type,
|
264
254
|
"correlation_id": event_context.correlation_id,
|
265
255
|
"organization_id": self.get_organization_id(event_context),
|
256
|
+
"workspace_id": str(self.get_workspace_id(event_context)),
|
266
257
|
"schedule_id": event_context.event.schedule_id
|
267
258
|
if isinstance(event_context.event, ScheduledEventBase)
|
268
259
|
else None,
|
@@ -287,8 +278,19 @@ class GXAgent:
|
|
287
278
|
self._current_task.add_done_callback(on_exit_callback)
|
288
279
|
|
289
280
|
def get_data_context(self, event_context: EventContext) -> CloudDataContext:
|
290
|
-
"""
|
291
|
-
|
281
|
+
"""Create a new CloudDataContext for each job using the event's workspace_id."""
|
282
|
+
with warnings.catch_warnings():
|
283
|
+
warnings.filterwarnings("ignore", message="You are using great_expectations version")
|
284
|
+
# Validate presence of workspace_id (required), even if not passed directly to get_context
|
285
|
+
if getattr(event_context.event, "workspace_id", None) is None:
|
286
|
+
raise GXAgentError()
|
287
|
+
|
288
|
+
context: CloudDataContext = get_context(
|
289
|
+
cloud_mode=True,
|
290
|
+
user_agent_str=self.user_agent_str,
|
291
|
+
)
|
292
|
+
self._configure_progress_bars(data_context=context)
|
293
|
+
return context
|
292
294
|
|
293
295
|
def get_organization_id(self, event_context: EventContext) -> UUID:
|
294
296
|
"""Helper method to get the organization ID. Overridden in GX-Runner."""
|
@@ -298,6 +300,13 @@ class GXAgent:
|
|
298
300
|
"""Helper method to get the auth key. Overridden in GX-Runner."""
|
299
301
|
return self._get_config().gx_cloud_access_token
|
300
302
|
|
303
|
+
def get_workspace_id(self, event_context: EventContext) -> UUID:
|
304
|
+
"""Helper method to get the workspace ID from the event."""
|
305
|
+
workspace_id: UUID | None = getattr(event_context.event, "workspace_id", None)
|
306
|
+
if workspace_id is None:
|
307
|
+
raise GXAgentError()
|
308
|
+
return workspace_id
|
309
|
+
|
301
310
|
def _set_sentry_tags(self, even_context: EventContext) -> None:
|
302
311
|
"""Used by GX-Runner to set tags for Sentry logging. No-op in the Agent."""
|
303
312
|
pass
|
@@ -320,14 +329,18 @@ class GXAgent:
|
|
320
329
|
)
|
321
330
|
|
322
331
|
org_id = self.get_organization_id(event_context)
|
332
|
+
workspace_id = self.get_workspace_id(event_context)
|
323
333
|
base_url = self._get_config().gx_cloud_base_url
|
324
334
|
auth_key = self.get_auth_key()
|
325
335
|
|
326
336
|
if isinstance(event_context.event, ScheduledEventBase):
|
327
|
-
self._create_scheduled_job_and_set_started(event_context, org_id)
|
337
|
+
self._create_scheduled_job_and_set_started(event_context, org_id, workspace_id)
|
328
338
|
else:
|
329
339
|
self._update_status(
|
330
|
-
correlation_id=event_context.correlation_id,
|
340
|
+
correlation_id=event_context.correlation_id,
|
341
|
+
status=JobStarted(),
|
342
|
+
org_id=org_id,
|
343
|
+
workspace_id=workspace_id,
|
331
344
|
)
|
332
345
|
LOGGER.info(
|
333
346
|
"Starting job",
|
@@ -335,6 +348,7 @@ class GXAgent:
|
|
335
348
|
"event_type": event_context.event.type,
|
336
349
|
"correlation_id": event_context.correlation_id,
|
337
350
|
"organization_id": str(org_id),
|
351
|
+
"workspace_id": str(workspace_id),
|
338
352
|
"schedule_id": event_context.event.schedule_id
|
339
353
|
if isinstance(event_context.event, ScheduledEventBase)
|
340
354
|
else None,
|
@@ -366,6 +380,7 @@ class GXAgent:
|
|
366
380
|
# warning: this method will not be executed in the main thread
|
367
381
|
|
368
382
|
org_id = self.get_organization_id(event_context)
|
383
|
+
workspace_id = self.get_workspace_id(event_context)
|
369
384
|
|
370
385
|
# get results or errors from the thread
|
371
386
|
error = future.exception()
|
@@ -385,6 +400,7 @@ class GXAgent:
|
|
385
400
|
"event_type": event_context.event.type,
|
386
401
|
"id": event_context.correlation_id,
|
387
402
|
"organization_id": str(org_id),
|
403
|
+
"workspace_id": str(workspace_id),
|
388
404
|
"schedule_id": event_context.event.schedule_id
|
389
405
|
if isinstance(event_context.event, ScheduledEventBase)
|
390
406
|
else None,
|
@@ -405,6 +421,7 @@ class GXAgent:
|
|
405
421
|
result.job_duration.total_seconds() if result.job_duration else None
|
406
422
|
),
|
407
423
|
"organization_id": str(org_id),
|
424
|
+
"workspace_id": str(workspace_id),
|
408
425
|
"schedule_id": event_context.event.schedule_id
|
409
426
|
if isinstance(event_context.event, ScheduledEventBase)
|
410
427
|
else None,
|
@@ -419,12 +436,16 @@ class GXAgent:
|
|
419
436
|
"event_type": event_context.event.type,
|
420
437
|
"correlation_id": event_context.correlation_id,
|
421
438
|
"organization_id": str(org_id),
|
439
|
+
"workspace_id": str(workspace_id),
|
422
440
|
},
|
423
441
|
)
|
424
442
|
|
425
443
|
try:
|
426
444
|
self._update_status(
|
427
|
-
correlation_id=event_context.correlation_id,
|
445
|
+
correlation_id=event_context.correlation_id,
|
446
|
+
status=status,
|
447
|
+
org_id=org_id,
|
448
|
+
workspace_id=workspace_id,
|
428
449
|
)
|
429
450
|
except Exception:
|
430
451
|
LOGGER.exception(
|
@@ -433,6 +454,7 @@ class GXAgent:
|
|
433
454
|
"correlation_id": event_context.correlation_id,
|
434
455
|
"status": str(status),
|
435
456
|
"organization_id": str(org_id),
|
457
|
+
"workspace_id": str(workspace_id),
|
436
458
|
},
|
437
459
|
)
|
438
460
|
# We do not want to cause an infinite loop of errors
|
@@ -552,7 +574,9 @@ class GXAgent:
|
|
552
574
|
)
|
553
575
|
)
|
554
576
|
|
555
|
-
def _update_status(
|
577
|
+
def _update_status(
|
578
|
+
self, correlation_id: str, status: JobStatus, org_id: UUID, workspace_id: UUID
|
579
|
+
) -> None:
|
556
580
|
"""Update GX Cloud on the status of a job.
|
557
581
|
|
558
582
|
Args:
|
@@ -565,11 +589,12 @@ class GXAgent:
|
|
565
589
|
"correlation_id": correlation_id,
|
566
590
|
"status": str(status),
|
567
591
|
"organization_id": str(org_id),
|
592
|
+
"workspace_id": str(workspace_id),
|
568
593
|
},
|
569
594
|
)
|
570
595
|
agent_sessions_url = urljoin(
|
571
596
|
self._get_config().gx_cloud_base_url,
|
572
|
-
f"/api/v1/organizations/{org_id}/agent-jobs/{correlation_id}",
|
597
|
+
f"/api/v1/organizations/{org_id}/workspaces/{workspace_id}/agent-jobs/{correlation_id}",
|
573
598
|
)
|
574
599
|
with create_session(access_token=self.get_auth_key()) as session:
|
575
600
|
data = UpdateJobStatusRequest(data=status).json()
|
@@ -580,6 +605,7 @@ class GXAgent:
|
|
580
605
|
"correlation_id": correlation_id,
|
581
606
|
"status": str(status),
|
582
607
|
"organization_id": str(org_id),
|
608
|
+
"workspace_id": str(workspace_id),
|
583
609
|
},
|
584
610
|
)
|
585
611
|
GXAgent._log_http_error(
|
@@ -587,7 +613,7 @@ class GXAgent:
|
|
587
613
|
)
|
588
614
|
|
589
615
|
def _create_scheduled_job_and_set_started(
|
590
|
-
self, event_context: EventContext, org_id: UUID
|
616
|
+
self, event_context: EventContext, org_id: UUID, workspace_id: UUID
|
591
617
|
) -> None:
|
592
618
|
"""Create a job in GX Cloud for scheduled events.
|
593
619
|
|
@@ -609,13 +635,14 @@ class GXAgent:
|
|
609
635
|
"correlation_id": str(event_context.correlation_id),
|
610
636
|
"event_type": str(event_context.event.type),
|
611
637
|
"organization_id": str(org_id),
|
638
|
+
"workspace_id": str(workspace_id),
|
612
639
|
"schedule_id": str(event_context.event.schedule_id),
|
613
640
|
},
|
614
641
|
)
|
615
642
|
|
616
643
|
agent_sessions_url = urljoin(
|
617
644
|
self._get_config().gx_cloud_base_url,
|
618
|
-
f"/api/v1/organizations/{org_id}/agent-jobs",
|
645
|
+
f"/api/v1/organizations/{org_id}/workspaces/{workspace_id}/agent-jobs",
|
619
646
|
)
|
620
647
|
data = CreateScheduledJobAndSetJobStarted(
|
621
648
|
type="run_scheduled_checkpoint.received",
|
@@ -636,6 +663,7 @@ class GXAgent:
|
|
636
663
|
"event_type": str(event_context.event.type),
|
637
664
|
"organization_id": str(org_id),
|
638
665
|
"schedule_id": str(event_context.event.schedule_id),
|
666
|
+
"workspace_id": str(workspace_id),
|
639
667
|
},
|
640
668
|
)
|
641
669
|
GXAgent._log_http_error(
|
@@ -686,8 +714,6 @@ class GXAgent:
|
|
686
714
|
Note: the Agent-Job-Id header value will be set for all GX Cloud request until this method is
|
687
715
|
called again.
|
688
716
|
"""
|
689
|
-
from great_expectations import __version__ # noqa: PLC0415
|
690
|
-
from great_expectations.core import http # noqa: PLC0415
|
691
717
|
|
692
718
|
header_name = self.get_header_name()
|
693
719
|
user_agent_header_value = self.user_agent_str
|
@@ -11,7 +11,7 @@ great_expectations_cloud/agent/actions/run_scheduled_checkpoint.py,sha256=XMvv59
|
|
11
11
|
great_expectations_cloud/agent/actions/run_window_checkpoint.py,sha256=khFmTSZ6W-MrInswgEHGrQAzVt-aelycurAMPbcLcLU,2264
|
12
12
|
great_expectations_cloud/agent/actions/unknown.py,sha256=mtWw9tDZqGZSiUWj7PtIlLFJ1dM-7AHBX3SO16-u2EM,739
|
13
13
|
great_expectations_cloud/agent/actions/utils.py,sha256=DuUy6Ntsin0RIdgG2n1K85WJUATKHsqcCgtXKjr7scQ,1269
|
14
|
-
great_expectations_cloud/agent/agent.py,sha256=
|
14
|
+
great_expectations_cloud/agent/agent.py,sha256=bybMcl0DwYrnKVG5GYsqPW_ub826Wl7FRTN-W7biZd0,31021
|
15
15
|
great_expectations_cloud/agent/agent_warnings.py,sha256=9-xl_AI2V9Py4o7KzFOQjG3lYx-vZ36fq4w2iiPNiUw,362
|
16
16
|
great_expectations_cloud/agent/cli.py,sha256=a_HmPxBMlVD59BEmkZnlbOOAFlezVMx9djZ2XIW-3W0,2885
|
17
17
|
great_expectations_cloud/agent/config.py,sha256=c1BOr-TrxZnciWNRuu4atGtfRh-XSmwIS0osDCzQa04,1348
|
@@ -21,14 +21,14 @@ great_expectations_cloud/agent/exceptions.py,sha256=XIDBVSmBfFpVQA5i9rZqEtORIdi5
|
|
21
21
|
great_expectations_cloud/agent/message_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
great_expectations_cloud/agent/message_service/asyncio_rabbit_mq_client.py,sha256=B2EwgG_Qdm1s_xkxbGPQxdRBkDSuhkKyT6rGFpXuqQ0,12391
|
23
23
|
great_expectations_cloud/agent/message_service/subscriber.py,sha256=K8szy9uM1MUBkMaMZt9o5ExnjqEn1hw6zYaH7pQkjoM,5975
|
24
|
-
great_expectations_cloud/agent/models.py,sha256=
|
24
|
+
great_expectations_cloud/agent/models.py,sha256=ea3d6eul8ECvsIubVSEJzeJbX6X9M40oEhaWhj4yuVI,10007
|
25
25
|
great_expectations_cloud/agent/run.py,sha256=V33RLoB1PFmJ0h0RfHG4SB5lN_Za8tW2Dua6GUpN9yY,639
|
26
26
|
great_expectations_cloud/agent/utils.py,sha256=3OvdcXeK1gk2oJgqG4jPvBRwlMCn8LioULW3YgRtj98,2950
|
27
27
|
great_expectations_cloud/logging/README.md,sha256=vbwU689x8SkGjzoBYQzZOzAvh28fR0RCa1XY5WD-Dgs,1762
|
28
28
|
great_expectations_cloud/logging/logging_cfg.py,sha256=W6mlm4_Z2bjzM5TuKmFg_WZor2XoJm4DAoLGaf2O__I,6579
|
29
29
|
great_expectations_cloud/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
-
great_expectations_cloud-
|
31
|
-
great_expectations_cloud-
|
32
|
-
great_expectations_cloud-
|
33
|
-
great_expectations_cloud-
|
34
|
-
great_expectations_cloud-
|
30
|
+
great_expectations_cloud-20250903.0.dev0.dist-info/LICENSE,sha256=_JJnoX6N_OkrAwlCRizCwil0tIjDAy2TG3GiJ50sM6k,2084
|
31
|
+
great_expectations_cloud-20250903.0.dev0.dist-info/METADATA,sha256=49yDtQB7jfbuCAVMXQfRWD7xgm7e77TGmrnFwg1QEyk,12352
|
32
|
+
great_expectations_cloud-20250903.0.dev0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
33
|
+
great_expectations_cloud-20250903.0.dev0.dist-info/entry_points.txt,sha256=ofJgdeS2gSzxXLyCAjfNhIaN1wmSyR7EAMs5qhVaXE4,68
|
34
|
+
great_expectations_cloud-20250903.0.dev0.dist-info/RECORD,,
|
File without changes
|
File without changes
|