1818 collect_table_ai_kwargs ,
1919 normalize_table_ai_overrides ,
2020)
21+ from ._tracing import get_traceparent
2122from .auth import AuthManager , auto_retry_auth
2223
2324logger = logging .getLogger (__name__ )
@@ -368,8 +369,21 @@ def _fetch_dataframe_arrow(
368369 logger .debug ("Full error details: " , exc_info = True )
369370 return None
370371
371- def _get_headers (self ) -> dict [str , str ]:
372- """Get authorization headers using auth manager."""
372+ def _get_headers (
373+ self , session_trace_id : str | None = None , traceparent : str | None = None
374+ ) -> dict [str , str ]:
375+ """Get authorization headers using auth manager.
376+
377+ Args:
378+ session_trace_id: Optional session trace ID for correlation when
379+ OTel is not available. Used to generate traceparent if no
380+ explicit traceparent is provided and OTel is not active.
381+ traceparent: Optional explicit traceparent header value. If provided,
382+ takes precedence over auto-generated values.
383+
384+ Returns:
385+ Headers dict with Authorization and optionally traceparent.
386+ """
373387 token = self ._auth_manager .get_token ()
374388 headers = {"Authorization" : f"Bearer { token } " }
375389
@@ -383,6 +397,15 @@ def _get_headers(self) -> dict[str, str]:
383397 org_slug = self ._to_slug (str (org_name ))
384398 headers ["X-Graphistry-Org" ] = org_slug
385399
400+ # Add traceparent for distributed tracing
401+ # Priority: explicit traceparent > OTel context > session trace
402+ if traceparent :
403+ headers ["traceparent" ] = traceparent
404+ else :
405+ tp = get_traceparent (session_trace_id )
406+ if tp :
407+ headers ["traceparent" ] = tp
408+
386409 return headers
387410
388411 def _to_slug (self , text : str ) -> str :
@@ -619,6 +642,7 @@ def add_cell(
619642 share_mode : str = "Private" ,
620643 table_ai_overrides : TableAIOverrides | Mapping [str , Any ] | None = None ,
621644 use_batch : bool | None = None ,
645+ session_trace_id : str | None = None ,
622646 ** legacy_overrides : Any ,
623647 ) -> Response :
624648 """Add a cell (query) to a thread and get response.
@@ -634,13 +658,15 @@ def add_cell(
634658 table_ai_overrides: Structured overrides via dataclass or mapping.
635659 use_batch: Force singleshot (`True`) or streaming (`False`); defaults to
636660 singleshot when overrides are provided.
661+ session_trace_id: Optional session trace ID for distributed tracing
662+ correlation when OpenTelemetry is not available.
637663 **legacy_overrides: Backwards-compatible Table AI keyword arguments like
638664 ``table_ai_semantic_mode``. Prefer `table_ai_overrides`.
639665
640666 Returns:
641667 Response object containing thread_id and all elements
642668 """
643- headers = self ._get_headers ()
669+ headers = self ._get_headers (session_trace_id = session_trace_id )
644670
645671 # Build query parameters
646672 params : dict [str , Any ] = {
@@ -940,6 +966,7 @@ def upload_dataframe(
940966 name : str | None = None ,
941967 folder : str | None = None ,
942968 parsing_options : dict [str , Any ] | None = None ,
969+ session_trace_id : str | None = None ,
943970 ) -> Response :
944971 """Upload a DataFrame with a natural language query for AI analysis.
945972
@@ -954,6 +981,8 @@ def upload_dataframe(
954981 name: Optional thread name
955982 folder: Optional folder path for the thread (server support required)
956983 parsing_options: Format-specific parsing options
984+ session_trace_id: Optional session trace ID for distributed tracing
985+ correlation when OpenTelemetry is not available.
957986
958987 Returns:
959988 Response object with analysis results
@@ -975,6 +1004,7 @@ def upload_dataframe(
9751004 name = name ,
9761005 folder = folder ,
9771006 parsing_options = parsing_options ,
1007+ session_trace_id = session_trace_id ,
9781008 )
9791009
9801010 def upload_image (
@@ -988,6 +1018,7 @@ def upload_image(
9881018 share_mode : str = "Private" ,
9891019 name : str | None = None ,
9901020 folder : str | None = None ,
1021+ session_trace_id : str | None = None ,
9911022 ) -> Response :
9921023 """Upload an image with a natural language query for analysis.
9931024
@@ -1000,6 +1031,8 @@ def upload_image(
10001031 share_mode: Visibility setting
10011032 name: Optional thread name
10021033 folder: Optional folder path for the thread (server support required)
1034+ session_trace_id: Optional session trace ID for distributed tracing
1035+ correlation when OpenTelemetry is not available.
10031036
10041037 Returns:
10051038 Response object with analysis results
@@ -1018,6 +1051,7 @@ def upload_image(
10181051 share_mode = share_mode ,
10191052 name = name ,
10201053 folder = folder ,
1054+ session_trace_id = session_trace_id ,
10211055 )
10221056
10231057 def upload_binary (
@@ -1032,6 +1066,7 @@ def upload_binary(
10321066 name : str | None = None ,
10331067 folder : str | None = None ,
10341068 filename : str | None = None ,
1069+ session_trace_id : str | None = None ,
10351070 ) -> Response :
10361071 """Upload a binary file with a natural language query for analysis.
10371072
@@ -1045,6 +1080,8 @@ def upload_binary(
10451080 name: Optional thread name
10461081 folder: Optional folder path for the thread (server support required)
10471082 filename: Optional filename to use
1083+ session_trace_id: Optional session trace ID for distributed tracing
1084+ correlation when OpenTelemetry is not available.
10481085
10491086 Returns:
10501087 Response object with analysis results
@@ -1064,6 +1101,7 @@ def upload_binary(
10641101 name = name ,
10651102 folder = folder ,
10661103 filename = filename ,
1104+ session_trace_id = session_trace_id ,
10671105 )
10681106
10691107 def __enter__ (self ):
0 commit comments