# coding: utf-8

"""
    ibl-data-manager

    API for iblai

    The version of the OpenAPI document: 4.202.1-ai-plus
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501
import warnings
from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
from typing import Any, Dict, List, Optional, Tuple, Union
from typing_extensions import Annotated

from datetime import date
from pydantic import Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import List, Optional
from typing_extensions import Annotated
from uuid import UUID
from iblai.models.access_times_heatmap import AccessTimesHeatmap
from iblai.models.base_finance_response import BaseFinanceResponse
from iblai.models.content_details_response import ContentDetailsResponse
from iblai.models.content_response import ContentResponse
from iblai.models.conversation_detail_response import ConversationDetailResponse
from iblai.models.conversation_list_response import ConversationListResponse
from iblai.models.current_users_response import CurrentUsersResponse
from iblai.models.finance_details_response import FinanceDetailsResponse
from iblai.models.invoice_report_response import InvoiceReportResponse
from iblai.models.learner_analytics_response import LearnerAnalyticsResponse
from iblai.models.learner_list_response import LearnerListResponse
from iblai.models.ratings_overtime import RatingsOvertime
from iblai.models.sessions_chart import SessionsChart
from iblai.models.topic_details import TopicDetails
from iblai.models.topics_overview import TopicsOverview
from iblai.models.user_detail import UserDetail

from iblai.api_client import ApiClient, RequestSerialized
from iblai.api_response import ApiResponse
from iblai.rest import RESTResponseType


class AnalyticsApi:
    """NOTE: This class is auto generated by OpenAPI Generator
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    def __init__(self, api_client=None) -> None:
        if api_client is None:
            api_client = ApiClient.get_default()
        self.api_client = api_client


    @validate_call
    def analytics_financial_details_retrieve(
        self,
        group_by: Annotated[str, Field(min_length=1, strict=True, description="Dimension to group by  * `provider` - Group by provider * `llm_model` - Group by LLM model * `username` - Group by username * `mentor` - Group by mentor * `platform` - Group by platform * `action` - Group by actions")],
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        limit: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None,
        llm_model: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        mentor_unique_id: Optional[UUID] = None,
        metrics: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Comma-separated list of metrics (e.g. total_cost,sessions, last_active)")] = None,
        page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        provider: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        search: Optional[StrictStr] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        username: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_financial_details_retrieve

        Financial Details Analytics API – paginated cost tables with flexible grouping.  This endpoint returns tabular cost metrics aggregated by the dimension specified via the `group_by` query parameter.  One or more KPI columns can be requested through the comma-separated `metrics` list while typical filters (date range, provider, platform_key, user, etc.) narrow the dataset.  Results are paginated with `page` / `limit`.  **Required query parameters** - group_by – provider | llm_model | username | mentor | platform - metrics – csv list of KPI names, e.g. total_cost, sessions  **Shared optional filters** - start_date, end_date   – ISO yyyy-mm-dd (ignored when all_time=true) - platform_key           – tenant isolation - mentor_unique_id       – filter to one mentor - username               – filter to a learner - provider / llm_model   – filter to LLM provider / model - all_time               – true → lifetime totals - page (default 1), limit (default 50)  **Examples** -------- 1. Cost by provider for the last week ```    GET /api/v2/analytics/financial/details?        group_by=provider&        metrics=total_cost&        start_date=2025-01-01&        end_date=2025-01-07&        page=1&limit=10 ```  2. Lifetime cost per user with extra KPIs    ```    GET /api/v2/analytics/financial/details?        group_by=username&        metrics=total_cost,sessions&        all_time=true&page=1&limit=50    ``` 3. Cost by LLM model with tenant filter ```    GET /api/v2/analytics/financial/details?        group_by=llm_model&        metrics=total_cost&        platform_key=web-app&        start_date=2025-01-01&end_date=2025-01-31 ``` Response structure ------------------- ``` {   \"page\": 1,   \"limit\": 10,   \"total_pages\": 1,   \"total_records\": 3,   \"rows\": [     {\"provider\": \"openai\", \"total_cost\": \"2.50000\"},     {\"provider\": \"anthropic\", \"total_cost\": \"1.00000\"},     {\"provider\": \"azure\",    \"total_cost\": \"0.50000\"}   ],   \"metrics\": [     {       \"name\": \"total_cost\",       \"unit\": \"$\",       \"description\": \"Cost for this entity in period\"     }   ],   \"total_cost\": \"4.00000\"   // optional grand-total when available } ``

        :param group_by: Dimension to group by  * `provider` - Group by provider * `llm_model` - Group by LLM model * `username` - Group by username * `mentor` - Group by mentor * `platform` - Group by platform * `action` - Group by actions (required)
        :type group_by: str
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param limit:
        :type limit: int
        :param llm_model:
        :type llm_model: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param metrics: Comma-separated list of metrics (e.g. total_cost,sessions, last_active)
        :type metrics: str
        :param page:
        :type page: int
        :param platform_key:
        :type platform_key: str
        :param provider:
        :type provider: str
        :param search:
        :type search: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param username:
        :type username: str
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_financial_details_retrieve_serialize(
            group_by=group_by,
            date_filter=date_filter,
            end_date=end_date,
            limit=limit,
            llm_model=llm_model,
            mentor_unique_id=mentor_unique_id,
            metrics=metrics,
            page=page,
            platform_key=platform_key,
            provider=provider,
            search=search,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            username=username,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "FinanceDetailsResponse",
            '400': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_financial_details_retrieve_serialize(
        self,
        group_by,
        date_filter,
        end_date,
        limit,
        llm_model,
        mentor_unique_id,
        metrics,
        page,
        platform_key,
        provider,
        search,
        start_date,
        usergroup_ids,
        username,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if group_by is not None:
            
            _query_params.append(('group_by', group_by))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if llm_model is not None:
            
            _query_params.append(('llm_model', llm_model))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metrics is not None:
            
            _query_params.append(('metrics', metrics))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if provider is not None:
            
            _query_params.append(('provider', provider))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        if username is not None:
            
            _query_params.append(('username', username))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/financial/details/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_financial_invoice_retrieve(
        self,
        end_date: Annotated[Optional[date], Field(description="End date for billing period (defaults to today)")] = None,
        include_breakdown: Annotated[Optional[StrictBool], Field(description="Whether to include provider and mentor breakdown")] = None,
        platform_key: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True, max_length=255)]], Field(description="Platform key to filter by (optional, required for platform admins)")] = None,
        start_date: Annotated[Optional[date], Field(description="Start date for billing period (defaults to 30 days ago)")] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        username: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True, max_length=255)]], Field(description="Username to generate invoice for (optional)")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_financial_invoice_retrieve

        Flexible Invoice Report API – Billing summary with username and platform filtering.  This endpoint generates invoice reports with flexible filtering options: - Platform admins can view their platform's data and filter by username within their platform - Super admins can view any combination of username/platform or global summaries  **Key Features:** - Flexible filtering by username and/or platform_key - Essential metrics: total cost, sessions, usage period - Provider breakdown (OpenAI, Anthropic, etc.) - Top mentors/actions by cost - Clean, invoice-ready format  **Query Parameters:** - username: Filter by specific username (optional) - platform_key: Filter by platform (optional, but required for platform admins) - start_date, end_date: billing period (defaults to last 30 days) - include_breakdown: show provider/mentor details (default: true)  **Permission Logic:** - Platform admins: Must include platform_key matching their permission scope - Super admins: Can use any combination of filters or none (global summary)  **Examples:** ``` # Platform admin viewing their platform GET /api/analytics/financial/invoice?platform_key=web-app  # Platform admin viewing specific user in their platform GET /api/analytics/financial/invoice?platform_key=web-app&username=john.doe  # Super admin viewing specific user across all platforms GET /api/analytics/financial/invoice?username=john.doe  # Super admin viewing global summary GET /api/analytics/financial/invoice ```  **Response Structure:** ```json {   \"entity\": {     \"type\": \"user|platform|global\",     \"username\": \"john.doe\",     \"platform_key\": \"web-app\",     \"platform_name\": \"Web Application\",     \"display_name\": \"John Doe on Web Application\"   },   \"billing_period\": {     \"start_date\": \"2025-01-01\",     \"end_date\": \"2025-01-31\",     \"days\": 31   },   \"summary\": {     \"total_cost\": 245.750,     \"total_sessions\": 1250,     \"active_users\": 85,     \"cost_per_session\": 0.196   },   \"breakdown\": {     \"by_provider\": [...],     \"by_mentor\": [...],     \"by_action\": [...]   } } ```

        :param end_date: End date for billing period (defaults to today)
        :type end_date: date
        :param include_breakdown: Whether to include provider and mentor breakdown
        :type include_breakdown: bool
        :param platform_key: Platform key to filter by (optional, required for platform admins)
        :type platform_key: str
        :param start_date: Start date for billing period (defaults to 30 days ago)
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param username: Username to generate invoice for (optional)
        :type username: str
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_financial_invoice_retrieve_serialize(
            end_date=end_date,
            include_breakdown=include_breakdown,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            username=username,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "InvoiceReportResponse",
            '400': None,
            '403': None,
            '404': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_financial_invoice_retrieve_serialize(
        self,
        end_date,
        include_breakdown,
        platform_key,
        start_date,
        usergroup_ids,
        username,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if include_breakdown is not None:
            
            _query_params.append(('include_breakdown', include_breakdown))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        if username is not None:
            
            _query_params.append(('username', username))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/financial/invoice/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_financial_retrieve(
        self,
        metric: Annotated[str, Field(min_length=1, strict=True, description="Type of financial metric to retrieve  * `total_costs` - Total costs for selected timeframe * `weekly_costs` - Costs for current/selected week * `monthly_costs` - Costs for current/selected month")],
        comparison_days: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Number of days for comparison period to calculate percentage change (e.g., 10 for 10-day comparison)")] = None,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        fill_method: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Method for filling missing time periods in overtime data  * `zero` - Fill missing periods with zero * `previous` - Fill missing periods with previous value")] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Time granularity for overtime series data  * `day` - Daily data points * `week` - Weekly data points * `month` - Monthly data points")] = None,
        llm_model: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Filter by specific LLM model (e.g., gpt-4o, claude-3-5-sonnet)")] = None,
        mentor_unique_id: Optional[UUID] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        provider: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Filter by AI provider  * `openai` - OpenAI * `anthropic` - Anthropic * `azure` - Azure * `google` - Google * `meta` - Meta * `other` - Other")] = None,
        show_overtime: Annotated[Optional[StrictBool], Field(description="Whether to include overtime series data in response")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        username: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Filter by specific username - returns costs for this user only")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_financial_retrieve

        Financial Analytics API - Get comprehensive cost metrics with comparison analysis.  This endpoint provides period-based cost analysis (not cumulative) with support for: - Multiple time granularities and metrics - Cross-dimensional filtering - Percentage change vs comparison periods - Forward-filled time series  **Examples:**  **Basic Weekly Costs:** ``` GET /api/analytics/financial/?metric=weekly_costs&comparison_days=10 ```  **Platform & Mentor Filtered:** ``` # Get total costs for a specific platform and mentor GET /api/analytics/financial/?metric=total_costs&platform_key=web-app&mentor_unique_id=mentor-123&comparison_days=14 ```  **Monthly Costs by Provider:** ``` GET /api/analytics/financial/?metric=monthly_costs&provider=openai&granularity=month&comparison_days=30 ```  **Daily Costs for Specific User:** ``` GET /api/analytics/financial/?metric=total_costs&username=user-456&granularity=day&start_date=2025-01-15&end_date=2025-01-21&comparison_days=7 ```   **Response Structure:** ```json {     \"metric\": \"weekly_costs\",     \"value\": 12.47,     \"percentage_change\": 8.5,     \"overtime\": [         {\"date\": \"2025-01-06\", \"value\": 2.89},         {\"date\": \"2025-01-13\", \"value\": 3.12}     ],     \"period_info\": {         \"start_date\": \"2025-01-01\",         \"end_date\": \"2025-01-31\",         \"period_days\": 31     },     \"comparison_info\": {         \"previous_period_value\": 11.50,         ...     } } ```

        :param metric: Type of financial metric to retrieve  * `total_costs` - Total costs for selected timeframe * `weekly_costs` - Costs for current/selected week * `monthly_costs` - Costs for current/selected month (required)
        :type metric: str
        :param comparison_days: Number of days for comparison period to calculate percentage change (e.g., 10 for 10-day comparison)
        :type comparison_days: int
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param fill_method: Method for filling missing time periods in overtime data  * `zero` - Fill missing periods with zero * `previous` - Fill missing periods with previous value
        :type fill_method: str
        :param granularity: Time granularity for overtime series data  * `day` - Daily data points * `week` - Weekly data points * `month` - Monthly data points
        :type granularity: str
        :param llm_model: Filter by specific LLM model (e.g., gpt-4o, claude-3-5-sonnet)
        :type llm_model: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param platform_key:
        :type platform_key: str
        :param provider: Filter by AI provider  * `openai` - OpenAI * `anthropic` - Anthropic * `azure` - Azure * `google` - Google * `meta` - Meta * `other` - Other
        :type provider: str
        :param show_overtime: Whether to include overtime series data in response
        :type show_overtime: bool
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param username: Filter by specific username - returns costs for this user only
        :type username: str
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_financial_retrieve_serialize(
            metric=metric,
            comparison_days=comparison_days,
            date_filter=date_filter,
            end_date=end_date,
            fill_method=fill_method,
            granularity=granularity,
            llm_model=llm_model,
            mentor_unique_id=mentor_unique_id,
            platform_key=platform_key,
            provider=provider,
            show_overtime=show_overtime,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            username=username,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "BaseFinanceResponse",
            '400': None,
            '403': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_financial_retrieve_serialize(
        self,
        metric,
        comparison_days,
        date_filter,
        end_date,
        fill_method,
        granularity,
        llm_model,
        mentor_unique_id,
        platform_key,
        provider,
        show_overtime,
        start_date,
        usergroup_ids,
        username,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if comparison_days is not None:
            
            _query_params.append(('comparison_days', comparison_days))
            
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if fill_method is not None:
            
            _query_params.append(('fill_method', fill_method))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if llm_model is not None:
            
            _query_params.append(('llm_model', llm_model))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if provider is not None:
            
            _query_params.append(('provider', provider))
            
        if show_overtime is not None:
            
            _query_params.append(('show_overtime', show_overtime))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        if username is not None:
            
            _query_params.append(('username', username))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/financial/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_learners_list_retrieve(
        self,
        platform_key: Annotated[str, Field(min_length=1, strict=True, description="Platform key to filter learners by platform")],
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Number of learners per page (default: 20, max: 100)")] = None,
        mentor_unique_id: Optional[UUID] = None,
        page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Page number for pagination (default: 1)")] = None,
        search: Annotated[Optional[StrictStr], Field(description="Search term to filter learners by username, email, or name")] = None,
        sort_by: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Field to sort learners by (default: last_activity)  * `username` - Username * `name` - Name * `last_activity` - Last Activity * `total_points` - Total Points * `total_time_spent_seconds` - Time Spent * `total_enrollments` - Enrollments * `total_skills_count` - Skills Count")] = None,
        sort_order: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Sort order (default: desc)  * `asc` - Ascending * `desc` - Descending")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_learners_list_retrieve

                 Retrieve a paginated list of learners for a specific platform with their comprehensive         metrics from the UserPlatformSummary materialized view. This endpoint is accessible only         to platform administrators and supports search, sorting, and pagination.         

        :param platform_key: Platform key to filter learners by platform (required)
        :type platform_key: str
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param limit: Number of learners per page (default: 20, max: 100)
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param page: Page number for pagination (default: 1)
        :type page: int
        :param search: Search term to filter learners by username, email, or name
        :type search: str
        :param sort_by: Field to sort learners by (default: last_activity)  * `username` - Username * `name` - Name * `last_activity` - Last Activity * `total_points` - Total Points * `total_time_spent_seconds` - Time Spent * `total_enrollments` - Enrollments * `total_skills_count` - Skills Count
        :type sort_by: str
        :param sort_order: Sort order (default: desc)  * `asc` - Ascending * `desc` - Descending
        :type sort_order: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_learners_list_retrieve_serialize(
            platform_key=platform_key,
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            page=page,
            search=search,
            sort_by=sort_by,
            sort_order=sort_order,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "LearnerListResponse",
            '400': None,
            '403': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_learners_list_retrieve_serialize(
        self,
        platform_key,
        date_filter,
        end_date,
        granularity,
        limit,
        mentor_unique_id,
        page,
        search,
        sort_by,
        sort_order,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if sort_by is not None:
            
            _query_params.append(('sort_by', sort_by))
            
        if sort_order is not None:
            
            _query_params.append(('sort_order', sort_order))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/learners/list/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_learners_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Number of records per page (default: 20, max: 100)")] = None,
        mentor_unique_id: Optional[UUID] = None,
        overtime: Annotated[Optional[StrictBool], Field(description="Include overtime metrics for the user in the platform (default: false)")] = None,
        page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Page number (default: 1)")] = None,
        platform_key: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Optional platform key - if provided, returns platform-specific detailed data")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        username: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="Username of the learner to get analytics for. Defaults to self if not provided.")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_learners_retrieve

        Unified API endpoint for learner analytics.  This endpoint provides either: 1. Cross-platform summary (when only username is provided) 2. Platform-specific detailed data (when username + platform_key are provided)  Query params: - username (required): Username of the learner - platform_key (optional): Platform key for platform-specific data - page (optional): Page number (default: 1) - limit (optional): Records per page (default: 20, max: 100)  Returns: - If platform_key provided: Detailed platform metrics - If no platform_key: Cross-platform summary with pagination

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param limit: Number of records per page (default: 20, max: 100)
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param overtime: Include overtime metrics for the user in the platform (default: false)
        :type overtime: bool
        :param page: Page number (default: 1)
        :type page: int
        :param platform_key: Optional platform key - if provided, returns platform-specific detailed data
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param username: Username of the learner to get analytics for. Defaults to self if not provided.
        :type username: str
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_learners_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            overtime=overtime,
            page=page,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            username=username,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "LearnerAnalyticsResponse",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_learners_retrieve_serialize(
        self,
        date_filter,
        end_date,
        granularity,
        limit,
        mentor_unique_id,
        overtime,
        page,
        platform_key,
        start_date,
        usergroup_ids,
        username,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if overtime is not None:
            
            _query_params.append(('overtime', overtime))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        if username is not None:
            
            _query_params.append(('username', username))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/learners/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_messages_details_retrieve(
        self,
        session_id: Annotated[str, Field(min_length=1, strict=True)],
        end_date: Optional[date] = None,
        mentor_unique_id: Optional[UUID] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_messages_details_retrieve

        Conversation detail endpoint for analytics.  Query params: - session_id (required): UUID of the session to fetch - platform_key, mentor_unique_id (optional): further scope - start_date, end_date (optional): date filter on message timestamps  Returns: summary metadata from conversation_list MV, and a list of human/ai message pairs in chronological order.

        :param session_id: (required)
        :type session_id: str
        :param end_date:
        :type end_date: date
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_messages_details_retrieve_serialize(
            session_id=session_id,
            end_date=end_date,
            mentor_unique_id=mentor_unique_id,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "ConversationDetailResponse",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_messages_details_retrieve_serialize(
        self,
        session_id,
        end_date,
        mentor_unique_id,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if session_id is not None:
            
            _query_params.append(('session_id', session_id))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/messages/details/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_messages_retrieve(
        self,
        end_date: Optional[date] = None,
        limit: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None,
        max_messages: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
        mentor_unique_id: Optional[UUID] = None,
        min_messages: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
        page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        search: Optional[StrictStr] = None,
        sentiment: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `positive` - positive * `negative` - negative * `neutral` - neutral")] = None,
        start_date: Optional[date] = None,
        topic: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_messages_retrieve

        Conversation list endpoint for analytics.  Query params (all optional unless specified by permissions): - platform_key: filter by platform - mentor_unique_id: filter by mentor - page: page number (default 1) - limit: page size (default 20, max 100) - search: search in user name and first user message - min_messages, max_messages: message_count range - sentiment: positive|negative|neutral - topic: topic name contains - start_date, end_date: date filter on conversation date  Returns: summary totals, results list (paginated), and pagination metadata.

        :param end_date:
        :type end_date: date
        :param limit:
        :type limit: int
        :param max_messages:
        :type max_messages: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param min_messages:
        :type min_messages: int
        :param page:
        :type page: int
        :param platform_key:
        :type platform_key: str
        :param search:
        :type search: str
        :param sentiment: * `positive` - positive * `negative` - negative * `neutral` - neutral
        :type sentiment: str
        :param start_date:
        :type start_date: date
        :param topic:
        :type topic: str
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_messages_retrieve_serialize(
            end_date=end_date,
            limit=limit,
            max_messages=max_messages,
            mentor_unique_id=mentor_unique_id,
            min_messages=min_messages,
            page=page,
            platform_key=platform_key,
            search=search,
            sentiment=sentiment,
            start_date=start_date,
            topic=topic,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "ConversationListResponse",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_messages_retrieve_serialize(
        self,
        end_date,
        limit,
        max_messages,
        mentor_unique_id,
        min_messages,
        page,
        platform_key,
        search,
        sentiment,
        start_date,
        topic,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if max_messages is not None:
            
            _query_params.append(('max_messages', max_messages))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if min_messages is not None:
            
            _query_params.append(('min_messages', min_messages))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if sentiment is not None:
            
            _query_params.append(('sentiment', sentiment))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if topic is not None:
            
            _query_params.append(('topic', topic))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/messages/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_ratings_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        mentor_unique_id: Optional[UUID] = None,
        metric: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `ratings` - Ratings over time")] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_ratings_retrieve

        Ratings overtime endpoint.  Query params: - metric: only 'ratings' is supported (default) - platform_key, mentor_unique_id: optional filters - granularity: 'day' (default) or 'hour' (hour only for today) - start_date, end_date: optional date range; defaults applied if not provided  Returns: { metric: 'ratings', points: [{date, value}, ...] }

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param metric: * `ratings` - Ratings over time
        :type metric: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_ratings_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            mentor_unique_id=mentor_unique_id,
            metric=metric,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "RatingsOvertime",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_ratings_retrieve_serialize(
        self,
        date_filter,
        end_date,
        granularity,
        mentor_unique_id,
        metric,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/ratings/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_sessions_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        mentor_unique_id: Optional[UUID] = None,
        metric: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `sessions` - Sessions over time * `headline` - Headline metrics for sessions (avg messages per session, avg rating)")] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_sessions_retrieve

        Mixin for RBAC validation for mentor analytics views.  Mentor analytics endpoints require: 1. Aggregate analytics: First checks if user has \"Ibl.Analytics/CanViewAnalytics/action\"    permission on the platform resource (/platforms/{pk}/) when retrieving aggregate data 2. Mentor-specific access validation:    - If mentor_unique_id is provided, validates access to that specific mentor    - Checks mentor owner access (if user created the mentor) via is_owner parameter    - Checks mentor-specific RBAC access: /platforms/{pk}/mentors/{mentor_id}/    - Uses action prefix \"Ibl.Analytics/Mentors/\" for mentor access validation 3. User/usergroup access for filtering:    - Uses \"Ibl.Analytics/Mentors/read\" action to determine accessible users    - Supports usergroup filtering via _get_accessible_user_ids()  This mixin extends AnalyticsRbacMixin to reuse shared RBAC validation logic while adding mentor-specific validation.  Special Case - Mentor Owner Unfiltered Access: If the requesting user owns the mentor (mentor.created_by == requesting_user.username) AND no usergroup_ids are specified, the _get_accessible_user_ids_for_mentor_analytics() method returns None to allow unfiltered access to all users in the platform.  Note: Mentor analytics APIs work with platform_key (from query params).

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param metric: * `sessions` - Sessions over time * `headline` - Headline metrics for sessions (avg messages per session, avg rating)
        :type metric: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_sessions_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            mentor_unique_id=mentor_unique_id,
            metric=metric,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "SessionsChart",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_sessions_retrieve_serialize(
        self,
        date_filter,
        end_date,
        granularity,
        mentor_unique_id,
        metric,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/sessions/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_time_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        mentor_unique_id: Optional[UUID] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_time_retrieve

                 Time Analytics API - User activity patterns by time of day and day of week.                  Provides heatmap data showing when users are most active, useful for:         - Understanding peak usage times         - Capacity planning and resource allocation         - User behavior analysis         - Support scheduling optimization                  **Key Features:**         - Day of week patterns (0=Sunday through 6=Saturday)         - Hour of day activity levels (0-23)         - Flexible date range filtering         - Platform and mentor-specific filtering         - Message count aggregation                  **Data Structure:**         - `day_of_week`: 0-6 (Sunday-Saturday)         - `hour`: 0-23 (24-hour format)         - `value`: Message count for that time slot         

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_time_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            mentor_unique_id=mentor_unique_id,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "AccessTimesHeatmap",
            '400': None,
            '403': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_time_retrieve_serialize(
        self,
        date_filter,
        end_date,
        granularity,
        mentor_unique_id,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/time/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_topics_details_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        limit: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None,
        mentor_unique_id: Optional[UUID] = None,
        page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        search: Annotated[Optional[StrictStr], Field(description="Search by topic name")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_topics_details_retrieve

        Returns topic details Analytics for a given platform and mentor.  Permission Required: - Platform Admin - Ibl.Analytics/Mentors/read

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param limit:
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param page:
        :type page: int
        :param platform_key:
        :type platform_key: str
        :param search: Search by topic name
        :type search: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_topics_details_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            page=page,
            platform_key=platform_key,
            search=search,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "TopicDetails",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_topics_details_retrieve_serialize(
        self,
        date_filter,
        end_date,
        limit,
        mentor_unique_id,
        page,
        platform_key,
        search,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/topics/details/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_topics_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        mentor_unique_id: Optional[UUID] = None,
        metric: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `overview` - Overall topic metrics * `sessions` - Sessions over time * `ratings` - Ratings over time * `highlighted` - Highlighted topics")] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_topics_retrieve

        Returns topics overview analytics for a given platform and mentor.  Permission Required: - Platform Admin - Ibl.Analytics/Mentors/read

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param metric: * `overview` - Overall topic metrics * `sessions` - Sessions over time * `ratings` - Ratings over time * `highlighted` - Highlighted topics
        :type metric: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_topics_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            mentor_unique_id=mentor_unique_id,
            metric=metric,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "TopicsOverview",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_topics_retrieve_serialize(
        self,
        date_filter,
        end_date,
        granularity,
        mentor_unique_id,
        metric,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/topics/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_users_details_retrieve(
        self,
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        limit: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None,
        mentor_unique_id: Optional[UUID] = None,
        page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        search: Annotated[Optional[StrictStr], Field(description="Search by email, full name, or user ID")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_users_details_retrieve

                 User Details API - Comprehensive user activity details with search and filtering.                  Provides detailed user information including:         - User contact information (email, full name)         - Activity metrics (message count, last activity)         - Search functionality across multiple fields         - Flexible date range filtering         - CSV export capability                  **Key Features:**         - Full-text search across email, name, and user ID         - Date range filtering for activity periods         - Platform and mentor-specific filtering         - Comprehensive pagination with metadata         - CSV export for data analysis         - User aggregation across platforms/mentors                  **Search Capabilities:**         - Email address matching         - Full name search         - User ID lookup         - Partial string matching (case-insensitive)                  **Export Options:**         - JSON response (default)         - CSV export (?export=csv)         - Includes all user fields in export         

        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param limit:
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param page:
        :type page: int
        :param platform_key:
        :type platform_key: str
        :param search: Search by email, full name, or user ID
        :type search: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_users_details_retrieve_serialize(
            date_filter=date_filter,
            end_date=end_date,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            page=page,
            platform_key=platform_key,
            search=search,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "UserDetail",
            '400': None,
            '403': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_users_details_retrieve_serialize(
        self,
        date_filter,
        end_date,
        limit,
        mentor_unique_id,
        page,
        platform_key,
        search,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/users/details/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def analytics_users_retrieve(
        self,
        metric: Annotated[str, Field(min_length=1, strict=True, description="* `currently_active` - Users logged in right now * `active_users` - Active users in a period * `registered_users` - Registered users * `active_users_last_30d` - Active users in the last 30 days")],
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        mentor_unique_id: Optional[UUID] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """analytics_users_retrieve

                 User Analytics API - Comprehensive user activity metrics and trends.                  Provides real-time and historical user analytics including:         - Currently active users (last hour)         - Active users over time periods (7d, 30d, 90d)         - Registered user counts and growth         - Time series charts with customizable granularity                  **Key Features:**         - Real-time active user counting         - Percentage change calculations vs previous periods         - Flexible date filtering and granularity         - Platform and mentor-specific filtering         - Forward-filled time series data                  **Supported Metrics:**         - `currently_active`: Users active in last hour         - `active_users`: Unique users in specified period         - `registered_users`: Total and new user counts         

        :param metric: * `currently_active` - Users logged in right now * `active_users` - Active users in a period * `registered_users` - Registered users * `active_users_last_30d` - Active users in the last 30 days (required)
        :type metric: str
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param platform_key:
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._analytics_users_retrieve_serialize(
            metric=metric,
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            mentor_unique_id=mentor_unique_id,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "CurrentUsersResponse",
            '400': None,
            '403': None,
            '500': None,
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _analytics_users_retrieve_serialize(
        self,
        metric,
        date_filter,
        end_date,
        granularity,
        mentor_unique_id,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/users/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def get_content_analytics(
        self,
        metric: Annotated[str, Field(min_length=1, strict=True, description="The type of content to retrieve (course, program, pathway, skill)  * `course` - course * `courses` - courses * `program` - program * `programs` - programs * `pathway` - pathway * `pathways` - pathways * `skill` - skill * `skills` - skills")],
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        granularity: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `day` - day * `hour` - hour * `week` - week * `month` - month")] = None,
        include_overtime: Annotated[Optional[StrictBool], Field(description="Include time spent over time data")] = None,
        limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Number of items per page (max 100)")] = None,
        mentor_unique_id: Optional[UUID] = None,
        page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Page number for pagination")] = None,
        platform_key: Annotated[Optional[StrictStr], Field(description="Optional platform key to filter results by platform")] = None,
        start_date: Optional[date] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """Get Content Analytics

                 Retrieve aggregated analytics for catalog content (courses, programs, pathways, skills).                  Returns both summary statistics and paginated list of content items with individual analytics.         When a platform_key is provided, results are filtered to show only content consumed by          learners associated with that platform.                  **RBAC Requirements:**         - Requires: Analytics Viewer role (Ibl.Analytics/Core/read) or Tenant Admin role (Ibl.*)                  **Metrics supported:**         - `course` or `courses`: Course analytics with time spent         - `program` or `programs`: Program analytics           - `pathway` or `pathways`: Pathway analytics         - `skill` or `skills`: Skill analytics                  **Platform Filtering:**         - Without platform_key: Shows global analytics across all platforms         - With platform_key: Shows analytics filtered by platform learners only                  **Time Spent Analytics:**         - Platform-level: Total time spent across all content and average per learner         - Course-level: Total time spent per course and average per enrolled learner         - Time values are provided in seconds for precision         - Overtime: Time series data showing platform time spent over last 7 days (courses only, and include_overtime=true)                  **External Content:**         - Content not owned by the requesting platform but used by its learners is marked as \"external\"         - External content has limited metadata exposure for privacy         

        :param metric: The type of content to retrieve (course, program, pathway, skill)  * `course` - course * `courses` - courses * `program` - program * `programs` - programs * `pathway` - pathway * `pathways` - pathways * `skill` - skill * `skills` - skills (required)
        :type metric: str
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param granularity: * `day` - day * `hour` - hour * `week` - week * `month` - month
        :type granularity: str
        :param include_overtime: Include time spent over time data
        :type include_overtime: bool
        :param limit: Number of items per page (max 100)
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param page: Page number for pagination
        :type page: int
        :param platform_key: Optional platform key to filter results by platform
        :type platform_key: str
        :param start_date:
        :type start_date: date
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._get_content_analytics_serialize(
            metric=metric,
            date_filter=date_filter,
            end_date=end_date,
            granularity=granularity,
            include_overtime=include_overtime,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            page=page,
            platform_key=platform_key,
            start_date=start_date,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "ContentResponse",
            '400': "object",
            '404': "object",
            '500': "object",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _get_content_analytics_serialize(
        self,
        metric,
        date_filter,
        end_date,
        granularity,
        include_overtime,
        limit,
        mentor_unique_id,
        page,
        platform_key,
        start_date,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if granularity is not None:
            
            _query_params.append(('granularity', granularity))
            
        if include_overtime is not None:
            
            _query_params.append(('include_overtime', include_overtime))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/content/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )




    @validate_call
    def get_content_details(
        self,
        content_id: StrictStr,
        metric: Annotated[str, Field(min_length=1, strict=True, description="Content type to fetch (course, program, pathway, skill)  * `course` - course * `courses` - courses * `program` - program * `programs` - programs * `pathway` - pathway * `pathways` - pathways * `skill` - skill * `skills` - skills")],
        date_filter: Annotated[Optional[Annotated[str, Field(min_length=1, strict=True)]], Field(description="* `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range")] = None,
        end_date: Optional[date] = None,
        limit: Annotated[Optional[Annotated[int, Field(le=30, strict=True, ge=1)]], Field(description="Number of learner records per page")] = None,
        mentor_unique_id: Optional[UUID] = None,
        page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None,
        platform_key: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None,
        search: Optional[StrictStr] = None,
        start_date: Optional[date] = None,
        time_metric: Annotated[Optional[StrictStr], Field(description="Optional time series metric (enrollments, completions, ratings, time_spent)")] = None,
        usergroup_ids: Annotated[Optional[List[StrictInt]], Field(description="Optional list of usergroup IDs to filter results")] = None,
        _request_timeout: Union[
            None,
            Annotated[StrictFloat, Field(gt=0)],
            Tuple[
                Annotated[StrictFloat, Field(gt=0)],
                Annotated[StrictFloat, Field(gt=0)]
            ]
        ] = None,
        _request_auth: Optional[Dict[StrictStr, Any]] = None,
        _content_type: Optional[StrictStr] = None,
        _headers: Optional[Dict[StrictStr, Any]] = None,
        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
    ) -> RESTResponseType:
        """Get Content Details

        Retrieve detailed analytics for a specific content item including summary statistics, learner-level data, and optional time series information.

        :param content_id: (required)
        :type content_id: str
        :param metric: Content type to fetch (course, program, pathway, skill)  * `course` - course * `courses` - courses * `program` - program * `programs` - programs * `pathway` - pathway * `pathways` - pathways * `skill` - skill * `skills` - skills (required)
        :type metric: str
        :param date_filter: * `today` - Today only * `7d` - Last 7 days * `30d` - Last 30 days * `90d` - Last 90 days * `all_time` - All time * `custom` - Custom date range
        :type date_filter: str
        :param end_date:
        :type end_date: date
        :param limit: Number of learner records per page
        :type limit: int
        :param mentor_unique_id:
        :type mentor_unique_id: str
        :param page:
        :type page: int
        :param platform_key:
        :type platform_key: str
        :param search:
        :type search: str
        :param start_date:
        :type start_date: date
        :param time_metric: Optional time series metric (enrollments, completions, ratings, time_spent)
        :type time_metric: str
        :param usergroup_ids: Optional list of usergroup IDs to filter results
        :type usergroup_ids: List[int]
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        :type _request_timeout: int, tuple(int, int), optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the
                              authentication in the spec for a single request.
        :type _request_auth: dict, optional
        :param _content_type: force content-type for the request.
        :type _content_type: str, Optional
        :param _headers: set to override the headers for a single
                         request; this effectively ignores the headers
                         in the spec for a single request.
        :type _headers: dict, optional
        :param _host_index: set to override the host_index for a single
                            request; this effectively ignores the host_index
                            in the spec for a single request.
        :type _host_index: int, optional
        :return: Returns the result object.
        """ # noqa: E501

        _param = self._get_content_details_serialize(
            content_id=content_id,
            metric=metric,
            date_filter=date_filter,
            end_date=end_date,
            limit=limit,
            mentor_unique_id=mentor_unique_id,
            page=page,
            platform_key=platform_key,
            search=search,
            start_date=start_date,
            time_metric=time_metric,
            usergroup_ids=usergroup_ids,
            _request_auth=_request_auth,
            _content_type=_content_type,
            _headers=_headers,
            _host_index=_host_index
        )

        _response_types_map: Dict[str, Optional[str]] = {
            '200': "ContentDetailsResponse",
            '400': "object",
            '404': "object",
            '500': "object",
        }
        response_data = self.api_client.call_api(
            *_param,
            _request_timeout=_request_timeout
        )
        return response_data.response


    def _get_content_details_serialize(
        self,
        content_id,
        metric,
        date_filter,
        end_date,
        limit,
        mentor_unique_id,
        page,
        platform_key,
        search,
        start_date,
        time_metric,
        usergroup_ids,
        _request_auth,
        _content_type,
        _headers,
        _host_index,
    ) -> RequestSerialized:

        _host = None

        _collection_formats: Dict[str, str] = {
            'usergroup_ids': 'multi',
        }

        _path_params: Dict[str, str] = {}
        _query_params: List[Tuple[str, str]] = []
        _header_params: Dict[str, Optional[str]] = _headers or {}
        _form_params: List[Tuple[str, str]] = []
        _files: Dict[str, Union[str, bytes]] = {}
        _body_params: Optional[bytes] = None

        # process the path parameters
        if content_id is not None:
            _path_params['content_id'] = content_id
        # process the query parameters
        if date_filter is not None:
            
            _query_params.append(('date_filter', date_filter))
            
        if end_date is not None:
            if isinstance(end_date, date):
                _query_params.append(
                    (
                        'end_date',
                        end_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('end_date', end_date))
            
        if limit is not None:
            
            _query_params.append(('limit', limit))
            
        if mentor_unique_id is not None:
            
            _query_params.append(('mentor_unique_id', mentor_unique_id))
            
        if metric is not None:
            
            _query_params.append(('metric', metric))
            
        if page is not None:
            
            _query_params.append(('page', page))
            
        if platform_key is not None:
            
            _query_params.append(('platform_key', platform_key))
            
        if search is not None:
            
            _query_params.append(('search', search))
            
        if start_date is not None:
            if isinstance(start_date, date):
                _query_params.append(
                    (
                        'start_date',
                        start_date.strftime(
                            self.api_client.configuration.date_format
                        )
                    )
                )
            else:
                _query_params.append(('start_date', start_date))
            
        if time_metric is not None:
            
            _query_params.append(('time_metric', time_metric))
            
        if usergroup_ids is not None:
            
            _query_params.append(('usergroup_ids', usergroup_ids))
            
        # process the header parameters
        # process the form parameters
        # process the body parameter


        # set the HTTP header `Accept`
        if 'Accept' not in _header_params:
            _header_params['Accept'] = self.api_client.select_header_accept(
                [
                    'application/json'
                ]
            )


        # authentication setting
        _auth_settings: List[str] = [
            'PlatformApiKeyAuthentication'
        ]

        return self.api_client.param_serialize(
            method='GET',
            resource_path='/api/analytics/content/details/{content_id}/',
            path_params=_path_params,
            query_params=_query_params,
            header_params=_header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            auth_settings=_auth_settings,
            collection_formats=_collection_formats,
            _host=_host,
            _request_auth=_request_auth
        )


