"""
This type stub file was generated by pyright.
"""

import logging
import temporalio.bridge.metric
import temporalio.common
from dataclasses import dataclass
from datetime import timedelta
from enum import Enum
from typing import ClassVar, Mapping, NewType, Optional, Sequence, Union
from typing_extensions import Protocol

"""Runtime for clients and workers. (experimental)

This module is currently experimental. The API may change.
"""
_default_runtime: Optional[Runtime] = ...
class Runtime:
    """Runtime for Temporal Python SDK.

    Users are encouraged to use :py:meth:`default`. It can be set with
    :py:meth:`set_default`. Every time a new runtime is created, a new internal
    thread pool is created.

    Runtimes do not work across forks.
    """
    @staticmethod
    def default() -> Runtime:
        """Get the default runtime, creating if not already created.

        If the default runtime needs to be different, it should be done with
        :py:meth:`set_default` before this is called or ever used.

        Returns:
            The default runtime.
        """
        ...
    
    @staticmethod
    def set_default(runtime: Runtime, *, error_if_already_set: bool = ...) -> None:
        """Set the default runtime to the given runtime.

        This should be called before any Temporal client is created, but can
        change the existing one. Any clients and workers created with the
        previous runtime will stay on that runtime.

        Args:
            runtime: The runtime to set.
            error_if_already_set: If True and default is already set, this will
                raise a RuntimeError.
        """
        ...
    
    def __init__(self, *, telemetry: TelemetryConfig) -> None:
        """Create a default runtime with the given telemetry config.

        Each new runtime creates a new internal thread pool, so use sparingly.
        """
        ...
    
    @property
    def metric_meter(self) -> temporalio.common.MetricMeter:
        """Metric meter for this runtime. This is a no-op metric meter if no
        metrics were configured.
        """
        ...
    


@dataclass
class TelemetryFilter:
    """Filter for telemetry use."""
    core_level: str
    other_level: str
    def formatted(self) -> str:
        """Return a formatted form of this filter."""
        ...
    


@dataclass(frozen=True)
class LoggingConfig:
    """Configuration for runtime logging."""
    filter: Union[TelemetryFilter, str]
    forwarding: Optional[LogForwardingConfig] = ...
    default: ClassVar[LoggingConfig]


_module_start_time = ...
@dataclass
class LogForwardingConfig:
    """Configuration for log forwarding from Core.

    Configuring this will send logs from Core to the given Python logger. By
    default, log timestamps are overwritten and internally throttled/buffered
    for a few milliseconds to prevent overloading Python. This means those log
    records may have a time in the past and technically may appear out of order
    with Python-originated log messages by a few milliseconds.

    If for some reason lots of logs occur within the buffered time (i.e.
    thousands), they may be sent earlier. Users are discouraged from using this
    with ``TRACE`` Core logging.

    All log records produced have a ``temporal_log`` attribute that contains a
    representation of the Core log. This representation has a ``fields``
    attribute which has arbitrary extra data from Core. By default a string
    representation of this extra ``fields`` attribute is appended to the
    message.

    .. warning::
        This API is experimental
    """
    logger: logging.Logger
    append_target_to_name: bool = ...
    prepend_target_on_message: bool = ...
    overwrite_log_record_time: bool = ...
    append_log_fields_to_message: bool = ...


class OpenTelemetryMetricTemporality(Enum):
    """Temporality for OpenTelemetry metrics."""
    CUMULATIVE = ...
    DELTA = ...


@dataclass(frozen=True)
class OpenTelemetryConfig:
    """Configuration for OpenTelemetry collector."""
    url: str
    headers: Optional[Mapping[str, str]] = ...
    metric_periodicity: Optional[timedelta] = ...
    metric_temporality: OpenTelemetryMetricTemporality = ...


@dataclass(frozen=True)
class PrometheusConfig:
    """Configuration for Prometheus metrics endpoint."""
    bind_address: str
    counters_total_suffix: bool = ...
    unit_suffix: bool = ...


class MetricBuffer:
    """A buffer that can be set on :py:class:`TelemetryConfig` to record
    metrics instead of ignoring/exporting them.

    .. warning::
        It is important that the buffer size is set to a high number and that
        :py:meth:`retrieve_updates` is called regularly to drain the buffer. If
        the buffer is full, metric updates will be dropped and an error will be
        logged.
    """
    def __init__(self, buffer_size: int) -> None:
        """Create a buffer with the given size.

        .. warning::
            It is important that the buffer size is set to a high number and is
            drained regularly. See :py:class:`MetricBuffer` warning.

        Args:
            buffer_size: Size of the buffer. Set this to a large value. A value
                in the tens of thousands or higher is plenty reasonable.
        """
        ...
    
    def retrieve_updates(self) -> Sequence[BufferedMetricUpdate]:
        """Drain the buffer and return all metric updates.

        .. warning::
            It is important that this is called regularly. See
            :py:class:`MetricBuffer` warning.

        Returns:
            A sequence of metric updates.
        """
        ...
    


@dataclass(frozen=True)
class TelemetryConfig:
    """Configuration for Core telemetry."""
    logging: Optional[LoggingConfig] = ...
    metrics: Optional[Union[OpenTelemetryConfig, PrometheusConfig, MetricBuffer]] = ...
    global_tags: Mapping[str, str] = ...
    attach_service_name: bool = ...
    metric_prefix: Optional[str] = ...


BufferedMetricKind = NewType("BufferedMetricKind", int)
BUFFERED_METRIC_KIND_COUNTER = ...
BUFFERED_METRIC_KIND_GAUGE = ...
BUFFERED_METRIC_KIND_HISTOGRAM = ...
class BufferedMetric(Protocol):
    """A metric for a buffered update.

    The same metric for the same name and runtime is guaranteed to be the exact
    same object for performance reasons. This means py:func:`id` will be the
    same for the same metric across updates.
    """
    @property
    def name(self) -> str:
        """Get the name of the metric."""
        ...
    
    @property
    def description(self) -> Optional[str]:
        """Get the description of the metric if any."""
        ...
    
    @property
    def unit(self) -> Optional[str]:
        """Get the unit of the metric if any."""
        ...
    
    @property
    def kind(self) -> BufferedMetricKind:
        """Get the metric kind.

        This is one of :py:const:`BUFFERED_METRIC_KIND_COUNTER`,
        :py:const:`BUFFERED_METRIC_KIND_GAUGE`, or
        :py:const:`BUFFERED_METRIC_KIND_HISTOGRAM`.
        """
        ...
    


class BufferedMetricUpdate(Protocol):
    """A single metric value update."""
    @property
    def metric(self) -> BufferedMetric:
        """Metric being updated.

        For performance reasons, this is the same object across updates for the
        same metric. This means py:func:`id` will be the same for the same
        metric across updates.
        """
        ...
    
    @property
    def value(self) -> Union[int, float]:
        """Value for the update.

        For counters this is a delta, for gauges and histograms this is just the
        value.
        """
        ...
    
    @property
    def attributes(self) -> temporalio.common.MetricAttributes:
        """Attributes for the update.

        For performance reasons, this is the same object across updates for the
        same attribute set. This means py:func:`id` will be the same for the
        same attribute set across updates. Note this is for same "attribute set"
        as created by the metric creator, but different attribute sets may have
        the same values.

        Do not mutate this.
        """
        ...
    


class _MetricMeter(temporalio.common.MetricMeter):
    def __init__(self, core_meter: temporalio.bridge.metric.MetricMeter, core_attrs: temporalio.bridge.metric.MetricAttributes) -> None:
        ...
    
    def create_counter(self, name: str, description: Optional[str] = ..., unit: Optional[str] = ...) -> temporalio.common.MetricCounter:
        ...
    
    def create_histogram(self, name: str, description: Optional[str] = ..., unit: Optional[str] = ...) -> temporalio.common.MetricHistogram:
        ...
    
    def create_gauge(self, name: str, description: Optional[str] = ..., unit: Optional[str] = ...) -> temporalio.common.MetricGauge:
        ...
    
    def with_additional_attributes(self, additional_attributes: temporalio.common.MetricAttributes) -> temporalio.common.MetricMeter:
        ...
    


class _MetricCounter(temporalio.common.MetricCounter):
    def __init__(self, name: str, description: Optional[str], unit: Optional[str], core_metric: temporalio.bridge.metric.MetricCounter, core_attrs: temporalio.bridge.metric.MetricAttributes) -> None:
        ...
    
    @property
    def name(self) -> str:
        ...
    
    @property
    def description(self) -> Optional[str]:
        ...
    
    @property
    def unit(self) -> Optional[str]:
        ...
    
    def add(self, value: int, additional_attributes: Optional[temporalio.common.MetricAttributes] = ...) -> None:
        ...
    
    def with_additional_attributes(self, additional_attributes: temporalio.common.MetricAttributes) -> temporalio.common.MetricCounter:
        ...
    


class _MetricHistogram(temporalio.common.MetricHistogram):
    def __init__(self, name: str, description: Optional[str], unit: Optional[str], core_metric: temporalio.bridge.metric.MetricHistogram, core_attrs: temporalio.bridge.metric.MetricAttributes) -> None:
        ...
    
    @property
    def name(self) -> str:
        ...
    
    @property
    def description(self) -> Optional[str]:
        ...
    
    @property
    def unit(self) -> Optional[str]:
        ...
    
    def record(self, value: int, additional_attributes: Optional[temporalio.common.MetricAttributes] = ...) -> None:
        ...
    
    def with_additional_attributes(self, additional_attributes: temporalio.common.MetricAttributes) -> temporalio.common.MetricHistogram:
        ...
    


class _MetricGauge(temporalio.common.MetricGauge):
    def __init__(self, name: str, description: Optional[str], unit: Optional[str], core_metric: temporalio.bridge.metric.MetricGauge, core_attrs: temporalio.bridge.metric.MetricAttributes) -> None:
        ...
    
    @property
    def name(self) -> str:
        ...
    
    @property
    def description(self) -> Optional[str]:
        ...
    
    @property
    def unit(self) -> Optional[str]:
        ...
    
    def set(self, value: int, additional_attributes: Optional[temporalio.common.MetricAttributes] = ...) -> None:
        ...
    
    def with_additional_attributes(self, additional_attributes: temporalio.common.MetricAttributes) -> temporalio.common.MetricGauge:
        ...
    


