[{'Text': '"""Snowflake database query and analysis tools."""\n\nimport json\nfrom typing import List, Optional\nfrom fastmcp import Context\nfrom point_topic_mcp.core.context_assembly import list_datasets, assemble_context\nfrom point_topic_mcp.core.utils import dynamic_docstring, check_env_vars\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\n# Snowflake database tools (require credentials)\nif check_env_vars(\'snowflake_tools\', [\'SNOWFLAKE_USER\', \'SNOWFLAKE_PASSWORD\']):\n    @dynamic_docstring([("{DATASETS}", list_datasets)])\n    def assemble_dataset_context(\n        dataset_names: List[str], \n        ctx: Optional[Context] = None\n    ) -> str:\n        """\n        Assemble full context (instructions, schema, examples) for one or more datasets.\n\n        This is essential before executing a query, for the agent to understand how to query the datasets.\n        \n        Args:\n            dataset_names: List of dataset names to include (e.g., [\'upc\', \'upc_take_up\'])\n        \n        {DATASETS}\n        \n        Returns the complete context needed for querying these datasets.\n        """\n        return assemble_context(dataset_names)\n\n    async def execute_query(\n        sql_query: str,\n        ctx: Optional[Context] = None,\n    ) -> str:\n        """\n        Execute safe SQL queries against the Snowflake database.\n        Only read-only queries allowed (SELECT, WITH, SHOW, DESCRIBE, EXPLAIN).\n\n        Multiple queries can be executed in one call by separating them with semicolons (;).\n        Each query will be validated and executed separately, with clearly labeled results.\n\n        You must first assemble the context for the datasets you are querying using the assemble_dataset_context tool.\n\n        Args:\n            sql_query: The SQL query or queries to execute (separated by semicolons for multiple queries)\n\n        Returns:\n            Results starting with `query_id:<id>` on the first line, followed by CSV data.\n            The query_id can be passed to cancel_query() to cancel a running query,\n            or to get_query_status() to check its current state.\n            For multiple queries, each result section includes its own query_id.\n\n        Examples:\n            Single query: "SELECT COUNT(*) FROM table1"\n            Multiple queries: "SELECT COUNT(*) FROM table1; SELECT AVG(price) FROM table2"\n        """\n        from point_topic_mcp.connectors.snowflake import SnowflakeDB, non_empty_sql_statements\n\n'}]