speedtest-ssh 2.8.0__tar.gz → 2.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {speedtest_ssh-2.8.0/speedtest_ssh.egg-info → speedtest_ssh-2.9.0}/PKG-INFO +1 -1
  2. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/pyproject.toml +7 -0
  3. speedtest_ssh-2.9.0/speedtest_ssh/_version.py +1 -0
  4. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/data_transfer.py +9 -3
  5. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/speedtest_ssh.py +36 -39
  6. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/util.py +4 -4
  7. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0/speedtest_ssh.egg-info}/PKG-INFO +1 -1
  8. speedtest_ssh-2.8.0/speedtest_ssh/_version.py +0 -1
  9. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/LICENSE +0 -0
  10. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/README.md +0 -0
  11. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/setup.cfg +0 -0
  12. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/__init__.py +0 -0
  13. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/config.py +0 -0
  14. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/ping.py +0 -0
  15. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/py.typed +0 -0
  16. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh/sftp_wrapper.py +0 -0
  17. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh.egg-info/SOURCES.txt +0 -0
  18. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh.egg-info/dependency_links.txt +0 -0
  19. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh.egg-info/entry_points.txt +0 -0
  20. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh.egg-info/requires.txt +0 -0
  21. {speedtest_ssh-2.8.0 → speedtest_ssh-2.9.0}/speedtest_ssh.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: speedtest_ssh
3
- Version: 2.8.0
3
+ Version: 2.9.0
4
4
  Summary: A tool meant to check inter-device speeds via ssh
5
5
  License: GPL
6
6
  Project-URL: Homepage, https://github.com/zwimer/speedtest_ssh
@@ -58,3 +58,10 @@ ignore = ["E731"]
58
58
  line-length = 120
59
59
  [tool.ruff.per-file-ignores]
60
60
  "__init__.py" = ["F401", "F403"]
61
+
62
+ [tool.bandit]
63
+ skips = ["B404", "B108"]
64
+
65
+ [tool.vulture]
66
+ ignore_names = ["cli"]
67
+ paths = ["speedtest_ssh"]
@@ -0,0 +1 @@
1
+ __version__: str = "2.9.0"
@@ -22,6 +22,13 @@ if TYPE_CHECKING:
22
22
  __all__ = ("DataTransfer", "SFTP", "Rsync")
23
23
 
24
24
 
25
+ _dict = string.ascii_uppercase + string.ascii_lowercase + string.digits
26
+
27
+
28
+ def _rand_str(size: int) -> str:
29
+ return "".join(random.choice(_dict) for _ in range(size)) # nosec B311
30
+
31
+
25
32
  class ProgressBar(tqdm):
26
33
  """
27
34
  A small tqdm wrapper for paramiko's SFTP callbacks to use
@@ -43,7 +50,7 @@ class ProgressBar(tqdm):
43
50
 
44
51
  class DataTransfer:
45
52
  """
46
- A context mananger used to send and receive data to and from the remote client
53
+ A context manager used to send and receive data to and from the remote client
47
54
  This class is a context manager; on exit will remove the remote file on deletion
48
55
  """
49
56
 
@@ -54,8 +61,7 @@ class DataTransfer:
54
61
  :param config: The Config object the DataTransfer instance should use
55
62
  """
56
63
  self._l = getLogger(self._LOG)
57
- rand = lambda: random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
58
- self._remote_f: str = f"/tmp/speedtest-ssh_{datetime.now()}_{''.join(rand() for _ in range(8))}.tmp"
64
+ self._remote_f: str = f"/tmp/speedtest-ssh_{datetime.now()}_{_rand_str(8)}.tmp"
59
65
  self._remote_f = self._remote_f.replace(":", "-").replace(" ", "_")
60
66
  # We promise that _remote_f components match: ^[a-zA-Z\d_.-]+$ (old rsync args suck)
61
67
  self._l.debug("Parsing ssh config and loading keys...")
@@ -5,7 +5,6 @@ from pathlib import Path
5
5
  import argparse
6
6
  import math
7
7
  import time
8
- import sys
9
8
  import os
10
9
 
11
10
  from .config import Config
@@ -15,7 +14,8 @@ from ._version import __version__
15
14
 
16
15
 
17
16
  base_size = 2 * (1024**2)
18
- _password_env_name = "SPEEDTEST_SSH_PASSWORD"
17
+ _password_env_name = "SPEEDTEST_SSH_PASSWORD" # nosec B105
18
+ _LOG_VERBOSITY: dict[int, int] = {0: WARNING, 1: INFO, 2: DEBUG}
19
19
  _LOG = "speedtest_ssh"
20
20
 
21
21
 
@@ -63,7 +63,7 @@ def _print_results(ping_delay: float | None, up_ns: int, down_ns: int, size: int
63
63
  print(f"{prefix}Upload Speed: {fmt(up_ns)}\nDownload Speed: {fmt(down_ns)}")
64
64
 
65
65
 
66
- def speedtest_ssh(num_seconds: int, ping: bool, mode: str, conf: Config) -> None:
66
+ def speedtest_ssh(seconds: int, ping: bool, mode: str, conf: Config) -> None:
67
67
  """
68
68
  Run speedtest_ssh
69
69
  """
@@ -78,7 +78,7 @@ def speedtest_ssh(num_seconds: int, ping: bool, mode: str, conf: Config) -> None
78
78
  print("Testing...")
79
79
  nano_sec: int = 0
80
80
  size: int = base_size
81
- remaining: int = int(1e9) * num_seconds
81
+ remaining: int = int(1e9) * seconds
82
82
  while int(1.5 * nano_sec) < remaining - 1: # Try to get close to seconds
83
83
  size *= 2 ** (0 if not nano_sec else max(1, int(math.log(remaining / nano_sec, 2))))
84
84
  # ^ Faster than just *=2
@@ -89,51 +89,48 @@ def speedtest_ssh(num_seconds: int, ping: bool, mode: str, conf: Config) -> None
89
89
  _print_results(ping_delay, up_t, down_t, size)
90
90
 
91
91
 
92
- def main(argv: list[str]) -> None:
92
+ def cli() -> None:
93
93
  """
94
- speedtest_ssh from arguments
94
+ speedtest_ssh main
95
95
  """
96
- base: str = os.path.basename(argv[0])
97
- parser = argparse.ArgumentParser(prog=base)
98
- parser.add_argument("--version", action="version", version=f"{base} {__version__}")
99
- parser.add_argument("host", help="The host to speedtest the conection to")
100
- parser.add_argument("--ping", action="store_true", help="Ping test the host as well")
101
- parser.add_argument("--verbose", action="store_true", help="Be verbose")
102
- parser.add_argument("--very-verbose", action="store_true", help="Be very verbose")
103
- parser.add_argument("-u", "--user", help="The user used for ssh")
104
- parser.add_argument(
105
- "--password-env", action="store_true", help=f"Read password from {_password_env_name} environment variable"
96
+ parser = argparse.ArgumentParser()
97
+ parser.add_argument("-V", "--version", action="version", version=f"{parser.prog} {__version__}")
98
+ remote = parser.add_argument_group("SSH Options")
99
+ remote.add_argument("host", help="The host to speedtest the conection to")
100
+ remote.add_argument("-u", "--user", help="The user used for ssh")
101
+ remote.add_argument("-p", "--port", type=int, help="The port used for ssh")
102
+ remote.add_argument(
103
+ "-E",
104
+ "--password-env",
105
+ action="store_true",
106
+ help=f"Read password from {_password_env_name} environment variable",
106
107
  )
107
- parser.add_argument("-p", "--port", type=int, help="The port used for ssh")
108
108
  parser.add_argument(
109
- "--num-seconds", type=int, default=20, help="An approximate number of seconds the speed tests should take"
109
+ "-v",
110
+ "--verbose",
111
+ action="count",
112
+ default=0,
113
+ help="Increase Log verbosity, pass more than once to increase verbosity",
110
114
  )
111
- parser.add_argument(
115
+ modes = parser.add_argument_group("SpeedTest Options")
116
+ modes.add_argument("-P", "--ping", action="store_true", help="Ping test the host as well")
117
+ modes.add_argument(
118
+ "-s", "--seconds", type=int, default=20, help="An approximate number of seconds the speed tests should take"
119
+ )
120
+ modes.add_argument(
112
121
  "-m", "--mode", choices=["rsync", "sftp"], default="sftp", help="The speedtest method. Defaults to rsync"
113
122
  )
114
- ns = vars(parser.parse_args(argv[1:]))
115
- basicConfig(level=WARNING, format="%(message)s")
116
- log = getLogger(_LOG)
117
- if ns.pop("verbose"):
118
- getLogger().setLevel(INFO)
119
- if ns.pop("very_verbose"):
120
- getLogger().setLevel(DEBUG)
121
- log.debug("Very verbose logging enabled")
123
+ ns = vars(parser.parse_args())
124
+ # Configure logging
125
+ lvl = ns.pop("verbose")
126
+ lvl = _LOG_VERBOSITY[max(i for i in _LOG_VERBOSITY if i <= lvl)]
127
+ basicConfig(level=lvl, format="%(levelname)-8s %(message)s")
128
+ getLogger("main").debug("Log level set to %d", lvl)
129
+ # Call speedtest
122
130
  ns["password"] = None
123
131
  if ns.pop("password_env"):
124
132
  ns["password"] = os.environ.get(_password_env_name, None)
125
133
  if ns["password"] is None:
126
134
  raise RuntimeError(f"{_password_env_name} is not set")
127
135
  conf = Config(**{i.name: ns.pop(i.name) for i in fields(Config)}) # type: ignore
128
- return speedtest_ssh(**ns, conf=conf) # type: ignore
129
-
130
-
131
- def cli() -> None:
132
- """
133
- speedtest_ssh CLI
134
- """
135
- main(sys.argv)
136
-
137
-
138
- if __name__ == "__main__":
139
- cli()
136
+ speedtest_ssh(**ns, conf=conf) # type: ignore
@@ -43,7 +43,7 @@ def run_cmd(cmd: Path, *args: str | Path, **kwargs) -> subprocess.CompletedProce
43
43
  :return: Completed process
44
44
  """
45
45
  _log_cmd(cmd, args)
46
- return subprocess.run((cmd, *args), **kwargs)
46
+ return subprocess.run((cmd, *args), **kwargs) # nosec B603
47
47
 
48
48
 
49
49
  def tee_cmd(cmd: Path, *args: str | Path, level: int, **kwargs) -> tuple[subprocess.Popen, str]:
@@ -54,11 +54,11 @@ def tee_cmd(cmd: Path, *args: str | Path, level: int, **kwargs) -> tuple[subproc
54
54
  :param kwargs: Fowarded to subprocess.Popen aside from test and stdout
55
55
  :return: Completed process, stdout (do not read stdout from CompletedProcess)
56
56
  """
57
- assert "text" not in kwargs
58
- assert "stdout" not in kwargs
57
+ assert "text" not in kwargs # nosec B101
58
+ assert "stdout" not in kwargs # nosec B101
59
59
  log = getLogger(_LOG)
60
60
  _log_cmd(cmd, args)
61
- p = subprocess.Popen((cmd, *args), text=True, stdout=subprocess.PIPE, **kwargs)
61
+ p = subprocess.Popen((cmd, *args), text=True, stdout=subprocess.PIPE, **kwargs) # nosec B603
62
62
  stdout = ""
63
63
  for line in p.stdout: # type: ignore
64
64
  log.log(level, line[:-1])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: speedtest_ssh
3
- Version: 2.8.0
3
+ Version: 2.9.0
4
4
  Summary: A tool meant to check inter-device speeds via ssh
5
5
  License: GPL
6
6
  Project-URL: Homepage, https://github.com/zwimer/speedtest_ssh
@@ -1 +0,0 @@
1
- __version__: str = "2.8.0"
File without changes
File without changes
File without changes