sdev 0.7.12__tar.gz → 1.0.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.
- sdev-1.0.0/PKG-INFO +185 -0
- sdev-1.0.0/README.md +161 -0
- sdev-1.0.0/pyproject.toml +38 -0
- sdev-1.0.0/sdev/__init__.py +1028 -0
- sdev-1.0.0/sdev/__main__.py +226 -0
- sdev-1.0.0/sdev.egg-info/PKG-INFO +185 -0
- sdev-1.0.0/sdev.egg-info/SOURCES.txt +32 -0
- sdev-1.0.0/sdev.egg-info/entry_points.txt +2 -0
- sdev-1.0.0/sdev.egg-info/requires.txt +1 -0
- sdev-1.0.0/tests/test_adversarial_ansi.py +56 -0
- sdev-1.0.0/tests/test_adversarial_api_edge.py +112 -0
- sdev-1.0.0/tests/test_adversarial_grep.py +161 -0
- sdev-1.0.0/tests/test_adversarial_grep_linebyline.py +128 -0
- sdev-1.0.0/tests/test_adversarial_interrupt.py +66 -0
- sdev-1.0.0/tests/test_adversarial_module_api.py +82 -0
- sdev-1.0.0/tests/test_adversarial_new_features.py +131 -0
- sdev-1.0.0/tests/test_adversarial_run_connect.py +56 -0
- sdev-1.0.0/tests/test_adversarial_serial_error.py +136 -0
- sdev-1.0.0/tests/test_adversarial_strip.py +116 -0
- sdev-1.0.0/tests/test_adversarial_timeout.py +169 -0
- sdev-1.0.0/tests/test_cli_integration.py +607 -0
- sdev-1.0.0/tests/test_doctor_silence.py +115 -0
- sdev-1.0.0/tests/test_doctor_wait_silence.py +79 -0
- sdev-1.0.0/tests/test_endflag_linemode.py +204 -0
- sdev-1.0.0/tests/test_error_handling.py +347 -0
- sdev-1.0.0/tests/test_probe.py +202 -0
- sdev-1.0.0/tests/test_resource_usage.py +32 -0
- sdev-1.0.0/tests/test_sdev.py +268 -0
- sdev-1.0.0/tests/test_serial_lock.py +113 -0
- sdev-1.0.0/tests/test_write.py +60 -0
- sdev-1.0.0/tests/test_xc01_real.py +130 -0
- sdev-0.7.12/LICENSE +0 -21
- sdev-0.7.12/MANIFEST.in +0 -6
- sdev-0.7.12/PKG-INFO +0 -181
- sdev-0.7.12/README.md +0 -146
- sdev-0.7.12/pyproject.toml +0 -46
- sdev-0.7.12/sdev/__init__.py +0 -12
- sdev-0.7.12/sdev/cli/__init__.py +0 -922
- sdev-0.7.12/sdev/cli/__main__.py +0 -14
- sdev-0.7.12/sdev/deprecated/demoboard.py +0 -135
- sdev-0.7.12/sdev/modules/__init__.py +0 -13
- sdev-0.7.12/sdev/modules/mcp_server.py +0 -124
- sdev-0.7.12/sdev/modules/serial_notebook.py +0 -254
- sdev-0.7.12/sdev/modules/serial_rw.py +0 -283
- sdev-0.7.12/sdev/modules/serial_rw_server.py +0 -544
- sdev-0.7.12/sdev.egg-info/PKG-INFO +0 -181
- sdev-0.7.12/sdev.egg-info/SOURCES.txt +0 -20
- sdev-0.7.12/sdev.egg-info/entry_points.txt +0 -2
- sdev-0.7.12/sdev.egg-info/requires.txt +0 -3
- sdev-0.7.12/setup.py +0 -40
- {sdev-0.7.12 → sdev-1.0.0}/sdev.egg-info/dependency_links.txt +0 -0
- {sdev-0.7.12 → sdev-1.0.0}/sdev.egg-info/top_level.txt +0 -0
- {sdev-0.7.12 → sdev-1.0.0}/setup.cfg +0 -0
sdev-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sdev
|
|
3
|
+
Version: 1.0.0
|
|
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.0/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.0"
|
|
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"
|