@@ -71,7 +71,7 @@ def __init__(
7171 self .ws_kwargs = {}
7272
7373 if verbose :
74- logging .getLogger (' binance.ws' ).setLevel (logging .DEBUG )
74+ logging .getLogger (" binance.ws" ).setLevel (logging .DEBUG )
7575
7676 def _get_stream_url (self , stream_url : Optional [str ] = None ):
7777 if stream_url :
@@ -134,7 +134,11 @@ def _get_account_socket(
134134 return self ._conns [conn_id ]
135135
136136 def _get_futures_socket (
137- self , path : str , futures_type : FuturesType , prefix : str = "stream?streams="
137+ self ,
138+ path : str ,
139+ futures_type : FuturesType ,
140+ prefix : str = "stream?streams=" ,
141+ category : Optional [str ] = None ,
138142 ):
139143 socket_type : BinanceSocketType = BinanceSocketType .USD_M_FUTURES
140144 if futures_type == FuturesType .USD_M :
@@ -143,6 +147,8 @@ def _get_futures_socket(
143147 stream_url = self .FSTREAM_TESTNET_URL
144148 elif self .demo :
145149 stream_url = self .FSTREAM_DEMO_URL
150+ if category :
151+ stream_url = f"{ stream_url } { category } /"
146152 else :
147153 stream_url = self .DSTREAM_URL
148154 if self .testnet :
@@ -174,7 +180,9 @@ def _get_options_socket(self, path: str, base_path: str, prefix: str = "ws/"):
174180 elif base_path == "market" :
175181 stream_url = base_url + "market/"
176182 else :
177- raise ValueError (f"base_path must be 'public' or 'market', got '{ base_path } '" )
183+ raise ValueError (
184+ f"base_path must be 'public' or 'market', got '{ base_path } '"
185+ )
178186
179187 return self ._get_socket (
180188 path ,
@@ -361,7 +369,9 @@ def kline_futures_socket(
361369 """
362370
363371 path = f"{ symbol .lower ()} _{ contract_type .value } @continuousKline_{ interval } "
364- return self ._get_futures_socket (path , prefix = "ws/" , futures_type = futures_type )
372+ return self ._get_futures_socket (
373+ path , prefix = "ws/" , futures_type = futures_type , category = "market"
374+ )
365375
366376 def miniticker_socket (self , update_time : int = 1000 ):
367377 """Start a miniticker websocket for all trades
@@ -487,7 +497,7 @@ def aggtrade_futures_socket(
487497
488498 """
489499 return self ._get_futures_socket (
490- symbol .lower () + "@aggTrade" , futures_type = futures_type
500+ symbol .lower () + "@aggTrade" , futures_type = futures_type , category = "market"
491501 )
492502
493503 def symbol_miniticker_socket (self , symbol : str ):
@@ -642,7 +652,9 @@ def futures_ticker_socket(self):
642652 }
643653 ]
644654 """
645- return self ._get_futures_socket ("!ticker@arr" , FuturesType .USD_M )
655+ return self ._get_futures_socket (
656+ "!ticker@arr" , FuturesType .USD_M , category = "market"
657+ )
646658
647659 def futures_coin_ticker_socket (self ):
648660 """Start a websocket for all ticker data
@@ -728,7 +740,7 @@ def symbol_mark_price_socket(
728740 """
729741 stream_name = "@markPrice@1s" if fast else "@markPrice"
730742 return self ._get_futures_socket (
731- symbol .lower () + stream_name , futures_type = futures_type
743+ symbol .lower () + stream_name , futures_type = futures_type , category = "market"
732744 )
733745
734746 def all_mark_price_socket (
@@ -755,7 +767,9 @@ def all_mark_price_socket(
755767 ]
756768 """
757769 stream_name = "!markPrice@arr@1s" if fast else "!markPrice@arr"
758- return self ._get_futures_socket (stream_name , futures_type = futures_type )
770+ return self ._get_futures_socket (
771+ stream_name , futures_type = futures_type , category = "market"
772+ )
759773
760774 def symbol_ticker_futures_socket (
761775 self , symbol : str , futures_type : FuturesType = FuturesType .USD_M
@@ -779,7 +793,7 @@ def symbol_ticker_futures_socket(
779793 ]
780794 """
781795 return self ._get_futures_socket (
782- symbol .lower () + "@bookTicker" , futures_type = futures_type
796+ symbol .lower () + "@bookTicker" , futures_type = futures_type , category = "public"
783797 )
784798
785799 def individual_symbol_ticker_futures_socket (
@@ -800,7 +814,7 @@ def individual_symbol_ticker_futures_socket(
800814 }
801815 """
802816 return self ._get_futures_socket (
803- symbol .lower () + "@ticker" , futures_type = futures_type
817+ symbol .lower () + "@ticker" , futures_type = futures_type , category = "market"
804818 )
805819
806820 def all_ticker_futures_socket (
@@ -832,7 +846,10 @@ def all_ticker_futures_socket(
832846 ]
833847 """
834848
835- return self ._get_futures_socket (channel , futures_type = futures_type )
849+ category = "public" if "bookTicker" in channel else "market"
850+ return self ._get_futures_socket (
851+ channel , futures_type = futures_type , category = category
852+ )
836853
837854 def symbol_book_ticker_socket (self , symbol : str ):
838855 """Start a websocket for the best bid or ask's price or quantity for a specified symbol.
@@ -916,10 +933,15 @@ def options_multiplex_socket(self, streams: List[str]):
916933 """
917934 stream_name = "/" .join (streams )
918935 stream_path = f"streams={ stream_name } "
919- return self ._get_options_socket (stream_path , base_path = "market" , prefix = "stream?" )
936+ return self ._get_options_socket (
937+ stream_path , base_path = "market" , prefix = "stream?"
938+ )
920939
921940 def futures_multiplex_socket (
922- self , streams : List [str ], futures_type : FuturesType = FuturesType .USD_M
941+ self ,
942+ streams : List [str ],
943+ futures_type : FuturesType = FuturesType .USD_M ,
944+ category : str = "market" ,
923945 ):
924946 """Start a multiplexed socket using a list of socket names.
925947 User stream sockets can not be included.
@@ -932,6 +954,7 @@ def futures_multiplex_socket(
932954
933955 :param streams: list of stream names in lower case
934956 :param futures_type: use USD-M or COIN-M futures default USD-M
957+ :param category: stream category for USD-M futures URL routing ("public", "market", or "private"), default "market"
935958
936959 :returns: connection key string if successful, False otherwise
937960
@@ -940,7 +963,7 @@ def futures_multiplex_socket(
940963 """
941964 path = f"streams={ '/' .join (streams )} "
942965 return self ._get_futures_socket (
943- path , prefix = "stream?" , futures_type = futures_type
966+ path , prefix = "stream?" , futures_type = futures_type , category = category
944967 )
945968
946969 def user_socket (self ):
@@ -975,6 +998,7 @@ def futures_user_socket(self):
975998 stream_url = self .FSTREAM_TESTNET_URL
976999 elif self .demo :
9771000 stream_url = self .FSTREAM_DEMO_URL
1001+ stream_url += "private/"
9781002 return self ._get_account_socket ("futures" , stream_url = stream_url )
9791003
9801004 def coin_futures_user_socket (self ):
@@ -1019,6 +1043,7 @@ def futures_socket(self):
10191043 stream_url = self .FSTREAM_TESTNET_URL
10201044 elif self .demo :
10211045 stream_url = self .FSTREAM_DEMO_URL
1046+ stream_url += "private/"
10221047 return self ._get_account_socket ("futures" , stream_url = stream_url )
10231048
10241049 def coin_futures_socket (self ):
@@ -1087,7 +1112,9 @@ def options_ticker_socket(self, symbol: str):
10871112 :param symbol: The option symbol to subscribe to (e.g. "BTC-220930-18000-C")
10881113 :type symbol: str
10891114 """
1090- return self ._get_options_socket (symbol .lower () + "@optionTicker" , base_path = "public" )
1115+ return self ._get_options_socket (
1116+ symbol .lower () + "@optionTicker" , base_path = "public"
1117+ )
10911118
10921119 def options_ticker_by_expiration_socket (self , symbol : str , expiration_date : str ):
10931120 """Subscribe to a 24-hour ticker info stream by underlying asset and expiration date.
@@ -1105,7 +1132,9 @@ def options_ticker_by_expiration_socket(self, symbol: str, expiration_date: str)
11051132 :param expiration_date: The expiration date (e.g., "251230" for Dec 30, 2025)
11061133 :type expiration_date: str
11071134 """
1108- return self ._get_options_socket (symbol .lower () + "@optionTicker@" + expiration_date , base_path = "public" )
1135+ return self ._get_options_socket (
1136+ symbol .lower () + "@optionTicker@" + expiration_date , base_path = "public"
1137+ )
11091138
11101139 def options_recent_trades_socket (self , symbol : str ):
11111140 """Subscribe to a real-time trade information stream.
@@ -1121,7 +1150,9 @@ def options_recent_trades_socket(self, symbol: str):
11211150 :param symbol: The option symbol or underlying asset (e.g., "BTC-200630-9000-P" or "BTCUSDT")
11221151 :type symbol: str
11231152 """
1124- return self ._get_options_socket (symbol .lower () + "@optionTrade" , base_path = "public" )
1153+ return self ._get_options_socket (
1154+ symbol .lower () + "@optionTrade" , base_path = "public"
1155+ )
11251156
11261157 def options_kline_socket (
11271158 self , symbol : str , interval = AsyncClient .KLINE_INTERVAL_1MINUTE
@@ -1142,9 +1173,13 @@ def options_kline_socket(
11421173 :param interval: Kline interval, default KLINE_INTERVAL_1MINUTE
11431174 :type interval: str
11441175 """
1145- return self ._get_options_socket (symbol .lower () + "@kline_" + interval , base_path = "market" )
1176+ return self ._get_options_socket (
1177+ symbol .lower () + "@kline_" + interval , base_path = "market"
1178+ )
11461179
1147- def options_depth_socket (self , symbol : str , depth : str = "10" , speed : str = "500ms" ):
1180+ def options_depth_socket (
1181+ self , symbol : str , depth : str = "10" , speed : str = "500ms"
1182+ ):
11481183 """Subscribe to partial book depth stream for options trading.
11491184
11501185 Top <levels> bids and asks. Valid levels are 5, 10, 20.
@@ -1162,7 +1197,9 @@ def options_depth_socket(self, symbol: str, depth: str = "10", speed: str = "500
11621197 :param speed: Update speed. Valid values: "100ms" or "500ms", default "500ms"
11631198 :type speed: str
11641199 """
1165- return self ._get_options_socket (symbol .lower () + "@depth" + str (depth ) + "@" + speed , base_path = "public" )
1200+ return self ._get_options_socket (
1201+ symbol .lower () + "@depth" + str (depth ) + "@" + speed , base_path = "public"
1202+ )
11661203
11671204 def options_book_ticker_socket (self , symbol : str ):
11681205 """Subscribe to an options book ticker stream.
@@ -1185,9 +1222,13 @@ def options_book_ticker_socket(self, symbol: str):
11851222 :param symbol: The option symbol (e.g., "BTC-251226-110000-C")
11861223 :type symbol: str
11871224 """
1188- return self ._get_options_socket (symbol .lower () + "@bookTicker" , base_path = "public" )
1225+ return self ._get_options_socket (
1226+ symbol .lower () + "@bookTicker" , base_path = "public"
1227+ )
11891228
1190- def futures_depth_socket (self , symbol : str , depth : str = "10" , futures_type = FuturesType .USD_M ):
1229+ def futures_depth_socket (
1230+ self , symbol : str , depth : str = "10" , futures_type = FuturesType .USD_M
1231+ ):
11911232 """Subscribe to a futures depth data stream
11921233
11931234 https://binance-docs.github.io/apidocs/futures/en/#partial-book-depth-streams
@@ -1199,7 +1240,9 @@ def futures_depth_socket(self, symbol: str, depth: str = "10", futures_type=Futu
11991240 :param futures_type: use USD-M or COIN-M futures default USD-M
12001241 """
12011242 return self ._get_futures_socket (
1202- symbol .lower () + "@depth" + str (depth ), futures_type = futures_type
1243+ symbol .lower () + "@depth" + str (depth ),
1244+ futures_type = futures_type ,
1245+ category = "public" ,
12031246 )
12041247
12051248 def futures_rpi_depth_socket (self , symbol : str , futures_type = FuturesType .USD_M ):
@@ -1215,7 +1258,9 @@ def futures_rpi_depth_socket(self, symbol: str, futures_type=FuturesType.USD_M):
12151258 :param futures_type: use USD-M or COIN-M futures default USD-M
12161259 """
12171260 return self ._get_futures_socket (
1218- symbol .lower () + "@rpiDepth@500ms" , futures_type = futures_type
1261+ symbol .lower () + "@rpiDepth@500ms" ,
1262+ futures_type = futures_type ,
1263+ category = "public" ,
12191264 )
12201265
12211266 def options_new_symbol_socket (self ):
@@ -1263,7 +1308,10 @@ def options_open_interest_socket(self, symbol: str, expiration_date: str):
12631308 :param expiration_date: The expiration date (e.g., "221125" for Nov 25, 2022)
12641309 :type expiration_date: str
12651310 """
1266- return self ._get_options_socket (symbol .lower () + "@optionOpenInterest@" + expiration_date , base_path = "market" )
1311+ return self ._get_options_socket (
1312+ symbol .lower () + "@optionOpenInterest@" + expiration_date ,
1313+ base_path = "market" ,
1314+ )
12671315
12681316 def options_mark_price_socket (self , symbol : str ):
12691317 """Subscribe to an options mark price stream.
@@ -1287,7 +1335,9 @@ def options_mark_price_socket(self, symbol: str):
12871335 :param symbol: The underlying asset (e.g., "BTCUSDT", "ETHUSDT")
12881336 :type symbol: str
12891337 """
1290- return self ._get_options_socket (symbol .lower () + "@optionMarkPrice" , base_path = "market" )
1338+ return self ._get_options_socket (
1339+ symbol .lower () + "@optionMarkPrice" , base_path = "market"
1340+ )
12911341
12921342 def options_index_price_socket (self ):
12931343 """Subscribe to an options index price stream.
@@ -1351,8 +1401,7 @@ def __init__(
13511401 async def _before_socket_listener_start (self ):
13521402 assert self ._client
13531403 self ._bsm = BinanceSocketManager (
1354- client = self ._client ,
1355- max_queue_size = self ._max_queue_size
1404+ client = self ._client , max_queue_size = self ._max_queue_size
13561405 )
13571406
13581407 def _start_async_socket (
@@ -1365,7 +1414,9 @@ def _start_async_socket(
13651414 start_time = time .time ()
13661415 while not self ._bsm :
13671416 if time .time () - start_time > 5 :
1368- raise RuntimeError ("Binance Socket Manager failed to initialize after 5 seconds" )
1417+ raise RuntimeError (
1418+ "Binance Socket Manager failed to initialize after 5 seconds"
1419+ )
13691420 time .sleep (0.1 )
13701421 socket = getattr (self ._bsm , socket_name )(** params )
13711422 socket_path : str = path or socket ._path # noqa
0 commit comments