55import re
66from typing import Any , Dict , Tuple , List , Optional , Union , TYPE_CHECKING , Set
77
8- from databricks .sql .backend .sea .models .base import ResultManifest , StatementStatus
8+ from databricks .sql .backend .sea .models .base import (
9+ ExternalLink ,
10+ ResultManifest ,
11+ StatementStatus ,
12+ )
13+ from databricks .sql .backend .sea .models .responses import GetChunksResponse
914from databricks .sql .backend .sea .utils .constants import (
1015 ALLOWED_SESSION_CONF_TO_DEFAULT_VALUES_MAP ,
1116 ResultFormat ,
1924if TYPE_CHECKING :
2025 from databricks .sql .client import Cursor
2126
22- from databricks .sql .result_set import SeaResultSet
27+ from databricks .sql .backend . sea . result_set import SeaResultSet
2328
2429from databricks .sql .backend .databricks_client import DatabricksClient
2530from databricks .sql .backend .types import (
@@ -110,6 +115,7 @@ class SeaDatabricksClient(DatabricksClient):
110115 STATEMENT_PATH = BASE_PATH + "statements"
111116 STATEMENT_PATH_WITH_ID = STATEMENT_PATH + "/{}"
112117 CANCEL_STATEMENT_PATH_WITH_ID = STATEMENT_PATH + "/{}/cancel"
118+ CHUNK_PATH_WITH_ID_AND_INDEX = STATEMENT_PATH + "/{}/result/chunks/{}"
113119
114120 # SEA constants
115121 POLL_INTERVAL_SECONDS = 0.2
@@ -296,7 +302,7 @@ def close_session(self, session_id: SessionId) -> None:
296302
297303 def _extract_description_from_manifest (
298304 self , manifest : ResultManifest
299- ) -> Optional [ List ]:
305+ ) -> List [ Tuple ]:
300306 """
301307 Extract column description from a manifest object, in the format defined by
302308 the spec: https://peps.python.org/pep-0249/#description
@@ -311,9 +317,6 @@ def _extract_description_from_manifest(
311317 schema_data = manifest .schema
312318 columns_data = schema_data .get ("columns" , [])
313319
314- if not columns_data :
315- return None
316-
317320 columns = []
318321 for col_data in columns_data :
319322 # Format: (name, type_code, display_size, internal_size, precision, scale, null_ok)
@@ -337,7 +340,7 @@ def _extract_description_from_manifest(
337340 )
338341 )
339342
340- return columns if columns else None
343+ return columns
341344
342345 def _results_message_to_execute_response (
343346 self , response : Union [ExecuteStatementResponse , GetStatementResponse ]
@@ -358,7 +361,7 @@ def _results_message_to_execute_response(
358361
359362 # Check for compression
360363 lz4_compressed = (
361- response .manifest .result_compression == ResultCompression .LZ4_FRAME
364+ response .manifest .result_compression == ResultCompression .LZ4_FRAME . value
362365 )
363366
364367 execute_response = ExecuteResponse (
@@ -647,6 +650,27 @@ def get_execution_result(
647650 response = self ._poll_query (command_id )
648651 return self ._response_to_result_set (response , cursor )
649652
653+ def get_chunk_links (
654+ self , statement_id : str , chunk_index : int
655+ ) -> List [ExternalLink ]:
656+ """
657+ Get links for chunks starting from the specified index.
658+ Args:
659+ statement_id: The statement ID
660+ chunk_index: The starting chunk index
661+ Returns:
662+ ExternalLink: External link for the chunk
663+ """
664+
665+ response_data = self ._http_client ._make_request (
666+ method = "GET" ,
667+ path = self .CHUNK_PATH_WITH_ID_AND_INDEX .format (statement_id , chunk_index ),
668+ )
669+ response = GetChunksResponse .from_dict (response_data )
670+
671+ links = response .external_links or []
672+ return links
673+
650674 # == Metadata Operations ==
651675
652676 def get_catalogs (
0 commit comments