Skip to main content

mono CLI Tool

Introduction

mono is a command-line interface (CLI) tool designed to streamline development workflows within our monorepository. It acts as a wrapper around our actual package manager (uv). Its primary goals are:

  • Simplify unintuitive behaviors in a monorepository
  • Customization of the development experience based on your team or needs
  • Provide shortcut commands for common tasks

Mono in 1 minute

# Initialize your environment
mono init [profile]

# Sync dependencies (install/remove/update)
mono sync

# Add a package
# Packages have to be added to a specific project (= a folder in apps/ or libs/)
# Example: mono add shared pandas openpyxl
# -> adds the packages pandas and openpyxl to the shared project (at libs/shared)
mono add <PROJECT> <PACKAGE>

# Remove a package
# Same as add, packages are managed at the project-level, so mono remove requires a target project
mono remove <PROJECT> <PACKAGE>

# Run a script
# mono run also has custom entries for Dagster, the data-tools server, etc... See below.
mono run path/to/script.py

Profiles

Working in a large monorepo can be complex, no doubt about that. Since not everyone will require the same setup, Mono introduces the concept of profiles. They are used to customize your development environment based on your needs, while working in the same codebase as everyone else.

There are currently two profiles:

  • all, the default profile that installs all projects and dependencies
  • process-eng, a profile designed to work in the aspen project (apps/aspen) and function well on Windows

When you first initialize your local environment with mono init [profile], a mono.toml file will be created at the root of the repository. This file is ignored by Git and stores your personal configuration.

If you run any Mono command without a mono.toml file, a default one will automatically be created.

Currently, Mono only stores the profile you use, which determines which projects get installed. If new profiles or further customization needs arise, please reach out to Erwin.

Commands

init

Initializes the mono.toml configuration file, installs all dependencies for the chosen profile, and sets up additional development utilities.

mono init [PROFILE] [--overwrite]

Arguments:

  • PROFILE (Optional): The profile to initialize the configuration with (e.g., 'all', 'process-eng'). If omitted, it uses a default profile.

Options:

  • --overwrite: If mono.toml already exists, this flag forces it to be overwritten with the specified profile's configuration.

Notes:

  • Installs nbstripout to automatically remove ignore the cell outputs in Jupyter notebooks when creating a commit, as they can get pretty heavy (images, long logs...)

sync

Automatically installs, removes, and updates dependencies in your local environment (this is called "synchronizing the environment"). The dependencies are based on the currently active profile and the dependencies defined in the pyproject.toml configuration of each project.

mono sync [PACKAGE] [--prod]

Arguments:

  • PACKAGE (Optional): Sync only a specific package in the workspace (e.g., 'datasmart'). When specified, only that package and its dependencies are synced.

Options:

  • --prod: Sync only production dependencies (exclude dev dependencies). Useful for testing that code works correctly in production-like environments.

Examples:

# Sync all dependencies for current profile
mono sync

# Sync only datasmart package
mono sync datasmart

# Sync datasmart with production dependencies only (no pytest, ruff, etc.)
mono sync datasmart --prod

use

Switches the active profile in mono.toml to the specified one and then automatically runs sync to update your environment's dependencies.

mono use <PROFILE>

Arguments:

  • PROFILE (Required): The profile to switch to. Valid profiles are listed in the command's help message (currently derived from mono.config.PROFILES).

Example:

mono use process-eng

add

Adds one or more Python packages to a specific workspace member or package group defined in pyproject.toml.

This is a very thin wrapper that just runs uv add --package <PROJECT> <PACKAGES> <FLAGS>. Its only job is to enforce a destination package, to avoid installing a dependency in the root pyproject.toml that will be imposed on all projects.

mono add <PROJECT> <PACKAGES>... [-- <FLAGS>]

Arguments:

  • PROJECT (Required): The workspace project to add the packages to (e.g., 'shared', 'data-infrastructure', 'aspen').
  • PACKAGES (Required): One or more Python package names to add.
  • FLAGS (Optional): Additional flags for uv add

Example:

mono add datasmart numpy pandas --extra some-extra

remove

Removes one or more Python packages from a specific workspace member or package group. It uses uv remove and then re-syncs all dependencies.

mono remove <PROJECT> <PACKAGES> [<FLAGS>]

Arguments:

  • PROJECT (Required): The workspace project to remove the packages from.
  • PACKAGES (Required): One or more Python package names to remove.
  • FLAGS (Optional): Additional flags for uv remove

Example:

mono remove datasmart numpy pandas

upgrade

Upgrades one or more packages across all projects. This command runs uv sync -P <PACKAGE> for each specified package.

mono upgrade <PACKAGES>... [<FLAGS>]

Arguments:

  • PACKAGES (Required): One or more Python package names to upgrade.
  • FLAGS (Optional): Additional flags to pass to the underlying sync command.

Example:

mono upgrade numpy pandas

run

Executes specific tools, applications, or Python scripts within the monorepo's environment using uv run.

mono run <TOOL | SCRIPT_PATH> [<ARGS>]

Arguments:

  • TOOL | SCRIPT_PATH (Required):
    • The name of a predefined tool/app (e.g., 'data-tools', 'dagster').
    • Or, the path to a Python script (.py) to execute.
  • ARGS (Optional): Arguments or flags for the underlying tool or script being executed.

Examples:

# Run a Python script and pass arguments to it
mono run apps/my_script.py --input data.csv --verbose

# Run the 'data-tools' application (Streamlit) and pass a port flag
mono run data-tools --server.port 8502

# Run the 'dagster' development server
mono run dagster

materialize

Materializes one or more Dagster assets locally. This is useful for testing, debugging, or running assets outside of the Dagster UI.

mono materialize <ASSETS>... [--from-prod | --from-dev] [--silent] [--file FILE]

Arguments:

  • ASSETS (Required): One or more Dagster asset keys to materialize. Supports comma-separated values.

Options:

  • --from-prod / --from-dev: Control where upstream inputs are read from. Default is --from-dev.
  • --silent, -s: Suppress all output.
  • --file, -f: Read asset keys from a file (newline- or comma-separated). Combined with positional ASSETs.

Examples:

# Materialize a single asset (reads inputs from dev by default)
mono materialize xrf_simplified

# Materialize multiple assets
mono materialize xrf_simplified xrd_profex

# Materialize with production inputs
mono materialize xrf_simplified --from-prod

# Materialize assets from a file
mono materialize --file assets.txt

Notes:

  • By default, upstream inputs are read from the dev database. Use --from-prod to read from production instead.
  • Requires the datasmart, database, and dagster-tools packages to be installed. If you get import errors, try mono use all followed by mono sync.

review

The review command group provides tools for comparing dev and prod data during development. There are two subcommands:

review asset

Compare dev vs prod tables for a single Dagster asset using an interactive TUI.

mono review asset [ASSET_KEY] [--primary-key COLUMNS] [--table SCHEMA.TABLE]

Arguments:

  • ASSET_KEY (Optional): Asset key to review. If omitted, opens an interactive picker to select an asset.

Options:

  • --primary-key: Comma-separated primary key columns for row-level comparison.
  • --table: Override the table reference as schema.table.

Examples:

# Open interactive asset picker
mono review asset

# Review a specific asset
mono review asset xrf_simplified

# Review with custom primary key for better diff detection
mono review asset xrf_simplified --primary-key sample_id,oxide

review sharepoint-asset

Review and triage differences between dev and prod for SharePoint-backed assets. Useful for validating data pipelines that ingest files from SharePoint.

mono review sharepoint-asset [OP] [--non-interactive] [--json]

Arguments:

  • OP (Optional): SharePoint asset op name (e.g., xrf_incremental). If omitted, shows all reviews across all assets.

Options:

  • --non-interactive: Create a new review, evaluate, and exit with pass/fail code. Useful for CI.
  • --json: Output evaluation results as JSON (for CI parsing). Requires --non-interactive.

Examples:

# Show all reviews across all assets
mono review sharepoint-asset

# Open/create review for a specific asset
mono review sharepoint-asset xrf_incremental

# CI mode: evaluate and exit with status code
mono review sharepoint-asset xrf_incremental --non-interactive

# CI mode with JSON output
mono review sharepoint-asset xrf_incremental --non-interactive --json

Notes:

  • Interactive mode launches a TUI where you can triage file differences (mark as expected, investigate issues, etc.).
  • Reviews are stored in .reviews/ folders and can be resumed across sessions.
  • The --non-interactive mode is designed for CI pipelines to validate that SharePoint data hasn't unexpectedly changed.

Developing Mono

Mono exists as a project within the monolith codebase. You will find it within apps/mono and the commands are defined in apps/mono/src/mono/main.py.