# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool
from typing import Any, ClassVar, Dict, List, Optional
from mixpeek.models.pagination import Pagination
from typing import Optional, Set
from typing_extensions import Self

class ExecuteRetrieverRequest(BaseModel):
    """
    Request to execute a retriever with optional streaming support.  Inherits all fields from RetrieverExecutionRequest including: - inputs: Runtime input values matching the retriever's input_schema - pagination: Pagination configuration (cursor, offset, etc.) - stream: Enable SSE streaming for real-time stage updates  Streaming Execution (stream=True):     When streaming is enabled, the response uses Server-Sent Events (SSE) format     with Content-Type: text/event-stream. Each stage emits events as it executes:      Event Types:     - stage_start: Emitted when a stage begins execution     - stage_complete: Emitted when a stage finishes with results     - stage_error: Emitted if a stage encounters an error     - execution_complete: Emitted after all stages finish successfully     - execution_error: Emitted if the entire execution fails      Each event is a StreamStageEvent containing:     - event_type: The type of event     - execution_id: Unique execution identifier     - stage_name: Human-readable stage name     - stage_index: Zero-based stage position     - total_stages: Total number of stages     - documents: Intermediate results (for stage_complete)     - statistics: Stage metrics (duration, counts, etc.)     - budget_used: Cumulative resource consumption      Example streaming client:     ```python     response = requests.post(         '/v1/retrievers/{id}/execute',         json={'inputs': {...}, 'stream': True},         stream=True     )     for line in response.iter_lines():         if line.startswith(b'data: '):             event = json.loads(line[6:])             print(f\"{event['event_type']}: {event.get('stage_name')}\")     ```  Standard Execution (stream=False, default):     Returns a single ExecuteRetrieverResponse with final documents,     pagination, and aggregate statistics after all stages complete.
    """ # noqa: E501
    inputs: Optional[Dict[str, Any]] = Field(default=None, description="Runtime inputs for the retriever mapped to the input schema. Keys must match the retriever's input_schema field names. Values depend on field types (text, vector, filters, etc.). REQUIRED unless all retriever inputs have defaults.   Common input keys: - 'query': Text search query - 'embedding': Pre-computed vector for search - 'top_k': Number of results to return - 'min_score': Minimum relevance threshold - Any custom fields defined in input_schema   **Template Syntax** (Jinja2):  Namespaces (uppercase or lowercase): - `INPUT` / `input`: Query inputs (e.g., `{{INPUT.query}}`) - `DOC` / `doc`: Document fields (e.g., `{{DOC.payload.title}}`) - `CONTEXT` / `context`: Execution context - `STAGE` / `stage`: Stage configuration - `SECRET` / `secret`: Vault secrets (e.g., `{{SECRET.api_key}}`)  Accessing Data: - Dot notation: `{{DOC.payload.metadata.title}}` - Bracket notation: `{{DOC.payload['special-key']}}` - Array index: `{{DOC.items[0]}}`, `{{DOC.tags[2]}}` - Array first/last: `{{DOC.items | first}}`, `{{DOC.items | last}}`  Array Operations: - Iterate: `{% for item in DOC.tags %}{{item}}{% endfor %}` - Extract key: `{{DOC.items | map(attribute='name') | list}}` - Join: `{{DOC.tags | join(', ')}}` - Length: `{{DOC.items | length}}` - Slice: `{{DOC.items[:5]}}`  Conditionals: - If: `{% if DOC.status == 'active' %}...{% endif %}` - If-else: `{% if DOC.score > 0.8 %}high{% else %}low{% endif %}` - Ternary: `{{'yes' if DOC.enabled else 'no'}}`  Built-in Functions: `max`, `min`, `abs`, `round`, `ceil`, `floor` Custom Filters: `slugify` (URL-safe), `bool` (truthy coercion), `tojson` (JSON encode)  S3 URLs: Internal S3 URLs (s3://bucket/key) are automatically presigned when accessed via DOC namespace.")
    pagination: Optional[Pagination] = None
    stream: Optional[StrictBool] = Field(default=False, description="Enable streaming execution to receive real-time stage updates via Server-Sent Events (SSE). NOT REQUIRED - defaults to False for standard execution.   When stream=True: - Response uses text/event-stream content type - Each stage completion emits a StreamStageEvent - Events include: stage_start, stage_complete, stage_error, execution_complete - Clients receive intermediate results and statistics as stages execute - Useful for progress tracking, debugging, and partial result display   When stream=False (default): - Response returns after all stages complete - Returns a single RetrieverExecutionResponse with final results - Lower overhead for simple queries   Use streaming when: - You want to show real-time progress to users - You need to display intermediate results - Pipeline has many stages or long-running operations - Debugging or monitoring pipeline performance   Example streaming client (JavaScript): ```javascript const eventSource = new EventSource('/v1/retrievers/ret_123/execute?stream=true'); eventSource.onmessage = (event) => {   const stageEvent = JSON.parse(event.data);   if (stageEvent.event_type === 'stage_complete') {     console.log(`Stage ${stageEvent.stage_name} completed`);     console.log(`Documents: ${stageEvent.documents.length}`);   } }; ```   Example streaming client (Python): ```python import requests response = requests.post('/v1/retrievers/ret_123/execute',                         json={'inputs': {...}, 'stream': True},                         stream=True) for line in response.iter_lines():     if line.startswith(b'data: '):         event = json.loads(line[6:])         print(f\"Stage {event['stage_name']}: {event['event_type']}\") ```")
    __properties: ClassVar[List[str]] = ["inputs", "pagination", "stream"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of ExecuteRetrieverRequest from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of pagination
        if self.pagination:
            _dict['pagination'] = self.pagination.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of ExecuteRetrieverRequest from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "inputs": obj.get("inputs"),
            "pagination": Pagination.from_dict(obj["pagination"]) if obj.get("pagination") is not None else None,
            "stream": obj.get("stream") if obj.get("stream") is not None else False
        })
        return _obj


