Git Product home page Git Product logo

ampy's Introduction

ampy replacement

We have been working on the next version of ampy which will solve various problems with the current system. Based on a new modular architecture, it makes adding device support and features very simple using plugins. It also aims to support coding over WiFi for supported devices. This should eliminate the need to have a wired connection and improve reliability as well. Here is an alpha release please go ahead and play with it. Leave suggestions for a new name in the issue section. :)

ampy

MicroPython Tool (ampy) - Utility to interact with a CircuitPython or MicroPython board over a serial connection.

Ampy is meant to be a simple command line tool to manipulate files and run code on a CircuitPython or MicroPython board over its serial connection. With ampy you can send files from your computer to the board's file system, download files from a board to your computer, and even send a Python script to a board to be executed.

Note that ampy by design is meant to be simple and does not support advanced interaction like a shell or terminal to send input to a board. Check out other MicroPython tools like rshell or mpfshell for more advanced interaction with boards.

Installation

You can use ampy with either Python 2.7.x or 3.x and can install it easily from Python's package index. On MacOS or Linux, in a terminal run the following command (assuming Python 3):

pip3 install --user adafruit-ampy

On Windows, do:

pip install adafruit-ampy

Note on some Linux and Mac OSX systems you might need to run as root with sudo:

sudo pip3 install adafruit-ampy

If you don't have Python 3 then try using Python 2 with:

pip install adafruit-ampy

Once installed verify you can run the ampy program and get help output:

ampy --help

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.

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.

If you'd like to install from the Github source then use the standard Python setup.py install (or develop mode):

python3 setup.py install

Note to run the unit tests on Python 2 you must install the mock library:

pip install mock

Usage

Ampy is made to talk to a CircuitPython MicroPython board over its serial connection. You will need your board connected and any drivers to access it serial port installed. Then for example to list the files on the board run a command like:

ampy --port /dev/tty.SLAB_USBtoUART ls

You should see a list of files on the board's root directory printed to the terminal. Note that you'll need to change the port parameter to the name or path to the serial port that the MicroPython board is connected to.

Other commands are available, run ampy with --help to see more information:

ampy --help

Each subcommand has its own help, for example to see help for the ls command run (note you unfortunately must have a board connected and serial port specified):

ampy --port /dev/tty.SLAB_USBtoUART ls --help

Configuration

For convenience you can set an AMPY_PORT environment variable which will be used if the port parameter is not specified. For example on Linux or OSX:

export AMPY_PORT=/dev/tty.SLAB_USBtoUART
ampy ls

Or on Windows (untested) try the SET command:

set AMPY_PORT=COM4
ampy ls

Similarly, you can set AMPY_BAUD and AMPY_DELAY to control your baud rate and the delay before entering RAW MODE.

To set these variables automatically each time you run ampy, copy them into a file named .ampy:

# Example .ampy file
# Please fill in your own port, baud rate, and delay
AMPY_PORT=/dev/cu.wchusbserial1410
AMPY_BAUD=115200
# Fix for macOS users' "Could not enter raw repl"; try 2.0 and lower from there:
AMPY_DELAY=0.5

You can put the .ampy file in your working directory, one of its parents, or in your home directory.

ampy's People

Contributors

beele avatar bxnxm avatar curiouswala avatar devxpy avatar dhalbert avatar ftylitak avatar garthk avatar hubertapo avatar ikelos avatar jepler avatar kattni avatar ladyada avatar larsks avatar mbuesch avatar miketeachman avatar phil303 avatar takeru avatar tannewt avatar tdicola avatar tlvlp avatar tonylhansen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ampy's Issues

not working on win10 with esp32s

Hi,

I've just installed ampy and it is not working on my setup. I run win10, try to communicate with and old version ESP32. Python version is 3.7. Here is the readout from cmd.exe.

C:\Users\Ivo\AppData\Local\Programs\Python\Python37\Scripts>ampy --port COM3 ls
b'\x1b[0;32mI (396) cpu_start: Pro cpu up.\x1b[0m\r\n\x1b[0;32mI (396) cpu_start: Single core mode\x1b[0m\r\n\x1b[0;32mI (396) heap_init: Initializing. RAM available for dynamic allocation:\x1b[0m\r\n\x1b[0;32mI (399) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM\x1b[0m\r\n\x1b[0;32mI (405) heap_init: At 3FFC5858 len 0001A7A8 (105 KiB): DRAM\x1b[0m\r\n\x1b[0;32mI (412) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM\x1b[0m\r\n\x1b[0;32mI (418) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM\x1b[0m\r\n\x1b[0;32mI (424) heap_init: At 40091B28 len 0000E4D8 (57 KiB): IRAM\x1b[0m\r\n\x1b[0;32mI (431) cpu_start: Pro cpu start user code\x1b[0m\r\n\x1b[0;32mI (225) cpu_start: Starting scheduler on PRO CPU.\x1b[0m\r\nOSError: [Errno 2] ENOENT\r\nMicroPython v1.9.4-241-g14ab81e8 on 2018-07-04; ESP32 module with ESP32\r\nType "help()" for more information.\r\n>>> '
Traceback (most recent call last):
File "C:\Users\Ivo\AppData\Local\Programs\Python\Python37\Scripts\ampy-script.py", line 11, in
load_entry_point('adafruit-ampy==1.0.3', 'console_scripts', 'ampy')()
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\click\core.py", line 722, in call
return self.main(*args, **kwargs)
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\click\core.py", line 697, in main
rv = self.invoke(ctx)
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\click\core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\click\core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\click\core.py", line 535, in invoke
return callback(*args, **kwargs)
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\ampy\cli.py", line 147, in ls
for f in board_files.ls(directory):
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\ampy\files.py", line 94, in ls
self._pyboard.enter_raw_repl()
File "c:\users\ivo\appdata\local\programs\python\python37\lib\site-packages\ampy\pyboard.py", line 192, in enter_raw_repl
raise PyboardError('could not enter raw repl')
ampy.pyboard.PyboardError: could not enter raw repl

C:\Users\Ivo\AppData\Local\Programs\Python\Python37\Scripts>

ampy no longer working with SDcard

Using ampy with Adafruit huzzah and Adalogger w/sdcard. ampy was working fine to put/get files to/from the sdcard for about a week. Now any ampy command dismounts the sdcard and performs actions on the esp8266 flash filesystem only. I detailed the issue and troubleshooting efforts in greater detail here: https://forums.adafruit.com/viewtopic.php?f=57&t=108474

$ ampy --version
ampy, version 0.6.3

Version of micropython:
MicroPython v1.8.6-174-gd227620 on 2016-12-18; ESP module with ESP8266

debugging is disabled "esp.osdebug(None)"

This is a vagrant build with frozen sdcard.py, but I re-installed supported versions downloaded from MicroPython and placed sdcard.py in the filesystem, manually performed mount.

import machine, sdcard, os
sd = sdcard.SDCard(machine.SPI(1), machine.Pin(15))
os.umount()
vfs = os.VfsFat(sd,

Same issue, ampy dismounts the sdcard before any action, performs on flash filesystem only.

ampy can't open Windows COM port numbers above 10

I have multiple USB hubs on my Windows PC and a fair number of USB devices. For some reason Python needs to see Windows port names with numbers above 10 in a non-obvious format or they will not be opened. For example, COM24 needs to be depicted as \.\COM24 or the open attempt will fail. The ampy utility doesn't take this into account, and it would not open the USB port my esp8266 is attached to.

I did a little looking around and found a function that can return a correctly formatted COM name;

import re
import serial

def full_port_name(portname):
""" Given a port-name (of the form COM7,
COM12, CNCA0, etc.) returns a full
name suitable for opening with the
Serial class.
"""
m = re.match('^COM(\d+)$', portname)
if m and int(m.group(1)) > 10:
portname = '\\.\' + portname
return portname

pn = full_port_name('COM24')
print pn

So I put that in cli.py and modified the cli() function as follows;

`def cli(port, baud):
"""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.
"""
global _board
pn = full_port_name(port)
#print(pn)
#_board = pyboard.Pyboard(port, baudrate=baud)
_board = pyboard.Pyboard(pn, baudrate=baud)`

Machine readable output

I have a downstream application that utilizes the output of the ls command to function.

 https://github.com/joewez/AmpyFileManager

Unfortunately, the latest changes to the output formats has totally thrashed my app!

While I mean to update the application to work with the new formatting ASAP, I have a couple of non-specific requests for help...

  1. How do I extract version 1.0.3 from the source on github? I know I should have it as soon as I clone the repo, but I'm not git savvy enough to switch to before the latest changes.

  2. Could you consider a means of differentiating the files from the sub-directories with the ls command? As it is, the only general difference is the lack of an extension.

Anyway, thanks everyone for their great work!

Display free space on storage medium

In addition to the comment in #35, which seems like a good idea, it might be useful to know how much free space is left or how much space has been used (which might be easier to calculate?) in flash memory?

Cannot distinguish directories from files with ls command

One nice enhancement would be the ability to distinguish files from directories with the ls (or some other) command. Currently I distinguish between the two by the presence or absence of an extension but I am not sure that will always work.

folder upload

Discovered what I think is a bug when updating a folder that already exists.

It appears that if you try and upload a folder that already exists, no changes are made and any new files in the local directory are not copied to the device.

The only way I can see is to overcome this at the moment completely remove the folder on the device and then re-add it again, but this is not very efficient

Possibility to rename files within the board

Hello guys!

Just a quick possible feature would be to add the option to rename files within the board, I don't really know if this is possible but I guess that it would be a kind of merge between:

  • get from the board and store it in memory
  • rm from board.
  • put the file stored in memory in the new directory.

Maybe something like this in the cli.py:

@cli.command()
@click.argument("remote_file")
@click.argument("remote_new_file", type=click.File("wb"), required=True)
def rename(remote_file, remote_new_file):
    # Get the file contents.
    board_files = files.Files(_board)
    contents = board_files.get(remote_file)
    # Delete the provided file/directory on the board.
    board_files = files.Files(_board)
    board_files.rm(remote_file)
    # Put the file on the board.
    board_files.put(remote_filename, contents)

I know it involve more than just those couple of line but just wanted to help a bit.

Regards.

Ampy is install yet linux indicates command not found.

I am trying to access my nodemcu file system using the ampy tool by trying to follow this guide.
I have run into the following problem even after installing ampy the system simply wont allow me to use it says ampy not installed.
Hope you can help me I have attached a screen-shot of the method i used to install and verify if ampy was installed or not.
screenshot from 2018-06-15 13-14-57

put get status

I think this is trivial if we use tqdm. When putting or getting a single file we can show transferred bytes. When uploading a folder, we can show transferred files. This would be very cool. Can send PR.

KeyboardInterrupt on Windows

Something seems not working with rising a KeyboardInterrupt on Windows 7, at least in my case. In command line window Ctrl+C does not stop program execution (I tried this combination also in ipython, where it works as expected, so it's not keyboard or terminal problem). I also tried to use Ctrl+Break combination, which closes process (new line with prompt appears), but program is still running on the board (I have a program which turns on/off relay every second, so I can hear a click when it is running).

ampy run doesn't work on Mac

Just setting up my Mac for working with the ESP32, and everything works great, except for ampy run /flash/test.py

Can anyone tell me what am I doing wrong?

Works perfectly on my windows machine

I can not copy files to the board

I can not copy files or create directories on the board (if I execute them and get them)
Error: ampy --port /dev/ttyUSB0 mkdir foo
Traceback (most recent call last):
File "/usr/local/bin/ampy", line 11, in
sys.exit(cli())
File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 722, in call
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 1066, in invoke
return process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.4/dist-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/ampy/cli.py", line 122, in mkdir
board_files.mkdir(directory)
File "/usr/local/lib/python3.4/dist-packages/ampy/files.py", line 122, in mkdir
raise ex
File "/usr/local/lib/python3.4/dist-packages/ampy/files.py", line 116, in mkdir
out = self.pyboard.exec(textwrap.dedent(command))
File "/usr/local/lib/python3.4/dist-packages/ampy/pyboard.py", line 257, in exec

raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n File "", line 3, in \r\n File "flashbdev.py", line 20, in writeblocks\r\nOSError: [Errno 5] EIO\r\n')

directory handling somewhat confusing

I can 'put' files to the board without specifying the directory:
ampy put test.py will put the file in /flash.
amp mkdir testdir will create a dir /flash/testdir

I would therefore expect ampy ls to show the files in /flash as well. It doesn't, it will show the files in /.
When putting files in subdirs one has to include the full path including /flash, like
ampy put test.py /flash/testdir/test.py instead of ampy put test.py /testdir/test.py

Finally, my understanding is that installing modules from micropython-lib one has to copy all files to the board. It would be nice to have ampy respect wildcards.

As it is, ampy is already very useful! Thanks.

I'm using a LoPy board.

ampy.pyboard.PyboardError: failed to access /dev/ttyUSB0

[alarm@archlinux ~]$ ampy -p /dev/ttyUSB0 -b 115200 run -n main.py
Traceback (most recent call last):
  File "/usr/bin/ampy", line 11, in <module>
    sys.exit(cli())
  File "/usr/lib/python3.5/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 1057, in invoke
    Command.invoke(self, ctx)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/ampy/cli.py", line 50, in cli
    _board = pyboard.Pyboard(port, baudrate=baud)
  File "/usr/lib/python3.5/site-packages/ampy/pyboard.py", line 143, in __init__
    raise PyboardError('failed to access ' + device)
ampy.pyboard.PyboardError: failed to access /dev/ttyUSB0

I can't use it on my nodemcu?what should I do?

Better Error Messages

I think error messages should be more user friendly. After all, many newcomers are going to use this tool.

Cannot rm a file or mkdir on ESP32

I have installed MicroPython 1.9.4 on a ESP32-Tiny with chip ESP32D0WDQ6 revision 1

I can connect to the board fine over the USB/serial interface, get an REPL prompt, connect to wifi, drive I/O, and upload files. All good.

But I cannot delete a file or create a directory.

E.g.:
$ ampy --port /dev/ttyUSB0 mkdir test
Traceback (most recent call last):
File "/usr/local/bin/ampy", line 11, in
load_entry_point('adafruit-ampy==1.0.3', 'console_scripts', 'ampy')()
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 722, in call
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
return process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/ampy/cli.py", line 127, in mkdir
exists_okay=exists_okay)
File "/usr/local/lib/python3.6/dist-packages/ampy/files.py", line 129, in mkdir
raise ex
File "/usr/local/lib/python3.6/dist-packages/ampy/files.py", line 122, in mkdir
out = self.pyboard.exec(textwrap.dedent(command))
File "/usr/local/lib/python3.6/dist-packages/ampy/pyboard.py", line 265, in exec

raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n File "", line 6, in \r\n File "/lib/os/init.py", line 80, in mkdir\r\nNameError: name 'mkdir_' is not defined\r\n')

It's like a library is not installed. Or there is something funny going on with those "\r\n"s... My host box is running linux.

Any ideas what is wrong?

Thanks,
Justin.

progress bar

It would be nice to get a progress bar, especially for larger file/folders

Not receiving prints from python application

I'm running the latest ampy (v1.0.1) and MicroPython v1.9.1-8-g7213e78d from the pre-build binaries with my Feather HUZZAH.
Everything works fine. I can put and run files with ampy.
However if a "print()" command is executed, I don't get any output inside ampy. The funny thing though is, I get the error traceback if something bad happened in one of my scripts.

Is there something I missed to set?

I'm running on windows BTW.

Ampy cannot run all programs

I use ampy run a lot and find it very useful. However, it turns out that not all programs can be run this way. When the exact same code is run on the board through the REPL (screen) it does work!
I do not understand why.

The program in question is an example from the micropython-lib umqtt module: example_sub.py

import time
from umqtt.simple import MQTTClient

# Publish test messages e.g. with:
# mosquitto_pub -t foo_topic -m hello

# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
    print((topic, msg))

def main(server="192.168.2.201"):
    c = MQTTClient("umqtt_client", server)
    c.set_callback(sub_cb)
    print("Before connect")
    c.connect()
    print("After connect")
    c.subscribe(b"foo_topic")
    while True:
        if True:
            # Blocking wait for message
            c.wait_msg()
        else:
            # Non-blocking wait for message
            c.check_msg()
            # Then need to sleep to avoid 100% CPU usage (in a real
            # app other useful actions would be performed instead)
            time.sleep(1)

    c.disconnect()

if __name__ == "__main__":
    main()

This is the exception:

Traceback (most recent call last):
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/bin/ampy", line 11, in <module>
    sys.exit(cli())
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/cli.py", line 197, in run
    output = board_files.run(local_file, not no_output)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/files.py", line 170, in run
    out = self._pyboard.execfile(filename)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/pyboard.py", line 263, in execfile
    return self.exec_(pyfile)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/pyboard.py", line 255, in exec_
    ret, ret_err = self.exec_raw(command)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/pyboard.py", line 247, in exec_raw
    return self.follow(timeout, data_consumer)
  File "/Users/mjm/Dropbox/Devel/_Experiments/PyCom/venv3/lib/python3.6/site-packages/ampy/pyboard.py", line 211, in follow
    raise PyboardError('timeout waiting for first EOF reception')

When I put the file on the LoPy board and call it from main.py, it works correctly. This is main.py:

from wifi import connect_to_wifi

SSID = 'myssid'
PASSWORD = 'mypassword'
connect_to_wifi(SSID, PASSWORD)

from example_sub_led import main

main()

Ampy broken

Unable to access device error on Linux platforms even after disabling debug output

socket.accept fails with ampy.pyboard.PyboardError: timeout waiting for first EOF reception

When I tried to execute https://github.com/micropython/micropython/blob/master/examples/network/http_server_simplistic.py it fails when res = s.accept() is used

File "c:\python27\lib\site-packages\ampy\pyboard.py", line 263, in execfile
return self.exec_(pyfile)
File "c:\python27\lib\site-packages\ampy\pyboard.py", line 255, in exec_
ret, ret_err = self.exec_raw(command)
File "c:\python27\lib\site-packages\ampy\pyboard.py", line 247, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\python27\lib\site-packages\ampy\pyboard.py", line 211, in follow
raise PyboardError('timeout waiting for first EOF reception')
ampy.pyboard.PyboardError: timeout waiting for first EOF reception

I have esp.osdebug(None) in the boot.py

Thanks!

Can the short timeout when calling Pyboard.follow() through ampy run command be removed?

When Pyboard.exec_raw() calls Pyboard.follow() and a timeout=10 is defaulted, this only gives a short time (I assume around 10 seconds) before the ampy run command without --no-output will raise PyboardError('timeout waiting for first EOF reception'). This is a problem if you have a long running program from which you wish to see output in a terminal window (I'm running on Windows 10) when it completes (you just get the pyboard error message).
I have modded def exec_raw(self, command, timeout=10, data_consumer=None): in pyboard.py to have a default timeout=None which allows ampy run to continue until the program running on the pyboard (in my case an ESP32) completes.
Is this a reasonable change that can be made or will it affect other operations?

Add hard reset / boot

The current reset command does not execute the boot.py script upon exiting the REPL. Would be nice to add hard reset that would automatically execute boot.py or add the execution of boot.py after entering the REPL.

This dirty hack makes the board the hard reset but it stops the executable from exiting. I am sure that there is a better way to do this.

def reset():
    """Perform soft reset/reboot of the board.

    Will connect to the board and perform a soft reset.  No arguments are
    necessary:

      ampy --port /board/serial/port reset
    """
    # Enter then exit the raw REPL, in the process the board will be soft reset
    # (part of enter raw REPL).
    _board.enter_raw_repl()
    _board.exec_('import machine')
    _board.exec_('machine.reset()') 
    _board.exit_raw_repl()

Does not work at Ubuntu 18.04 64

Hi,

can't get it working at Ubuntu 18.04 64 with python3

$ pip3 install adafruit-ampy
Collecting adafruit-ampy
Collecting pyserial (from adafruit-ampy)
. . .
Successfully installed adafruit-ampy-1.0.5 click-6.7 pyserial-3.4 python-dotenv-0.9.1
$ ampy --help

Command 'ampy' not found, did you mean:

  command 'mpy' from deb yorick-mpy-mpich2
  command 'mpy' from deb yorick-mpy-openmpi
  command 'empy' from deb python-empy
  command 'amph' from deb amphetamine

Try: sudo apt install <deb name>

The same result is for Python 2.x

"could not enter raw repl"

When running ampy several times in succession, I often see fails that look like this:

b'PL; CTRL-B to exit\r\n>'
Traceback (most recent call last):
  File "/home/lars/.local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy', 'console_scripts', 'ampy')()
  File "/home/lars/.local/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/lars/.local/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/lars/.local/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/lars/.local/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/lars/.local/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/lars/src/ampy/ampy/cli.py", line 220, in put
    board_files.put(remote, infile.read())
  File "/home/lars/src/ampy/ampy/files.py", line 157, in put
    self._pyboard.enter_raw_repl()
  File "/home/lars/src/ampy/ampy/pyboard.py", line 192, in enter_raw_repl
    raise PyboardError('could not enter raw repl')
ampy.pyboard.PyboardError: could not enter raw repl

The issue is that it obviously was able to enter raw repl mode; that's why we see b'PL; CTRL-B to exit\r\n>' printed at the top there (that comes from https://github.com/adafruit/ampy/blob/ff35f29b5b668f2555e52cf12a0d320f93f93c16/ampy/pyboard.py#L191).

ampy leaves ports open in Windows

If ampy is unable to complete a serial port IO operation for some reason it will hang. When this happens the user must control-c in order to terminate it and return to a command line prompt. However! The python process keeps running and holds the serial port open. Subsequent invocations of ampy will fail because the port is locked!

The only solution is to either reboot or bring up the Windows Task Manager, look for the python process, and kill it.

AttributeError: module 'click' has no attribute 'group'

I installed ampy with
sudo pip3 install adafruit-ampy
When I run it, it produces this error:

$ ampy --help

Traceback (most recent call last):
File "/usr/local/bin/ampy", line 7, in
from ampy.cli import cli
File "/usr/local/lib/python3.5/dist-packages/ampy/cli.py", line 34, in <module>
@click.group()
AttributeError: module 'click' has no attribute 'group'

Ampy tries to work while picocom is open

I think ampy should check if port is being used and if it is, raise an error. A simple approach would be using fuser to check if any process is holding the file descriptor.

GET command does not work for feather52

The get command does not work when accessing my nrf52 - feather52 board via ampy.

ls and put work, but no get

Note: this example includes PR #46 but the issues was also present without it.

jerryneedell@Ubuntu-Macmini:~/projects/feather52$ ampy -d 1.5 -p /dev/ttyUSB0  put test.py
jerryneedell@Ubuntu-Macmini:~/projects/feather52$ ampy -d 1.5 -p /dev/ttyUSB0  ls
test.py
my_scan.py
jerryneedell@Ubuntu-Macmini:~/projects/feather52$ ampy -d 1.5 -p /dev/ttyUSB0  get test.py
Traceback (most recent call last):
  File "/usr/local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy==1.0.4', 'console_scripts', 'ampy')()
  File "/usr/local/lib/python3.5/dist-packages/click-6.7-py3.5.egg/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click-6.7-py3.5.egg/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click-6.7-py3.5.egg/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click-6.7-py3.5.egg/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click-6.7-py3.5.egg/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_ampy-1.0.4-py3.5.egg/ampy/cli.py", line 99, in get
  File "/usr/local/lib/python3.5/dist-packages/adafruit_ampy-1.0.4-py3.5.egg/ampy/files.py", line 77, in get
  File "/usr/local/lib/python3.5/dist-packages/adafruit_ampy-1.0.4-py3.5.egg/ampy/files.py", line 70, in get
  File "/usr/local/lib/python3.5/dist-packages/adafruit_ampy-1.0.4-py3.5.egg/ampy/pyboard.py", line 267, in exec_
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 8, in <module>\r\n  File "<stdin>", line 8, in <module>\r\nAttributeError: \'module\' object has no attribute \'stdout\'\r\n')

ls does not work for subdirectories

This issue has been present for awhile but I forgot to file an isse on it -- here it is failing on an ESP8266, but the same problem exists for the nrf52

any attempt to use the "ls" command on a sub-directory fails and it leaves the board in the "Raw REPL"
A control-B brings it back to normal REPL

I am using ampy 1.0.5 with the following .ampy file

jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ cat .ampy
# Example .ampy file
# Please fill in your own port, baud rate, and delay
AMPY_PORT=/dev/ttyUSB0
AMPY_BAUD=115200
AMPY_DELAY=0

create subdirectory lib and copy a file to the lib subdirectory

jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy mkdir lib
jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy put ~/projects/Adafruit_Circuitpython_Bundle/3.x/lib/neopixel.mpy lib/neopixel.mpy
jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy put jewel.py
jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy ls
boot.py
lib
jewel.py

using os.listdir, - verify that the files are present

>>> 
>>> 
>>> import os
>>> os.listdir()
['boot.py', 'lib', 'jewel.py']
>>> os.listdir('lib')
['neopixel.mpy']
>>> os.listdir('lib')


Here are various attempts to us "ls"

jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy ls lib
Traceback (most recent call last):
  File "/usr/local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy==1.0.5', 'console_scripts', 'ampy')()
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 700, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 680, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1027, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 873, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/ampy/cli.py", line 162, in ls
    for f in board_files.ls(directory, long_format=long_format):
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 124, in ls
    raise ex
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 117, in ls
    out = self._pyboard.exec_(textwrap.dedent(command))
  File "/usr/local/lib/python3.5/dist-packages/ampy/pyboard.py", line 267, in exec_
    raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 6, in <module>\r\nOSError: [Errno 22] Invalid argument\r\n')
jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy ls lib/
Traceback (most recent call last):
  File "/usr/local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy==1.0.5', 'console_scripts', 'ampy')()
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 700, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 680, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1027, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 873, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/ampy/cli.py", line 162, in ls
    for f in board_files.ls(directory, long_format=long_format):
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 124, in ls
    raise ex
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 117, in ls
    out = self._pyboard.exec_(textwrap.dedent(command))
  File "/usr/local/lib/python3.5/dist-packages/ampy/pyboard.py", line 267, in exec_
    raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 6, in <module>\r\nOSError: [Errno 22] Invalid argument\r\n')
jerryneedell@Ubuntu-Macmini:~/projects/esp8266/ampy$ ampy ls /lib
Traceback (most recent call last):
  File "/usr/local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy==1.0.5', 'console_scripts', 'ampy')()
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 700, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 680, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1027, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 873, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/ampy/cli.py", line 162, in ls
    for f in board_files.ls(directory, long_format=long_format):
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 124, in ls
    raise ex
  File "/usr/local/lib/python3.5/dist-packages/ampy/files.py", line 117, in ls
    out = self._pyboard.exec_(textwrap.dedent(command))
  File "/usr/local/lib/python3.5/dist-packages/ampy/pyboard.py", line 267, in exec_
    raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 6, in <module>\r\nOSError: [Errno 22] Invalid argument\r\n')

Latest changes to ls failing in Windows 10 for sub-directories

Upgrading to 1.0.5...

I can no longer list files in a subdirectory...

D:\Development>ampy -p com4 -b 115200 ls /wwwroot/ Traceback (most recent call last): File "C:\Users\Joseph\AppData\Local\Programs\Python\Python36-32\Scripts\ampy-script.py", line 11, in <module> load_entry_point('adafruit-ampy==1.0.5', 'console_scripts', 'ampy')() File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\click\core.py", line 722, in __call__ return self.main(*args, **kwargs) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\click\core.py", line 697, in main rv = self.invoke(ctx) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\click\core.py", line 1066, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\click\core.py", line 895, in invoke return ctx.invoke(self.callback, **ctx.params) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\click\core.py", line 535, in invoke return callback(*args, **kwargs) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\ampy\cli.py", line 162, in ls for f in board_files.ls(directory, long_format=long_format): File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\ampy\files.py", line 124, in ls raise ex File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\ampy\files.py", line 117, in ls out = self._pyboard.exec_(textwrap.dedent(command)) File "c:\users\joseph\appdata\local\programs\python\python36-32\lib\site-packages\ampy\pyboard.py", line 267, in exec_ raise PyboardError('exception', ret, ret_err) ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n File "<stdin>", line 6, in <module>\r\nOSError: [Errno 22] EINVAL\r\n')

Esp8266 for Micropython on Windows 10 exception

I'm using PyCharm with Micropython plugin to programming on Esp8266, I made a folder 'drivers' in the root path, and drag 2 files into it, when I upload files to Esp8266, the first file in 'drivers' will upload success, but, the second file will thrown exception at all.

here is the output

Traceback (most recent call last):
File "C:\Users\walkl.PyCharmCE2018.2\config\plugins\intellij-micropython/scripts/microupload.py", line 138, in
main(sys.argv[1:])
File "C:\Users\walkl.PyCharmCE2018.2\config\plugins\intellij-micropython/scripts/microupload.py", line 79, in main
files.put(remote_path, fd.read())
File "C:\Python3\lib\site-packages\ampy\files.py", line 158, in put
self.pyboard.exec("f = open('{0}', 'wb')".format(filename))
File "C:\Python3\lib\site-packages\ampy\pyboard.py", line 266, in exec_
raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n File "", line 1, in \r\nOSError: [Errno 13] EACCES\r\n')

if I put all my flies in the root, upload will all success, how can I fix this bug?

adafruit-ampy: 1.0.5
Micropython for Esp8266 fireware: esp8266-20180511-v1.9.4.bin
PyCharm: Community 2018.2
Micropython plugin for PyCharm: 1.0.9

I'm a begginer, so I think all of those software & fireware are newest at this time

Please help me, thanks~

print filesizes with ls command

Hello, thanks for this wonderful utility.
Only thing I am missing is file size info for ls command - it would be the easiest check if the file is same as on my PC.
So i suggest adding something like -l parameter to show more about files, than just names.

Thanks.

ampy not working while main.py is running

If I have a main.py file in which a while-loop runs forever, then I can not issue the ampy command.
I don't think this is a bug, but I will have to use esptool.py to erase my esp32 borad, and flush firmware.
Is there any other way to edit or delete the none-stoping main.py file

--EDIT---------
I had the issue above with Ubuntu16.
Now on Win10, I don't have the issue any more, I can "ampy rm main.py" while main.py is running

Problem with ESP32

ampy works well using wemos d1 mini, but has some problems with the ESP_Core_Board_V2
If I issue "ampy ls" command, the files in the directory appear. Issuing same command again, ampy hangs.

"ampy put file.py" sends file OK, but ampy never returns. Tried on 2 different modules.

GET, PUT and LS commands do not work with esp8266

GET, PUT and LS commands do not work with esp8266 via ampy.

Firmware: Micropython 1.9.4
Command: sudo ampy --port /dev/ttyUSB0 --baud 115200 ls

Traceback (most recent call last):
  File "/usr/local/bin/ampy", line 11, in <module>
    load_entry_point('adafruit-ampy==1.0.3', 'console_scripts', 'ampy')()
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/ampy/cli.py", line 147, in ls
    for f in board_files.ls(directory):
  File "/usr/local/lib/python3.6/dist-packages/ampy/files.py", line 103, in ls
    raise ex
  File "/usr/local/lib/python3.6/dist-packages/ampy/files.py", line 96, in ls
    out = self._pyboard.exec_(textwrap.dedent(command))
  File "/usr/local/lib/python3.6/dist-packages/ampy/pyboard.py", line 265, in exec_
    raise PyboardError('exception', ret, ret_err)
ampy.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 6, in <module>\r\nAttributeError: no such attribute\r\n')

error uploading _odroid_go_ package

Environment

Windows 10 x64
ampy 1.0.5
Python 3.6 x86

Description

I've tried to upload the odroid_go package using this command (the package was uncompressed prior)

ampy -p COM7 -b 115200 put odroid_go

If I list the odroid_go folder on the device I get this:

['odroid_go.py', '__init__.py', 'examples', 'examples\x08attery', 'examples\x08utton', 'examples\\hello_world', 'examples\\led', 'examples\\led_pwm', 'examples\\speaker', 'utils', 'utils\x08attery', 'utils\x08utton', 'utils\\lcd', 'utils\\speaker']

Can not run twice for ESP32

When I use it on my MAC OS, I found it will be hanged when i run ampy --port /dev/tty.SLAB_USBtoUART ls in second time. If I want to use it again, I have to replug usb cable.

I used the ampy 1.0.3 version, and micropython firmware of esp32-20180302-v1.9.3-386-g9884a2c7.bin, python version is 3.6.4

default

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/click/core.py", line 535, in invoke return callback(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ampy/cli.py", line 147, in ls for f in board_files.ls(directory): File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ampy/files.py", line 94, in ls self._pyboard.enter_raw_repl() File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ampy/pyboard.py", line 192, in enter_raw_repl raise PyboardError('could not enter raw repl') ampy.pyboard.PyboardError: could not enter raw repl

I checked the source code of micropython, and think may be the issue caused by it firmware code in ports/esp32/main.c

for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } }

Commands only work once on Linux

I already tried this tool on windows and it worked perfectly.
Now, I tried it on Linux (Linux MINT 18.2 | Kernel 4.10.0-30 | Python 3.5.2) and it's kinda buggy.
If I connect my esp32 running micropython (esp32-20170810-v1.9.1-397-g3ec00f0d.bin) and try the command ampy -p /dev/ttyUSB0 ls, I get this output: boot.py. But If I run the command again, nothing happens until I abort using ctrl+c. It starts working again after plugging out/in my ESP32 or pressing the EN button on my board.

Again, this issue was not present on Windows.
I'd appreciate a fix or a tip what the issue may be so I can fix it myself!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.