great-expectations-cloud 20240625.0__tar.gz → 20260114.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.

Files changed (44) hide show
  1. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/PKG-INFO +53 -50
  2. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/README.md +43 -33
  3. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/__init__.py +3 -0
  4. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/actions/__init__.py +5 -5
  5. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/agent_action.py +43 -0
  6. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/actions/draft_datasource_config_action.py +42 -24
  7. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/generate_data_quality_check_expectations_action.py +557 -0
  8. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/list_asset_names.py +65 -0
  9. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/run_checkpoint.py +159 -0
  10. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/actions/run_metric_list_action.py +11 -8
  11. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/run_scheduled_checkpoint.py +91 -0
  12. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/run_window_checkpoint.py +66 -0
  13. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/actions/utils.py +35 -0
  14. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/agent.py +972 -0
  15. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/cli.py +2 -2
  16. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/config.py +33 -0
  17. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/event_handler.py +49 -12
  18. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/exceptions.py +9 -0
  19. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/message_service/asyncio_rabbit_mq_client.py +108 -15
  20. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/message_service/subscriber.py +12 -5
  21. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/models.py +303 -0
  22. great_expectations_cloud-20260114.0.dev0/great_expectations_cloud/agent/utils.py +84 -0
  23. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/logging/logging_cfg.py +20 -4
  24. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/pyproject.toml +43 -50
  25. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/agent_action.py +0 -28
  26. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/data_assistants/__init__.py +0 -8
  27. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/data_assistants/run_missingness_data_assistant.py +0 -45
  28. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/data_assistants/run_onboarding_data_assistant.py +0 -45
  29. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/data_assistants/utils.py +0 -123
  30. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/list_table_names.py +0 -79
  31. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/run_checkpoint.py +0 -68
  32. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/actions/run_scheduled_checkpoint.py +0 -25
  33. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/agent.py +0 -486
  34. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/config.py +0 -19
  35. great_expectations_cloud-20240625.0/great_expectations_cloud/agent/models.py +0 -138
  36. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/LICENSE +0 -0
  37. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/__init__.py +0 -0
  38. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/actions/unknown.py +0 -0
  39. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/agent_warnings.py +0 -0
  40. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/constants.py +0 -0
  41. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/message_service/__init__.py +0 -0
  42. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/agent/run.py +0 -0
  43. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/logging/README.md +0 -0
  44. {great_expectations_cloud-20240625.0 → great_expectations_cloud-20260114.0.dev0}/great_expectations_cloud/py.typed +0 -0
@@ -1,40 +1,33 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: great_expectations_cloud
3
- Version: 20240625.0
3
+ Version: 20260114.0.dev0
4
4
  Summary: Great Expectations Cloud
5
- Home-page: https://greatexpectations.io
6
5
  License: Proprietary
7
6
  Author: The Great Expectations Team
8
7
  Author-email: team@greatexpectations.io
9
- Requires-Python: >=3.8,<3.12
8
+ Requires-Python: >=3.11.4,<3.12
10
9
  Classifier: Development Status :: 3 - Alpha
11
10
  Classifier: Intended Audience :: Developers
12
11
  Classifier: Intended Audience :: Science/Research
13
12
  Classifier: License :: Other/Proprietary License
14
13
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
14
  Classifier: Topic :: Scientific/Engineering
20
15
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
21
16
  Classifier: Topic :: Software Development :: Quality Assurance
22
17
  Classifier: Topic :: Software Development :: Testing
23
- Provides-Extra: postgres
24
- Provides-Extra: snowflake
25
- Requires-Dist: great-expectations (>=0.18.16,<0.19.0)
18
+ Requires-Dist: great-expectations[databricks,gx-redshift,mssql,postgresql,snowflake,trino] (==1.11.0)
26
19
  Requires-Dist: orjson (>=3.9.7,<4.0.0,!=3.9.10)
27
- Requires-Dist: packaging (>=21.3,<25.0)
20
+ Requires-Dist: packaging (>=21.3,<26.0)
28
21
  Requires-Dist: pika (>=1.3.1,<2.0.0)
29
- Requires-Dist: psycopg2-binary ; extra == "postgres"
30
- Requires-Dist: pydantic (<3)
31
- Requires-Dist: snowflake-sqlalchemy ; extra == "snowflake"
32
- Requires-Dist: sqlalchemy ; extra == "postgres"
33
- Requires-Dist: tenacity (>=8.2.3,<9.0.0)
22
+ Requires-Dist: pydantic (>=2.8.1,<3)
23
+ Requires-Dist: setuptools (==80.9.0)
24
+ Requires-Dist: sqlalchemy (>=2.0)
25
+ Requires-Dist: tenacity (>=8.2.3,<10.0.0)
26
+ Project-URL: Homepage, https://greatexpectations.io
34
27
  Project-URL: Repository, https://github.com/great-expectations/cloud
35
28
  Description-Content-Type: text/markdown
36
29
 
37
- # cloud
30
+ # GX cloud
38
31
 
39
32
  [![PyPI](https://img.shields.io/pypi/v/great_expectations_cloud)](https://pypi.org/project/great-expectations_cloud/#history)
40
33
  [![Docker Pulls](https://img.shields.io/docker/pulls/greatexpectations/agent)](https://hub.docker.com/r/greatexpectations/agent)
@@ -45,19 +38,30 @@ Description-Content-Type: text/markdown
45
38
 
46
39
  ## Quick Start
47
40
 
48
- ### Python
41
+ To use the GX Agent, you will need to have a Great Expectations Cloud account. You can sign up for free at [https://app.greatexpectations.io](https://app.greatexpectations.io).
49
42
 
50
- #### Install
43
+ Deployment instructions for the GX Agent can be found in the [GX Cloud documentation](https://docs.greatexpectations.io/docs/cloud/deploy/deploy_gx_agent).
51
44
 
52
- ```console
53
- pip install great_expectations_cloud
54
- ```
45
+ ## Dev Setup
55
46
 
56
- ##### Optional Dependencies
47
+ The following instructions are for those who are contributing to the GX Agent, to deploy and use the GX agent please see the Quick Start section above.
57
48
 
58
- ```console
59
- pip install 'great_expectations_cloud[sql]'
60
- ```
49
+ See also [CONTRIBUTING.md](https://github.com/great-expectations/cloud/blob/main/CONTRIBUTING.md)
50
+
51
+ 1. [Install or upgrade `poetry` to the latest version](https://python-poetry.org/docs/#installing-with-pipx)
52
+ - `pipx install poetry` or `pipx upgrade poetry`
53
+ 2. Set up virtual environment and install dependencies
54
+ - `poetry sync`
55
+ 3. Activate your virtual environment
56
+ - `eval $(poetry env activate)`
57
+ 4. Set up precommit hooks
58
+ - `pre-commit install`
59
+
60
+ ### Troubleshooting
61
+
62
+ If you run into issues, you can try `pipx reinstall-all`
63
+
64
+ ### Running locally for development
61
65
 
62
66
  ```console
63
67
  $ gx-agent --help
@@ -74,45 +78,33 @@ optional arguments:
74
78
  --version Show the GX Agent version.
75
79
  ```
76
80
 
77
- #### Set env variables
81
+ #### Set ENV variables
78
82
 
79
83
  `GX_CLOUD_ACCESS_TOKEN`
80
84
  `GX_CLOUD_ORGANIZATION_ID`
81
85
 
82
- ### Start the Agent
86
+ If you want to override where the GX Agent looks for the RabbitMQ queue you can also set
87
+ `AMQP_HOST_OVERRIDE` and `AMQP_PORT_OVERRIDE`. For example, if you are running a local dockerized RabbitMQ
88
+ service exposed on localhost port 5672, you can set `AMQP_HOST_OVERRIDE=127.0.0.1` and
89
+ `AMQP_PORT_OVERRIDE=5672`.
90
+
91
+ ### Start the GX Agent
83
92
 
84
- If you intend to run the Agent against local services (Cloud backend or datasources) run the Agent outside of the container.
93
+ If you intend to run the GX Agent against local services (Cloud backend or datasources) run the Agent outside of the container.
85
94
 
86
95
  ```
87
96
  gx-agent
88
97
  ```
89
98
 
90
- ### Docker
91
-
92
- [Building and running the Agent with Docker](#building-and-running-the-gx-agent-image)
93
-
94
- ## Dev Setup
95
-
96
- See also [CONTRIBUTING.md](https://github.com/great-expectations/cloud/blob/main/CONTRIBUTING.md)
97
-
98
- 1. [Install `poetry`](https://python-poetry.org/docs/#installation)
99
- - [`pipx install poetry`](https://python-poetry.org/docs/#installing-with-pipx)
100
- 2. Set up virtual environment and install dependencies
101
- - `poetry install --sync`
102
- 3. Activate your virtual environment
103
- - `poetry shell`
104
- 4. Set up precommit hooks
105
- - `pre-commit install`
106
-
107
99
  ### Developer Tasks
108
100
 
109
- Common developer tasks are available via `invoke` (defined in `tasks.py`)
101
+ Common developer tasks are available via `invoke` (defined in `tasks.py`).
110
102
 
111
103
  `invoke --list` to see available tasks.
112
104
 
113
105
  #### Synchronize Dependencies
114
106
 
115
- To ensure you are using the latest version of the core and development dependencies run `poetry install --sync`.
107
+ To ensure you are using the latest version of the core and development dependencies run `poetry sync`.
116
108
  Also available as an invoke task.
117
109
 
118
110
  ```console
@@ -121,6 +113,11 @@ invoke deps
121
113
 
122
114
  #### Updating `poetry.lock` dependencies
123
115
 
116
+ Use the latest version of poetry
117
+ ```console
118
+ pipx upgrade poetry
119
+ ```
120
+
124
121
  The dependencies installed in our CI and the Docker build step are determined by the [poetry.lock file](https://python-poetry.org/docs/basic-usage/#installing-with-poetrylock).
125
122
 
126
123
  [To update only a specific dependency](https://python-poetry.org/docs/cli/#update) (such as `great_expectations`) ...
@@ -129,6 +126,8 @@ The dependencies installed in our CI and the Docker build step are determined by
129
126
  poetry update great_expectations
130
127
  ```
131
128
 
129
+ **Note:** If `poetry update` does not find the latest version of `great_expectations`, you can manually update the version in `pyproject.toml`, and then update the lockfile using `poetry lock`.
130
+
132
131
  [To resolve and update all dependencies ...](https://python-poetry.org/docs/cli/#lock)
133
132
 
134
133
  ```console
@@ -252,13 +251,15 @@ We use the GitHub Actions workflow to automate the release and pre-release proce
252
251
  A visual representation of the workflow is shown [here](https://github.com/great-expectations/cloud/blob/main/.github/workflows/agent_release_workflows.png)
253
252
 
254
253
  ### Dependabot and Releases/Pre-releases
254
+
255
255
  GitHub's Dependabot regularly checks our dependencies for vulnerabilty-based updates and proposes PRs to update dependency version numbers accordingly.
256
256
 
257
257
  Dependabot may only update the `poetry.lock` file. If only changes to `poetry.lock` are made, this may be done in a pre-release.
258
258
 
259
259
  For changes to the `pyproject.toml` file:
260
+
260
261
  - If the version of a tool in the `[tool.poetry.group.dev.dependencies]` group is updated, this may be done without any version bump.
261
- - While doing this, make sure any version references in the pre-commit config `.pre-commit-config.yaml` are kept in sync (e.g., ruff).
262
+ - While doing this, make sure any version references in the pre-commit config `.pre-commit-config.yaml` are kept in sync (e.g., ruff).
262
263
  - For other dependency updates or package build metadata changes, a new release should be orchestrated. This includes updates in the following sections:
263
264
  - `[tool.poetry.dependencies]`
264
265
  - `[tool.poetry.group.*.dependencies]` where `*` is the name of the group (not including the `dev` group)
@@ -266,3 +267,5 @@ For changes to the `pyproject.toml` file:
266
267
  - Only modifying dev dependencies.
267
268
  - Only modifying tests that do not change functionality.
268
269
 
270
+ NOTE: Dependabot does not have permissions to access secrets in our CI. You may notice that integration tests fail on PRs that dependabot creates. If you add a commit (as a GX member) to the PR, the tests will run again and pass because they now have access to the secrets. That commit can be anything, including an empty commit e.g. `git commit -m "some message" --allow-empty`.
271
+
@@ -1,4 +1,4 @@
1
- # cloud
1
+ # GX cloud
2
2
 
3
3
  [![PyPI](https://img.shields.io/pypi/v/great_expectations_cloud)](https://pypi.org/project/great-expectations_cloud/#history)
4
4
  [![Docker Pulls](https://img.shields.io/docker/pulls/greatexpectations/agent)](https://hub.docker.com/r/greatexpectations/agent)
@@ -9,19 +9,30 @@
9
9
 
10
10
  ## Quick Start
11
11
 
12
- ### Python
12
+ To use the GX Agent, you will need to have a Great Expectations Cloud account. You can sign up for free at [https://app.greatexpectations.io](https://app.greatexpectations.io).
13
13
 
14
- #### Install
14
+ Deployment instructions for the GX Agent can be found in the [GX Cloud documentation](https://docs.greatexpectations.io/docs/cloud/deploy/deploy_gx_agent).
15
15
 
16
- ```console
17
- pip install great_expectations_cloud
18
- ```
16
+ ## Dev Setup
19
17
 
20
- ##### Optional Dependencies
18
+ The following instructions are for those who are contributing to the GX Agent, to deploy and use the GX agent please see the Quick Start section above.
21
19
 
22
- ```console
23
- pip install 'great_expectations_cloud[sql]'
24
- ```
20
+ See also [CONTRIBUTING.md](https://github.com/great-expectations/cloud/blob/main/CONTRIBUTING.md)
21
+
22
+ 1. [Install or upgrade `poetry` to the latest version](https://python-poetry.org/docs/#installing-with-pipx)
23
+ - `pipx install poetry` or `pipx upgrade poetry`
24
+ 2. Set up virtual environment and install dependencies
25
+ - `poetry sync`
26
+ 3. Activate your virtual environment
27
+ - `eval $(poetry env activate)`
28
+ 4. Set up precommit hooks
29
+ - `pre-commit install`
30
+
31
+ ### Troubleshooting
32
+
33
+ If you run into issues, you can try `pipx reinstall-all`
34
+
35
+ ### Running locally for development
25
36
 
26
37
  ```console
27
38
  $ gx-agent --help
@@ -38,45 +49,33 @@ optional arguments:
38
49
  --version Show the GX Agent version.
39
50
  ```
40
51
 
41
- #### Set env variables
52
+ #### Set ENV variables
42
53
 
43
54
  `GX_CLOUD_ACCESS_TOKEN`
44
55
  `GX_CLOUD_ORGANIZATION_ID`
45
56
 
46
- ### Start the Agent
57
+ If you want to override where the GX Agent looks for the RabbitMQ queue you can also set
58
+ `AMQP_HOST_OVERRIDE` and `AMQP_PORT_OVERRIDE`. For example, if you are running a local dockerized RabbitMQ
59
+ service exposed on localhost port 5672, you can set `AMQP_HOST_OVERRIDE=127.0.0.1` and
60
+ `AMQP_PORT_OVERRIDE=5672`.
61
+
62
+ ### Start the GX Agent
47
63
 
48
- If you intend to run the Agent against local services (Cloud backend or datasources) run the Agent outside of the container.
64
+ If you intend to run the GX Agent against local services (Cloud backend or datasources) run the Agent outside of the container.
49
65
 
50
66
  ```
51
67
  gx-agent
52
68
  ```
53
69
 
54
- ### Docker
55
-
56
- [Building and running the Agent with Docker](#building-and-running-the-gx-agent-image)
57
-
58
- ## Dev Setup
59
-
60
- See also [CONTRIBUTING.md](https://github.com/great-expectations/cloud/blob/main/CONTRIBUTING.md)
61
-
62
- 1. [Install `poetry`](https://python-poetry.org/docs/#installation)
63
- - [`pipx install poetry`](https://python-poetry.org/docs/#installing-with-pipx)
64
- 2. Set up virtual environment and install dependencies
65
- - `poetry install --sync`
66
- 3. Activate your virtual environment
67
- - `poetry shell`
68
- 4. Set up precommit hooks
69
- - `pre-commit install`
70
-
71
70
  ### Developer Tasks
72
71
 
73
- Common developer tasks are available via `invoke` (defined in `tasks.py`)
72
+ Common developer tasks are available via `invoke` (defined in `tasks.py`).
74
73
 
75
74
  `invoke --list` to see available tasks.
76
75
 
77
76
  #### Synchronize Dependencies
78
77
 
79
- To ensure you are using the latest version of the core and development dependencies run `poetry install --sync`.
78
+ To ensure you are using the latest version of the core and development dependencies run `poetry sync`.
80
79
  Also available as an invoke task.
81
80
 
82
81
  ```console
@@ -85,6 +84,11 @@ invoke deps
85
84
 
86
85
  #### Updating `poetry.lock` dependencies
87
86
 
87
+ Use the latest version of poetry
88
+ ```console
89
+ pipx upgrade poetry
90
+ ```
91
+
88
92
  The dependencies installed in our CI and the Docker build step are determined by the [poetry.lock file](https://python-poetry.org/docs/basic-usage/#installing-with-poetrylock).
89
93
 
90
94
  [To update only a specific dependency](https://python-poetry.org/docs/cli/#update) (such as `great_expectations`) ...
@@ -93,6 +97,8 @@ The dependencies installed in our CI and the Docker build step are determined by
93
97
  poetry update great_expectations
94
98
  ```
95
99
 
100
+ **Note:** If `poetry update` does not find the latest version of `great_expectations`, you can manually update the version in `pyproject.toml`, and then update the lockfile using `poetry lock`.
101
+
96
102
  [To resolve and update all dependencies ...](https://python-poetry.org/docs/cli/#lock)
97
103
 
98
104
  ```console
@@ -216,16 +222,20 @@ We use the GitHub Actions workflow to automate the release and pre-release proce
216
222
  A visual representation of the workflow is shown [here](https://github.com/great-expectations/cloud/blob/main/.github/workflows/agent_release_workflows.png)
217
223
 
218
224
  ### Dependabot and Releases/Pre-releases
225
+
219
226
  GitHub's Dependabot regularly checks our dependencies for vulnerabilty-based updates and proposes PRs to update dependency version numbers accordingly.
220
227
 
221
228
  Dependabot may only update the `poetry.lock` file. If only changes to `poetry.lock` are made, this may be done in a pre-release.
222
229
 
223
230
  For changes to the `pyproject.toml` file:
231
+
224
232
  - If the version of a tool in the `[tool.poetry.group.dev.dependencies]` group is updated, this may be done without any version bump.
225
- - While doing this, make sure any version references in the pre-commit config `.pre-commit-config.yaml` are kept in sync (e.g., ruff).
233
+ - While doing this, make sure any version references in the pre-commit config `.pre-commit-config.yaml` are kept in sync (e.g., ruff).
226
234
  - For other dependency updates or package build metadata changes, a new release should be orchestrated. This includes updates in the following sections:
227
235
  - `[tool.poetry.dependencies]`
228
236
  - `[tool.poetry.group.*.dependencies]` where `*` is the name of the group (not including the `dev` group)
229
237
  - To stop the auto-version bump add the `no version bump` label to the PR. Use this when:
230
238
  - Only modifying dev dependencies.
231
239
  - Only modifying tests that do not change functionality.
240
+
241
+ NOTE: Dependabot does not have permissions to access secrets in our CI. You may notice that integration tests fail on PRs that dependabot creates. If you add a commit (as a GX member) to the PR, the tests will run again and pass because they now have access to the secrets. That commit can be anything, including an empty commit e.g. `git commit -m "some message" --allow-empty`.
@@ -2,4 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import great_expectations_cloud.agent.actions # import actions to register them
4
4
  from great_expectations_cloud.agent.agent import GXAgent
5
+ from great_expectations_cloud.agent.event_handler import register_event_action
6
+ from great_expectations_cloud.agent.models import Event, EventType
5
7
  from great_expectations_cloud.agent.run import get_version, run_agent
8
+ from great_expectations_cloud.agent.utils import triangular_interpolation
@@ -7,16 +7,16 @@ from great_expectations_cloud.agent.actions.agent_action import (
7
7
  )
8
8
 
9
9
  # Import all actions to register them:
10
- from great_expectations_cloud.agent.actions.data_assistants import (
11
- RunMissingnessDataAssistantAction,
12
- RunOnboardingDataAssistantAction,
13
- )
14
10
  from great_expectations_cloud.agent.actions.draft_datasource_config_action import (
15
11
  DraftDatasourceConfigAction,
16
12
  )
17
- from great_expectations_cloud.agent.actions.list_table_names import ListTableNamesAction
13
+ from great_expectations_cloud.agent.actions.generate_data_quality_check_expectations_action import (
14
+ GenerateDataQualityCheckExpectationsAction,
15
+ )
16
+ from great_expectations_cloud.agent.actions.list_asset_names import ListAssetNamesAction
18
17
  from great_expectations_cloud.agent.actions.run_checkpoint import RunCheckpointAction
19
18
  from great_expectations_cloud.agent.actions.run_metric_list_action import MetricListAction
20
19
  from great_expectations_cloud.agent.actions.run_scheduled_checkpoint import (
21
20
  RunScheduledCheckpointAction,
22
21
  )
22
+ from great_expectations_cloud.agent.actions.run_window_checkpoint import RunWindowCheckpointAction
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from abc import abstractmethod
5
+ from collections.abc import Sequence
6
+ from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union
7
+
8
+ from pydantic.v1 import BaseModel
9
+
10
+ from great_expectations_cloud.agent.models import (
11
+ AgentBaseExtraForbid,
12
+ AgentBaseExtraIgnore,
13
+ CreatedResource,
14
+ DomainContext,
15
+ )
16
+
17
+ if TYPE_CHECKING:
18
+ from great_expectations.data_context import CloudDataContext
19
+
20
+
21
+ class ActionResult(BaseModel):
22
+ id: str
23
+ type: str
24
+ created_resources: Sequence[CreatedResource]
25
+ job_duration: Optional[datetime.timedelta] = ( # noqa: UP045
26
+ None # Python 3.8 doesn't support `X | Y` for type annotation
27
+ )
28
+
29
+
30
+ _EventT = TypeVar("_EventT", bound=Union[AgentBaseExtraForbid, AgentBaseExtraIgnore])
31
+
32
+
33
+ class AgentAction(Generic[_EventT]):
34
+ def __init__(
35
+ self, context: CloudDataContext, base_url: str, domain_context: DomainContext, auth_key: str
36
+ ):
37
+ self._context = context
38
+ self._base_url = base_url
39
+ self._domain_context = domain_context
40
+ self._auth_key = auth_key
41
+
42
+ @abstractmethod
43
+ def run(self, event: _EventT, id: str) -> ActionResult: ...
@@ -1,18 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from typing import Any
4
+ from urllib.parse import urljoin
4
5
  from uuid import UUID
5
6
 
6
- from great_expectations.compatibility import pydantic
7
7
  from great_expectations.core.http import create_session
8
+ from great_expectations.datasource.fluent import SQLDatasource
8
9
  from great_expectations.datasource.fluent.interfaces import TestConnectionError
9
10
  from typing_extensions import override
10
11
 
11
12
  from great_expectations_cloud.agent.actions import ActionResult, AgentAction
12
- from great_expectations_cloud.agent.config import (
13
- GxAgentEnvVars,
14
- generate_config_validation_error_text,
15
- )
13
+ from great_expectations_cloud.agent.actions.utils import get_asset_names
16
14
  from great_expectations_cloud.agent.event_handler import register_event_action
17
15
  from great_expectations_cloud.agent.exceptions import ErrorCode, raise_with_error_code
18
16
  from great_expectations_cloud.agent.models import DraftDatasourceConfigEvent
@@ -46,11 +44,10 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
46
44
  datasource_type = draft_config.get("type", None)
47
45
  if datasource_type is None:
48
46
  raise TypeError( # noqa: TRY003 # one off error
49
- "The DraftDatasourceConfigAction can only be used with a "
50
- "fluent-style Data Source."
47
+ "The DraftDatasourceConfigAction can only be used with a fluent-style Data Source."
51
48
  )
52
49
  try:
53
- datasource_cls = self._context.sources.type_lookup[datasource_type]
50
+ datasource_cls = self._context.data_sources.type_lookup[datasource_type]
54
51
  except LookupError as exc:
55
52
  raise TypeError( # noqa: TRY003 # one off error
56
53
  "DraftDatasourceConfigAction received an unknown Data Source type."
@@ -58,32 +55,53 @@ class DraftDatasourceConfigAction(AgentAction[DraftDatasourceConfigEvent]):
58
55
  datasource = datasource_cls(**draft_config)
59
56
  datasource._data_context = self._context
60
57
  datasource.test_connection(test_assets=True) # raises `TestConnectionError` on failure
61
- return ActionResult(id=id, type=event.type, created_resources=[])
62
58
 
63
- def get_draft_config(self, config_id: UUID) -> dict[str, Any]:
64
- try:
65
- config = GxAgentEnvVars()
66
- except pydantic.ValidationError as validation_err:
67
- raise RuntimeError(
68
- generate_config_validation_error_text(validation_err)
69
- ) from validation_err
70
- resource_url = (
71
- f"{config.gx_cloud_base_url}/organizations/"
72
- f"{config.gx_cloud_organization_id}/datasources/drafts/{config_id}"
59
+ if isinstance(datasource, SQLDatasource):
60
+ asset_names = get_asset_names(datasource)
61
+ self._update_asset_names_list(config_id=event.config_id, asset_names=asset_names)
62
+
63
+ return ActionResult(
64
+ id=id,
65
+ type=event.type,
66
+ created_resources=[],
73
67
  )
74
- session = create_session(access_token=config.gx_cloud_access_token)
75
- response = session.get(resource_url)
68
+
69
+ def _update_asset_names_list(self, config_id: UUID, asset_names: list[str]) -> None:
70
+ with create_session(access_token=self._auth_key) as session:
71
+ url = urljoin(
72
+ base=self._base_url,
73
+ url=f"/api/v1/organizations/{self._domain_context.organization_id}/workspaces/{self._domain_context.workspace_id}/draft-table-names/{config_id}",
74
+ )
75
+ response = session.put(
76
+ url=url,
77
+ json={"data": {"table_names": asset_names}},
78
+ )
76
79
  if not response.ok:
77
80
  raise RuntimeError( # noqa: TRY003 # one off error
78
- "DraftDatasourceConfigAction encountered an error while " "connecting to GX Cloud"
81
+ f"DraftDatasourceConfigAction encountered an error while connecting to GX Cloud. "
82
+ f"Unable to update "
83
+ f"table_names for Draft Config with ID"
84
+ f"={config_id}.",
79
85
  )
86
+
87
+ def get_draft_config(self, config_id: UUID) -> dict[str, Any]:
88
+ resource_url = urljoin(
89
+ base=self._base_url,
90
+ url=f"/api/v1/organizations/{self._domain_context.organization_id}/workspaces/{self._domain_context.workspace_id}/draft-datasources/{config_id}",
91
+ )
92
+ with create_session(access_token=self._auth_key) as session:
93
+ response = session.get(resource_url)
94
+ if not response.ok:
95
+ raise RuntimeError( # noqa: TRY003 # one off error
96
+ "DraftDatasourceConfigAction encountered an error while connecting to GX Cloud"
97
+ )
80
98
  data = response.json()
81
99
  try:
82
- return data["data"]["attributes"]["draft_config"] # type: ignore[no-any-return]
100
+ return data["data"]["config"] # type: ignore[no-any-return]
83
101
  except KeyError as e:
84
102
  raise RuntimeError( # noqa: TRY003 # one off error
85
103
  "Malformed response received from GX Cloud"
86
104
  ) from e
87
105
 
88
106
 
89
- register_event_action("0", DraftDatasourceConfigEvent, DraftDatasourceConfigAction)
107
+ register_event_action("1", DraftDatasourceConfigEvent, DraftDatasourceConfigAction)