# AUTO-GENERATED FILE - DO NOT EDIT
# This file was automatically generated by the XDK build tool.
# Any manual changes will be overwritten on the next generation.

"""
Auto-generated activity client for the X API.

This module provides a client for interacting with the activity endpoints of the X API.
Real-time streaming operations return generators that yield data as it arrives.
Streaming connections are automatically managed with exponential backoff retry logic for robust handling.
All methods, parameters, and response models are generated from the OpenAPI specification.

Generated automatically - do not edit manually.
"""

from __future__ import annotations
from typing import (
    Dict,
    List,
    Optional,
    Any,
    Union,
    cast,
    TYPE_CHECKING,
    Iterator,
    Generator,
)
import requests
import time
import urllib.parse

from ..streaming import StreamConfig, StreamError, stream_with_retry


if TYPE_CHECKING:
    from ..client import Client
from .models import (
    GetSubscriptionsResponse,
    CreateSubscriptionRequest,
    CreateSubscriptionResponse,
    UpdateSubscriptionRequest,
    UpdateSubscriptionResponse,
    DeleteSubscriptionResponse,
    StreamResponse,
)


class ActivityClient:
    """Streaming Client for activity operations"""


    def __init__(self, client: Client):
        self.client = client


    def get_subscriptions(
        self,
    ) -> GetSubscriptionsResponse:
        """
        Get X activity subscriptions
        Get a list of active subscriptions for XAA
        Returns:
            GetSubscriptionsResponse: Response data
        """
        url = self.client.base_url + "/2/activity/subscriptions"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        params = {}
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return GetSubscriptionsResponse.model_validate(response_data)


    def create_subscription(
        self, body: Optional[CreateSubscriptionRequest] = None
    ) -> CreateSubscriptionResponse:
        """
        Create X activity subscription
        Creates a subscription for an X activity event
        body: Request body
        Returns:
            CreateSubscriptionResponse: Response data
        """
        url = self.client.base_url + "/2/activity/subscriptions"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        params = {}
        headers = {}
        headers["Content-Type"] = "application/json"
        # Prepare request data
        json_data = None
        if body is not None:
            json_data = (
                body.model_dump(exclude_none=True)
                if hasattr(body, "model_dump")
                else body
            )
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "post" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            if json_data:
                # OAuth1 spec: JSON bodies are NOT included in signature
                # But we still need to pass the body for the request
                body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="post", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.post(
            url,
            params=params,
            headers=headers,
            json=json_data,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return CreateSubscriptionResponse.model_validate(response_data)


    def update_subscription(
        self, subscription_id: Any, body: Optional[UpdateSubscriptionRequest] = None
    ) -> UpdateSubscriptionResponse:
        """
        Update X activity subscription
        Updates a subscription for an X activity event
        Args:
            subscription_id: The ID of the subscription to update.
            body: Request body
        Returns:
            UpdateSubscriptionResponse: Response data
        """
        url = self.client.base_url + "/2/activity/subscriptions/{subscription_id}"
        url = url.replace("{subscription_id}", str(subscription_id))
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        params = {}
        headers = {}
        headers["Content-Type"] = "application/json"
        # Prepare request data
        json_data = None
        if body is not None:
            json_data = (
                body.model_dump(exclude_none=True)
                if hasattr(body, "model_dump")
                else body
            )
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "put" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            if json_data:
                # OAuth1 spec: JSON bodies are NOT included in signature
                # But we still need to pass the body for the request
                body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="put", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.put(
            url,
            params=params,
            headers=headers,
            json=json_data,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return UpdateSubscriptionResponse.model_validate(response_data)


    def delete_subscription(self, subscription_id: Any) -> DeleteSubscriptionResponse:
        """
        Deletes X activity subscription
        Deletes a subscription for an X activity event
        Args:
            subscription_id: The ID of the subscription to delete.
            Returns:
            DeleteSubscriptionResponse: Response data
        """
        url = self.client.base_url + "/2/activity/subscriptions/{subscription_id}"
        url = url.replace("{subscription_id}", str(subscription_id))
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        params = {}
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "delete" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="delete", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.delete(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return DeleteSubscriptionResponse.model_validate(response_data)


    def stream(
        self,
        backfill_minutes: int = None,
        start_time: str = None,
        end_time: str = None,
        stream_config: Optional[StreamConfig] = None,
    ) -> Generator[StreamResponse, None, None]:
        """
        Activity Stream (Streaming)
        Stream of X Activities
        This is a streaming endpoint that yields data in real-time as it becomes available.
        Each yielded item represents a single data point from the stream.
        The connection is automatically managed with exponential backoff retry logic.
        If the stream disconnects, the SDK will automatically reconnect without client intervention.
        Args:
            backfill_minutes: The number of minutes of backfill requested.
            start_time: YYYY-MM-DDTHH:mm:ssZ. The earliest UTC timestamp from which the Post labels will be provided.
            end_time: YYYY-MM-DDTHH:mm:ssZ. The latest UTC timestamp from which the Post labels will be provided.
            stream_config: Optional StreamConfig for customizing retry behavior, timeouts, and callbacks.
                Configure max_retries (-1 for infinite), initial_backoff, max_backoff, and lifecycle callbacks
                (on_connect, on_disconnect, on_reconnect, on_error) for monitoring connection state.
        Yields:
            StreamResponse: Individual streaming data items
        Raises:
            StreamError: If a non-retryable error occurs (auth errors, client errors) or max retries exceeded.
        """
        url = self.client.base_url + "/2/activity/stream"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        params = {}
        if backfill_minutes is not None:
            params["backfill_minutes"] = backfill_minutes
        if start_time is not None:
            params["start_time"] = start_time
        if end_time is not None:
            params["end_time"] = end_time
        headers = {
            "Accept": "application/json",
        }
        # Prepare request data
        json_data = None
        # Ensure params is defined (build_query_params should set it, but initialize if not)
        try:
            _ = params  # Check if params exists
        except NameError:
            params = {}  # Initialize if not defined
        # Use robust streaming with automatic retry and exponential backoff
        yield from stream_with_retry(
            session=self.client.session,
            method="get",
            url=url,
            config=stream_config,
            params=params,
            headers=headers,
            response_model=StreamResponse,
        )
