sdev 0.7.12__tar.gz → 1.0.1__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 (53) hide show
  1. sdev-1.0.1/PKG-INFO +185 -0
  2. sdev-1.0.1/README.md +161 -0
  3. sdev-1.0.1/pyproject.toml +38 -0
  4. sdev-1.0.1/sdev/__init__.py +1164 -0
  5. sdev-1.0.1/sdev/__main__.py +281 -0
  6. sdev-1.0.1/sdev.egg-info/PKG-INFO +185 -0
  7. sdev-1.0.1/sdev.egg-info/SOURCES.txt +32 -0
  8. sdev-1.0.1/sdev.egg-info/entry_points.txt +2 -0
  9. sdev-1.0.1/sdev.egg-info/requires.txt +1 -0
  10. sdev-1.0.1/tests/test_adversarial_ansi.py +56 -0
  11. sdev-1.0.1/tests/test_adversarial_api_edge.py +112 -0
  12. sdev-1.0.1/tests/test_adversarial_grep.py +161 -0
  13. sdev-1.0.1/tests/test_adversarial_grep_linebyline.py +128 -0
  14. sdev-1.0.1/tests/test_adversarial_interrupt.py +66 -0
  15. sdev-1.0.1/tests/test_adversarial_module_api.py +82 -0
  16. sdev-1.0.1/tests/test_adversarial_new_features.py +131 -0
  17. sdev-1.0.1/tests/test_adversarial_run_connect.py +56 -0
  18. sdev-1.0.1/tests/test_adversarial_serial_error.py +136 -0
  19. sdev-1.0.1/tests/test_adversarial_strip.py +116 -0
  20. sdev-1.0.1/tests/test_adversarial_timeout.py +169 -0
  21. sdev-1.0.1/tests/test_cli_integration.py +607 -0
  22. sdev-1.0.1/tests/test_doctor_silence.py +115 -0
  23. sdev-1.0.1/tests/test_doctor_wait_silence.py +85 -0
  24. sdev-1.0.1/tests/test_endflag_linemode.py +204 -0
  25. sdev-1.0.1/tests/test_error_handling.py +347 -0
  26. sdev-1.0.1/tests/test_probe.py +202 -0
  27. sdev-1.0.1/tests/test_resource_usage.py +32 -0
  28. sdev-1.0.1/tests/test_sdev.py +268 -0
  29. sdev-1.0.1/tests/test_serial_lock.py +113 -0
  30. sdev-1.0.1/tests/test_write.py +60 -0
  31. sdev-1.0.1/tests/test_xc01_real.py +130 -0
  32. sdev-0.7.12/LICENSE +0 -21
  33. sdev-0.7.12/MANIFEST.in +0 -6
  34. sdev-0.7.12/PKG-INFO +0 -181
  35. sdev-0.7.12/README.md +0 -146
  36. sdev-0.7.12/pyproject.toml +0 -46
  37. sdev-0.7.12/sdev/__init__.py +0 -12
  38. sdev-0.7.12/sdev/cli/__init__.py +0 -922
  39. sdev-0.7.12/sdev/cli/__main__.py +0 -14
  40. sdev-0.7.12/sdev/deprecated/demoboard.py +0 -135
  41. sdev-0.7.12/sdev/modules/__init__.py +0 -13
  42. sdev-0.7.12/sdev/modules/mcp_server.py +0 -124
  43. sdev-0.7.12/sdev/modules/serial_notebook.py +0 -254
  44. sdev-0.7.12/sdev/modules/serial_rw.py +0 -283
  45. sdev-0.7.12/sdev/modules/serial_rw_server.py +0 -544
  46. sdev-0.7.12/sdev.egg-info/PKG-INFO +0 -181
  47. sdev-0.7.12/sdev.egg-info/SOURCES.txt +0 -20
  48. sdev-0.7.12/sdev.egg-info/entry_points.txt +0 -2
  49. sdev-0.7.12/sdev.egg-info/requires.txt +0 -3
  50. sdev-0.7.12/setup.py +0 -40
  51. {sdev-0.7.12 → sdev-1.0.1}/sdev.egg-info/dependency_links.txt +0 -0
  52. {sdev-0.7.12 → sdev-1.0.1}/sdev.egg-info/top_level.txt +0 -0
  53. {sdev-0.7.12 → sdev-1.0.1}/setup.cfg +0 -0
sdev-1.0.1/PKG-INFO ADDED
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: sdev
3
+ Version: 1.0.1
4
+ Summary: Small toolkit for automating a serial-attached Linux shell
5
+ Author-email: klrc <1440698245@qq.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/klrc/sdev-autoresearch
8
+ Project-URL: Repository, https://github.com/klrc/sdev-autoresearch
9
+ Project-URL: Bug Tracker, https://github.com/klrc/sdev-autoresearch/issues
10
+ Keywords: serial,shell,embedded,cli,linux,automation
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: System :: Hardware
20
+ Classifier: Topic :: Terminals :: Serial
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: pyserial>=3.5
24
+
25
+ # sdev
26
+
27
+ Small toolkit for automating a serial-attached Linux shell.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install -e .
33
+ ```
34
+
35
+ ## CLI
36
+
37
+ ```bash
38
+ # Run a command
39
+ sdev -p "ls /proc/meminfo" -d /dev/ttyUSB0 -b 115200
40
+
41
+ # Stream output incrementally
42
+ sdev -p "tail -f /var/log/syslog" --stream
43
+
44
+ # Stream with server-side regex filter
45
+ sdev -p "tail -f /var/log/syslog" --stream --grep "ERROR"
46
+
47
+ # Stream with complete-line output only
48
+ sdev -p "dmesg" --stream --line-mode
49
+
50
+ # Parse output with regex
51
+ sdev -p "cat /proc/meminfo" --parse "Mem.*"
52
+
53
+ # Wait for a specific output marker instead of shell prompt
54
+ sdev -p "./mnn_perf -m model.mnn" --end-flag "Frame rate:"
55
+
56
+ # Clear stray processes before running a command
57
+ sdev -p "uptime" --doctor
58
+
59
+ # Save defaults so you can omit -d and -b
60
+ sdev set-default /dev/ttyUSB0 115200
61
+ sdev -p "ls /proc/meminfo"
62
+
63
+ # Send Ctrl+C to interrupt a running command (without -p)
64
+ sdev --interrupt -d /dev/ttyUSB0 -b 115200
65
+
66
+ # Detect serial boards on this system
67
+ sdev --probe
68
+ sdev --probe --probe-baud 9600 --probe-baud 38400
69
+
70
+ # Custom prompt patterns for non-standard shells
71
+ sdev -p "ls" --prompt "[root@board]# " --prompt "admin@box> "
72
+ ```
73
+
74
+ ### CLI options
75
+
76
+ | Flag | Description |
77
+ |------|-------------|
78
+ | `-p, --command` | Command to execute |
79
+ | `-d, --device` | Serial device path |
80
+ | `-b, --baud` | Baud rate |
81
+ | `-t, --timeout` | Timeout in seconds (default: 300) |
82
+ | `--stream` | Incremental output instead of buffered |
83
+ | `--grep REGEX` | Filter `--stream` lines by regex |
84
+ | `--line-mode` | Only yield complete lines in `--stream` |
85
+ | `--parse REGEX` | Show only matching lines |
86
+ | `--end-flag STR` | Stop when this string appears in output |
87
+ | `--doctor` | Clear foreground processes before command |
88
+ | `--prompt PATTERN` | Custom shell prompt pattern (repeatable) |
89
+ | `--interrupt` | Send Ctrl+C and wait for prompt |
90
+ | `--probe` | Detect serial boards and print info |
91
+ | `--probe-baud BAUD` | Baud rates to try during `--probe` (repeatable) |
92
+ | `set-default` | Persist device/baud as defaults |
93
+
94
+ ## Design Goals
95
+
96
+ - **Stability**: strict 5-minute timeout on all blocking operations
97
+ - **Simplicity**: small surface area, obvious API
98
+ - **Predictability**: prompt detection to determine command completion
99
+ - **Streaming**: incremental output for long-running commands
100
+ - **Parsing**: structured output with optional regex filtering
101
+
102
+ ## Python API
103
+
104
+ ```python
105
+ import sdev
106
+
107
+ # Session-based (recommended)
108
+ with sdev.SerialSession("/dev/ttyUSB0", 115200) as session:
109
+ result = session.cli("ls /proc/meminfo")
110
+ print(result.output)
111
+
112
+ # Custom prompt detection for non-standard shells
113
+ session = sdev.SerialSession("/dev/ttyUSB0", 115200, prompts=[b"[root@board]# "])
114
+ session.connect()
115
+
116
+ # Streaming for long-running commands
117
+ for chunk in session.stream("tail -f /var/log/syslog"):
118
+ print(chunk, end="")
119
+
120
+ # Streaming with line mode — only yields complete lines
121
+ for line in session.stream("tail -f /var/log/syslog", line_mode=True):
122
+ process(line)
123
+
124
+ # Streaming with server-side filter
125
+ for chunk in session.stream("tail -f /var/log/syslog", filter_fn=lambda t: t.upper()):
126
+ print(chunk, end="")
127
+
128
+ # Parsing with regex filtering
129
+ parsed = session.parse("cat /proc/meminfo", pattern=r"Mem.*")
130
+ print(parsed.matched)
131
+
132
+ # Wait for a specific output marker instead of shell prompt
133
+ # Useful for benchmarks that print results then keep running
134
+ result = session.cli("./mnn_perf -m model.mnn", end_flag="Frame rate:")
135
+
136
+ # Interrupt a running command (sends Ctrl+C and waits for prompt)
137
+ session.interrupt(timeout=5)
138
+
139
+ # Clear stray foreground processes and get a clean prompt
140
+ session.doctor()
141
+
142
+ # Wait until no data arrives for N seconds (boot completion)
143
+ session.wait_for_silence(timeout=1.5)
144
+
145
+ # Recover from device reboot without creating a new session
146
+ session.reconnect()
147
+
148
+ # Monitor CPU/memory during long operations
149
+ usage = sdev.resource_usage()
150
+ print(f"RSS: {usage['memory_mb']} MB, CPU: {usage['cpu_percent']}%")
151
+
152
+ # Detect serial boards and get OS/arch info
153
+ for device in sdev.probe():
154
+ print(f"{device['device']} @ {device['baud']}: {device['info']['os_name']}")
155
+
156
+ # Send raw bytes over serial (control sequences, custom protocols)
157
+ sdev.connect("/dev/ttyUSB0", 115200)
158
+ n = sdev.write(b"reboot\n")
159
+ print(f"Wrote {n} bytes")
160
+
161
+ # Clear stray foreground processes on the default connection
162
+ sdev.doctor()
163
+
164
+ # Wait for boot completion (no serial data for N seconds)
165
+ sdev.wait_for_silence(timeout=2.0)
166
+ ```
167
+
168
+ ### Thread safety
169
+
170
+ Each `SerialSession` has an internal `threading.Lock`. Only one `cli()`
171
+ or `stream()` call can run at a time per session. Concurrent callers
172
+ will raise `RuntimeError` after 10s if the lock is held. `interrupt()`
173
+ does not acquire the lock — it remains the emergency escape hatch.
174
+
175
+ ### Module-level convenience API
176
+
177
+ ```python
178
+ sdev.connect("/dev/ttyUSB0", 115200)
179
+ result = sdev.cli("ls /proc/meminfo")
180
+ sdev.disconnect()
181
+ ```
182
+
183
+ ## License
184
+
185
+ MIT
sdev-1.0.1/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # sdev
2
+
3
+ Small toolkit for automating a serial-attached Linux shell.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install -e .
9
+ ```
10
+
11
+ ## CLI
12
+
13
+ ```bash
14
+ # Run a command
15
+ sdev -p "ls /proc/meminfo" -d /dev/ttyUSB0 -b 115200
16
+
17
+ # Stream output incrementally
18
+ sdev -p "tail -f /var/log/syslog" --stream
19
+
20
+ # Stream with server-side regex filter
21
+ sdev -p "tail -f /var/log/syslog" --stream --grep "ERROR"
22
+
23
+ # Stream with complete-line output only
24
+ sdev -p "dmesg" --stream --line-mode
25
+
26
+ # Parse output with regex
27
+ sdev -p "cat /proc/meminfo" --parse "Mem.*"
28
+
29
+ # Wait for a specific output marker instead of shell prompt
30
+ sdev -p "./mnn_perf -m model.mnn" --end-flag "Frame rate:"
31
+
32
+ # Clear stray processes before running a command
33
+ sdev -p "uptime" --doctor
34
+
35
+ # Save defaults so you can omit -d and -b
36
+ sdev set-default /dev/ttyUSB0 115200
37
+ sdev -p "ls /proc/meminfo"
38
+
39
+ # Send Ctrl+C to interrupt a running command (without -p)
40
+ sdev --interrupt -d /dev/ttyUSB0 -b 115200
41
+
42
+ # Detect serial boards on this system
43
+ sdev --probe
44
+ sdev --probe --probe-baud 9600 --probe-baud 38400
45
+
46
+ # Custom prompt patterns for non-standard shells
47
+ sdev -p "ls" --prompt "[root@board]# " --prompt "admin@box> "
48
+ ```
49
+
50
+ ### CLI options
51
+
52
+ | Flag | Description |
53
+ |------|-------------|
54
+ | `-p, --command` | Command to execute |
55
+ | `-d, --device` | Serial device path |
56
+ | `-b, --baud` | Baud rate |
57
+ | `-t, --timeout` | Timeout in seconds (default: 300) |
58
+ | `--stream` | Incremental output instead of buffered |
59
+ | `--grep REGEX` | Filter `--stream` lines by regex |
60
+ | `--line-mode` | Only yield complete lines in `--stream` |
61
+ | `--parse REGEX` | Show only matching lines |
62
+ | `--end-flag STR` | Stop when this string appears in output |
63
+ | `--doctor` | Clear foreground processes before command |
64
+ | `--prompt PATTERN` | Custom shell prompt pattern (repeatable) |
65
+ | `--interrupt` | Send Ctrl+C and wait for prompt |
66
+ | `--probe` | Detect serial boards and print info |
67
+ | `--probe-baud BAUD` | Baud rates to try during `--probe` (repeatable) |
68
+ | `set-default` | Persist device/baud as defaults |
69
+
70
+ ## Design Goals
71
+
72
+ - **Stability**: strict 5-minute timeout on all blocking operations
73
+ - **Simplicity**: small surface area, obvious API
74
+ - **Predictability**: prompt detection to determine command completion
75
+ - **Streaming**: incremental output for long-running commands
76
+ - **Parsing**: structured output with optional regex filtering
77
+
78
+ ## Python API
79
+
80
+ ```python
81
+ import sdev
82
+
83
+ # Session-based (recommended)
84
+ with sdev.SerialSession("/dev/ttyUSB0", 115200) as session:
85
+ result = session.cli("ls /proc/meminfo")
86
+ print(result.output)
87
+
88
+ # Custom prompt detection for non-standard shells
89
+ session = sdev.SerialSession("/dev/ttyUSB0", 115200, prompts=[b"[root@board]# "])
90
+ session.connect()
91
+
92
+ # Streaming for long-running commands
93
+ for chunk in session.stream("tail -f /var/log/syslog"):
94
+ print(chunk, end="")
95
+
96
+ # Streaming with line mode — only yields complete lines
97
+ for line in session.stream("tail -f /var/log/syslog", line_mode=True):
98
+ process(line)
99
+
100
+ # Streaming with server-side filter
101
+ for chunk in session.stream("tail -f /var/log/syslog", filter_fn=lambda t: t.upper()):
102
+ print(chunk, end="")
103
+
104
+ # Parsing with regex filtering
105
+ parsed = session.parse("cat /proc/meminfo", pattern=r"Mem.*")
106
+ print(parsed.matched)
107
+
108
+ # Wait for a specific output marker instead of shell prompt
109
+ # Useful for benchmarks that print results then keep running
110
+ result = session.cli("./mnn_perf -m model.mnn", end_flag="Frame rate:")
111
+
112
+ # Interrupt a running command (sends Ctrl+C and waits for prompt)
113
+ session.interrupt(timeout=5)
114
+
115
+ # Clear stray foreground processes and get a clean prompt
116
+ session.doctor()
117
+
118
+ # Wait until no data arrives for N seconds (boot completion)
119
+ session.wait_for_silence(timeout=1.5)
120
+
121
+ # Recover from device reboot without creating a new session
122
+ session.reconnect()
123
+
124
+ # Monitor CPU/memory during long operations
125
+ usage = sdev.resource_usage()
126
+ print(f"RSS: {usage['memory_mb']} MB, CPU: {usage['cpu_percent']}%")
127
+
128
+ # Detect serial boards and get OS/arch info
129
+ for device in sdev.probe():
130
+ print(f"{device['device']} @ {device['baud']}: {device['info']['os_name']}")
131
+
132
+ # Send raw bytes over serial (control sequences, custom protocols)
133
+ sdev.connect("/dev/ttyUSB0", 115200)
134
+ n = sdev.write(b"reboot\n")
135
+ print(f"Wrote {n} bytes")
136
+
137
+ # Clear stray foreground processes on the default connection
138
+ sdev.doctor()
139
+
140
+ # Wait for boot completion (no serial data for N seconds)
141
+ sdev.wait_for_silence(timeout=2.0)
142
+ ```
143
+
144
+ ### Thread safety
145
+
146
+ Each `SerialSession` has an internal `threading.Lock`. Only one `cli()`
147
+ or `stream()` call can run at a time per session. Concurrent callers
148
+ will raise `RuntimeError` after 10s if the lock is held. `interrupt()`
149
+ does not acquire the lock — it remains the emergency escape hatch.
150
+
151
+ ### Module-level convenience API
152
+
153
+ ```python
154
+ sdev.connect("/dev/ttyUSB0", 115200)
155
+ result = sdev.cli("ls /proc/meminfo")
156
+ sdev.disconnect()
157
+ ```
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sdev"
7
+ version = "1.0.1"
8
+ description = "Small toolkit for automating a serial-attached Linux shell"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "klrc", email = "1440698245@qq.com" },
14
+ ]
15
+ keywords = ["serial", "shell", "embedded", "cli", "linux", "automation"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: System :: Hardware",
26
+ "Topic :: Terminals :: Serial",
27
+ ]
28
+ dependencies = [
29
+ "pyserial>=3.5",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/klrc/sdev-autoresearch"
34
+ Repository = "https://github.com/klrc/sdev-autoresearch"
35
+ "Bug Tracker" = "https://github.com/klrc/sdev-autoresearch/issues"
36
+
37
+ [project.scripts]
38
+ sdev = "sdev.__main__:main"