32
32
import time
33
33
from random import randint
34
34
35
+ try :
36
+ from typing import List , Tuple , Type , Union
37
+ except ImportError :
38
+ pass
39
+
35
40
from micropython import const
36
41
37
42
from .matcher import MQTTMatcher
@@ -84,7 +89,7 @@ class TemporaryError(Exception):
84
89
85
90
86
91
# Legacy ESP32SPI Socket API
87
- def set_socket (sock , iface = None ):
92
+ def set_socket (sock , iface = None ) -> None :
88
93
"""Legacy API for setting the socket and network interface.
89
94
90
95
:param sock: socket object.
@@ -100,7 +105,7 @@ def set_socket(sock, iface=None):
100
105
101
106
102
107
class _FakeSSLSocket :
103
- def __init__ (self , socket , tls_mode ):
108
+ def __init__ (self , socket , tls_mode ) -> None :
104
109
self ._socket = socket
105
110
self ._mode = tls_mode
106
111
self .settimeout = socket .settimeout
@@ -117,10 +122,10 @@ def connect(self, address):
117
122
118
123
119
124
class _FakeSSLContext :
120
- def __init__ (self , iface ):
125
+ def __init__ (self , iface ) -> None :
121
126
self ._iface = iface
122
127
123
- def wrap_socket (self , socket , server_hostname = None ):
128
+ def wrap_socket (self , socket , server_hostname = None ) -> _FakeSSLSocket :
124
129
"""Return the same socket"""
125
130
# pylint: disable=unused-argument
126
131
return _FakeSSLSocket (socket , self ._iface .TLS_MODE )
@@ -134,7 +139,7 @@ def nothing(self, msg: str, *args) -> None:
134
139
"""no action"""
135
140
pass
136
141
137
- def __init__ (self ):
142
+ def __init__ (self ) -> None :
138
143
for log_level in ["debug" , "info" , "warning" , "error" , "critical" ]:
139
144
setattr (NullLogger , log_level , self .nothing )
140
145
@@ -166,21 +171,21 @@ class MQTT:
166
171
def __init__ (
167
172
self ,
168
173
* ,
169
- broker ,
170
- port = None ,
171
- username = None ,
172
- password = None ,
173
- client_id = None ,
174
- is_ssl = None ,
175
- keep_alive = 60 ,
176
- recv_timeout = 10 ,
174
+ broker : str ,
175
+ port : Union [ int , None ] = None ,
176
+ username : Union [ str , None ] = None ,
177
+ password : Union [ str , None ] = None ,
178
+ client_id : Union [ str , None ] = None ,
179
+ is_ssl : Union [ bool , None ] = None ,
180
+ keep_alive : int = 60 ,
181
+ recv_timeout : int = 10 ,
177
182
socket_pool = None ,
178
183
ssl_context = None ,
179
- use_binary_mode = False ,
180
- socket_timeout = 1 ,
181
- connect_retries = 5 ,
184
+ use_binary_mode : bool = False ,
185
+ socket_timeout : int = 1 ,
186
+ connect_retries : int = 5 ,
182
187
user_data = None ,
183
- ):
188
+ ) -> None :
184
189
185
190
self ._socket_pool = socket_pool
186
191
self ._ssl_context = ssl_context
@@ -253,7 +258,7 @@ def __init__(
253
258
self ._lw_retain = False
254
259
255
260
# List of subscribed topics, used for tracking
256
- self ._subscribed_topics = []
261
+ self ._subscribed_topics : List [ str ] = []
257
262
self ._on_message_filtered = MQTTMatcher ()
258
263
259
264
# Default topic callback methods
@@ -265,7 +270,7 @@ def __init__(
265
270
self .on_unsubscribe = None
266
271
267
272
# pylint: disable=too-many-branches
268
- def _get_connect_socket (self , host , port , * , timeout = 1 ):
273
+ def _get_connect_socket (self , host : str , port : int , * , timeout : int = 1 ):
269
274
"""Obtains a new socket and connects to a broker.
270
275
271
276
:param str host: Desired broker hostname
@@ -338,20 +343,20 @@ def _get_connect_socket(self, host, port, *, timeout=1):
338
343
def __enter__ (self ):
339
344
return self
340
345
341
- def __exit__ (self , exception_type , exception_value , traceback ):
346
+ def __exit__ (self , exception_type , exception_value , traceback ) -> None :
342
347
self .deinit ()
343
348
344
- def deinit (self ):
349
+ def deinit (self ) -> None :
345
350
"""De-initializes the MQTT client and disconnects from the mqtt broker."""
346
351
self .disconnect ()
347
352
348
353
@property
349
- def mqtt_msg (self ):
354
+ def mqtt_msg (self ) -> Tuple [ int , int ] :
350
355
"""Returns maximum MQTT payload and topic size."""
351
356
return self ._msg_size_lim , MQTT_TOPIC_LENGTH_LIMIT
352
357
353
358
@mqtt_msg .setter
354
- def mqtt_msg (self , msg_size ) :
359
+ def mqtt_msg (self , msg_size : int ) -> None :
355
360
"""Sets the maximum MQTT message payload size.
356
361
357
362
:param int msg_size: Maximum MQTT payload size.
@@ -388,7 +393,7 @@ def will_set(self, topic=None, payload=None, qos=0, retain=False):
388
393
self ._lw_msg = payload
389
394
self ._lw_retain = retain
390
395
391
- def add_topic_callback (self , mqtt_topic , callback_method ):
396
+ def add_topic_callback (self , mqtt_topic : str , callback_method ) -> None :
392
397
"""Registers a callback_method for a specific MQTT topic.
393
398
394
399
:param str mqtt_topic: MQTT topic identifier.
@@ -398,7 +403,7 @@ def add_topic_callback(self, mqtt_topic, callback_method):
398
403
raise ValueError ("MQTT topic and callback method must both be defined." )
399
404
self ._on_message_filtered [mqtt_topic ] = callback_method
400
405
401
- def remove_topic_callback (self , mqtt_topic ) :
406
+ def remove_topic_callback (self , mqtt_topic : str ) -> None :
402
407
"""Removes a registered callback method.
403
408
404
409
:param str mqtt_topic: MQTT topic identifier string.
@@ -421,10 +426,10 @@ def on_message(self):
421
426
return self ._on_message
422
427
423
428
@on_message .setter
424
- def on_message (self , method ):
429
+ def on_message (self , method ) -> None :
425
430
self ._on_message = method
426
431
427
- def _handle_on_message (self , client , topic , message ):
432
+ def _handle_on_message (self , client , topic : str , message : str ):
428
433
matched = False
429
434
if topic is not None :
430
435
for callback in self ._on_message_filtered .iter_match (topic ):
@@ -434,7 +439,7 @@ def _handle_on_message(self, client, topic, message):
434
439
if not matched and self .on_message : # regular on_message
435
440
self .on_message (client , topic , message )
436
441
437
- def username_pw_set (self , username , password = None ):
442
+ def username_pw_set (self , username : str , password : Union [ str , None ] = None ) -> None :
438
443
"""Set client's username and an optional password.
439
444
440
445
:param str username: Username to use with your MQTT broker.
@@ -447,7 +452,13 @@ def username_pw_set(self, username, password=None):
447
452
if password is not None :
448
453
self ._password = password
449
454
450
- def connect (self , clean_session = True , host = None , port = None , keep_alive = None ):
455
+ def connect (
456
+ self ,
457
+ clean_session : bool = True ,
458
+ host : Union [str , None ] = None ,
459
+ port : Union [int , None ] = None ,
460
+ keep_alive : Union [int , None ] = None ,
461
+ ) -> int :
451
462
"""Initiates connection with the MQTT Broker. Will perform exponential back-off
452
463
on connect failures.
453
464
@@ -503,7 +514,13 @@ def connect(self, clean_session=True, host=None, port=None, keep_alive=None):
503
514
raise MMQTTException (exc_msg )
504
515
505
516
# pylint: disable=too-many-branches, too-many-statements, too-many-locals
506
- def _connect (self , clean_session = True , host = None , port = None , keep_alive = None ):
517
+ def _connect (
518
+ self ,
519
+ clean_session : bool = True ,
520
+ host : Union [str , None ] = None ,
521
+ port : Union [int , None ] = None ,
522
+ keep_alive : Union [int , None ] = None ,
523
+ ) -> int :
507
524
"""Initiates connection with the MQTT Broker.
508
525
509
526
:param bool clean_session: Establishes a persistent session.
@@ -616,7 +633,7 @@ def _connect(self, clean_session=True, host=None, port=None, keep_alive=None):
616
633
f"No data received from broker for { self ._recv_timeout } seconds."
617
634
)
618
635
619
- def disconnect (self ):
636
+ def disconnect (self ) -> None :
620
637
"""Disconnects the MiniMQTT client from the MQTT broker."""
621
638
self ._connected ()
622
639
self .logger .debug ("Sending DISCONNECT packet to broker" )
@@ -631,7 +648,7 @@ def disconnect(self):
631
648
if self .on_disconnect is not None :
632
649
self .on_disconnect (self , self ._user_data , 0 )
633
650
634
- def ping (self ):
651
+ def ping (self ) -> list [ int ] :
635
652
"""Pings the MQTT Broker to confirm if the broker is alive or if
636
653
there is an active network connection.
637
654
Returns response codes of any messages received while waiting for PINGRESP.
@@ -651,7 +668,13 @@ def ping(self):
651
668
return rcs
652
669
653
670
# pylint: disable=too-many-branches, too-many-statements
654
- def publish (self , topic , msg , retain = False , qos = 0 ):
671
+ def publish (
672
+ self ,
673
+ topic : str ,
674
+ msg : Union [str , int , float , bytes ],
675
+ retain : bool = False ,
676
+ qos : int = 0 ,
677
+ ) -> None :
655
678
"""Publishes a message to a topic provided.
656
679
657
680
:param str topic: Unique topic identifier.
@@ -740,7 +763,7 @@ def publish(self, topic, msg, retain=False, qos=0):
740
763
f"No data received from broker for { self ._recv_timeout } seconds."
741
764
)
742
765
743
- def subscribe (self , topic , qos = 0 ) :
766
+ def subscribe (self , topic : str , qos : int = 0 ) -> None :
744
767
"""Subscribes to a topic on the MQTT Broker.
745
768
This method can subscribe to one topics or multiple topics.
746
769
@@ -807,7 +830,7 @@ def subscribe(self, topic, qos=0):
807
830
f"No data received from broker for { self ._recv_timeout } seconds."
808
831
)
809
832
810
- def unsubscribe (self , topic ) :
833
+ def unsubscribe (self , topic : str ) -> None :
811
834
"""Unsubscribes from a MQTT topic.
812
835
813
836
:param str|list topic: Unique MQTT topic identifier string or list.
@@ -861,7 +884,7 @@ def unsubscribe(self, topic):
861
884
f"No data received from broker for { self ._recv_timeout } seconds."
862
885
)
863
886
864
- def _recompute_reconnect_backoff (self ):
887
+ def _recompute_reconnect_backoff (self ) -> None :
865
888
"""
866
889
Recompute the reconnection timeout. The self._reconnect_timeout will be used
867
890
in self._connect() to perform the actual sleep.
@@ -891,7 +914,7 @@ def _recompute_reconnect_backoff(self):
891
914
)
892
915
self ._reconnect_timeout += jitter
893
916
894
- def _reset_reconnect_backoff (self ):
917
+ def _reset_reconnect_backoff (self ) -> None :
895
918
"""
896
919
Reset reconnect back-off to the initial state.
897
920
@@ -900,7 +923,7 @@ def _reset_reconnect_backoff(self):
900
923
self ._reconnect_attempt = 0
901
924
self ._reconnect_timeout = float (0 )
902
925
903
- def reconnect (self , resub_topics = True ):
926
+ def reconnect (self , resub_topics : bool = True ) -> int :
904
927
"""Attempts to reconnect to the MQTT broker.
905
928
Return the value from connect() if successful. Will disconnect first if already connected.
906
929
Will perform exponential back-off on connect failures.
@@ -924,13 +947,13 @@ def reconnect(self, resub_topics=True):
924
947
925
948
return ret
926
949
927
- def loop (self , timeout = 0 ) :
950
+ def loop (self , timeout : float = 0 ) -> Union [ list [ int ], None ] :
928
951
# pylint: disable = too-many-return-statements
929
952
"""Non-blocking message loop. Use this method to
930
953
check incoming subscription messages.
931
954
Returns response codes of any messages received.
932
955
933
- :param int timeout: Socket timeout, in seconds.
956
+ :param float timeout: Socket timeout, in seconds.
934
957
935
958
"""
936
959
@@ -964,7 +987,7 @@ def loop(self, timeout=0):
964
987
965
988
return rcs if rcs else None
966
989
967
- def _wait_for_msg (self , timeout = 0.1 ):
990
+ def _wait_for_msg (self , timeout : float = 0.1 ) -> Union [ int , None ] :
968
991
# pylint: disable = too-many-return-statements
969
992
970
993
"""Reads and processes network events.
@@ -1004,7 +1027,7 @@ def _wait_for_msg(self, timeout=0.1):
1004
1027
sz = self ._recv_len ()
1005
1028
# topic length MSB & LSB
1006
1029
topic_len = self ._sock_exact_recv (2 )
1007
- topic_len = ( topic_len [0 ] << 8 ) | topic_len [1 ]
1030
+ topic_len = int (( topic_len [0 ] << 8 ) | topic_len [1 ])
1008
1031
1009
1032
if topic_len > sz - 2 :
1010
1033
raise MMQTTException (
@@ -1034,19 +1057,18 @@ def _wait_for_msg(self, timeout=0.1):
1034
1057
1035
1058
return res [0 ]
1036
1059
1037
- def _recv_len (self ):
1060
+ def _recv_len (self ) -> int :
1038
1061
"""Unpack MQTT message length."""
1039
1062
n = 0
1040
1063
sh = 0
1041
- b = bytearray (1 )
1042
1064
while True :
1043
1065
b = self ._sock_exact_recv (1 )[0 ]
1044
1066
n |= (b & 0x7F ) << sh
1045
1067
if not b & 0x80 :
1046
1068
return n
1047
1069
sh += 7
1048
1070
1049
- def _sock_exact_recv (self , bufsize ) :
1071
+ def _sock_exact_recv (self , bufsize : int ) -> bytearray :
1050
1072
"""Reads _exact_ number of bytes from the connected socket. Will only return
1051
1073
string with the exact number of bytes requested.
1052
1074
@@ -1100,7 +1122,7 @@ def _sock_exact_recv(self, bufsize):
1100
1122
)
1101
1123
return rc
1102
1124
1103
- def _send_str (self , string ) :
1125
+ def _send_str (self , string : str ) -> None :
1104
1126
"""Encodes a string and sends it to a socket.
1105
1127
1106
1128
:param str string: String to write to the socket.
@@ -1114,7 +1136,7 @@ def _send_str(self, string):
1114
1136
self ._sock .send (string )
1115
1137
1116
1138
@staticmethod
1117
- def _valid_topic (topic ) :
1139
+ def _valid_topic (topic : str ) -> None :
1118
1140
"""Validates if topic provided is proper MQTT topic format.
1119
1141
1120
1142
:param str topic: Topic identifier
@@ -1130,7 +1152,7 @@ def _valid_topic(topic):
1130
1152
raise MMQTTException ("Topic length is too large." )
1131
1153
1132
1154
@staticmethod
1133
- def _valid_qos (qos_level ) :
1155
+ def _valid_qos (qos_level : int ) -> None :
1134
1156
"""Validates if the QoS level is supported by this library
1135
1157
1136
1158
:param int qos_level: Desired QoS level.
@@ -1142,21 +1164,21 @@ def _valid_qos(qos_level):
1142
1164
else :
1143
1165
raise MMQTTException ("QoS must be an integer." )
1144
1166
1145
- def _connected (self ):
1167
+ def _connected (self ) -> None :
1146
1168
"""Returns MQTT client session status as True if connected, raises
1147
1169
a `MMQTTException` if `False`.
1148
1170
"""
1149
1171
if not self .is_connected ():
1150
1172
raise MMQTTException ("MiniMQTT is not connected" )
1151
1173
1152
- def is_connected (self ):
1174
+ def is_connected (self ) -> bool :
1153
1175
"""Returns MQTT client session status as True if connected, False
1154
1176
if not.
1155
1177
"""
1156
1178
return self ._is_connected and self ._sock is not None
1157
1179
1158
1180
# Logging
1159
- def enable_logger (self , log_pkg , log_level = 20 , logger_name = "log" ):
1181
+ def enable_logger (self , log_pkg , log_level : int = 20 , logger_name : str = "log" ):
1160
1182
"""Enables library logging by getting logger from the specified logging package
1161
1183
and setting its log level.
1162
1184
@@ -1173,6 +1195,6 @@ def enable_logger(self, log_pkg, log_level=20, logger_name="log"):
1173
1195
1174
1196
return self .logger
1175
1197
1176
- def disable_logger (self ):
1198
+ def disable_logger (self ) -> None :
1177
1199
"""Disables logging."""
1178
1200
self .logger = NullLogger ()
0 commit comments