mpytool 2.0.0__tar.gz → 2.2.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 (35) hide show
  1. mpytool-2.2.0/PKG-INFO +462 -0
  2. mpytool-2.2.0/README.md +448 -0
  3. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/conn.py +29 -0
  4. mpytool-2.2.0/mpytool/conn_serial.py +121 -0
  5. mpytool-2.2.0/mpytool/mpy.py +1322 -0
  6. mpytool-2.2.0/mpytool/mpy_comm.py +281 -0
  7. mpytool-2.2.0/mpytool/mpytool.py +1561 -0
  8. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/terminal.py +1 -1
  9. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/utils.py +6 -6
  10. mpytool-2.2.0/mpytool.egg-info/PKG-INFO +462 -0
  11. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool.egg-info/SOURCES.txt +1 -0
  12. {mpytool-2.0.0 → mpytool-2.2.0}/pyproject.toml +4 -1
  13. mpytool-2.2.0/tests/test_integration.py +1469 -0
  14. mpytool-2.2.0/tests/test_mpy.py +529 -0
  15. mpytool-2.2.0/tests/test_mpytool.py +1053 -0
  16. {mpytool-2.0.0 → mpytool-2.2.0}/tests/test_utils.py +33 -1
  17. mpytool-2.0.0/PKG-INFO +0 -233
  18. mpytool-2.0.0/README.md +0 -219
  19. mpytool-2.0.0/mpytool/conn_serial.py +0 -34
  20. mpytool-2.0.0/mpytool/mpy.py +0 -337
  21. mpytool-2.0.0/mpytool/mpy_comm.py +0 -152
  22. mpytool-2.0.0/mpytool/mpytool.py +0 -913
  23. mpytool-2.0.0/mpytool.egg-info/PKG-INFO +0 -233
  24. mpytool-2.0.0/tests/test_integration.py +0 -551
  25. mpytool-2.0.0/tests/test_mpy.py +0 -27
  26. {mpytool-2.0.0 → mpytool-2.2.0}/LICENSE +0 -0
  27. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/__init__.py +0 -0
  28. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/conn_socket.py +0 -0
  29. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool/logger.py +0 -0
  30. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool.egg-info/dependency_links.txt +0 -0
  31. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool.egg-info/entry_points.txt +0 -0
  32. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool.egg-info/requires.txt +0 -0
  33. {mpytool-2.0.0 → mpytool-2.2.0}/mpytool.egg-info/top_level.txt +0 -0
  34. {mpytool-2.0.0 → mpytool-2.2.0}/setup.cfg +0 -0
  35. {mpytool-2.0.0 → mpytool-2.2.0}/tests/test_errors.py +0 -0
mpytool-2.2.0/PKG-INFO ADDED
@@ -0,0 +1,462 @@
1
+ Metadata-Version: 2.4
2
+ Name: mpytool
3
+ Version: 2.2.0
4
+ Summary: MPY tool - manage files on devices running MicroPython
5
+ Author-email: Pavel Revak <pavel.revak@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/pavelrevak/mpytool
8
+ Keywords: MPY,micropython
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pyserial>=3.0
13
+ Dynamic: license-file
14
+
15
+ # mpytool
16
+
17
+ MPY tool - manage files on devices running MicroPython
18
+
19
+ It is an alternative to the official [mpremote](https://docs.micropython.org/en/latest/reference/mpremote.html).
20
+
21
+ ## Features
22
+
23
+ - **Fast file transfers** - optimized chunked transfer with automatic compression
24
+ - **Skip unchanged files** - compares size + SHA256 hash, re-upload in <1s
25
+ - **Auto-detect serial port** - no need to specify `-p` when only one device connected
26
+ - **Robust REPL handling** - works reliably with USB-UART bridges (CP2102, CH340)
27
+ - **Multiple reset options** - soft, MCU, hardware (RTS), bootloader entry
28
+ - **General-purpose serial terminal** - `repl` and `monitor` work with any serial device
29
+ - **Python API** - suitable for IDE integration and automation
30
+ - **Raw-paste mode** - flow-controlled code execution with reduced RAM usage (API)
31
+ - **Shell completion** - ZSH and Bash with remote path completion
32
+ - **Network support** - connect over TCP
33
+
34
+ ## Installation
35
+
36
+ ```
37
+ pip3 install mpytool
38
+ ```
39
+
40
+ ### Installation from git (latest development version)
41
+
42
+ ```bash
43
+ pip3 install git+https://github.com/pavelrevak/mpytool.git
44
+ ```
45
+
46
+ ### Installation in virtualenv
47
+
48
+ Create a dedicated virtualenv for CLI tools (keeps your system Python clean):
49
+
50
+ ```bash
51
+ # Create virtualenv (once)
52
+ python3 -m venv ~/.venv/tools
53
+
54
+ # Install mpytool
55
+ ~/.venv/tools/bin/pip install mpytool
56
+
57
+ # Run directly
58
+ ~/.venv/tools/bin/mpytool --help
59
+ ```
60
+
61
+ To use `mpytool` command without full path, add the venv bin to end of your PATH:
62
+
63
+ **ZSH** (`~/.zshrc`):
64
+ ```bash
65
+ export PATH="$PATH:$HOME/.venv/tools/bin"
66
+ ```
67
+
68
+ **Bash** (`~/.bashrc`):
69
+ ```bash
70
+ export PATH="$PATH:$HOME/.venv/tools/bin"
71
+ ```
72
+
73
+ Then restart your shell (`exec zsh` or `exec bash`) and use `mpytool` directly.
74
+
75
+ Adding venv bin at the end of PATH keeps your system `python` and `pip` as default, while making `mpytool` available when not found elsewhere.
76
+
77
+ ## Examples:
78
+
79
+ help:
80
+ ```
81
+ $ mpytool --help
82
+ ```
83
+
84
+ list files:
85
+ ```
86
+ $ mpytool -p /dev/ttyACM0 ls # list CWD (default)
87
+ $ mpytool -p /dev/ttyACM0 ls :/lib # list /lib
88
+ ```
89
+
90
+ tree:
91
+ ```
92
+ $ mpytool -p /dev/ttyACM0 tree # tree of CWD (default)
93
+ ```
94
+
95
+ copy files (: prefix = device path):
96
+ ```
97
+ $ mpytool cp main.py :/ # upload file to device root
98
+ $ mpytool cp main.py lib.py :/lib/ # upload multiple files to directory
99
+ $ mpytool cp myapp :/ # upload directory (creates :/myapp/)
100
+ $ mpytool cp myapp :/lib/ # upload directory into :/lib/ (creates :/lib/myapp/)
101
+ $ mpytool cp myapp/ :/lib/ # upload directory contents into :/lib/
102
+ $ mpytool cp :/main.py ./ # download file to current directory
103
+ $ mpytool cp :/ ./backup/ # download entire device to backup/
104
+ $ mpytool cp :/old.py :/new.py # copy file on device
105
+ $ mpytool cp -f main.py :/ # force upload even if unchanged
106
+ ```
107
+
108
+ Path semantics: `:` = device CWD, `:/` = device root. Trailing `/` on source = copy contents only.
109
+ Unchanged files are automatically skipped (compares size and SHA256 hash).
110
+ Use `-f` or `--force` to upload all files regardless.
111
+
112
+ transfer options:
113
+ ```
114
+ $ mpytool cp -z main.py :/ # force compression (auto-detected by default)
115
+ $ mpytool cp --no-compress data.bin :/ # disable compression
116
+ $ mpytool -c 8K cp main.py :/ # set chunk size (512, 1K, 2K, 4K, 8K, 16K, 32K)
117
+ ```
118
+
119
+ Compression is auto-detected based on device RAM and deflate module availability.
120
+ Chunk size is auto-detected based on free RAM (larger chunks = faster transfer).
121
+
122
+ move/rename on device:
123
+ ```
124
+ $ mpytool mv :/old.py :/new.py # rename file
125
+ $ mpytool mv :/file.py :/lib/ # move file to directory
126
+ $ mpytool mv :/a.py :/b.py :/lib/ # move multiple files to directory
127
+ ```
128
+
129
+ view file contents:
130
+ ```
131
+ $ mpytool cat :boot.py # print file from CWD
132
+ $ mpytool cat :/lib/module.py # print file with absolute path
133
+ ```
134
+
135
+ make directory, delete files (: prefix = device path):
136
+ ```
137
+ $ mpytool mkdir :lib :data # create directories in CWD
138
+ $ mpytool mkdir :/lib/subdir # create with absolute path
139
+ $ mpytool rm :old.py # delete file in CWD
140
+ $ mpytool rm :mydir # delete directory and contents
141
+ $ mpytool rm :mydir/ # delete contents only, keep directory
142
+ $ mpytool rm : # delete everything in CWD
143
+ $ mpytool rm :/ # delete everything on device (root)
144
+ ```
145
+
146
+ current working directory:
147
+ ```
148
+ $ mpytool pwd # print current directory
149
+ /
150
+ $ mpytool cd :/lib # change to /lib
151
+ $ mpytool cd :subdir # change to relative path (from CWD)
152
+ $ mpytool cd :.. # change to parent directory
153
+ $ mpytool cd :/lib -- ls # change directory and list files
154
+ ```
155
+
156
+ reset and REPL:
157
+ ```
158
+ $ mpytool reset # soft reset (Ctrl-D, runs boot.py/main.py)
159
+ $ mpytool reset --raw # soft reset in raw REPL (clears RAM only)
160
+ $ mpytool reset --machine # MCU reset (machine.reset, auto-reconnect)
161
+ $ mpytool reset --machine -t 30 # MCU reset with 30s reconnect timeout
162
+ $ mpytool reset --rts # hardware reset via RTS signal (serial only)
163
+ $ mpytool reset --boot # enter bootloader (machine.bootloader)
164
+ $ mpytool reset --dtr-boot # enter bootloader via DTR/RTS (ESP32 only)
165
+ $ mpytool reset -- monitor # reset and monitor output
166
+ $ mpytool repl # enter REPL mode
167
+ $ mpytool sleep 2 # sleep for 2 seconds (useful between commands)
168
+ ```
169
+
170
+ serial terminal and monitor (general purpose):
171
+ ```
172
+ $ mpytool repl # auto-detect port, 115200 baud
173
+ $ mpytool -p /dev/ttyUSB0 repl # specify port
174
+ $ mpytool -b 9600 repl # specify baudrate
175
+ $ mpytool -p /dev/ttyUSB0 -b 9600 monitor # monitor at 9600 baud
176
+ ```
177
+
178
+ Both `repl` and `monitor` can be used as general-purpose serial tools - not just for MicroPython devices. Use them to interact with any serial device (Arduino, ESP with custom firmware, GPS modules, etc.). When only one serial port is detected, it is used automatically. Default baudrate is 115200.
179
+
180
+ execute Python code on device:
181
+ ```
182
+ $ mpytool exec "print('Hello!')"
183
+ $ mpytool exec "import sys; print(sys.version)"
184
+ ```
185
+
186
+ show device information:
187
+ ```
188
+ $ mpytool info
189
+ Platform: rp2
190
+ Version: 3.4.0; MicroPython v1.27.0 on 2025-12-09
191
+ Impl: micropython
192
+ Machine: Raspberry Pi Pico with RP2040
193
+ Serial: e660123456789abc
194
+ Memory: 36.4 KB / 240 KB (15.15%)
195
+ Flash: 120 KB / 1.38 MB (8.52%)
196
+ ```
197
+
198
+ On devices with WiFi or Ethernet, MAC addresses are also shown:
199
+ ```
200
+ MAC WiFi: aa:bb:cc:dd:ee:01
201
+ MAC WiFi AP: aa:bb:cc:dd:ee:02
202
+ ```
203
+
204
+ flash operations (RP2 and ESP32):
205
+ ```
206
+ # RP2 - user flash (entire filesystem area)
207
+ $ mpytool flash # show flash info and filesystem type
208
+ $ mpytool flash read backup.bin # backup entire user flash
209
+ $ mpytool flash write backup.bin # restore from backup
210
+ $ mpytool flash erase # quick erase (reset filesystem)
211
+ $ mpytool flash erase --full # full erase
212
+
213
+ # ESP32 - partitions (by label)
214
+ $ mpytool flash # list all partitions with filesystem info
215
+ Label Type Subtype Address Size Block Actual FS Flags
216
+ ------------------------------------------------------------------------------------------
217
+ factory app factory 0x10000 1.94M running
218
+ nvs data nvs 0x9000 24.0K
219
+ vfs data littlefs 0x200000 2.00M 4 KB littlefs2
220
+
221
+ Boot partition: factory
222
+ Next OTA: (none)
223
+
224
+ $ mpytool flash read vfs backup.bin # backup partition to file
225
+ $ mpytool flash write nvs nvs_backup.bin # restore partition from file
226
+ $ mpytool flash erase vfs # quick erase partition
227
+ $ mpytool flash erase vfs --full # full erase partition
228
+ ```
229
+
230
+ OTA firmware update (ESP32):
231
+ ```
232
+ $ mpytool ota firmware.app-bin # flash to next OTA partition
233
+ $ mpytool ota firmware.app-bin -- reset --machine # flash and reboot
234
+ $ mpytool ota firmware.app-bin -- reset --machine -t 30 # flash and reboot with 30s timeout
235
+ ```
236
+
237
+ multiple commands separated by `--`:
238
+ ```
239
+ $ mpytool cp main.py boot.py : -- reset -- monitor
240
+ $ mpytool rm :old.py -- cp new.py : -- reset
241
+ ```
242
+
243
+ auto-detect serial port (if only one device is connected):
244
+ ```
245
+ $ mpytool ls lib/
246
+ uhttp/
247
+ 23.2 KB wlan.py
248
+ 4.95 KB wlan_http.py
249
+ ```
250
+
251
+ tree view:
252
+ ```
253
+ $ mpytool tree
254
+ 142 KB ./
255
+ 41.3 KB ├─ html/
256
+ 587 B │ ├─ index.html
257
+ 40.8 KB │ └─ wlan.html
258
+ 97.7 KB ├─ lib/
259
+ 69.6 KB │ ├─ uhttp/
260
+ 93 B │ │ ├─ __init__.py
261
+ 26.3 KB │ │ ├─ client.py
262
+ 43.2 KB │ │ └─ server.py
263
+ 23.2 KB │ ├─ wlan.py
264
+ 4.95 KB │ └─ wlan_http.py
265
+ 23 B ├─ boot.py
266
+ 3.03 KB └─ main.py
267
+ ```
268
+
269
+ connect over network (TCP, default port 23):
270
+ ```
271
+ $ mpytool -a 192.168.1.100 ls
272
+ $ mpytool -a 192.168.1.100:8266 tree
273
+ ```
274
+
275
+ set baudrate (default 115200):
276
+ ```
277
+ $ mpytool -p /dev/ttyACM0 -b 9600 ls
278
+ ```
279
+
280
+ show version:
281
+ ```
282
+ $ mpytool -V
283
+ ```
284
+
285
+ ## Python API
286
+
287
+ ```python
288
+ >>> import mpytool
289
+ >>> conn = mpytool.ConnSerial(port='/dev/ttyACM0', baudrate=115200)
290
+ >>> mpy = mpytool.Mpy(conn)
291
+ >>> mpy.ls()
292
+ [('lib', None), ('boot.py', 215), ('main.py', 3102)]
293
+ >>> mpy.get('boot.py')
294
+ b'import machine\nimport time\n...'
295
+ >>> mpy.put(b'print("Hello")', 'test.py')
296
+ >>> mpy.delete('test.py')
297
+ ```
298
+
299
+ Raw-paste mode for efficient code execution (MicroPython 1.17+):
300
+ ```python
301
+ >>> mpy.comm.exec_raw_paste("print('Hello')") # flow-controlled, less RAM
302
+ b'Hello\r\n'
303
+ ```
304
+
305
+ See [README_API.md](README_API.md) for full API documentation.
306
+
307
+ ## Progress and verbose output
308
+
309
+ Progress is shown by default during file transfers:
310
+ ```
311
+ $ mpytool cp main.py lib.py :/lib/
312
+ [1/2] 100% 1.2KB main.py -> :/lib/main.py
313
+ [2/2] 100% 3.4KB lib.py -> :/lib/lib.py
314
+ ```
315
+
316
+ use `-v` or `--verbose` to also show commands being executed:
317
+ ```
318
+ $ mpytool -v rm /old.py
319
+ delete: /old.py
320
+ ```
321
+
322
+ use `-q` or `--quiet` to disable all output:
323
+ ```
324
+ $ mpytool -q cp main.py :/
325
+ ```
326
+
327
+ ## Output Example
328
+
329
+ Complete workflow - upload changed files, reset device, and monitor output:
330
+ ```
331
+ $ mpytool cp ~/Work/mpy/wlan/main.py ~/Work/mpy/wlan/html :/ -- cp ~/Work/mpy/wlan/wlan_http.py ~/Work/mpy/wlan/wlan.py ~/Work/mpy/uhttp/uhttp :/lib/ -- cp ~/Tmp/test0.bin :/lib/ -- reset -- monitor
332
+ COPY (chunk: 16K, compress: on)
333
+ [1/9] 100% 3.03K ../mpy/wlan/main.py -> :/main.py (compressed)
334
+ [2/9] skip 587B ../mpy/wlan/html/index.html -> :/html/index.html (unchanged)
335
+ [3/9] 100% 40.8K ../mpy/wlan/html/wlan.html -> :/html/wlan.html (compressed)
336
+ [4/9] skip 4.95K ../mpy/wlan/wlan_http.py -> :/lib/wlan_http.py (unchanged)
337
+ [5/9] 100% 23.1K ../mpy/wlan/wlan.py -> :/lib/wlan.py (compressed)
338
+ [6/9] skip 43.2K ../mpy/uhttp/uhttp/server.py -> :/lib/uhttp/server.py (unchanged)
339
+ [7/9] skip 26.3K ../mpy/uhttp/uhttp/client.py -> :/lib/uhttp/client.py (unchanged)
340
+ [8/9] skip 93B ../mpy/uhttp/uhttp/__init__.py -> :/lib/uhttp/__init__.py (unchanged)
341
+ [9/9] skip 10.0K ../../Tmp/test0.bin -> :/lib/test0.bin (unchanged)
342
+ 66.9K 29.7K/s 2.3s speedup 6.5x (3 transferred, 6 skipped)
343
+ RESET
344
+ MONITOR (Ctrl+C to stop)
345
+
346
+ starting web server...
347
+ Config file not created
348
+ AP started: ESP32 (WPA2_PSK, IP: 192.168.4.1)
349
+ Scanning...
350
+ ```
351
+
352
+ ## Debug output
353
+
354
+ - `-d` print warnings (yellow)
355
+ - `-dd` print info messages (purple)
356
+ - `-ddd` print debug messages (blue)
357
+
358
+ For reporting bugs, please include `-ddd` output in the issue.
359
+
360
+ ## Performance
361
+
362
+ `mpytool` uses optimized chunked transfer with automatic compression, which allows copying files very quickly. See [README_BENCH.md](README_BENCH.md) for detailed benchmarks.
363
+
364
+ ### Summary
365
+
366
+ - **Large files upload: 3x - 5x faster** than mpremote
367
+ - **Small files upload: 2x - 3x faster** than mpremote
368
+ - **Skip unchanged: 1.5x - 2.5x faster** than mpremote
369
+
370
+ ## Shell Completion
371
+
372
+ Tab completion for ZSH and Bash with support for commands, options, and remote file paths on the device.
373
+
374
+ Completion files are in `completions/` directory:
375
+ - `_mpytool` - ZSH completion
376
+ - `mpytool.bash` - Bash completion
377
+
378
+ ### ZSH
379
+
380
+ **Completion file:** `completions/_mpytool`
381
+
382
+ **Where to put it:**
383
+ - `~/.zsh/completions/_mpytool` (user directory, recommended)
384
+ - `/usr/local/share/zsh/site-functions/_mpytool` (system-wide)
385
+
386
+ **Configuration in `~/.zshrc`:**
387
+ ```bash
388
+ fpath=(~/.zsh/completions $fpath)
389
+ autoload -Uz compinit && compinit
390
+ ```
391
+
392
+ **Quick install (or update):**
393
+ ```bash
394
+ mkdir -p ~/.zsh/completions
395
+ curl -fsSL https://raw.githubusercontent.com/pavelrevak/mpytool/main/completions/_mpytool -o ~/.zsh/completions/_mpytool
396
+ grep -q '\.zsh/completions' ~/.zshrc || echo 'fpath=(~/.zsh/completions $fpath); autoload -Uz compinit && compinit' >> ~/.zshrc
397
+ exec zsh
398
+ ```
399
+
400
+ ### Bash
401
+
402
+ **Completion file:** `completions/mpytool.bash`
403
+
404
+ **Where to put it:**
405
+ - `/etc/bash_completion.d/mpytool` (Linux system-wide, requires sudo)
406
+ - `/usr/local/etc/bash_completion.d/mpytool` (macOS Homebrew)
407
+ - `~/.mpytool-completion.bash` (user directory)
408
+
409
+ **Configuration in `~/.bashrc`** (only for user directory):
410
+ ```bash
411
+ source ~/.mpytool-completion.bash
412
+ ```
413
+
414
+ **Quick install (Linux system-wide):**
415
+ ```bash
416
+ sudo curl -fsSL https://raw.githubusercontent.com/pavelrevak/mpytool/main/completions/mpytool.bash -o /etc/bash_completion.d/mpytool && exec bash
417
+ ```
418
+
419
+ **Quick install (macOS Homebrew):**
420
+ ```bash
421
+ curl -fsSL https://raw.githubusercontent.com/pavelrevak/mpytool/main/completions/mpytool.bash -o /usr/local/etc/bash_completion.d/mpytool && exec bash
422
+ ```
423
+
424
+ **Quick install (user directory):**
425
+ ```bash
426
+ curl -fsSL https://raw.githubusercontent.com/pavelrevak/mpytool/main/completions/mpytool.bash -o ~/.mpytool-completion.bash
427
+ grep -q 'mpytool-completion' ~/.bashrc || echo 'source ~/.mpytool-completion.bash' >> ~/.bashrc
428
+ exec bash
429
+ ```
430
+
431
+ ### Completion features
432
+
433
+ - Tab completion for all commands and aliases
434
+ - Remote file/directory completion (cached for 60 seconds)
435
+ - Support for `--` command separator
436
+ - Works with both relative and absolute paths
437
+
438
+ ## Requirements
439
+
440
+ Working only with MicroPython boards, not with CircuitPython
441
+
442
+ - python v3.10+
443
+ - pyserial v3.0+
444
+
445
+ ### Running on:
446
+
447
+ - Linux
448
+ - MacOS
449
+ - Windows (limited support - REPL mode is disabled)
450
+
451
+ ## Credits
452
+
453
+ (c) 2022-2026 by Pavel Revak
454
+
455
+ ### License
456
+
457
+ MIT
458
+
459
+ ### Support
460
+
461
+ - Basic support is free over GitHub issues.
462
+ - Professional support is available over email: [Pavel Revak](mailto:pavel.revak@gmail.com?subject=[GitHub]%20mpytool).