Thanks to some hard work by Vladimir Kotal (@vladak)❤️, an open-source community contributor on GitHub who added this pull request, and thanks to our own CircuitPython wizard Tim (@foamyguy), there is now the ability to use circup
with the web-workflow.
I had a play by pulling from github last month as I was desperate. I had a device that was going to be left plugged into the mains, which was running out-of-date code and libraries (but otherwise functional), and so along the way fixed a couple of issues for Windows users or anyone needing libraries with nested folders.
Install circup
, at least version 1.6.1:
To begin with we'll explore how install and to use it, then I'll take you through my specific example...
Install latest CIRCUP:pip install circup --force
[ --force forcefully overwrites / upgrades]
Read help and test CIRCUP has new --host command line argument:
Enter the circup command followed by the --help argument. Most commands support --help or --usage:
circup --help
You should then see the following output, which mentions the --host
, --password
, --path
, and --verbose
, all of which can be very useful, but only the first two are required.
The other one I read about in the pull-request was --auto-file
which is where circup searches when automatically installing required libraries using the --auto
install option.
Lastly it doesn't mention my favourite install option --py
which installs the source python files for libraries rather than the compressed .mpy files, thereby allowing library modifications or just easy reference.
Before you can connect to your device over web workflow, it needs to be configured for wifi... You'll see accessing via the IP address, but a future update should allow you to connect using the generic hostname circuitpython.local
For now read on, the guide will be updated once that's a seamless process (currently you get told not authenticated and it reports the devices .local name instead, which you can directly connect to as the host argument).
We start by assuming you've got a settings.toml
file setup with the normal things and the web api password key, CIRCUITPY_WEB_API_PASSWORD
, something like this:
CIRCUITPY_WIFI_SSID="free4all"
CIRCUITPY_WIFI_PASSWORD="password"
CIRCUITPY_WEB_API_PASSWORD="good-enough"
CIRCUITPY_WEB_INSTANCE_NAME="good enough Air Quality (CO2/VOC/PPM)"
Then we can try to connect to the device. This means using the web workflow, which can be accessed via IP address or using multicast-DNS (mDNS), but IP based communication is most reliable so we'll go for that option, and only rely on mDNS to find the IP of our device if necessary.
You'll want to find your devices IP, it shows up in the CircuitPython REPL, and my device has a screen so it tells me the IP, but you can usually find it on your wireless router web control page (URL = ip of your wifi router - sometimes port 8080 search google) e.g. mine is at http://192.168.0.1/
Lastly CircuitPython includes mDNS, so if your PC + network allow it then you can connect to the CircuitPython's web workflow page using the address circuitpython.local
, e.g. http://circuitpython.local/, and from there it should list other CircuitPython devices and give clickable links to their respective web workflows. That's the same technology that allows https://code.circuitpython.org/ to work (it becomes circuitpython.local/code)
Once on a devices web workflow page then it says the devices IP along with name etc.
From here you can goto the file browser and confirm the password is working as expected, along with check the library modules and files on the device.
Stumbling blocks: Potential Issues with circup
or device:
1️⃣ Device not found - "Could not find a connected CircuitPython device."
This occurs when the usb cable is no good for data, or most likely when the device has a drive/disk label that doesn't match CIRCUITPY. You can fix that on windows with the label
command followed by the drive location.
e.g. label d:
for the D:\ drive, then type CIRCUITPY and press enter/return when asked for the new label.
2️⃣ Can't automatically detect and install libraries to install - "Auto file not found: code.py"
You'll need to specify the auto-file location, using the --auto-file
command-line argument, discussed later.
e.g. circup install --auto --py --auto-file=D:\code.py
3️⃣ Something else:
Check the official circup help/documentation: https://github.com/adafruit/circup?tab=readme-ov-file#circup
Read the learn guide https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup.
Ask for help in the #help-with-circuitpython Discord channel (adafru.it/discord) or the Adafruit forums.
It could equally be a bug rather than user error, if you believe so then leave the bug report along with a minimum recreation code example in a github issue on the circup repository. Last resort, reset your bootloader and board using the section at the end of the CircuitPython downloads page for your board.
Checking for outdated modules on device:
As we saw when we got the help output from circup, it showed at the bottom the list of sub-commands. The first we'll look at is list
, which is the subcommand that lists the modules on the device, and shows if they are outdated.
Sometimes it wont be able to detect if the version is outdated and will assume it is. Probably the safer option for new users, but dangerous if you modify library files manually so take note, the default option for update is 'No' though so don't fear!
So with the knowledge that my devices IP address is 192.168.0.150, and the password is good-enough then I run this:
circup --host 192.168.0.150 --password good-enough list
Updating outdated modules
If you use the update
subcommand, then it asks you whether to update each outdated module, defaulting to N for no to updating that specific module. If you add the -y
argument then it will upgrade all outdated modules.
I ran it without -y and then answered yes to the update question (by typing y
then pressing Enter/Return) like this:
circup --host 192.168.0.150 --password good-enough update
Which looked like this in my powershell terminal window:
Uninstall a module, or many...
You may find the installed copy of a library is not working correctly, or you wish to replace it with an updated version or the raw python files. In this case you'll want to uninstall a library from your device.
Simply use the uninstall
subcommand and pass along the names of the libraries to uninstall, for example here I attempt to uninstall two libraries:
circup --host 192.168.0.150 --password good-enough uninstall sensirion_i2c_sen5x sensirion_i2c_driver
If you ever have any problems here just delete the folders using the web workflow page instead.
You'll receive something like this if they have already been deleted or if the folders are empty:
Install Modules:
As expected the install
subcommand is your best friend.
It has the additional arguments --auto
which will look at the auto-file (code.py by default) and find all import statements, then install those as dependencies.
By default to save space, all library modules are installed as compressed .mpy files, which is really handy, but occasionally you'll want to have the source code copy of the library installed. In that event uninstall the .mpy version first if required, then use the --py
argument to ask for source versions of the installed libraries. It combines with --auto well, for example on a local device:
circup install --auto --py
or with the additional web workflow arguments:
circup --host 192.168.0.150 --password good-enough install --auto --py
Final Useful Arguments
--timeout
The --timeout argument which allows you to specify the HTTP timeout value in seconds, stopping circup from waiting forever for your device to respond. The timeout argument defaults to 30seconds.
--verbose
This gives extra logging information which shows what circup is doing during it's normal processes.
My Use-Case - Installing nested files and folders with dependencies
So for my example (an Air Quality device) I wanted to install a custom circuitpython bundle first, to allow access to the CircuitPython library for the Sensirion SEN55/SEN54/SEN50 (SEN5x) series of particle sensors. The complication was the sen5x driver has a commands folder with more source files inside, which tripped up circup until I fixed it.
I also was uninstalling the existing circup copy, to ensure my git version is the only one active.
Lastly I wanted to uninstall the existing copies of the libraries and install new ones in python format using the --py command line argument.
This string of commands (5 lines/sets of commands) will execute safely in most terminals (tested in powershell).
pip install circup --force
circup --host 192.168.0.150 --password password bundle-add good-enough-technology/circuitpython_goodenough_bundle
circup --host 192.168.0.150 --password password uninstall sensirion_i2c_driver sensirion_i2c_sen5x
circup --host 192.168.0.150 --password password install --auto --py