Package and deploy a module

At this point you should have a working module, deployed locally on a machine for testing. To make it available to deploy on more machines, the following steps will show you how to package it and upload it to the registry.

Prepare the module for upload

1

Create a README (strongly recommended)

It’s quite helpful to create a README to document what your module does and how to configure and use it, especially if you plan to share your module with others.

Example sensor module README
# `meteo_PM` modular component

This module implements the [Viam sensor API](https://docs.viam.com/dev/reference/apis/components/sensor/) in a `jessamy:weather:meteo_PM` model.
With this model, you can gather [Open-Meteo](https://open-meteo.com/en/docs/air-quality-api) PM2.5 and PM10 air quality data from anywhere in the world, at the coordinates you specify.

Navigate to the **CONFIGURE** tab of your machine's page.
Click the **+** button, select **Component or service**, then select the `sensor / weather:meteo_PM` model provided by the [`weather` module](https://app.viam.com/module/jessamy/weather).
Click **Add module**, enter a name for your sensor, and click **Create**.

## Configure your `meteo_PM` sensor

On the new component panel, copy and paste the following attribute template into your sensor's **Attributes** box:

```json
{
  "latitude": <float>,
  "longitude": <float>
}
```

### Attributes

The following attributes are available for `rdk:sensor:jessamy:weather:meteo_PM` sensors:

| Name        | Type  | Inclusion | Description                            |
| ----------- | ----- | --------- | -------------------------------------- |
| `latitude`  | float | Optional  | Latitude at which to get the readings  |
| `longitude` | float | Optional  | Longitude at which to get the readings |

### Example Configuration

```json
{
  "latitude": -40.6,
  "longitude": 93.125
}
```
2

Create a GitHub repo and link to it from your meta.json

Create a GitHub repository with all the source code and the README for your module. This is required for cloud build to work.

3

Add the link to the repo to the meta.json file

Add the link to that repo as the url in the meta.json file.

4

Edit the meta.json file

Make any necessary edits to the meta.json file. For example, if you’ve changed the module’s functionality, update the description in the meta.json file. Click below for information about the available fields.

If you want to share the module outside of your organization, set "visibility": "public".

meta.json reference
NameTypeInclusionDescription
module_idstringRequiredThe module ID, which includes either the module namespace or organization ID, followed by its name.
visibilitystringRequiredWhether the module is accessible only to members of your organization (private), or visible to all Viam users (public). You can later make a private module public using the viam module update command. Once you make a module public, you can change it back to private if it is not configured on any machines outside of your organization.
urlstringRequired for cloud buildThe URL of the GitHub repository containing the source code of the module. Cloud build will fail if you do not provide this. Optional for local modules.
descriptionstringRequiredA description of your module and what it provides.
modelsarrayOptional

A list of one or more models provided by your custom module. You must provide at least one model in the models array or one application in the applications array. A model consists of an api and model key pair. If you are publishing a public module ("visibility": "public"), the namespace of your model must match the namespace of your organization.

You are strongly encouraged to include a markdown_link to the section of the README containing configuration information about each model, so that the section will be displayed alongside the configuration panel when configuring the model. For example, "README.md#configure-your-meteo_pm-sensor". Please also include a short_description describing what hardware the model supports.

entrypointstringOptionalThe name of the file that starts your module program. This can be a compiled executable, a script, or an invocation of another program. If you are providing your module as a single file to the upload command, provide the path to that single file. If you are providing a directory containing your module to the upload command, provide the path to the entry point file contained within that directory. Required if you are shipping a model.
buildobjectOptionalAn object containing the command to run to build your module, as well as optional fields for the path to your dependency setup script, the target architectures to build for, and the path to your built module. Use this with the Viam CLI's build subcommand.
  • "setup" (Optional): Command to run for setting up the build environment.
  • "build" (Required): Command to run to build the module tarball.
  • "path" (Optional): Path to the build module tarball.
  • "arch" (Required): Array of architectures to build for. For more information see Supported platforms for automatic updates.
  • "darwin_deps" (Required): Array of homebrew dependencies for Darwin builds. Explicitly pass [] for empty. Default: ["go", "pkg-config", "nlopt-static", "x264", "jpeg-turbo", "ffmpeg"]
markdown_linkstringOptionalLink to the documentation (README) for this module. Viam uses this to render your README on your module's page in the registry. Similar to the markdown_link within the models object (described above), which allows the app to render info for a specific model in the configuration panel.
$schemastringOptionalEnables VS Code hover and autocomplete as you edit your module code. Gets auto-generated when you run viam module generate or viam module create. Has no impact on the module's function.
applicationsarrayOptionalObjects that provide information about the applications provided by the module.

Package and upload the module

1

Package and upload

To package (for Python) and upload your module and make it available to configure on machines in your organization (or in any organization, depending on how you set visibility in the meta.json file):

The recommended approach for Python is to use PyInstaller to compile your module into a packaged executable: a standalone file containing your program, the Python interpreter, and all of its dependencies. When packaged in this fashion, you can run the resulting executable on your desired target platform or platforms without needing to install additional software or manage dependencies manually.

Edit your meta.json file back to its original state, reverting the edits you made for local testing purposes. It should resemble the following:

 "entrypoint": "dist/main",
 "first_run": "",
 "build": {
   "build": "./build.sh",
   "setup": "./setup.sh",
   "path": "dist/archive.tar.gz",
   "arch": [
     "linux/amd64",
     "linux/arm64"
   ]
 }

Delete the reload.sh script since it was only meant for testing purposes.

Now you are ready to build and upload your module, either using Viam’s cloud build tooling which is recommended for continuous integration, or a more manual process:

We recommend you use PyInstaller with the build-action GitHub action which provides a simple cross-platform build setup for multiple platforms: x86 and Arm Linux distributions, and MacOS.

The viam module generate command already generated the build-action file in your .github/workflows folder, so you just need to set up authentication in GitHub, and then create a new release to trigger the action:

  1. In your terminal, run viam organizations list to view your organization ID.

  2. Create an organization API key by running the following command:

    viam organization api-key create --org-id YOUR_ORG_UUID --name descriptive-key-name
    
  3. In the GitHub repo for your project, go to SettingsSecrets and variablesActions. Create two new secrets using the New repository secret button:

    • VIAM_KEY_ID with the UUID from Key ID: in your terminal
    • VIAM_KEY_VALUE with the string from Key Value: in your terminal
  4. From the main code page of your GitHub repo, find Releases in the right side menu and click Create a new release.

  5. In the Choose a tag dropdown, create a new tag with a name consisting of three numbers separated by periods, following the regular expression [0-9]+.[0-9]+.[0-9]+ (for example, 1.0.0). You must follow this format to trigger the build action. For details about versioning, see Module versioning.

  6. Click Publish release. The cloud build action will begin building the new module version for each architecture listed in your meta.json, and any machines configured to use the latest release of the module will receive the update once it has finished building.

See Update an existing module using a GitHub action for more information.

From within the module directory, create a virtual Python environment with the necessary packages and then build an executable by running the setup and build scripts:

sh setup.sh
sh build.sh

Run the viam module upload CLI command to upload the module to the registry. If your module can only be run on Linux or macOS, for example due to platform-specific dependencies, replace any with linux/any or darwin/any, respectively. If your module runs on all platforms, keep any:

viam module upload --version 1.0.0 --platform any dist/archive.tar.gz

For details on platform support, see Using the --platform argument.

For details about versioning, see Module versioning.

You can use the following package and upload method if you opted not to enable cloud build when you ran viam module generate.

  1. Package the module as an archive by running the following command from inside the module directory:

    tar -czf module.tar.gz run.sh setup.sh requirements.txt src meta.json
    

    where run.sh is your entrypoint file, requirements.txt is your pip dependency list file, and src is the directory that contains the source code of your module.

    This creates a tarball called module.tar.gz.

  2. Run the viam module upload CLI command to upload the module to the registry. If your module can only be run on Linux or macOS, for example due to platform-specific dependencies, replace any with linux/any or darwin/any, respectively. If your module runs on all platforms, keep any:

    viam module upload --version 1.0.0 --platform any module.tar.gz
    

    For details on platform support, see Using the --platform argument.

    For details about versioning, see Module versioning.

From within your module’s directory, run the viam module upload CLI command to upload the module to the registry. If your module can only be run on Linux or macOS, for example due to platform-specific dependencies, replace <platform> with linux/amd64, linux/arm64, or another platform.

viam module upload --version 1.0.0 --platform <platform> .

For details about versioning, see Module versioning.

2

If you look at the Viam Registry page while logged into your account, you’ll be able to find your module listed.

3

If your module supports hardware, add the hardware name in the Components & services section on the module registry page under the heading Supported hardware.

For information about updating modules, see Update and manage modules you created.

Use your uploaded module

Once your module is in the registry, you can use the registry version of your module on machines. Configure it just as you would configure any other component or service in the registry:

  1. Go to your machine’s CONFIGURE tab.

  2. Click the + button.

  3. Select Component or service, and search for and select your model. If you cannot find your new module, it may be private and not accessible to the organization you are in. Check that you are in an organization that can access the module.

  4. Click Add module.

  5. Enter a name for your resource and click Create.

  6. If the module has requires attributes, configure them.

  7. Click Save.

Your module will now be added to your machine.

If you used a local module for testing, you can safely delete it.