Skip to content

Commit 333c59e

Browse files
author
cav71
authored
restore old code for execute_command (#33)
* restore old code * update project info * new syncops module * rename execute as rexec in syncops
1 parent 7f0aa70 commit 333c59e

File tree

11 files changed

+467
-166
lines changed

11 files changed

+467
-166
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ help: ## Display the list of available targets
1414

1515

1616
.PHONY: check
17-
check: check-fmt lint test ## Check code formatting and run tests
17+
check: check-fmt lint ## Check code formatting
1818
@echo "🟢 pass"
1919

2020
.PHONY: check-fmt

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
55

66
[project]
77
name = "luxos"
8-
version = "0.1.0"
8+
version = "0.1.1"
99
description = "The all encompassing LuxOS python library."
1010
readme = "README.md"
1111
license = { text = "MIT" } # TODO I don't think this is a MIT??

src/luxos/asyncops.py

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import asyncio
4+
import contextlib
45
import functools
56
import json
67
import logging
@@ -126,9 +127,9 @@ def validate_message(
126127
port: int,
127128
res: dict[str, Any],
128129
extrakey: str | None = None,
129-
minfields: None | int = None,
130-
maxfields: None | int = None,
131-
) -> dict[str, Any]:
130+
minfields: None | int = 1,
131+
maxfields: None | int = 1,
132+
) -> Any:
132133
# all miner message comes with a STATUS
133134
for key in ["STATUS", "id", *([extrakey] if extrakey else [])]:
134135
if key in res:
@@ -142,17 +143,17 @@ def validate_message(
142143

143144
n = len(res[extrakey])
144145
msg = None
145-
if minfields and (n < minfields):
146+
if (minfields is not None) and (n < minfields):
146147
msg = f"found {n} fields for {extrakey} invalid: " f"{n} <= {minfields}"
147-
elif maxfields and (n > maxfields):
148+
elif (maxfields is not None) and (n > maxfields):
148149
msg = f"found {n} fields for {extrakey} invalid: " f"{n} >= {maxfields}"
149150
if msg is None:
150151
return res[extrakey]
151152
raise exceptions.MinerCommandMalformedMessageError(host, port, msg, res)
152153

153154

154155
@wrapped
155-
async def logon(host: str, port: int, timeout: float | None = 3) -> str:
156+
async def logon(host: str, port: int, timeout: float | None = None) -> str:
156157
timeout = TIMEOUT if timeout is None else timeout
157158
res = await roundtrip(host, port, {"command": "logon"}, timeout=timeout)
158159

@@ -166,7 +167,7 @@ async def logon(host: str, port: int, timeout: float | None = 3) -> str:
166167
)
167168
sessions = validate_message(host, port, res, "SESSION", 1, 1)
168169

169-
session = sessions[0] # type: ignore
170+
session = sessions[0]
170171

171172
if "SessionID" not in session:
172173
raise exceptions.MinerCommandSessionAlreadyActive(
@@ -177,56 +178,15 @@ async def logon(host: str, port: int, timeout: float | None = 3) -> str:
177178

178179
@wrapped
179180
async def logoff(
180-
host: str, port: int, sid: str, timeout: float | None = 3
181+
host: str, port: int, sid: str, timeout: float | None = None
181182
) -> dict[str, Any]:
182183
timeout = TIMEOUT if timeout is None else timeout
183184
return await roundtrip(
184185
host, port, {"command": "logoff", "parameter": sid}, timeout=timeout
185186
)
186187

187188

188-
@wrapped
189-
async def execute_command(
190-
host: str,
191-
port: int,
192-
timeout_sec: float | None,
193-
cmd: str,
194-
parameters: list[str] | None = None,
195-
verbose: bool = False,
196-
asjson: bool | None = True,
197-
add_address: bool = False,
198-
) -> tuple[tuple[str, int], dict[str, Any]] | dict[str, Any]:
199-
timeout = TIMEOUT if timeout_sec is None else timeout_sec
200-
parameters = parameters or []
201-
202-
sid = None
203-
if api.logon_required(cmd):
204-
sid = await logon(host, port)
205-
parameters = [sid, *parameters]
206-
log.debug("session id requested & obtained for %s:%i (%s)", host, port, sid)
207-
else:
208-
log.debug("no logon required for command '%s' on %s:%i", cmd, host, port)
209-
210-
try:
211-
packet = {"command": cmd}
212-
if parameters:
213-
packet["parameter"] = ",".join(parameters)
214-
log.debug(
215-
"executing command '%s' on '%s:%i' with parameters: %s",
216-
cmd,
217-
host,
218-
port,
219-
packet.get("parameter", ""),
220-
)
221-
ret = await roundtrip(host, port, packet, timeout=timeout, asjson=asjson)
222-
log.debug("received from %s:%s: %s", host, port, str(ret))
223-
return ((host, port), ret) if add_address else ret
224-
finally:
225-
if sid:
226-
await logoff(host, port, sid)
227-
228-
229-
def _rexec_parameters(
189+
def parameters_to_list(
230190
parameters: str | list[Any] | dict[str, Any] | None = None,
231191
) -> list[str]:
232192
if isinstance(parameters, dict):
@@ -256,9 +216,7 @@ async def rexec(
256216
retry: int | None = None,
257217
retry_delay: float | None = None,
258218
) -> dict[str, Any] | None:
259-
from . import api
260-
261-
parameters = _rexec_parameters(parameters)
219+
parameters = parameters_to_list(parameters)
262220

263221
timeout = TIMEOUT if timeout is None else timeout
264222
retry = RETRIES if retry is None else retry
@@ -328,3 +286,14 @@ async def rexec(
328286
await logoff(host, port, sid)
329287
if isinstance(failure, Exception):
330288
raise failure
289+
290+
291+
@contextlib.asynccontextmanager
292+
async def with_atm(host, port, enabled: bool, timeout: float | None = None):
293+
res = await rexec(host, port, "atm", timeout=timeout)
294+
if not res:
295+
raise exceptions.MinerConnectionError(host, port, "cannot check atm")
296+
current = validate_message(host, port, res, "ATM")[0]["Enabled"]
297+
await rexec(host, port, "atmset", {"enabled": enabled}, timeout=timeout)
298+
yield current
299+
await rexec(host, port, "atmset", {"enabled": current}, timeout=timeout)

src/luxos/cli/flags.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ def add_arguments_database(parser: LuxosParserBase):
204204

205205
group = parser.add_argument_group("database", "Database related options")
206206
group.add_argument("--db", dest="engine", help="sqlalchemy uri or filename")
207+
group.add_argument(
208+
"--db-create", action="store_true", help="create the db structures"
209+
)
207210

208211
def callback(args: argparse.Namespace):
209212
from sqlalchemy import create_engine

src/luxos/exceptions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,19 @@ class MinerCommandSessionAlreadyActive(MinerConnectionError):
3232

3333
class MinerCommandMalformedMessageError(MinerConnectionError):
3434
pass
35+
36+
37+
class LuxosLaunchError(MinerConnectionError):
38+
def __init__(self, tback: str, host: str, port: int, *args, **kwargs):
39+
self.tback = tback
40+
super().__init__(host, port, *args, **kwargs)
41+
42+
def __str__(self):
43+
from .text import indent
44+
45+
msg = indent(str(self.tback), "| ")
46+
return f"{self.address}: \n{msg}"
47+
48+
49+
class LuxosLaunchTimeoutError(LuxosLaunchError, asyncio.TimeoutError):
50+
pass

src/luxos/ips.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,27 @@ def iter_ip_ranges(
129129
cur += 1
130130

131131

132+
def ip_ranges(
133+
txt: str, rsep: str = "-", gsep: str = ":"
134+
) -> list[tuple[str, int | None]]:
135+
"""return a list of ips given a text expression.
136+
137+
Eg.
138+
>>> for ip in ip_ranges("127.0.0.1"):
139+
... print(ip)
140+
127.0.0.1
141+
142+
>>> for ip in ip_ranges("127.0.0.1-127.0.0.3"):
143+
... print(ip)
144+
127.0.0.1
145+
127.0.0.2
146+
127.0.0.3
147+
148+
NOTE: use the `:` (gsep) to separate ips groups, and `-` (rsep) to define a range.
149+
"""
150+
return list(iter_ip_ranges(txt, rsep=rsep, gsep=gsep))
151+
152+
132153
def load_ips_from_csv(path: Path | str, port: int = 4028) -> list[tuple[str, int]]:
133154
"""loads ip addresses from a csv file
134155

src/luxos/scripts/luxos.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,11 @@
1111
from pathlib import Path
1212

1313
from ..cli import v1 as cli
14+
from ..syncops import execute_command
1415

1516
log = logging.getLogger(__name__)
1617

1718

18-
def execute_command(host: str, port: int, timeout_sec: int, cmd: str, parameters: list, verbose: bool):
19-
from ..asyncops import rexec
20-
def adapter(awaitable):
21-
with contextlib.suppress(asyncio.TimeoutError):
22-
loop = asyncio.get_event_loop()
23-
return loop.run_until_complete(awaitable)
24-
return adapter(rexec(host, port, timeout=timeout_sec, cmd=cmd, parameters=parameters))
25-
26-
2719
def add_arguments(parser: cli.LuxosParserBase) -> None:
2820

2921
def add_miners_arguments(group):

0 commit comments

Comments
 (0)