Circup¶
A tool to manage and update libraries (modules) on a CircuitPython device.
Installation¶
Circup requires Python 3.10 or higher.
In a virtualenv,
pip install circup should do the trick. This is the simplest way to make it
work.
If you have no idea what a virtualenv is, try the following command,
pip3 install --user circup.
Note
If you use the pip3 command to install Circup you must make sure that
your path contains the directory into which the script will be installed.
To discover this path,
On Unix-like systems, type
python3 -m site --user-baseand appendbinto the resulting path.On Windows, type the same command, but append
Scriptsto the resulting path.
What does Circup Do?¶
Each CircuitPython library on the device usually has a version number as metadata within the module.
This utility looks at all the libraries on the device and checks if they are the most recent (compared to the versions found in the most recent version of the Adafruit CircuitPython Bundle and Circuitpython Community Bundle). If the libraries are out of date, the utility helps you update them.
The Adafruit CircuitPython Bundle can be found here:
https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest
Full details of these libraries, what they’re for and how to get them, can be found here:
https://circuitpython.org/libraries
The Circuitpython Community Bundle can be found here:
https://github.com/adafruit/CircuitPython_Community_Bundle/releases/latest
Usage¶
If you need more detailed help using Circup see the Learn Guide article “Use Circup to easily keep your CircuitPython libraries up to date”.
First, plug in a device running CircuiPython. This should appear as a mounted
storage device called CIRCUITPY.
To get help, just type the command:
$ circup
Usage: circup [OPTIONS] COMMAND [ARGS]...
A tool to manage and update libraries on a CircuitPython device.
Options:
--verbose Comprehensive logging is sent to stdout.
--path DIRECTORY Path to CircuitPython directory. Overrides automatic
path detection.
--host TEXT Hostname or IP address of a device. Overrides automatic
path detection.
--password TEXT Password to use for authentication when --host is used.
--timeout INTEGER Specify the timeout in seconds for any network
operations.
--board-id TEXT Manual Board ID of the CircuitPython device. If provided
in combination with --cpy-version, it overrides the
detected board ID.
--cpy-version TEXT Manual CircuitPython version. If provided in combination
with --board-id, it overrides the detected CPy version.
--version Show the version and exit.
--help Show this message and exit.
Commands:
bundle-add Add bundles to the local bundles list, by "user/repo"...
bundle-remove Remove one or more bundles from the local bundles list.
bundle-show Show the list of bundles, default and local, with URL,...
example Copy named example(s) from a bundle onto the device.
freeze Output details of all the modules found on the connected...
install Install a named module(s) onto the device.
list Lists all out of date modules found on the connected...
show Show a list of available modules in the bundle.
uninstall Uninstall a named module(s) from the connected device.
update Update modules on the device. Use --all to automatically
update all modules without Major Version warnings.
To automatically install all modules imported by code.py,
$ circup install --auto:
$ circup install --auto
Found device at /Volumes/CIRCUITPY, running CircuitPython 7.0.0-alpha.5.
Searching for dependencies for: ['adafruit_bmp280']
Ready to install: ['adafruit_bmp280', 'adafruit_bus_device', 'adafruit_register']
Installed 'adafruit_bmp280'.
Installed 'adafruit_bus_device'.
Installed 'adafruit_register'.
To search for a specific module containing the name bme:
$ circup show bme:
$ circup show bme
Found device at /Volumes/CIRCUITPY, running CircuitPython 6.1.0-beta.2.
adafruit_bme280
adafruit_bme680
2 shown of 257 packages.
To show version information for all the modules currently on a connected CIRCUITPYTHON device:
$ circup freeze
adafruit_binascii==v1.0
adafruit_bme280==2.3.1
adafruit_ble==1.0.2
With $ circup freeze -r, Circup will save, in the current working directory,
a requirements.txt file with a list of all modules currently installed on the
connected device.
To list all the modules that require an update:
$ circup list
The following modules are out of date or probably need an update.
Module Version Latest
------------------ -------- --------
adafruit_binascii v1.0 1.0.1
adafruit_ble 1.0.2 4.0
To interactively update the out-of-date modules:
$ circup update
Found 3 module[s] needing update.
Please indicate which modules you wish to update:
Update 'adafruit_binascii'? [y/N]: Y
OK
Update 'adafruit_ble'? [y/N]: Y
OK
Install a module or modules onto the connected device with:
$ circup install adafruit_thermal_printer
Installed 'adafruit_thermal_printer'.
$ circup install adafruit_thermal_printer adafruit_bus_io
Installed 'adafruit_thermal_printer'.
Installed 'adafruit_bus_io'.
If you need to work with the original .py version of a module, use the –py flag.
$ circup install –py adafruit_thermal_printer Installed ‘adafruit_thermal_printer’.
You can also install a list of modules from a requirements.txt file in the current working directory with:
$ circup install -r requirements.txt
Installed 'adafruit_bmp280'.
Installed 'adafruit_lis3mdl'.
Installed 'adafruit_lsm6ds'.
Installed 'adafruit_sht31d'.
Installed 'neopixel'.
Uninstall a module or modules like this:
$ circup uninstall adafruit_thermal_printer
Uninstalled 'adafruit_thermal_printer'.
$ circup uninstall adafruit_thermal_printer adafruit_bus_io
Uninstalled 'adafruit_thermal_printer'.
Uninstalled 'adafruit_bus_io'.
Use the --verbose flag to see the logs as the command is working:
$ circup --verbose freeze
Logging to /home/ntoll/.cache/circup/log/circup.log
10/18/2020 00:54:43 INFO: ### Started Circup ###
10/18/2020 00:54:43 INFO: Found device: /Volumes/CIRCUITPY
Found device at /Volumes/CIRCUITPY, running CircuitPython 6.0.0-alpha.1-1352-gf0b37313c.
10/18/2020 00:54:44 INFO: Freeze
10/18/2020 00:54:44 INFO: Found device: /Volumes/CIRCUITPY
... etc ...
The --path flag let’s you pass in a different path to the CircuitPython
mounted volume. This is helpful when you have renamed or have more than one
CircuitPython devices attached:
$ circup --path /run/media/user/CIRCUITPY1 list
The --version flag will tell you the current version of the
circup command itself:
$ circup --version
Circup, A CircuitPython module updater. Version 0.0.1
To use circup via the Web Workflow. on devices that support it. Use the --host and --password arguments before your circup command.:
$ circup --host 192.168.1.119 --password s3cr3t install adafruit_hid
$ circup --host cpy-9573b2.local --password s3cr3t install adafruit_hid
That’s it!
Library Name Autocomplete¶
When enabled, circup will autocomplete library names, simliar to other command line tools.
For example:
circup install n+ tab -circup install neopixel(+tab: offersneopixelandneopixel_spicompletions)
circup install a+ tab -circup install adafruit\_+ m a g + tab -circup install adafruit_magtag
How to Activate Library Name Autocomplete¶
In order to activate shell completion, you need to inform your shell that completion is available for your script. Any Click application automatically provides support for that.
For Bash, add this to ~/.bashrc:
eval "$(_CIRCUP_COMPLETE=bash_source circup)"
For Zsh, add this to ~/.zshrc:
autoload -U compinit; compinit
eval "$(_CIRCUP_COMPLETE=zsh_source circup)"
For Fish, add this to ~/.config/fish/completions/foo-bar.fish:
eval (env _CIRCUP_COMPLETE=fish_source circup)
Open a new shell to enable completion. Or run the eval command directly in your current shell to enable it temporarily. ### Activation Script
The above eval examples will invoke your application every time a shell is started. This may slow down shell startup time significantly.
Alternatively, export the generated completion code as a static script to be executed. You can ship this file with your builds; tools like Git do this. At least Zsh will also cache the results of completion files, but not eval scripts.
For Bash:
_CIRCUP_COMPLETE=bash_source circup circup-complete.sh
For Zsh:
_CIRCUP_COMPLETE=zsh_source circup circup-complete.sh
For Fish:
_CIRCUP_COMPLETE=fish_source circup circup-complete.sh
In .bashrc or .zshrc, source the script instead of the eval command:
. /path/to/circup-complete.sh
For Fish, add the file to the completions directory:
_CIRCUP_COMPLETE=fish_source circup ~/.config/fish/completions/circup-complete.fish
Note
If you find a bug, or you want to suggest an enhancement or new feature feel free to create an issue or submit a pull request here:
Discussion of this tool happens on the Adafruit CircuitPython Discord channel.
wwshell¶
A tool to manage files on a CircuitPython device via wireless workflows. Currently supports Web Workflow.
Installation¶
wwshell is bundled along with Circup. When you install Circup you’ll get wwshell automatically.
Circup requires Python 3.5 or higher.
In a virtualenv,
pip install circup should do the trick. This is the simplest way to make it
work.
If you have no idea what a virtualenv is, try the following command,
pip3 install --user circup.
Note
If you use the pip3 command to install CircUp you must make sure that
your path contains the directory into which the script will be installed.
To discover this path,
On Unix-like systems, type
python3 -m site --user-baseand appendbinto the resulting path.On Windows, type the same command, but append
Scriptsto the resulting path.
What does wwshell do?¶
It lets you view, delete, upload, and download files from your Circuitpython device via wireless workflows. Similar to ampy, but operates over wireless workflow rather than USB serial.
Usage¶
To use web workflow you need to enable it by putting WIFI credentials and a web workflow password into your settings.toml file. See here,
To get help, just type the command:
$ wwshell
Usage: wwshell [OPTIONS] COMMAND [ARGS]...
A tool to manage files CircuitPython device over web workflow.
Options:
--verbose Comprehensive logging is sent to stdout.
--path DIRECTORY Path to CircuitPython directory. Overrides automatic path
detection.
--host TEXT Hostname or IP address of a device. Overrides automatic
path detection.
--password TEXT Password to use for authentication when --host is used.
You can optionally set an environment variable
CIRCUP_WEBWORKFLOW_PASSWORD instead of passing this
argument. If both exist the CLI arg takes precedent.
--timeout INTEGER Specify the timeout in seconds for any network
operations.
--version Show the version and exit.
--help Show this message and exit.
Commands:
get Download a copy of a file or directory from the device to the...
ls Lists the contents of a directory.
put Upload a copy of a file or directory from the local computer to...
rm Delete a file on the device.
Note
If you find a bug, or you want to suggest an enhancement or new feature feel free to create an issue or submit a pull request here:
Discussion of this tool happens on the Adafruit CircuitPython Discord channel.
Contributing¶
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. Participation covers any forum used to converse about CircuitPython including unofficial and official spaces. Failure to do so will result in corrective actions such as time out or ban from the project.
Licensing¶
By contributing to this repository you are certifying that you have all necessary permissions to license the code under an MIT License. You still retain the copyright but are granting many permissions under the MIT License.
If you have an employment contract with your employer please make sure that they don’t automatically own your work product. Make sure to get any necessary approvals before contributing. Another term for this contribution off-hours is moonlighting.
Developer Setup¶
Note
Please try to use Python 3.10+ while developing Circup. This is so we can use the Black code formatter and so that we’re supporting versions which still receive security updates.
Clone the repository and from the root of the project,
If you’d like you can setup a virtual environment and activate it.:
python3 -m venv .env
source .env/bin/activate
install the development requirements:
pip install -r optional_requirements.txt
Run the test suite:
pytest --random-order --cov-config .coveragerc --cov-report term-missing --cov=circup
How Does Circup Work?¶
The circup tool checks for a connected CircuitPython device by
interrogating the local filesystem to find a path to a directory which ends
with "CIRCUITPYTHON" (the name under which a CircuitPython device is
mounted by the host operating system). This is handled in the find_device
function.
A Python module on a connected device is represented by an instance of the
Module class. This class provides useful methods for discerning if the
module is out of date, returning useful representations of it in order to
display information to the user, or updating the module on the connected
device with whatever the version is in the latest Adafruit CircuitPython
Bundle.
All of the libraries included in the Adafruit CircuitPython Bundle contain,
somewhere within their code, two metadata objects called __version__ and
__repo__.
The __repo__ object is a string containing the GitHub repository URL, as
used to clone the project.
The __version__ object is interesting because within the source code in
Git the value is always the string "0.0.0-auto.0". When a new release
is made of the bundle, this value is automatically replaced by the build
scripts to the correct version information, which will always conform to the
semver standard.
Given this context, the circup tool will check a configuration file
to discern what it thinks is the latest version of the bundle. If there is
no configuration file (for example, on first run), then the bundle version is
assumed to be "0".
Next, it checks GitHub for the tag value (denoting the version) of the very
latest bundle release. Bundle versions are based upon the date of release, for
instance "20190904". If the latest version on GitHub is later than the
version circup currently has, then the latest version of the bundle
is automatically downloaded and cached away somewhere.
In this way, the circup tool is able to have available to it both a path
to a connected CIRCUITPYTHON devce and a copy of the latest version, including
the all important version information, of the Adafruit CircuitPython Bundle.
Exactly the same function (get_modules) is used to extract the metadata
from the modules on both the connected device and in the bundle cache. This
metadata is used to instantiate instances of the Module class which is
subsequently used to facilitate the various commands the tool makes available.
These commands are defined at the very end of the circup.py code.
Unit tests can be found in the tests directory. Circup uses
pytest style testing conventions. Test
functions should include a comment to describe its intention. We currently
have 100% unit test coverage for all the core functionality (excluding
functions used to define the CLI commands).
To run the full test suite, type:
pytest --random-order --cov-config .coveragerc --cov-report term-missing --cov=circup
All code is formatted using the stylistic conventions enforced by black. Python coding standard are enforced by Pylint and verification of licensing is handled by REUSE. All of these are run using pre-commit, which you can run by using:
pip install pre-commit
pre-commit run --all-files
Please see the output from pre-commit for more information about the various
available options to help you work with the code base.
Before submitting a PR, please remember to pre-commit run --all-files.
But if you forget the CI process in Github will run it for you. ;-)
Circup uses the Click module to run command-line interaction. The AppDirs module is used to determine where to store user-specific assets created by the tool in such a way that meets the host operating system’s usual conventions. The python-semver package is used to validate and compare the semver values associated with modules. The ubiquitous requests module is used for HTTP activity.
Documentation, generated by Sphinx,
is based on this README and assembled by assets in the doc subdirectory.
The latest version of the docs will be found on
Read the Docs.
Discussion of this tool happens on the Adafruit CircuitPython Discord channel.
API¶
Circup – a utility to manage and update libraries on a CircuitPython device.
License¶
MIT License
Copyright (c) 2019 Adafruit Industries
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.