"""
Binance Spot WebSocket Streams

OpenAPI Specifications for the Binance Spot WebSocket Streams

API documents:
  - [Github web-socket-streams documentation file](https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-streams.md)
  - [General API information for web-socket-streams on website](https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams)

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

Do not edit the class manually.
"""

from binance_common.errors import RequiredError
from binance_common.utils import ws_streams_placeholder
from binance_common.websocket import (
    WebSocketStreamBase,
    RequestStream,
    RequestStreamHandle,
)

from ..models import AggTradeResponse
from ..models import AllMarketRollingWindowTickerResponse
from ..models import AllMiniTickerResponse
from ..models import AvgPriceResponse
from ..models import BookTickerResponse
from ..models import DiffBookDepthResponse
from ..models import KlineResponse
from ..models import KlineOffsetResponse
from ..models import MiniTickerResponse
from ..models import PartialBookDepthResponse
from ..models import RollingWindowTickerResponse
from ..models import TickerResponse
from ..models import TradeResponse


from ..models import AllMarketRollingWindowTickerWindowSizeEnum
from ..models import KlineIntervalEnum
from ..models import KlineOffsetIntervalEnum
from ..models import PartialBookDepthLevelsEnum
from ..models import RollingWindowTickerWindowSizeEnum

from typing import Optional, Union


class WebSocketStreamsApi:
    """Client for WebSocketStreamsApi endpoints."""

    def __init__(self, websocket_base: WebSocketStreamBase) -> None:
        self.websocket_base = websocket_base

    async def agg_trade(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Aggregate Trade Streams
        /<symbol>@aggTrade
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams

        The Aggregate Trade Streams push trade information that is aggregated for a single taker order.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@aggTrade".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=AggTradeResponse
        )

    async def all_market_rolling_window_ticker(
        self,
        window_size: Union[AllMarketRollingWindowTickerWindowSizeEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
            WebSocket All Market Rolling Window Statistics Streams
            /!ticker_<windowSize>@arr
            https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-rolling-window-statistics-streams

            Rolling window ticker statistics for all market symbols, computed over multiple windows.
        Note that only tickers that have changed will be present in the array.

            Args:
                    window_size (Union[AllMarketRollingWindowTickerWindowSizeEnum, None]):
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                RequestStreamHandle

            Raises:
                RequiredError: If a required parameter is missing.

        """

        if window_size is None:
            raise RequiredError(
                field="window_size",
                error_message="Missing required parameter 'window_size'",
            )

        stream = ws_streams_placeholder(
            "/!ticker_<windowSize>@arr".replace("/", "", 1),
            {
                "window_size": window_size,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base,
            stream=stream,
            response_model=AllMarketRollingWindowTickerResponse,
        )

    async def all_mini_ticker(
        self,
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket All Market Mini Tickers Stream
        /!miniTicker@arr
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream

        24hr rolling window mini-ticker statistics for all symbols that changed in an array. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs. Note that only tickers that have changed will be present in the array.

        Args:
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        stream = ws_streams_placeholder(
            "/!miniTicker@arr".replace("/", "", 1),
            {
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=AllMiniTickerResponse
        )

    async def avg_price(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Average Price
        /<symbol>@avgPrice
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#average-price

        Average price streams push changes in the average price over a fixed time interval.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@avgPrice".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=AvgPriceResponse
        )

    async def book_ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
            WebSocket Individual Symbol Book Ticker Streams
            /<symbol>@bookTicker
            https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-book-ticker-streams

            Pushes any update to the best bid or ask's price or quantity in real-time for a specified symbol.
        Multiple `<symbol>@bookTicker` streams can be subscribed to over one connection.

            Args:
                    symbol (Union[str, None]): Symbol to query
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                RequestStreamHandle

            Raises:
                RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@bookTicker".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=BookTickerResponse
        )

    async def diff_book_depth(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
        update_speed: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Diff. Depth Stream
        /<symbol>@depth@<updateSpeed>
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream

        Order book price and quantity depth updates used to locally manage an order book.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.
                update_speed (Optional[str] = None): 1000ms or 100ms

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@depth@<updateSpeed>".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
                "update_speed": update_speed,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=DiffBookDepthResponse
        )

    async def kline(
        self,
        symbol: Union[str, None],
        interval: Union[KlineIntervalEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
            WebSocket Kline/Candlestick Streams for UTC
            /<symbol>@kline_<interval>
            https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc

            The Kline/Candlestick Stream push updates to the current klines/candlestick every second in `UTC+0` timezone

        <a id="kline-intervals"></a>

            Args:
                    symbol (Union[str, None]): Symbol to query
                    interval (Union[KlineIntervalEnum, None]):
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                RequestStreamHandle

            Raises:
                RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if interval is None:
            raise RequiredError(
                field="interval", error_message="Missing required parameter 'interval'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@kline_<interval>".replace("/", "", 1),
            {
                "symbol": symbol,
                "interval": interval,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=KlineResponse
        )

    async def kline_offset(
        self,
        symbol: Union[str, None],
        interval: Union[KlineOffsetIntervalEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Kline/Candlestick Streams with timezone offset
        /<symbol>@kline_<interval>@+08:00
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-with-timezone-offset

        The Kline/Candlestick Stream push updates to the current klines/candlestick every second in `UTC+8` timezone

        Args:
                symbol (Union[str, None]): Symbol to query
                interval (Union[KlineOffsetIntervalEnum, None]):
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if interval is None:
            raise RequiredError(
                field="interval", error_message="Missing required parameter 'interval'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@kline_<interval>@+08:00".replace("/", "", 1),
            {
                "symbol": symbol,
                "interval": interval,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=KlineOffsetResponse
        )

    async def mini_ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Mini Ticker Stream
        /<symbol>@miniTicker
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream

        24hr rolling window mini-ticker statistics. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@miniTicker".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=MiniTickerResponse
        )

    async def partial_book_depth(
        self,
        symbol: Union[str, None],
        levels: Union[PartialBookDepthLevelsEnum, None],
        id: Optional[str] = None,
        update_speed: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Partial Book Depth Streams
        /<symbol>@depth<levels>@<updateSpeed>
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams

        Top **\<levels\>** bids and asks, pushed every second. Valid **\<levels\>** are 5, 10, or 20.

        Args:
                symbol (Union[str, None]): Symbol to query
                levels (Union[PartialBookDepthLevelsEnum, None]):
                id (Optional[str] = None): Unique WebSocket request ID.
                update_speed (Optional[str] = None): 1000ms or 100ms

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if levels is None:
            raise RequiredError(
                field="levels", error_message="Missing required parameter 'levels'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@depth<levels>@<updateSpeed>".replace("/", "", 1),
            {
                "symbol": symbol,
                "levels": levels,
                "id": id,
                "update_speed": update_speed,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=PartialBookDepthResponse
        )

    async def rolling_window_ticker(
        self,
        symbol: Union[str, None],
        window_size: Union[RollingWindowTickerWindowSizeEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Rolling Window Statistics Streams
        /<symbol>@ticker_<windowSize>
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-rolling-window-statistics-streams

        Rolling window ticker statistics for a single symbol, computed over multiple windows.

        Args:
                symbol (Union[str, None]): Symbol to query
                window_size (Union[RollingWindowTickerWindowSizeEnum, None]):
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if window_size is None:
            raise RequiredError(
                field="window_size",
                error_message="Missing required parameter 'window_size'",
            )

        stream = ws_streams_placeholder(
            "/<symbol>@ticker_<windowSize>".replace("/", "", 1),
            {
                "symbol": symbol,
                "window_size": window_size,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base,
            stream=stream,
            response_model=RollingWindowTickerResponse,
        )

    async def ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Ticker Streams
        /<symbol>@ticker
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-ticker-streams

        24hr rolling window ticker statistics for a single symbol. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@ticker".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=TickerResponse
        )

    async def trade(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Trade Streams
        /<symbol>@trade
        https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#trade-streams

        The Trade Streams push raw trade information; each trade has a unique buyer and seller.

        Args:
                symbol (Union[str, None]): Symbol to query
                id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )

        stream = ws_streams_placeholder(
            "/<symbol>@trade".replace("/", "", 1),
            {
                "symbol": symbol,
                "id": id,
            },
        )

        return await RequestStream(
            self.websocket_base, stream=stream, response_model=TradeResponse
        )
