Skip to content

Commit

Permalink
verbose output through python logging
Browse files Browse the repository at this point in the history
  • Loading branch information
ftylitak committed Jul 16, 2020
1 parent 51b543f commit 8b83a71
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 41 deletions.
40 changes: 28 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,39 @@ You should see usage information displayed like below:
Usage: ampy [OPTIONS] COMMAND [ARGS]...

ampy - Adafruit MicroPython Tool

Ampy is a tool to control MicroPython boards over a serial connection.
Using ampy you can manipulate files on the board's internal filesystem and
even run scripts.

Options:
-p, --port PORT Name of serial port for connected board. [required]
-b, --baud BAUD Baud rate for the serial connection. (default 115200)
-d, --delay DELAY Delay in seconds before entering RAW MODE (default 0)
--help Show this message and exit.

-p, --port PORT Name of serial port for connected board. Can optionally
specify with AMPY_PORT environment variable. [required]

-b, --baud BAUD Baud rate for the serial connection (default 115200).
Can optionally specify with AMPY_BAUD environment
variable.

-d, --delay DELAY Delay in seconds before entering RAW MODE (default 0).
Can optionally specify with AMPY_DELAY environment
variable.

-v, --verbose Print messages to monitor the progress of the requested
operation.

--version Show the version and exit.
--help Show this message and exit.

Commands:
get Retrieve a file from the board.
ls List contents of a directory on the board.
put Put a file on the board.
rm Remove a file from the board.
run Run a script and print its output.
get Retrieve a file from the board.
ls List contents of a directory on the board.
mkdir Create a directory on the board.
put Put a file or folder and its contents on the board.
reset Perform soft reset/reboot of the board.
rm Remove a file from the board.
rmdir Forcefully remove a folder and all its children from the board.
run Run a script and print its output.


If you'd like to install from the Github source then use the standard Python
setup.py install (or develop mode):
Expand Down
28 changes: 18 additions & 10 deletions ampy/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@

import click
import dotenv
import logging

logging.basicConfig(format="%(asctime)s: %(message)s")
logger = logging.getLogger("ampy")

# Load AMPY_PORT et al from .ampy file
# Performed here because we need to beat click's decorators.
Expand Down Expand Up @@ -102,16 +106,18 @@ def cli(port, baud, delay, verbose):
scripts.
"""
global _board

level = logging.INFO
if verbose:
level = logging.DEBUG
logger.setLevel(level)

# On Windows fix the COM port path name for ports above 9 (see comment in
# windows_full_port_name function).
if platform.system() == "Windows":
port = windows_full_port_name(port)
_board = pyboard.Pyboard(port, baudrate=baud, rawdelay=delay)

_verbose = verbose
files.SetVerboseStatus(verbose)


@cli.command()
@click.argument("remote_file")
@click.argument("local_file", type=click.File("wb"), required=False)
Expand Down Expand Up @@ -139,7 +145,7 @@ def get(remote_file, local_file):
contents = board_files.get(remote_file)
# Print the file out if no local file was provided, otherwise save it.
if local_file is None:
print(contents.decode("utf-8"))
logger.info(os.linesep + contents.decode("utf-8"))
else:
local_file.write(contents)

Expand Down Expand Up @@ -204,8 +210,11 @@ def ls(directory, long_format, recursive):
"""
# List each file/directory on a separate line.
board_files = files.Files(_board)
filesStr = os.linesep
for f in board_files.ls(directory, long_format=long_format, recursive=recursive):
print(f)
filesStr += f + os.linesep

logger.info(filesStr)


@cli.command()
Expand Down Expand Up @@ -328,7 +337,6 @@ def rmdir(remote_folder, missing_okay):
)
def run(local_file, no_output):
"""Run a script and print its output.
Run will send the specified file to the board and execute it immediately.
Any output from the board will be printed to the console (note that this is
not a 'shell' and you can't send input to the program).
Expand All @@ -348,9 +356,9 @@ def run(local_file, no_output):
# Run the provided file and print its output.
board_files = files.Files(_board)
try:
output = board_files.run(local_file, not no_output, not no_output)
output = board_files.run(local_file, not no_output)
if output is not None:
print(output.decode("utf-8"), end="")
logger.info(os.linesep + output.decode("utf-8")) # , end="")
except IOError:
click.echo(
"Failed to find or read input file: {0}".format(local_file), err=True
Expand Down Expand Up @@ -415,7 +423,7 @@ def reset():
"""
)
r = _board.eval("on_next_reset({})".format(repr(mode)))
print("here we are", repr(r))
logger.info("here we are" + repr(r))
if r:
click.echo(r, err=True)
return
Expand Down
21 changes: 9 additions & 12 deletions ampy/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import ast
import textwrap
import binascii
import logging

from ampy.pyboard import PyboardError

logger = logging.getLogger("ampy")


BUFFER_SIZE = 32 # Amount of data to read or write to the serial port at a time.
# This is kept small because small chips and USB to serial
Expand Down Expand Up @@ -77,8 +80,7 @@ def get(self, filename):
)
self._pyboard.enter_raw_repl()
try:
if(_verbose):
print("Getting file: " + filename)
logger.debug("Getting file: " + filename)
out = self._pyboard.exec_(textwrap.dedent(command))
except PyboardError as ex:
# Check if this is an OSError #2, i.e. file doesn't exist and
Expand Down Expand Up @@ -202,14 +204,12 @@ def mkdir(self, directory, exists_okay=False):
)
self._pyboard.enter_raw_repl()
try:
if(_verbose):
print("Creating directory: " + directory)
logger.debug("Creating directory: " + directory)
out = self._pyboard.exec_(textwrap.dedent(command))
except PyboardError as ex:
# Check if this is an OSError #17, i.e. directory already exists.
if ex.args[2].decode("utf-8").find("OSError: [Errno 17] EEXIST") != -1:
if(_verbose):
print(" Directory already exists")
logger.debug(" Directory already exists")
if not exists_okay:
raise DirectoryExistsError(
"Directory already exists: {0}".format(directory)
Expand All @@ -222,8 +222,7 @@ def put(self, filename, data):
"""Create or update the specified file with the provided data.
"""
# Open the file for writing on the board and write chunks of data.
if(_verbose):
print("Putting file: " + filename)
logger.debug("Putting file: " + filename)
self._pyboard.enter_raw_repl()
self._pyboard.exec_("f = open('{0}', 'wb')".format(filename))
size = len(data)
Expand Down Expand Up @@ -251,8 +250,7 @@ def rm(self, filename):
)
self._pyboard.enter_raw_repl()
try:
if(_verbose):
print("Deleting file: " + filename),
logger.debug("Deleting file: " + filename)
out = self._pyboard.exec_(textwrap.dedent(command))
except PyboardError as ex:
message = ex.args[2].decode("utf-8")
Expand Down Expand Up @@ -300,8 +298,7 @@ def rmdir(directory):
)
self._pyboard.enter_raw_repl()
try:
if(_verbose):
print("Deleting directory: " + directory)
logger.debug("Deleting directory: " + directory)
out = self._pyboard.exec_(textwrap.dedent(command))
except PyboardError as ex:
message = ex.args[2].decode("utf-8")
Expand Down
23 changes: 16 additions & 7 deletions ampy/pyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@

import sys
import time
import logging

logger = logging.getLogger("ampy")
_rawdelay = None

try:
Expand Down Expand Up @@ -143,10 +145,10 @@ def __init__(self, device, baudrate=115200, user='micro', password='python', wai
sys.stdout.flush()
else:
if delayed:
print('')
logger.info('')
raise PyboardError('failed to access ' + device)
if delayed:
print('')
logger.info('')

def close(self):
self.serial.close()
Expand Down Expand Up @@ -192,13 +194,13 @@ def enter_raw_repl(self):
self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL
data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n>')
if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
print(data)
logger.info(data)
raise PyboardError('could not enter raw repl')

self.serial.write(b'\x04') # ctrl-D: soft reset
data = self.read_until(1, b'soft reboot\r\n')
if not data.endswith(b'soft reboot\r\n'):
print(data)
logger.info(data)
raise PyboardError('could not enter raw repl')
# By splitting this into 2 reads, it allows boot.py to print stuff,
# which will show up after the soft reboot and before the raw REPL.
Expand All @@ -212,7 +214,7 @@ def enter_raw_repl(self):
# End modification above.
data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n')
if not data.endswith(b'raw REPL; CTRL-B to exit\r\n'):
print(data)
logger.info(data)
raise PyboardError('could not enter raw repl')

def exit_raw_repl(self):
Expand Down Expand Up @@ -303,11 +305,18 @@ def main():
cmd_parser.add_argument('-u', '--user', default='micro', help='the telnet login username')
cmd_parser.add_argument('-p', '--password', default='python', help='the telnet login password')
cmd_parser.add_argument('-c', '--command', help='program passed in as string')
cmd_parser.add_argument('-v', '--verbose', help='Print messages to monitor the progress of the requested operation.')
cmd_parser.add_argument('-w', '--wait', default=0, type=int, help='seconds to wait for USB connected board to become available')
cmd_parser.add_argument('--follow', action='store_true', help='follow the output after running the scripts [default if no scripts given]')
cmd_parser.add_argument('files', nargs='*', help='input files')

args = cmd_parser.parse_args()

level = logging.INFO
if args.verbose:
level = logging.DEBUG
logger.setLevel(level)

def execbuffer(buf):
try:
pyb = Pyboard(args.device, args.baudrate, args.user, args.password, args.wait)
Expand All @@ -316,7 +325,7 @@ def execbuffer(buf):
pyb.exit_raw_repl()
pyb.close()
except PyboardError as er:
print(er)
logger.error(er)
sys.exit(1)
except KeyboardInterrupt:
sys.exit(1)
Expand All @@ -338,7 +347,7 @@ def execbuffer(buf):
ret, ret_err = pyb.follow(timeout=None, data_consumer=stdout_write_bytes)
pyb.close()
except PyboardError as er:
print(er)
logger.error(er)
sys.exit(1)
except KeyboardInterrupt:
sys.exit(1)
Expand Down

0 comments on commit 8b83a71

Please sign in to comment.