# Python Tools Setup & Install

> Instructions to install and setup the Infuse-IoT Python tools.

The Infuse-IoT Python Tools can be installed on:

- Windows (Natively or using [WSL - Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/about)).
<tip>

Instructions for WSL falls under <icon name="i-simple-icons-linux">



</icon>

 Ubuntu and <icon name="i-simple-icons-gnubash">



</icon>

 Bash categories below.

</tip>
- Ubuntu + other Linux Distros.
- macOS.

## Prerequisites

<steps level="3">

### Install Python

Ensure a suitable version of [Python](https://www.python.org/downloads/) is installed on your system.
The Python Tools are tested with Python versions 3.10 through to 3.14.
Checking if Python is installed (and which version) can be done by running the following in your terminal.

```bash
python --version
```

<callout color="info" icon="i-lucide-info">

If ZephyrRTOS or Infuse-IoT is setup and working on your machine,
Python is already installed and setup, skip to [Installation](#installation).

</callout>

<tabs sync="OS">
<tabs-item label="Ubuntu" icon="i-simple-icons-linux">

```bash
sudo apt install python3-dev
```

</tabs-item>

<tabs-item label="macOS" icon="i-simple-icons:apple">

Avoid using macOS's built-in Python for development,
as it is managed by the operating system and used by system tools.
Installing a separate Python version helps avoids conflicts, and keeps your development environment isolated.

<steps level="3">

### Install Homebrew

If you don't already have Homebrew, you can install it by following Homebrew's
[installation instructions](https://brew.sh/).

### Install Python using Homebrew

```zsh
brew install python3
```

</steps>
</tabs-item>

<tabs-item label="Windows" icon="i-simple-icons-windows">

Windows has many ways in which Python can be installed:

- The Microsoft Store's [Python 3.12](https://apps.microsoft.com/detail/9ncvdn91xzqp)
- Windows' preinstalled package manager [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/)
(on Windows 11 and recent Windows 10 systems). `winget` installation can be verified by running `winget --version`
in the terminal. If it's missing, you can [install](https://aka.ms/getwinget) winget first.
```ps
winget install Python.Python.3.12
```
- The Python Homepage [Downloads](https://www.python.org/downloads/)

</tabs-item>
</tabs>

### Do you need a Virtual Environment

Python now requires virtual environments to avoid package conflicts.

The next steps depends on whether you:

- Already have your own virtual environment (or one using a different environment manager) for Infuse-IoT Python Tools, or
intend to use the same virtual environment created as part of an existing ZephyrRTOS or Infuse-IoT SDK installation.
- Don't have one (or know if you have one), but plan to install the Infuse-IoT embedded SDK, or
- Plan to use Infuse-IoT Python tools standalone (without the Infuse-IoT embedded SDK installed).

<tabs>
<tabs-item label="Existing Virtual Environment">

Skip to [Installation](#installation).

<tip>

Ensure your intended venv created is active before continuing.

</tip>
</tabs-item>

<tabs-item label="Plan to install Infuse-IoT">

The easiest way to setup the venv is to install the Infuse-IoT Embedded SDK.
Follow the Infuse-IoT
[Embedded SDK Getting Started Guide](https://docs.dev.infuse-iot.com/latest/guides/embedded/index.html)
to install the embedded SDK, and then continue to [Installation](#installation).

<tip>

If you can't install the entire Infuse-IoT embedded SDK right now, you can follow the steps found in
[Setting up a virutal env](#setup-a-virtual-environment-venv) to setup a virtual environment.
Just be sure to use the same venv when following the rest of the ZephyRTOS and Infuse-IoT embedded SDK
installations.

</tip>

<tip>

If you don't fully install the Infuse-IoT embedded SDK, keep a note of where you got up to,
So you don't forget where you left off when you resume setting up the SDK.

</tip>
</tabs-item>

<tabs-item label="Standalone">

The easiest method to install the Python Tools is to use `pipx` (instead of `pip`).

<warning>

If you need to use Infuse-IoT Python Tools with 3rd party tools, do not utilise `pipx`.
Instead ignore this step and skip to [Setup a Virtual Environment (.venv)](#setup-a-virtual-environment-venv)

</warning>

Run the following to install `pipx` depending on your OS.

<tabs sync="OS">
<tabs-item label="Ubuntu" icon="i-simple-icons-linux">

```bash
sudo apt install pipx
```

Or follow the instructions in the [pipx documentation](https://pipx.pypa.io/latest/how-to/install-pipx.html#linux)

</tabs-item>

<tabs-item label="macOS" icon="i-simple-icons:apple">

Follow the instructions in the [pipx documentation](https://pipx.pypa.io/latest/how-to/install-pipx.html#macos)

</tabs-item>

<tabs-item label="Windows" icon="i-simple-icons-windows">

Follow the instructions in the [pipx documentation](https://pipx.pypa.io/latest/how-to/install-pipx.html#windows)

</tabs-item>
</tabs>

Once `pipx` is installed, continue to [Installation](#installation),
noting to substitute `pip` with `pipx`.

</tabs-item>
</tabs>

### Setup a Virtual Environment (.venv)

Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html#get-zephyr-and-install-python-dependencies)
outlines the process to setup a virtual environment in `zephyrproject` (in your user profile/home directory).
Follow the instructions to setup a Virtual Environment.

<tip>

The Virtual Environment can be installed to a different location if desired,
but the corresponding commands will need to be changed to accomodate the new path.
Similarly, other Python Environment managers (e.g. Anaconda) can be used,
if you're comfortable doing so.

</tip>

<warning>

Once created, a virtual environment cannot be moved, so ensure the location is convenient.
However, a venv can be recreated by following the specific steps in the
[Infuse-IoT Getting Started Guide](https://docs.dev.infuse-iot.com/latest/guides/embedded/index.html#useful-tips)

</warning>

#### Don't forget to activate your environment

Remember to activate your virtual environment every time your start a new terminal before working with Infuse-IoT Python Tools,
or it won't function. With the default installation path, this can be done by running:

<tabs sync="terminal">
<tabs-item label="Bash/Zsh" icon="i-lucide-terminal">

```bash
source ~/zephyrproject/.venv/bin/activate
```

<tip>

If you do not usually use Python or only use this Python Virtual Environments, this line can be added to your
`.zshrc`/`.bashrc` to automatically launch the virtual environment when opening a shell to avoid needing to
type it each time. Otherwise using an alias can make it easier to switch between different venv's.

</tip>
</tabs-item>

<tabs-item label="Windows (CMD)" icon="i-lucide-terminal">

```text
zephyrproject\.venv\Scripts\Activate.bat
```

</tabs-item>

<tabs-item label="Windows (Powershell)" icon="i-vscode-icons-file-type-powershell">

```text
zephyrproject\.venv\Scripts\Activate.ps1
```

</tabs-item>
</tabs>
</steps>

## Installation

The Python tools can be installed from PyPI.

<warning>

Select the option depending on whether you are using a virtual environment (pip) or not (pipx)

</warning>

Utilise the following command to install Infuse-IoT Python Tools.

<tabs>
<tabs-item label="Using a venv (pip)">

```bash
pip install infuse-iot
```

<tip>

Ensure your venv is activated before installing.

</tip>
</tabs-item>

<tabs-item label="Not using a virtual environment (pipx)">

```bash
pipx install infuse-iot
```

</tabs-item>
</tabs>

Once installed, some additional setup required.

## Additional Setup

<steps level="3">

### Keyring

Infuse-IoT Python Tools utilises [Keyring](https://pypi.org/project/keyring/) to securely store secrets such as API
keys and caching Network Credentials and installs it as part of Infuse-IoT's installation.
Keyring is cross platform by utilising different backends on different OS's.

Check that Keyring is correctly setup by running:

```text
keyring --list-backends
```

This will output the supported backends on your machine such as:

```text
> keyring --list-backends
keyring.backends.chainer.ChainerBackend (priority: -1)
keyring.backends.fail.Keyring (priority: 0)
keyring.backends.SecretService.Keyring (priority: 5)
```

Search for a backend with a priority above 0.

<tabs sync="OS">
<tabs-item label="Ubuntu" icon="i-simple-icons-linux" sync="ubuntu">

Ubuntu and other distros won't always have a default credential provider.
The preferred predential storage provider is provided by
[gnome-keyring](https://gitlab.gnome.org/GNOME/gnome-keyring) and appears as:

`keyring.backends.SecretService.Keyring`.

It can be installed with:

```bash
sudo apt install gnome-keyring
```

</tabs-item>

<tabs-item label="macOS" icon="i-simple-icons:apple">

Apple's Keychain is the preferred credential storage provider and is preinstalled.
It appears as:

`keyring.backends.macOS.Keyring`.

</tabs-item>

<tabs-item label="Windows" icon="i-simple-icons-windows">

Windows Credential Locker is the preferred credential storage provider and is preinstalled.
It appears as:

`keyring.backends.Windows.WinVaultKeyring`.

</tabs-item>
</tabs>

### Setup Infuse-IoT Credentials

The Python tools interract with the Infuse-IoT cloud API to setup boards and run cloud RPCs.
To perform these tasks, the Python tools require a Cloud API key to authorise the commands.

These can either be:

- [Personal API Keys](https://portal.infuse-cloud.io/account/api-keys): For the same permissions you have.
- [Service Account Keys](https://portal.infuse-cloud.io/access/service-accounts): Useful for temporary access and/or scoped permissions.

Legacy Infuse-IoT admin keys are deprecated and being retired. Use a personal or service-account API key.

To create a profile with a name and your API key,
run the command below (replacing `[API_KEY]` with your API key).

<tip>

If your API starts with `Bearer `, omit this prefix

</tip>

```text
infuse profile configure --name [PROFILE_NAME] --api-key [API_KEY]
```

<tip>

API Keys are scoped to an organisation. If you manage multiple organisations, create a profiles per organisations
by using a different `--name` and the corresponding API key for that org.<br />


To switch between profiles run:

```text
infuse profile set --name [PROFILE_NAME]
```

to switch between them.

</tip>

<warning>

Some systems running WSL may have issues with keyring raising:

```text
secretstorage.exceptions.PromptDismissedException: Prompt dismissed
```

This is likely because WSL launches the distro headless.
Running the following command once should fix it.

```text
dbus-update-activation-environment --systemd DBUS_SESSION_BUS_ADDRESS DISPLAY XAUTHORITY
```

<accordion>
<accordion-item label="Keyring works until I restart WSL">

Try adding the command your `.bashrc`.

Then run `wsl --shutdown` from Command Prompt or PowerShell to restart WSL.

</accordion-item>

<accordion-item label="It's still not working?">

Try a Scorched Earth Reset (this will reset your keyring).

1. Remove gnome-keyring & keychains

```bash
sudo apt remove gnome-keyring
rm -rf ~/.local/share/keyrings/*
```

1. Reboot WSL (run in PowerShell or Command Prompt)

```ps
wsl --shutdown
```

1. Reopen a wsl prompt, Reinstall `gnome-keyring` and `seahorse`
gnome-keyring and seahorse:

```bash
sudo apt install gnome-keyring seahorse
```

1. Refresh dbus, Open Seahorse and follow the prompts to create a new password for the default keychain

```bash
dbus-update-activation-environment --all
seahorse
```

</accordion-item>
</accordion>
</warning>

When launching `infuse` it will attempt to unlock the keyring to access its credentials,
and you will receive a password prompt.

<tip>

For WSL users, this prompt will only ask for a password. This password will correspond to the user account
created inside WSL (not the account used to sign into Windows).

</tip>

### Register Autocomplete (Optional)

Enable Tab auto completion for the Python Tools.

<tabs sync="terminal">
<tabs-item label="Bash" icon="i-simple-icons-gnubash">

Add the following to your `.bashrc`

```bash
eval "$(register-python-argcomplete infuse)"
```

<tip>

If you auto-load your Virtual Environment in your `.bashrc`,
ensure to add this line afterwards.

</tip>
</tabs-item>

<tabs-item label="zsh" icon="i-simple-icons-zsh">

Add the following to your `.zshrc`.

```zsh
autoload -Uz compinit
compinit
eval "$(register-python-argcomplete infuse)"
```

<tip>

If you auto-load your Virtual Environment in your `.zshrc`,
ensure to add this line afterwards

</tip>
</tabs-item>

<tabs-item label="CMD/PowerShell" icon="i-lucide-terminal">

Tab Autocomplete is not supported on Windows terminals.

</tabs-item>
</tabs>

### Cache Network Credentials (Optional)

During development, Infuse-IoT SDK powered devices utilise a default, publicly available network key for encryption.
A custom, non-public network key may be used during development and should be used for releases.
For the Python tools to communicate with these devices, the encryption key must be registered with the Python Tools.
These custom keys are generated by the embedded SDK as a `.yaml`file and can be shared and imported into the Python
tools with:

```bash
infuse credentials --network network_key_file.yaml
```

### Load Project Specific Definitions & Scripts (Optional)

If you're using a custom project that includes custom definitions (for RPCs, TDFs, KV, etc), you can import those
into the Python tools.

Import custom tools:

```bash
python credentials --custom-tools /path/to/tools_folder
```

<tip>

If your embedded SDK project contains custom tools, they will typically be found under the project's
`scripts/tools` folder

</tip>

Import custom definitions:

```bash
python credentials --custom-definitions /path/to/definitions_folder
```

<tip>

If your embedded SDK project contains custom tools, they will typically be found under the project's `generated` folder

</tip>
</steps>

## Updating

If you are running an outdated version of the Infuse-IoT Python tools
and want to update your installation run:

```text
pip install --upgrade infuse-iot
```

## Development

Updating or Fixing the Infuse-IoT Python Tools?

All of the above methods utilises pre-archived packages (wheels), and this means that the source code cannot be easily changed.
To setup an editable installation, clone the repo and install using the `-e` editable flag:

```bash
git clone git@github.com:Embeint/python-tools.git
cd python-tools
pip install -e .
```

<caution>

If Infuse-IoT python tools were installed using `pipx`, it could be a path resolution override.
Ideally remove the Infuse-IoT Python Tools installation on pipx before continuing. It can always to reinstalled later on.

</caution>

This will cause the Infuse-IoT Python tools to run in an editable mode
ensuring that changes to your local environment are included at runtime.

<tip>

By editable, code changes will only be applied after corresponding tools have been closed and re-openned.

</tip>

<warning>

Running the Infuse-IoT Python Tools in editable mode may
cause the tools to run slower or less responsively, especially for tab completion. As a result it's not advisable to do so permanently.

</warning>

<style>

html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}

</style>

---

- [Open in PyPI](https://pypi.org/project/infuse-iot/)
- [Source repository](https://github.com/Embeint/python-tools)
