Repository navigation
Expand file tree
/
Copy pathspeedify.py
More file actions
executable file
·2845 lines (2215 loc) · 86.6 KB
/
Copy pathspeedify.py
File metadata and controls
executable file
·2845 lines (2215 loc) · 86.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/python3
# Uses Python 3.7
import json
import logging
import subprocess
import os
import platform
import socket
from enum import Enum
from functools import wraps
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
"""
.. module:: speedify
:synopsis: Python wrapper for the Speedify CLI (Command Line Interface)
This module provides a comprehensive Python interface to control Speedify, a bonding VPN service.
It wraps nearly all functionality available in the Speedify CLI, allowing programmatic control of:
- Connection management (connect, disconnect, server selection)
- Authentication (login, logout, OAuth)
- Settings configuration (mode, encryption, transport, etc.)
- Adapter management (priority, rate limits, data limits)
- Privacy settings (killswitch, DNS leak protection)
- Traffic rules (streaming, bypass, fixed delay)
- Network sharing (Pair & Share)
- Statistics and monitoring
All functions communicate with the Speedify daemon via the speedify_cli executable using subprocess calls.
Responses are returned as parsed JSON dictionaries. Errors raise SpeedifyError or SpeedifyAPIError exceptions.
The CLI executable path is automatically detected on Windows, macOS, and Linux. You can override the default
by setting the SPEEDIFY_CLI environment variable or calling set_cli() with a custom path.
Example:
import speedify
# Check current state
state = speedify.show_state()
# Connect to closest server
speedify.connect_closest()
# Change settings
speedify.mode("speed")
speedify.encryption(True)
# Disconnect
speedify.disconnect()
"""
# ============================================================================
# Utility Functions (merged from utils.py and speedifyutil.py)
# ============================================================================
def ping_internet(host="8.8.8.8", port=53, timeout=3):
"""
Check if internet connection is available by connecting to a host.
:param host: Host to connect to (default: 8.8.8.8 - Google Public DNS)
:param port: Port to connect to (default: 53 - DNS)
:param timeout: Connection timeout in seconds (default: 3)
:return: True if connection successful, False otherwise
Example:
>>> ping_internet()
True
>>> ping_internet(host="1.1.1.1", port=80)
True
"""
try:
socket.setdefaulttimeout(timeout)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
return True
except socket.error as ex:
logging.warning(str(ex))
return False
def use_shell():
"""
Determine if shell=True should be used for subprocess calls.
:return: True on Windows, False on macOS/Linux
This is needed because Windows requires shell=True for some commands,
while Unix-like systems work better with shell=False.
"""
if platform.system().lower() == "darwin":
return False
if platform.system().lower() == "linux":
return False
else:
return True
def confirm_state_speedify(state):
"""
Confirm whether Speedify is in the specified state.
:param state: Expected State enum value
:return: True if Speedify is in the specified state, False otherwise
Example:
>>> confirm_state_speedify(State.CONNECTED)
True
"""
desc = show_state()
if state == desc:
return True
else:
logging.error("confirmStateSpeedify Failed command results: " + str(desc))
return False
def list_servers_speedify(public=True, private=False, excludeTest=True):
"""
Get a flattened list of Speedify server tags.
:param public: Include public servers (default: True)
:param private: Include private/dedicated servers (default: False)
:param excludeTest: Exclude servers with '-test' in the name (default: True)
:return: List of server tags, or "ERROR" on failure
Example:
>>> servers = list_servers_speedify()
>>> 'us-nyc' in servers
True
"""
try:
serverlist = []
jret = show_servers()
if public:
if "public" in jret:
for server in jret["public"]:
serverlist.append(server["tag"])
if private:
if "private" in jret:
for server in jret["private"]:
serverlist.append(server["tag"])
if excludeTest:
# servers with "test" in the name are bad news
serverlist2 = [x for x in serverlist if "-test" not in x]
serverlist = serverlist2
return serverlist
except SpeedifyError as err:
logging.error("Failed to get server list: " + str(err))
return "ERROR"
def using_speedify(destination="8.8.8.8"):
"""
Check if internet traffic is really going through Speedify.
Uses traceroute/mtr to verify that traffic is passing through 10.202.0.1
(the Speedify virtual adapter IP).
:param destination: Destination IP to trace (default: 8.8.8.8)
:return: True if traffic is going through Speedify, False otherwise
Example:
>>> using_speedify()
True
"""
tracert = ["traceroute", "-m", "2", destination]
if platform.system() == "Windows":
tracert = ["tracert", "-h", "1", "-d", destination]
elif platform.system() == "Linux":
tracert = ["mtr", "-m", "2", "-c", "2", "--report", destination]
try:
result = subprocess.run(tracert, stdout=subprocess.PIPE, shell=use_shell())
except FileNotFoundError as e:
logging.error(e)
raise e
resultstr = result.stdout.decode("utf-8")
if "10.202.0.1" in resultstr:
return True
else:
return False
# ============================================================================
# Enums and Exception Classes
# ============================================================================
class State(Enum):
"""Enum of speedify states."""
LOGGED_OUT = 0
LOGGING_IN = 1
LOGGED_IN = 2
AUTO_CONNECTING = 3
CONNECTING = 4
DISCONNECTING = 5
CONNECTED = 6
OVERLIMIT = 7
UNKNOWN = 8
class Priority(Enum):
"""Enum of speedify connection priorities."""
AUTOMATIC = "automatic"
ALWAYS = "always"
BACKUP = "backup"
SECONDARY = "secondary"
NEVER = "never"
class SpeedifyError(Exception):
"""Generic error thrown by library."""
def __init__(self, message):
self.message = message
class SpeedifyAPIError(SpeedifyError):
"""Error thrown if speedify gave a bad json response."""
def __init__(self, error_code, error_type, error_message):
self.error_code = error_code
self.error_type = error_type
self.error_message = error_message
self.message = error_message
_cli_path = None
def set_cli(new_cli_path):
"""Change the path to the cli after importing the module.
The path defaults to the cli's default install location.
:param new_cli_path: Full path to speedify_cli.
:type new_cli_path: str
"""
global _cli_path
_cli_path = new_cli_path
def get_cli():
"""
:returns: str -- The full path to the speedify cli.
"""
global _cli_path
if (_cli_path == None) or (_cli_path == ""):
_cli_path = _find_cli()
return _cli_path
def find_state_for_string(mystate):
"""
Converts a string representation of a Speedify state to a State enum.
:param mystate: String representation of the state (case-insensitive).
:type mystate: str
:returns: speedify.State -- The corresponding State enum value.
:raises KeyError: If the state string is not a valid State enum value.
"""
return State[str(mystate).upper().strip()]
def exception_wrapper(argument):
"""
Decorator that wraps functions to provide standardized error logging for SpeedifyError exceptions.
This decorator catches SpeedifyError exceptions, logs them with a contextual message,
and then re-raises the exception. It's applied to most public API functions to ensure
consistent error handling and logging throughout the module.
:param argument: Contextual error message prefix to use when logging errors.
:type argument: str
:returns: function -- The decorated function with error handling.
Example:
@exception_wrapper("Failed to connect")
def connect(server=""):
# Function implementation
pass
"""
def decorator(function):
@wraps(function)
def wrapper(*args, **kwargs):
try:
result = function(*args, **kwargs)
return result
except SpeedifyError as err:
logger.error(argument + ": " + err.message)
raise err
return wrapper
return decorator
# Functions for controlling Speedify State
@exception_wrapper("Failed to connect")
def connect(server: str = ""):
"""
connect(server="")
Tell Speedify to connect. Returns serverInformation if success, raises Speedify if unsuccessful.
See show_servers() for the list of servers available.
Example:
connect()
connect("us nyc 11") # server numbers may change, use show_servers()
:param server: Server to connect to.
:type server: str
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
args = ["connect"] + server.split()
return _run_speedify_cmd(args)
def connect_closest():
"""Connects to the closest server
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect("closest")
def connect_public():
"""Connects to the closest public server
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect("public")
def connect_private():
"""Connects to the closest private server
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect("private")
def connect_p2p():
"""Connects to a server that allows p2p traffic
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect("p2p")
def connect_country(country: str = "us"):
"""Connects to a server via the 2 letter country code
See show_servers() for the list of servers available.
:param country: 2 letter country code.
:type country: str
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect(country)
def connect_last():
"""Connects to the last server
:returns: dict -- :ref:`JSON currentserver <connect>` from speedify.
"""
return connect("last")
@exception_wrapper("Disconnect failed")
def disconnect():
"""
disconnect()
Disconnects. Waits for disconnect to complete
:returns: bool -- TRUE if disconnect succeeded
"""
_run_speedify_cmd(["disconnect"])
return True
@exception_wrapper("Failed to set connect method")
def connectmethod(method, country="us", city=None, num=None):
"""
connectmethod(method, country="us", city=None, num=None)
Sets the default connectmethod of --
closest
public
private
p2p
country (in which case country is required)
:param method: The connect method.
:type method: str
:param country: 2 letter country code.
:type country: str
:param city: The (optional) city the server is located.
:type city: str
:param num: The (optional) server number.
:type num: int
:returns: dict -- :ref:`JSON connectmethod <connectmethod>` from speedify.
"""
args = ["connectmethod"]
if method == "dedicated":
method = "private"
if method == "country":
args.append(country)
if city != None:
args.append(city)
if num != None:
args.append(num)
elif method:
args.append(method)
resultjson = _run_speedify_cmd(args)
return resultjson
def connectmethod_as_string(connectMethodObject, hypens=True):
"""
Converts a connectmethod JSON object to a formatted string.
Takes the JSON object returned by show_connectmethod() and converts it to a string
representation. The separator can be either hyphens (for "us-nova-2" style strings)
or spaces (for "us nova 2" style strings suitable for command line arguments).
Example:
method_obj = show_connectmethod()
# Returns "us-nova-2" with hyphens
hyphenated = connectmethod_as_string(method_obj, hypens=True)
# Returns "us nova 2" with spaces
spaced = connectmethod_as_string(method_obj, hypens=False)
:param connectMethodObject: The JSON object returned by show_connectmethod().
:type connectMethodObject: dict
:param hypens: If True, use hyphens as separator; if False, use spaces.
:type hypens: bool
:returns: str -- Formatted connection method string.
"""
sep = " "
if hypens:
sep = "-"
ret = connectMethodObject["connectMethod"]
if ret == "country":
ret = str(connectMethodObject["country"])
if connectMethodObject["city"]:
ret = ret + sep + str(connectMethodObject["city"])
if connectMethodObject["num"]:
ret = ret + sep + str(connectMethodObject["num"])
return ret
@exception_wrapper("Failed to login")
def login(user, password):
"""
login(user, password)
Login. Returns a State. State object will hold
information on the success of this command.
:param user: username
:type user: str
:param password: password
:type password: str
:returns: speedify.State -- The speedify state enum.
"""
args = ["login", user, password]
resultjson = _run_speedify_cmd(args)
return find_state_for_string(resultjson["state"])
@exception_wrapper("Failed to login")
def login_auto():
"""
login()
Attempt to login automatically.
Returns a state indicating success category.
:returns: speedify.State -- The speedify state enum.
"""
resultjson = _run_speedify_cmd(["login", "auto"])
return find_state_for_string(resultjson["state"])
@exception_wrapper("Failed to login")
def login_oauth(token: str):
"""
login_oauth(token)
Attempt to login via an oauth token.
Returns a state indicating success category.
:param token: The oauth token.
:type token: str
:returns: speedify.State -- The speedify state enum.
"""
resultjson = _run_speedify_cmd("login", "oauth", token)
return find_state_for_string(resultjson["state"])
@exception_wrapper("Failed to logout")
def logout():
"""
logout()
logout. returns the state, desc=LOGGED_OUT is a success
:returns: speedify.State -- The speedify state enum.
"""
jret = _run_speedify_cmd(["logout"])
return find_state_for_string(jret["state"])
@exception_wrapper("Failed to refresh OAuth token")
def refresh_oauth(token: str):
"""
refresh_oauth(token)
Accepts a new security token for the same user to be used when communicating with servers.
If changing users, use login_oauth() instead.
Example:
refresh_oauth("abdef1234567890")
:param token: The new OAuth access token.
:type token: str
:returns: dict -- JSON response from speedify.
"""
return _run_speedify_cmd(["refresh", "oauth", token])
def esni(is_on: bool = True):
"""
esni(is_on)
Turn esni functionality on or off.
:param is_on: Whether esni should be on... or not.
:type is_on: bool
"""
if is_on is True:
is_on = "on"
elif is_on is False:
is_on = "off"
else:
raise ValueError("is_on neither True nor False")
return _run_speedify_cmd(["esni", is_on])
def headercompression(is_on: bool = True):
"""
headercompression(is_on)
Turn header compression on or off.
:param is_on: Whether headercompression should be on... or not.
:type is_on: bool
"""
if is_on is True:
is_on = "on"
elif is_on is False:
is_on = "off"
else:
raise ValueError("is_on neither True nor False")
return _run_speedify_cmd(["headercompression", is_on])
def gateway(uri: str):
"""
gateway(uri)
Set the gateway uri.
:param uri: The gateway uri.
:type uri: str
"""
return _run_speedify_cmd(["gateway", uri])
def daemon(method: str):
"""
daemon(method)
Call `method` on the daemon. Only "exit" is supported.
:param method: The method to call. Only "exit" is available.
"""
return _run_speedify_cmd(["daemon", method])
#
# Getter functions
#
@exception_wrapper("Failed to show server list")
def show_servers():
"""
show_servers()
Returns all the servers, public and private
:returns: dict -- :ref:`JSON server list <show-servers>` from speedify.
"""
return _run_speedify_cmd(["show", "servers"])
@exception_wrapper("Failed to show privacy")
def show_privacy():
"""
show_privacy()
Returns privacy settings
:returns: dict -- dict -- :ref:`JSON privacy <show-privacy>` from speedify.
"""
return _run_speedify_cmd(["show", "privacy"])
@exception_wrapper("Failed to set advanced ISP stats")
def privacy_advanced_isp_stats(is_on: bool):
"""
privacy_advanced_isp_stats(is_on)
Enables or disables advanced ISP statistics. When enabled, extra stats are available from some ISPs (e.g., Starlink).
Example:
privacy_advanced_isp_stats(True)
:param is_on: Enable (True) or disable (False) advanced ISP stats.
:type is_on: bool
:returns: dict -- JSON privacy settings.
"""
return _run_speedify_cmd(["privacy", "advancedIspStats", "on" if is_on else "off"])
@exception_wrapper("Failed to set API protection")
def privacy_api_protection(is_on: bool):
"""
privacy_api_protection(is_on)
Enables or disables protection on the Speedify API port. When disabled, speedify_cli can control a remote Speedify installation.
Example:
privacy_api_protection(True)
:param is_on: Enable (True) or disable (False) API protection.
:type is_on: bool
:returns: dict -- JSON privacy settings.
"""
return _run_speedify_cmd(["privacy", "apiProtection", "on" if is_on else "off"])
@exception_wrapper("Failed to set DoH request")
def privacy_request_disable_doh(is_on: bool):
"""
privacy_request_disable_doh(is_on)
If the Speedify VPN connection should request that browsers disable DNS over HTTPS.
Enabling this can help streaming and streamingbypass rules function.
Example:
privacy_request_disable_doh(True)
:param is_on: Enable (True) or disable (False) request to disable DoH.
:type is_on: bool
:returns: dict -- JSON privacy settings.
"""
return _run_speedify_cmd(["privacy", "requestToDisableDoH", "on" if is_on else "off"])
@exception_wrapper("Failed to show settings")
def show_settings():
"""
show_settings()
Returns current settings
:returns: dict -- dict -- :ref:`JSON settings <show-settings>` from speedify.
"""
return _run_speedify_cmd(["show", "settings"])
@exception_wrapper("Failed to show adapters")
def show_adapters():
"""
show_adapters()
Returns current adapters
:returns: dict -- dict -- :ref:`JSON list of adapters <show-adapters>` from speedify.
"""
return _run_speedify_cmd(["show", "adapters"])
@exception_wrapper("Failed to show directory")
def show_directory():
"""
show_directory()
Returns current directory service
:returns: dict -- dict -- :ref:`JSON object for the current directory service <show-directory>` from speedify.
"""
return _run_speedify_cmd(["show", "directory"])
@exception_wrapper("Failed to do captiveportal_check")
def captiveportal_check():
"""
captiveportal_check()
Returns adapters which are currently blocked by a captive portal
:returns: dict -- dict -- :ref:`JSON list of adapters behind captive portal` from speedify.
"""
return _run_speedify_cmd(["captiveportal", "check"])
@exception_wrapper("Failed to do captiveportal_login")
def captiveportal_login(proxy: bool = True, adapterID: str = None):
"""
captiveportal_login()
Starts or stops the local proxy intercepting traffic on ports 52,80,433, for
filling in a captive portal. If the user interface is running, once this is
turned on, it will launch a captive portal browser. If it's not, then it's
up to you to launch a browser pointing at an http website to get to the
portal page.
:param proxy: Whether the local proxy should intercept captive portal traffic
:type priority: boolean
:param adapterID: The interface adapterID
:type adapterID: str
:returns: dict -- dict -- :ref:`JSON list of adapters behind captive portal` from speedify.
"""
args = ["captiveportal", "login"]
startproxy = True
if proxy == "on":
args.append("on")
elif proxy == "off":
startproxy = False
args.append("off")
elif proxy:
args.append("on")
else:
startproxy = False
args.append("off")
if adapterID and startproxy:
args.append(adapterID)
return _run_speedify_cmd(args)
@exception_wrapper("Failed to show connectmethod")
def show_connectmethod():
"""
show_connectmethod()
Returns the current state of the 'connectmethod' setting.
:returns dict -- :ref:`JSON connectmethod <show-connectmethod>`.
"""
return _run_speedify_cmd(["show", "connectmethod"])
@exception_wrapper("Failed to show streamingbypass")
def show_streamingbypass():
"""
show_streamingbypass()
Returns the current state of the 'streamingbypass' setting.
:returns dict -- :ref:`JSON streamingbypass <show-streamingbypass>`.
"""
return _run_speedify_cmd(["show", "streamingbypass"])
@exception_wrapper("Failed to show disconnect")
def show_disconnect():
"""
show_disconnect()
Returns the last reason for a disconnection.
:returns dict -- :ref:`JSON disconnect <show-disconnect>`.
"""
return _run_speedify_cmd(["show", "disconnect"])
@exception_wrapper("Failed to show streaming")
def show_streaming():
"""
show_streaming()
Returns the current state of the 'streaming' setting.
:returns dict -- :ref:`JSON streaming <show-streaming>`.
"""
return _run_speedify_cmd(["show", "streaming"])
@exception_wrapper("Failed to show speedtest")
def show_speedtest():
"""
show_speedtest()
Returns the current results of 'speedtest'.
:returns dict -- :ref:`JSON speedtest <show-speedtest>`.
"""
return _run_speedify_cmd(["show", "speedtest"])
@exception_wrapper("Failed to show fixeddelay")
def show_fixeddelay():
"""
show_fixeddelay()
Shows the current rules for including traffic in the jitter buffer (fixed delay).
Rules for domains, ports, and IP addresses are supported.
:returns dict -- :ref:`JSON traffic rules with fixed_delay action <show-fixeddelay>`.
"""
return _run_speedify_cmd(["show", "fixeddelay"])
@exception_wrapper("Failed to show traffic rules")
def show_trafficrules():
"""
show_trafficrules()
Shows the current traffic rules setting.
:returns dict -- :ref:`JSON traffic rules <show-trafficrules>`.
"""
return _run_speedify_cmd(["show", "trafficrules"])
@exception_wrapper("Failed to get current server")
def show_currentserver():
"""
show_currentserver()
Returns current server
:returns: dict -- :ref:`JSON currentserver <show-currentserver>` from speedify.
"""
return _run_speedify_cmd(["show", "currentserver"])
@exception_wrapper("Failed to get current user")
def show_user():
"""
show_user()
Returns current user
:returns: dict -- :ref:`JSON response <show-user>` from speedify.
"""
return _run_speedify_cmd(["show", "user"])
@exception_wrapper("Failed to show connect method")
def show_connectmethod():
"""
show_connectmethod()
Returns the connectmethod related settings
:returns: :ref:`JSON response <show-connectmethod>` from speedify.
"""
return _run_speedify_cmd(["show", "connectmethod"])
@exception_wrapper("getting state")
def show_state():
"""
show_state()
Returns the current state of Speedify (CONNECTED, CONNECTING, etc.)
:returns: speedify.State -- The speedify state enum.
"""
resultjson = _run_speedify_cmd(["state"])
return find_state_for_string(resultjson["state"])
@exception_wrapper("Failed to get version")
def show_version():
"""
show_version()
Returns speedify version
:returns: dict -- :ref:`JSON version <version>` from speedify.
"""
return _run_speedify_cmd(["version"])
@exception_wrapper("Failed to get activation code")
def activationcode():
"""
activationcode()
Obtain activation code to activate a device on my.speedify.com
Example:
result = activationcode()
print(result["activationCode"])
print(result["activationUrl"])
:returns: dict -- JSON with activationCode and activationUrl fields.
"""
return _run_speedify_cmd(["activationcode"])
@exception_wrapper("Failed to show logsettings")
def show_logsettings():
"""
show_logsettings()
Returns current log settings
:returns: dict -- :ref:`JSON logsettings <show-logsettings>` from speedify.
"""
return _run_speedify_cmd(["show", "logsettings"])
@exception_wrapper("Failed to erase logs")
def log_erase():
"""
log_erase()
Deletes the Speedify daemon's log files.
:returns: dict -- JSON response from speedify.
"""
return _run_speedify_cmd(["log", "erase"])
@exception_wrapper("Failed to configure daemon logs")
def log_daemon(file_size: int, files_per_daemon: int, total_files: int, log_level: str):
"""
log_daemon(file_size, files_per_daemon, total_files, log_level)
Configure the size and number of the Speedify daemon's log files.
Example:
log_daemon(3145728, 7, 9, "info")
:param file_size: Size of each log file in bytes.
:type file_size: int
:param files_per_daemon: Number of log files per daemon.
:type files_per_daemon: int
:param total_files: Total number of log files.
:type total_files: int
:param log_level: Log level (verbose|info|warn|error).
:type log_level: str
:returns: dict -- :ref:`JSON log settings <log-daemon>` from speedify.
"""
return _run_speedify_cmd(
["log", "daemon", str(file_size), str(files_per_daemon), str(total_files), log_level]
)
@exception_wrapper("Failed to show dscp")
def show_dscp():
"""
show_dscp()
Returns current DSCP queue settings
Note: DSCP (Differentiated Services Code Point) settings are only supported on Linux.
On other platforms, this will raise a SpeedifyAPIError.
:returns: dict -- :ref:`JSON dscp settings <show-dscp>` from speedify.
:raises SpeedifyAPIError: On non-Linux platforms where DSCP is not supported.
"""
return _run_speedify_cmd(["show", "dscp"])
@exception_wrapper("Failed to add DSCP queue")
def dscp_queues_add(dscp: int, priority: str = None, replication: str = None, retransmissions: int = None):
"""
dscp_queues_add(dscp, priority, replication, retransmissions)
Add a DSCP queue configuration.
Note: DSCP settings are only supported on Linux.
Example:
dscp_queues_add(0, priority="on", replication="auto", retransmissions=2)
:param dscp: DSCP value (0-63).
:type dscp: int
:param priority: Priority setting (on|off|auto), optional.
:type priority: str
:param replication: Replication setting (on|off|auto), optional.
:type replication: str
:param retransmissions: Number of retransmission attempts (0-255), optional.
:type retransmissions: int
:returns: dict -- JSON with updated DSCP queue settings.
:raises SpeedifyAPIError: On non-Linux platforms where DSCP is not supported.
"""
args = ["dscp", "queues", "add", str(dscp)]
if priority is not None:
args.extend(["priority", priority])
if replication is not None:
args.extend(["replication", replication])
if retransmissions is not None:
args.extend(["retransmissions", str(retransmissions)])
return _run_speedify_cmd(args)
@exception_wrapper("Failed to set DSCP queue")
def dscp_queues_set(dscp: int, priority: str = None, replication: str = None, retransmissions: int = None):
"""
dscp_queues_set(dscp, priority, replication, retransmissions)
Set a DSCP queue configuration.
Note: DSCP settings are only supported on Linux.
Example:
dscp_queues_set(0, priority="on", replication="auto", retransmissions=2)
:param dscp: DSCP value (0-63).
:type dscp: int
:param priority: Priority setting (on|off|auto), optional.
:type priority: str
:param replication: Replication setting (on|off|auto), optional.
:type replication: str