datahub-agent-context 1.3.1.10rc1__tar.gz → 1.4.0rc2__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.
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/PKG-INFO +18 -11
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/README.md +3 -2
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/setup.py +8 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/__init__.py +11 -3
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/_version.py +1 -1
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/cli.py +152 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/context.py +110 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/langchain_tools/builder.py +6 -4
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/base.py +6 -3
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/mcp_tools/save_document.py +634 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/__init__.py +0 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generate_udfs.py +306 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generators/__init__.py +21 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generators/configuration.py +104 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generators/cortex_agent.py +725 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generators/network_rules.py +53 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/generators/stored_procedure.py +87 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/snowflake.py +662 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/__init__.py +1 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/add_glossary_terms.py +61 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/add_owners.py +59 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/add_structured_properties.py +57 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/add_tags.py +61 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/base.py +45 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/get_dataset_queries.py +68 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/get_entities.py +47 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/get_lineage.py +61 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/get_lineage_paths_between.py +69 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/get_me.py +51 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/grep_documents.py +70 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/list_schema_fields.py +80 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/remove_domains.py +45 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/remove_glossary_terms.py +57 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/remove_owners.py +56 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/remove_structured_properties.py +56 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/remove_tags.py +57 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/search_datahub.py +71 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/search_documents.py +58 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/set_domains.py +55 -0
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context/snowflake/udfs/update_description.py +60 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context.egg-info/PKG-INFO +18 -11
- datahub_agent_context-1.4.0rc2/src/datahub_agent_context.egg-info/SOURCES.txt +72 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context.egg-info/requires.txt +15 -8
- datahub_agent_context-1.3.1.10rc1/src/datahub_agent_context/context.py +0 -97
- datahub_agent_context-1.3.1.10rc1/src/datahub_agent_context.egg-info/SOURCES.txt +0 -40
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/pyproject.toml +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/setup.cfg +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/langchain_tools/__init__.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/__init__.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/_token_estimator.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/descriptions.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/documents.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/domains.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/entities.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/get_me.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/__init__.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/document_search.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/document_semantic_search.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/entity_details.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/queries.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/query_entity.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/read_documents.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/gql/search.gql +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/helpers.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/lineage.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/owners.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/queries.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/search.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/structured_properties.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/tags.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/mcp_tools/terms.py +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context/py.typed +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context.egg-info/dependency_links.txt +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context.egg-info/not-zip-safe +0 -0
- {datahub_agent_context-1.3.1.10rc1 → datahub_agent_context-1.4.0rc2}/src/datahub_agent_context.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datahub-agent-context
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0rc2
|
|
4
4
|
Summary: DataHub Agent Context - MCP Tools for AI Agents
|
|
5
5
|
Home-page: https://datahub.io/
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -29,26 +29,32 @@ Classifier: Topic :: Software Development
|
|
|
29
29
|
Requires-Python: >=3.9
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
Requires-Dist: jmespath<2.0.0,>=1.0.0
|
|
32
|
+
Requires-Dist: acryl-datahub==1.4.0rc2
|
|
32
33
|
Requires-Dist: cachetools<7.0.0,>=5.0.0
|
|
33
|
-
Requires-Dist:
|
|
34
|
+
Requires-Dist: httpcore<2.0,>=1.0.9
|
|
34
35
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
35
|
-
Requires-Dist: json-repair<1.0.0,>=0.25.0
|
|
36
36
|
Requires-Dist: h11<1.0,>=0.16
|
|
37
37
|
Requires-Dist: google-re2<2.0,>=1.0
|
|
38
|
-
Requires-Dist:
|
|
38
|
+
Requires-Dist: json-repair<1.0.0,>=0.25.0
|
|
39
39
|
Provides-Extra: dev
|
|
40
|
-
Requires-Dist: types-
|
|
40
|
+
Requires-Dist: types-requests<3.0.0,>=2.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: click<9.0.0,>=8.0.0; extra == "dev"
|
|
41
42
|
Requires-Dist: types-PyYAML<7.0.0,>=6.0.0; extra == "dev"
|
|
42
|
-
Requires-Dist: mypy==1.17.1; extra == "dev"
|
|
43
43
|
Requires-Dist: types-toml<1.0.0,>=0.10.0; extra == "dev"
|
|
44
|
+
Requires-Dist: langchain-core<2.0.0,>=1.2.7; extra == "dev"
|
|
44
45
|
Requires-Dist: types-cachetools<7.0.0,>=5.0.0; extra == "dev"
|
|
45
|
-
Requires-Dist: pytest<9.0.0,>=8.3.4; extra == "dev"
|
|
46
46
|
Requires-Dist: pytest-cov<7.0.0,>=2.8.0; extra == "dev"
|
|
47
|
-
Requires-Dist:
|
|
48
|
-
Requires-Dist: tox<5.0.0,>=4.0.0; extra == "dev"
|
|
47
|
+
Requires-Dist: mypy==1.17.1; extra == "dev"
|
|
49
48
|
Requires-Dist: ruff==0.11.7; extra == "dev"
|
|
49
|
+
Requires-Dist: types-jmespath<2.0.0,>=1.0.0; extra == "dev"
|
|
50
|
+
Requires-Dist: snowflake-connector-python<4.0.0,>=3.0.0; extra == "dev"
|
|
51
|
+
Requires-Dist: pytest<9.0.0,>=8.3.4; extra == "dev"
|
|
52
|
+
Requires-Dist: tox<5.0.0,>=4.0.0; extra == "dev"
|
|
50
53
|
Provides-Extra: langchain
|
|
51
54
|
Requires-Dist: langchain-core<2.0.0,>=1.2.7; extra == "langchain"
|
|
55
|
+
Provides-Extra: snowflake
|
|
56
|
+
Requires-Dist: snowflake-connector-python<4.0.0,>=3.0.0; extra == "snowflake"
|
|
57
|
+
Requires-Dist: click<9.0.0,>=8.0.0; extra == "snowflake"
|
|
52
58
|
Dynamic: classifier
|
|
53
59
|
Dynamic: description
|
|
54
60
|
Dynamic: description-content-type
|
|
@@ -105,7 +111,7 @@ from datahub_agent_context.mcp_tools.entities import get_entities
|
|
|
105
111
|
client = DataHubClient.from_env()
|
|
106
112
|
|
|
107
113
|
# Search for datasets
|
|
108
|
-
with client
|
|
114
|
+
with client as client:
|
|
109
115
|
results = search(
|
|
110
116
|
query="user_data",
|
|
111
117
|
filters={"entity_type": ["dataset"]},
|
|
@@ -113,7 +119,7 @@ with client.graph as graph:
|
|
|
113
119
|
)
|
|
114
120
|
|
|
115
121
|
# Get detailed entity information
|
|
116
|
-
with client
|
|
122
|
+
with client as client:
|
|
117
123
|
entities = get_entities(
|
|
118
124
|
urns=[result["entity"]["urn"] for result in results["searchResults"]]
|
|
119
125
|
)
|
|
@@ -175,6 +181,7 @@ agent = create_agent(model, tools=tools, system_prompt="...")
|
|
|
175
181
|
- `add_owners()`, `remove_owners()` - Manage owners
|
|
176
182
|
- `add_glossary_terms()`, `remove_glossary_terms()` - Manage glossary terms
|
|
177
183
|
- `add_structured_properties()`, `remove_structured_properties()` - Manage structured properties
|
|
184
|
+
- `save_document()` - Save or update a Document.
|
|
178
185
|
|
|
179
186
|
#### User Tools
|
|
180
187
|
|
|
@@ -43,7 +43,7 @@ from datahub_agent_context.mcp_tools.entities import get_entities
|
|
|
43
43
|
client = DataHubClient.from_env()
|
|
44
44
|
|
|
45
45
|
# Search for datasets
|
|
46
|
-
with client
|
|
46
|
+
with client as client:
|
|
47
47
|
results = search(
|
|
48
48
|
query="user_data",
|
|
49
49
|
filters={"entity_type": ["dataset"]},
|
|
@@ -51,7 +51,7 @@ with client.graph as graph:
|
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
# Get detailed entity information
|
|
54
|
-
with client
|
|
54
|
+
with client as client:
|
|
55
55
|
entities = get_entities(
|
|
56
56
|
urns=[result["entity"]["urn"] for result in results["searchResults"]]
|
|
57
57
|
)
|
|
@@ -113,6 +113,7 @@ agent = create_agent(model, tools=tools, system_prompt="...")
|
|
|
113
113
|
- `add_owners()`, `remove_owners()` - Manage owners
|
|
114
114
|
- `add_glossary_terms()`, `remove_glossary_terms()` - Manage glossary terms
|
|
115
115
|
- `add_structured_properties()`, `remove_structured_properties()` - Manage structured properties
|
|
116
|
+
- `save_document()` - Save or update a Document.
|
|
116
117
|
|
|
117
118
|
#### User Tools
|
|
118
119
|
|
|
@@ -69,9 +69,16 @@ langchain_requirements = {
|
|
|
69
69
|
"langchain-core>=1.2.7,<2.0.0",
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
snowflake_requirements = {
|
|
73
|
+
"click>=8.0.0,<9.0.0",
|
|
74
|
+
"snowflake-connector-python>=3.0.0,<4.0.0",
|
|
75
|
+
}
|
|
76
|
+
|
|
72
77
|
dev_requirements = {
|
|
73
78
|
*lint_requirements,
|
|
74
79
|
*mypy_stubs,
|
|
80
|
+
*snowflake_requirements,
|
|
81
|
+
*langchain_requirements,
|
|
75
82
|
"pytest>=8.3.4,<9.0.0",
|
|
76
83
|
"pytest-cov>=2.8.0,<7.0.0",
|
|
77
84
|
"tox>=4.0.0,<5.0.0",
|
|
@@ -123,5 +130,6 @@ setuptools.setup(
|
|
|
123
130
|
extras_require={
|
|
124
131
|
"dev": list(dev_requirements),
|
|
125
132
|
"langchain": list(langchain_requirements),
|
|
133
|
+
"snowflake": list(snowflake_requirements),
|
|
126
134
|
},
|
|
127
135
|
)
|
|
@@ -17,9 +17,17 @@
|
|
|
17
17
|
from datahub_agent_context._version import __version__
|
|
18
18
|
from datahub_agent_context.context import (
|
|
19
19
|
DataHubContext,
|
|
20
|
+
get_datahub_client,
|
|
20
21
|
get_graph,
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
reset_client,
|
|
23
|
+
set_client,
|
|
23
24
|
)
|
|
24
25
|
|
|
25
|
-
__all__ = [
|
|
26
|
+
__all__ = [
|
|
27
|
+
"__version__",
|
|
28
|
+
"DataHubContext",
|
|
29
|
+
"get_datahub_client",
|
|
30
|
+
"get_graph",
|
|
31
|
+
"set_client",
|
|
32
|
+
"reset_client",
|
|
33
|
+
]
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group()
|
|
9
|
+
def agent() -> None:
|
|
10
|
+
"""Helper commands for Creating and managing Agent on DataHub."""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@agent.group()
|
|
15
|
+
def create() -> None:
|
|
16
|
+
"""Create an agent on DataHub."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@create.command(name="snowflake")
|
|
21
|
+
@click.option(
|
|
22
|
+
"--sf-account",
|
|
23
|
+
default=None,
|
|
24
|
+
help="Snowflake account identifier (auto-detected if not provided)",
|
|
25
|
+
)
|
|
26
|
+
@click.option(
|
|
27
|
+
"--sf-user",
|
|
28
|
+
default=None,
|
|
29
|
+
help="Snowflake user name (auto-detected if not provided)",
|
|
30
|
+
)
|
|
31
|
+
@click.option(
|
|
32
|
+
"--sf-role",
|
|
33
|
+
default=None,
|
|
34
|
+
help="Snowflake role (auto-detected if not provided)",
|
|
35
|
+
)
|
|
36
|
+
@click.option(
|
|
37
|
+
"--sf-warehouse",
|
|
38
|
+
default=None,
|
|
39
|
+
help="Snowflake warehouse name (auto-detected if not provided)",
|
|
40
|
+
)
|
|
41
|
+
@click.option(
|
|
42
|
+
"--sf-database",
|
|
43
|
+
default=None,
|
|
44
|
+
help="Snowflake database name (auto-detected if not provided)",
|
|
45
|
+
)
|
|
46
|
+
@click.option(
|
|
47
|
+
"--sf-schema",
|
|
48
|
+
default=None,
|
|
49
|
+
help="Snowflake schema name (auto-detected if not provided)",
|
|
50
|
+
)
|
|
51
|
+
@click.option("--datahub-url", required=True, help="DataHub instance URL")
|
|
52
|
+
@click.option("--datahub-token", required=True, help="DataHub Personal Access Token")
|
|
53
|
+
@click.option(
|
|
54
|
+
"--agent-name", default="DATAHUB_SQL_AGENT", help="Agent name in Snowflake"
|
|
55
|
+
)
|
|
56
|
+
@click.option(
|
|
57
|
+
"--agent-display-name",
|
|
58
|
+
default="DataHub SQL Assistant",
|
|
59
|
+
help="Agent display name in Snowflake UI",
|
|
60
|
+
)
|
|
61
|
+
@click.option(
|
|
62
|
+
"--agent-color",
|
|
63
|
+
default="blue",
|
|
64
|
+
help="Agent color in Snowflake UI",
|
|
65
|
+
type=click.Choice(["blue", "red", "green", "yellow", "purple", "orange"]),
|
|
66
|
+
)
|
|
67
|
+
@click.option(
|
|
68
|
+
"--output-dir",
|
|
69
|
+
default="./snowflake_setup",
|
|
70
|
+
help="Output directory for generated SQL files",
|
|
71
|
+
)
|
|
72
|
+
@click.option(
|
|
73
|
+
"--execute",
|
|
74
|
+
is_flag=True,
|
|
75
|
+
default=False,
|
|
76
|
+
help="Connect to Snowflake and execute the SQL scripts directly",
|
|
77
|
+
)
|
|
78
|
+
@click.option(
|
|
79
|
+
"--sf-password",
|
|
80
|
+
help="Snowflake password (required if --execute is used with password authentication)",
|
|
81
|
+
)
|
|
82
|
+
@click.option(
|
|
83
|
+
"--sf-authenticator",
|
|
84
|
+
default="snowflake",
|
|
85
|
+
type=click.Choice(["snowflake", "externalbrowser", "oauth"], case_sensitive=False),
|
|
86
|
+
help="Authentication method: 'snowflake' (password), 'externalbrowser' (SSO), or 'oauth' (token-based). Default: snowflake",
|
|
87
|
+
)
|
|
88
|
+
@click.option(
|
|
89
|
+
"--enable-mutations/--no-enable-mutations",
|
|
90
|
+
default=True,
|
|
91
|
+
help="Include mutation/write tools (tags, descriptions, owners, etc.). Default: enabled",
|
|
92
|
+
)
|
|
93
|
+
def create_snowflake(
|
|
94
|
+
sf_account: str | None,
|
|
95
|
+
sf_user: str | None,
|
|
96
|
+
sf_role: str | None,
|
|
97
|
+
sf_warehouse: str | None,
|
|
98
|
+
sf_database: str | None,
|
|
99
|
+
sf_schema: str | None,
|
|
100
|
+
datahub_url: str,
|
|
101
|
+
datahub_token: str,
|
|
102
|
+
agent_name: str,
|
|
103
|
+
agent_display_name: str,
|
|
104
|
+
agent_color: str,
|
|
105
|
+
output_dir: str,
|
|
106
|
+
execute: bool,
|
|
107
|
+
sf_password: str | None,
|
|
108
|
+
sf_authenticator: str,
|
|
109
|
+
enable_mutations: bool,
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Create a Snowflake agent on DataHub.
|
|
112
|
+
|
|
113
|
+
Snowflake connection parameters (account, user, role, warehouse, database, schema)
|
|
114
|
+
will be auto-detected from your current session if not provided explicitly.
|
|
115
|
+
|
|
116
|
+
Authentication methods:
|
|
117
|
+
- snowflake (default): Standard password authentication
|
|
118
|
+
- externalbrowser: SSO authentication via browser (no password required)
|
|
119
|
+
- oauth: OAuth token-based authentication
|
|
120
|
+
|
|
121
|
+
Examples:
|
|
122
|
+
# Generate SQL files only (default)
|
|
123
|
+
$ datahub agent create snowflake --datahub-url=... --datahub-token=...
|
|
124
|
+
|
|
125
|
+
# Execute with password authentication
|
|
126
|
+
$ datahub agent create snowflake --execute --sf-password=secret ...
|
|
127
|
+
|
|
128
|
+
# Execute with SSO authentication (browser-based)
|
|
129
|
+
$ datahub agent create snowflake --execute --sf-authenticator=externalbrowser ...
|
|
130
|
+
"""
|
|
131
|
+
from datahub_agent_context.snowflake.snowflake import create_snowflake_agent
|
|
132
|
+
|
|
133
|
+
ctx = click.get_current_context()
|
|
134
|
+
ctx.invoke(
|
|
135
|
+
create_snowflake_agent,
|
|
136
|
+
sf_account=sf_account,
|
|
137
|
+
sf_user=sf_user,
|
|
138
|
+
sf_role=sf_role,
|
|
139
|
+
sf_warehouse=sf_warehouse,
|
|
140
|
+
sf_database=sf_database,
|
|
141
|
+
sf_schema=sf_schema,
|
|
142
|
+
datahub_url=datahub_url,
|
|
143
|
+
datahub_token=datahub_token,
|
|
144
|
+
agent_name=agent_name,
|
|
145
|
+
agent_display_name=agent_display_name,
|
|
146
|
+
agent_color=agent_color,
|
|
147
|
+
output_dir=output_dir,
|
|
148
|
+
execute=execute,
|
|
149
|
+
sf_password=sf_password,
|
|
150
|
+
sf_authenticator=sf_authenticator,
|
|
151
|
+
enable_mutations=enable_mutations,
|
|
152
|
+
)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Context management for DataHub tools.
|
|
2
|
+
|
|
3
|
+
This module provides a context manager pattern for managing DataHubClient instances
|
|
4
|
+
across tool calls without explicit parameter passing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import contextvars
|
|
8
|
+
from typing import TYPE_CHECKING, Optional
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from datahub.ingestion.graph.client import DataHubGraph
|
|
12
|
+
from datahub.sdk.main_client import DataHubClient
|
|
13
|
+
|
|
14
|
+
# Context variable to store the current DataHubClient instance
|
|
15
|
+
_client_context: contextvars.ContextVar[Optional["DataHubClient"]] = (
|
|
16
|
+
contextvars.ContextVar("datahub_client", default=None)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_datahub_client() -> "DataHubClient":
|
|
21
|
+
"""Get the current DataHubClient from context.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
DataHubClient instance from context
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
RuntimeError: If no client is set in context
|
|
28
|
+
"""
|
|
29
|
+
client = _client_context.get()
|
|
30
|
+
if client is None:
|
|
31
|
+
raise RuntimeError(
|
|
32
|
+
"No DataHubClient in context. "
|
|
33
|
+
"Make sure to use DataHubContext context manager or set_client() before calling tools."
|
|
34
|
+
)
|
|
35
|
+
return client
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_graph() -> "DataHubGraph":
|
|
39
|
+
"""Get the current DataHubGraph from context (convenience method).
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
DataHubGraph instance from the client in context
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
RuntimeError: If no client is set in context
|
|
46
|
+
"""
|
|
47
|
+
return get_datahub_client()._graph
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def set_client(client: "DataHubClient") -> contextvars.Token:
|
|
51
|
+
"""Set the DataHubClient in context.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
client: DataHubClient instance to set
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Token that can be used to reset the context
|
|
58
|
+
"""
|
|
59
|
+
return _client_context.set(client)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def reset_client(token: contextvars.Token) -> None:
|
|
63
|
+
"""Reset the DataHubClient context to its previous value.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
token: Token returned by set_client()
|
|
67
|
+
"""
|
|
68
|
+
_client_context.reset(token)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class DataHubContext:
|
|
72
|
+
"""Context manager for DataHub tool execution.
|
|
73
|
+
|
|
74
|
+
This context manager sets the DataHubClient in context for the duration
|
|
75
|
+
of the with block, allowing tools to access it without explicit parameter passing.
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
from datahub.sdk.main_client import DataHubClient
|
|
79
|
+
from datahub_agent_context.context import DataHubContext
|
|
80
|
+
from datahub_agent_context.mcp_tools import search
|
|
81
|
+
|
|
82
|
+
client = DataHubClient(...)
|
|
83
|
+
|
|
84
|
+
with DataHubContext(client):
|
|
85
|
+
results = search(query="users") # No client parameter needed!
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, client: "DataHubClient"):
|
|
89
|
+
"""Initialize the context manager.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
client: DataHubClient instance to use in this context
|
|
93
|
+
"""
|
|
94
|
+
self.client = client
|
|
95
|
+
self._token: Optional[contextvars.Token] = None
|
|
96
|
+
|
|
97
|
+
def __enter__(self) -> "DataHubClient":
|
|
98
|
+
"""Enter the context and set the client.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
The DataHubClient instance
|
|
102
|
+
"""
|
|
103
|
+
self._token = set_client(self.client)
|
|
104
|
+
return self.client
|
|
105
|
+
|
|
106
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
107
|
+
"""Exit the context and reset the client."""
|
|
108
|
+
if self._token is not None:
|
|
109
|
+
reset_client(self._token)
|
|
110
|
+
self._token = None
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import functools
|
|
4
4
|
from typing import TYPE_CHECKING, Callable
|
|
5
5
|
|
|
6
|
-
from datahub_agent_context.context import
|
|
6
|
+
from datahub_agent_context.context import set_client
|
|
7
7
|
from datahub_agent_context.mcp_tools import get_me
|
|
8
8
|
from datahub_agent_context.mcp_tools.documents import grep_documents, search_documents
|
|
9
9
|
from datahub_agent_context.mcp_tools.domains import remove_domains, set_domains
|
|
@@ -32,6 +32,7 @@ from datahub_agent_context.mcp_tools.lineage import (
|
|
|
32
32
|
)
|
|
33
33
|
from datahub_agent_context.mcp_tools.owners import add_owners, remove_owners
|
|
34
34
|
from datahub_agent_context.mcp_tools.queries import get_dataset_queries
|
|
35
|
+
from datahub_agent_context.mcp_tools.save_document import save_document
|
|
35
36
|
from datahub_agent_context.mcp_tools.search import search
|
|
36
37
|
from datahub_agent_context.mcp_tools.tags import add_tags, remove_tags
|
|
37
38
|
from datahub_agent_context.mcp_tools.terms import (
|
|
@@ -57,14 +58,14 @@ def create_context_wrapper(func: Callable, client: "DataHubClient") -> Callable:
|
|
|
57
58
|
@functools.wraps(func)
|
|
58
59
|
def wrapper(*args, **kwargs):
|
|
59
60
|
# Set graph in context for this function call
|
|
60
|
-
token =
|
|
61
|
+
token = set_client(client)
|
|
61
62
|
try:
|
|
62
63
|
return func(*args, **kwargs)
|
|
63
64
|
finally:
|
|
64
65
|
# Always reset context, even if function raises
|
|
65
|
-
from datahub_agent_context.context import
|
|
66
|
+
from datahub_agent_context.context import reset_client
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
reset_client(token)
|
|
68
69
|
|
|
69
70
|
return wrapper
|
|
70
71
|
|
|
@@ -123,5 +124,6 @@ def build_langchain_tools(
|
|
|
123
124
|
tools.append(tool(create_context_wrapper(remove_tags, client)))
|
|
124
125
|
tools.append(tool(create_context_wrapper(add_glossary_terms, client)))
|
|
125
126
|
tools.append(tool(create_context_wrapper(remove_glossary_terms, client)))
|
|
127
|
+
tools.append(tool(create_context_wrapper(save_document, client)))
|
|
126
128
|
|
|
127
129
|
return tools
|
|
@@ -152,9 +152,12 @@ def _is_datahub_cloud(graph: DataHubGraph) -> bool:
|
|
|
152
152
|
)
|
|
153
153
|
return False
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
try:
|
|
156
|
+
is_cloud = hasattr(graph, "frontend_base_url") and graph.frontend_base_url
|
|
157
|
+
logger.debug(f"Cloud detection: {is_cloud}")
|
|
158
|
+
return bool(is_cloud)
|
|
159
|
+
except ValueError:
|
|
160
|
+
return False
|
|
158
161
|
|
|
159
162
|
|
|
160
163
|
def _is_field_validation_error(error_msg: str) -> bool:
|