blob: 50ec4ee7ff7b631d22f2282ee6935246d8389cd4 [file]
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2024-08-13T16:17:40.744646Z",
"start_time": "2024-08-13T16:17:32.149272Z"
}
},
"source": "%load_ext hamilton.plugins.jupyter_magic",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/stefankrawczyk/.pyenv/versions/knowledge_retrieval-py39/lib/python3.9/site-packages/pyspark/pandas/__init__.py:50: UserWarning: 'PYARROW_IGNORE_TIMEZONE' environment variable was not set. It is required to set this environment variable to '1' in both driver and executor sides if you use pyarrow>=2.0.0. pandas-on-Spark will set it for you but it does not work if there is a Spark context already launched.\n",
" warnings.warn(\n"
]
}
],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-08-13T16:17:52.022254Z",
"start_time": "2024-08-13T16:17:51.439954Z"
}
},
"cell_type": "code",
"source": [
"%%cell_to_module good_module --display\n",
"from hamilton.function_modifiers import tag\n",
"\n",
"@tag(node_type=\"output\", table_name=\"my_table\")\n",
"def foo() -> str:\n",
" return \"Hello, world!\"\n"
],
"id": "acac6adfe569cbc",
"outputs": [
{
"data": {
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 12.0.0 (20240704.0754)\n -->\n<!-- Pages: 1 -->\n<svg width=\"109pt\" height=\"165pt\"\n viewBox=\"0.00 0.00 108.85 164.80\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 160.8)\">\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-160.8 104.85,-160.8 104.85,4 -4,4\"/>\n<g id=\"clust1\" class=\"cluster\">\n<title>cluster__legend</title>\n<polygon fill=\"#ffffff\" stroke=\"black\" points=\"8,-73.8 8,-148.8 92.85,-148.8 92.85,-73.8 8,-73.8\"/>\n<text text-anchor=\"middle\" x=\"50.42\" y=\"-131.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Legend</text>\n</g>\n<!-- foo -->\n<g id=\"node1\" class=\"node\">\n<title>foo</title>\n<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M65.42,-63.6C65.42,-63.6 35.42,-63.6 35.42,-63.6 29.42,-63.6 23.42,-57.6 23.42,-51.6 23.42,-51.6 23.42,-12 23.42,-12 23.42,-6 29.42,0 35.42,0 35.42,0 65.42,0 65.42,0 71.42,0 77.42,-6 77.42,-12 77.42,-12 77.42,-51.6 77.42,-51.6 77.42,-57.6 71.42,-63.6 65.42,-63.6\"/>\n<text text-anchor=\"start\" x=\"39.92\" y=\"-40.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">foo</text>\n<text text-anchor=\"start\" x=\"42.92\" y=\"-12.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">str</text>\n</g>\n<!-- function -->\n<g id=\"node2\" class=\"node\">\n<title>function</title>\n<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M72.85,-118.1C72.85,-118.1 28,-118.1 28,-118.1 22,-118.1 16,-112.1 16,-106.1 16,-106.1 16,-93.5 16,-93.5 16,-87.5 22,-81.5 28,-81.5 28,-81.5 72.85,-81.5 72.85,-81.5 78.85,-81.5 84.85,-87.5 84.85,-93.5 84.85,-93.5 84.85,-106.1 84.85,-106.1 84.85,-112.1 78.85,-118.1 72.85,-118.1\"/>\n<text text-anchor=\"middle\" x=\"50.42\" y=\"-94\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">function</text>\n</g>\n</g>\n</svg>\n",
"text/plain": [
"<graphviz.graphs.Digraph at 0x14f34ebe0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"execution_count": 2
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-08-13T16:18:06.041014Z",
"start_time": "2024-08-13T16:18:05.676209Z"
}
},
"cell_type": "code",
"source": [
"%%cell_to_module bad_module --display\n",
"from hamilton.function_modifiers import tag\n",
"\n",
"@tag(node_type=\"output\")\n",
"def foo() -> str:\n",
" return \"Hello, world!\""
],
"id": "667a78a28d435a0f",
"outputs": [
{
"data": {
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 12.0.0 (20240704.0754)\n -->\n<!-- Pages: 1 -->\n<svg width=\"109pt\" height=\"165pt\"\n viewBox=\"0.00 0.00 108.85 164.80\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 160.8)\">\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-160.8 104.85,-160.8 104.85,4 -4,4\"/>\n<g id=\"clust1\" class=\"cluster\">\n<title>cluster__legend</title>\n<polygon fill=\"#ffffff\" stroke=\"black\" points=\"8,-73.8 8,-148.8 92.85,-148.8 92.85,-73.8 8,-73.8\"/>\n<text text-anchor=\"middle\" x=\"50.42\" y=\"-131.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Legend</text>\n</g>\n<!-- foo -->\n<g id=\"node1\" class=\"node\">\n<title>foo</title>\n<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M65.42,-63.6C65.42,-63.6 35.42,-63.6 35.42,-63.6 29.42,-63.6 23.42,-57.6 23.42,-51.6 23.42,-51.6 23.42,-12 23.42,-12 23.42,-6 29.42,0 35.42,0 35.42,0 65.42,0 65.42,0 71.42,0 77.42,-6 77.42,-12 77.42,-12 77.42,-51.6 77.42,-51.6 77.42,-57.6 71.42,-63.6 65.42,-63.6\"/>\n<text text-anchor=\"start\" x=\"39.92\" y=\"-40.5\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">foo</text>\n<text text-anchor=\"start\" x=\"42.92\" y=\"-12.5\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">str</text>\n</g>\n<!-- function -->\n<g id=\"node2\" class=\"node\">\n<title>function</title>\n<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M72.85,-118.1C72.85,-118.1 28,-118.1 28,-118.1 22,-118.1 16,-112.1 16,-106.1 16,-106.1 16,-93.5 16,-93.5 16,-87.5 22,-81.5 28,-81.5 28,-81.5 72.85,-81.5 72.85,-81.5 78.85,-81.5 84.85,-87.5 84.85,-93.5 84.85,-93.5 84.85,-106.1 84.85,-106.1 84.85,-112.1 78.85,-118.1 72.85,-118.1\"/>\n<text text-anchor=\"middle\" x=\"50.42\" y=\"-94\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">function</text>\n</g>\n</g>\n</svg>\n",
"text/plain": [
"<graphviz.graphs.Digraph at 0x14f359790>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"execution_count": 3
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-08-13T16:19:09.270965Z",
"start_time": "2024-08-13T16:19:09.266344Z"
}
},
"cell_type": "code",
"source": [
"# Validator\n",
"from typing import Optional\n",
"from hamilton.lifecycle import api\n",
"from hamilton.graph_types import HamiltonNode\n",
"\n",
"\n",
"class MyTagValidator(api.StaticValidator):\n",
" \"\"\"Static validator that is run right after the graph is built.\"\"\"\n",
"\n",
" def run_to_validate_node(\n",
" self, *, node: HamiltonNode, **future_kwargs\n",
" ) -> tuple[bool, Optional[str]]:\n",
" if node.tags.get(\"node_type\", \"\") == \"output\":\n",
" table_name = node.tags.get(\"table_name\")\n",
" if not table_name: # None or empty\n",
" error_msg = f\"Node {node.tags['module']}.{node.name} is an output node, but does not have a table_name tag.\"\n",
" return False, error_msg\n",
" return True, None\n",
"\n",
"tag_validator = MyTagValidator()"
],
"id": "b4303b258c107981",
"outputs": [],
"execution_count": 5
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-08-13T16:19:09.998394Z",
"start_time": "2024-08-13T16:19:09.975269Z"
}
},
"cell_type": "code",
"source": [
"from hamilton import driver\n",
"\n",
"dr = (\n",
" driver.Builder()\n",
" .with_modules(good_module)\n",
" .with_adapters(tag_validator)\n",
" .build()\n",
")\n",
"dr.execute([good_module.foo])"
],
"id": "63cfc94d37dff5b",
"outputs": [
{
"data": {
"text/plain": [
"{'foo': 'Hello, world!'}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 6
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-08-13T16:19:11.923694Z",
"start_time": "2024-08-13T16:19:10.870198Z"
}
},
"cell_type": "code",
"source": [
"# this should error\n",
"dr = (\n",
" driver.Builder()\n",
" .with_modules(bad_module)\n",
" .with_adapters(tag_validator)\n",
" .build()\n",
")"
],
"id": "58c203af8cd4e793",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"-------------------------------------------------------------------\n",
"Oh no an error! Need help with Hamilton?\n",
"Join our slack and ask for help! https://join.slack.com/t/hamilton-opensource/shared_invite/zt-2niepkra8-DGKGf_tTYhXuJWBTXtIs4g\n",
"-------------------------------------------------------------------\n",
"\n"
]
},
{
"ename": "ValidationException",
"evalue": "Node validation failed! 1 errors encountered:\n foo: Node bad_module.foo is an output node, but does not have a table_name tag.",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mValidationException\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[7], line 3\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;66;03m# this should error\u001B[39;00m\n\u001B[1;32m 2\u001B[0m dr \u001B[38;5;241m=\u001B[39m (\n\u001B[0;32m----> 3\u001B[0m \u001B[43mdriver\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mBuilder\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 4\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mwith_modules\u001B[49m\u001B[43m(\u001B[49m\u001B[43mbad_module\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 5\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mwith_adapters\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtag_validator\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 6\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mbuild\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 7\u001B[0m )\n",
"File \u001B[0;32m~/dagworks/hamilton/hamilton/driver.py:1872\u001B[0m, in \u001B[0;36mBuilder.build\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 1865\u001B[0m grouping_strategy \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mgrouping_strategy \u001B[38;5;129;01mor\u001B[39;00m grouping\u001B[38;5;241m.\u001B[39mGroupByRepeatableBlocks()\n\u001B[1;32m 1866\u001B[0m graph_executor \u001B[38;5;241m=\u001B[39m TaskBasedGraphExecutor(\n\u001B[1;32m 1867\u001B[0m execution_manager\u001B[38;5;241m=\u001B[39mexecution_manager,\n\u001B[1;32m 1868\u001B[0m grouping_strategy\u001B[38;5;241m=\u001B[39mgrouping_strategy,\n\u001B[1;32m 1869\u001B[0m adapter\u001B[38;5;241m=\u001B[39mlifecycle_base\u001B[38;5;241m.\u001B[39mLifecycleAdapterSet(\u001B[38;5;241m*\u001B[39madapter),\n\u001B[1;32m 1870\u001B[0m )\n\u001B[0;32m-> 1872\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mDriver\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 1873\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mconfig\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 1874\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodules\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 1875\u001B[0m \u001B[43m \u001B[49m\u001B[43madapter\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43madapter\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 1876\u001B[0m \u001B[43m \u001B[49m\u001B[43m_materializers\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmaterializers\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 1877\u001B[0m \u001B[43m \u001B[49m\u001B[43m_graph_executor\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mgraph_executor\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 1878\u001B[0m \u001B[43m \u001B[49m\u001B[43m_use_legacy_adapter\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m 1879\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n",
"File \u001B[0;32m~/dagworks/hamilton/hamilton/driver.py:412\u001B[0m, in \u001B[0;36mDriver.__init__\u001B[0;34m(self, config, adapter, _materializers, _graph_executor, _use_legacy_adapter, *modules)\u001B[0m\n\u001B[1;32m 410\u001B[0m error \u001B[38;5;241m=\u001B[39m telemetry\u001B[38;5;241m.\u001B[39msanitize_error(\u001B[38;5;241m*\u001B[39msys\u001B[38;5;241m.\u001B[39mexc_info())\n\u001B[1;32m 411\u001B[0m logger\u001B[38;5;241m.\u001B[39merror(SLACK_ERROR_MESSAGE)\n\u001B[0;32m--> 412\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[1;32m 413\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[1;32m 414\u001B[0m \u001B[38;5;66;03m# TODO -- update this to use the lifecycle methods\u001B[39;00m\n\u001B[1;32m 415\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcapture_constructor_telemetry(error, modules, config, adapter)\n",
"File \u001B[0;32m~/dagworks/hamilton/hamilton/driver.py:399\u001B[0m, in \u001B[0;36mDriver.__init__\u001B[0;34m(self, config, adapter, _materializers, _graph_executor, _use_legacy_adapter, *modules)\u001B[0m\n\u001B[1;32m 393\u001B[0m materializer_factories, extractor_factories \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_process_materializers(\n\u001B[1;32m 394\u001B[0m _materializers\n\u001B[1;32m 395\u001B[0m )\n\u001B[1;32m 396\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mgraph \u001B[38;5;241m=\u001B[39m materialization\u001B[38;5;241m.\u001B[39mmodify_graph(\n\u001B[1;32m 397\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mgraph, materializer_factories, extractor_factories\n\u001B[1;32m 398\u001B[0m )\n\u001B[0;32m--> 399\u001B[0m \u001B[43mDriver\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_perform_graph_validations\u001B[49m\u001B[43m(\u001B[49m\u001B[43madapter\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mgraph\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mgraph\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mgraph_modules\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mmodules\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 400\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m adapter\u001B[38;5;241m.\u001B[39mdoes_hook(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mpost_graph_construct\u001B[39m\u001B[38;5;124m\"\u001B[39m, is_async\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m):\n\u001B[1;32m 401\u001B[0m adapter\u001B[38;5;241m.\u001B[39mcall_all_lifecycle_hooks_sync(\n\u001B[1;32m 402\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mpost_graph_construct\u001B[39m\u001B[38;5;124m\"\u001B[39m, graph\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mgraph, modules\u001B[38;5;241m=\u001B[39mmodules, config\u001B[38;5;241m=\u001B[39mconfig\n\u001B[1;32m 403\u001B[0m )\n",
"File \u001B[0;32m~/dagworks/hamilton/hamilton/driver.py:339\u001B[0m, in \u001B[0;36mDriver._perform_graph_validations\u001B[0;34m(adapter, graph, graph_modules)\u001B[0m\n\u001B[1;32m 329\u001B[0m errors \u001B[38;5;241m=\u001B[39m [\n\u001B[1;32m 330\u001B[0m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mnode_name\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m: \u001B[39m\u001B[38;5;132;01m{\u001B[39;00merror_delimiter\u001B[38;5;241m.\u001B[39mjoin([item\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mfor\u001B[39;00m\u001B[38;5;250m \u001B[39mitem\u001B[38;5;250m \u001B[39m\u001B[38;5;129;01min\u001B[39;00m\u001B[38;5;250m \u001B[39mmessages])\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 331\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m node_name, messages \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28msorted\u001B[39m(\n\u001B[1;32m 332\u001B[0m node_validation_results\u001B[38;5;241m.\u001B[39mitems(), key\u001B[38;5;241m=\u001B[39moperator\u001B[38;5;241m.\u001B[39mitemgetter(\u001B[38;5;241m0\u001B[39m)\n\u001B[1;32m 333\u001B[0m )\n\u001B[1;32m 334\u001B[0m ]\n\u001B[1;32m 335\u001B[0m error_str \u001B[38;5;241m=\u001B[39m (\n\u001B[1;32m 336\u001B[0m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mNode validation failed! \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mlen\u001B[39m(errors)\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m errors encountered:\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 337\u001B[0m \u001B[38;5;241m+\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m \u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mjoin(errors)\n\u001B[1;32m 338\u001B[0m )\n\u001B[0;32m--> 339\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m lifecycle_base\u001B[38;5;241m.\u001B[39mValidationException(error_str)\n\u001B[1;32m 340\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m adapter\u001B[38;5;241m.\u001B[39mdoes_validation(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalidate_graph\u001B[39m\u001B[38;5;124m\"\u001B[39m):\n\u001B[1;32m 341\u001B[0m validation_results \u001B[38;5;241m=\u001B[39m adapter\u001B[38;5;241m.\u001B[39mcall_all_validators_sync(\n\u001B[1;32m 342\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalidate_graph\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[1;32m 343\u001B[0m output_only_failures\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 346\u001B[0m config\u001B[38;5;241m=\u001B[39mgraph\u001B[38;5;241m.\u001B[39mconfig,\n\u001B[1;32m 347\u001B[0m )\n",
"\u001B[0;31mValidationException\u001B[0m: Node validation failed! 1 errors encountered:\n foo: Node bad_module.foo is an output node, but does not have a table_name tag."
]
}
],
"execution_count": 7
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "",
"id": "b508258007d9283c"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}