Skip to content

Configuration

cxg can be configured through YAML config files and/or environment variables. Config files are useful for setting persistent default filters and display preferences so you don't need to repeat CLI flags on every invocation.

Precedence

When the same setting is specified in multiple places, cxg uses this precedence order:

  1. CLI flags (highest priority)
  2. Environment variables
  3. Project config file
  4. User config file
  5. Hardcoded defaults (lowest priority)

For list-type filter options (organism, tissue, etc.), a higher-priority value replaces the lower-priority value entirely. Values are never merged across levels. If your user config sets organism: [Mus musculus] and a project config sets organism: [Homo sapiens], only Homo sapiens is used.

Config file levels

cxg supports user- and project-level config files.

User config

Personal preferences that apply everywhere.

  • Linux: ~/.config/cxg/config.yml
  • macOS: ~/Library/Application Support/cxg/config.yml

Override the location with the CXG_CONFIG_FILE environment variable:

export CXG_CONFIG_FILE=~/my-cxg-config.yml

Project config

Project-specific overrides that apply when working in a particular directory tree.

  • Filename: cxg.yml in the current directory or any parent directory

cxg walks up from the current working directory looking for cxg.yml, stopping at the filesystem root.

Merging

When both a user config and a project config exist they are merged with project-level configuration taking precedence.

  • Dict sections (like defaults, display) are merged recursively: only the keys present in the higher-priority file override the lower-priority values
  • Scalar values (like display.output) are replaced entirely
  • List values (like defaults.organism) are replaced entirely
  • Keys not present in the higher-priority file are preserved from the lower-priority file

For example, with this user config:

defaults:
  organism:
    - Mus musculus
  tissue:
    - brain
display:
  limit: 50

And this project config (cxg.yml):

defaults:
  organism:
    - Homo sapiens
display:
  output: json

The effective merged config is:

defaults:
  organism:           # replaced by project
    - Homo sapiens
  tissue:             # preserved from user
    - brain
display:
  output: json        # added by project
  limit: 50           # preserved from user

Config file structure

# yaml-language-server: $schema=<path-to-schema>
defaults:
  organism:
    - Mus musculus
  disease:
    - normal

display:
  output: table
  columns: title,organism,tissue,cell_count
  limit: 50
  sort_by: cell_count desc

cache:
  ttl: 43200
  dir: ~/my-cache

api:
  base_url: https://api.cellxgene.cziscience.com/curation/v1

Sections

defaults

Default filter values applied when the corresponding CLI flag is omitted. Each filter accepts a list of strings.

Key Description
organism Default organism filter
tissue Default tissue filter
assay Default assay filter
cell_type Default cell type filter
disease Default disease filter
suspension_type Default suspension type filter

display

Display preferences for list output.

Key Type Description
output table, json, or tsv Output format
columns string Comma-separated list of columns
limit integer (>= 1) Maximum number of results
sort_by string Sort key and direction, e.g. cell_count desc

cache

Cache behavior settings. See Cache for details.

Key Type Description
ttl integer (>= 0) Cache time-to-live in seconds
dir string Override cache directory path

api

API connection settings.

Key Type Description
base_url string CELLxGene API base URL

IDE autocompletion

A JSON Schema is bundled with cxg and can provide autocompletion and validation in editors that support yaml-language-server. When cxg config set creates a new user config file, it automatically adds the schema directive as a comment at the top.

To add it manually, find the schema path and add it to the first line of your config file:

cxg config path --schema
# yaml-language-server: $schema=/path/to/cxg/schemas/config.schema.json

Validation

Config files are validated on load using Pydantic. If a file contains invalid values (wrong types, unknown keys, out-of-range numbers), cxg prints a warning to stderr and falls back to default settings.

Managing config files

cxg config subcommands follow the gh config pattern. All commands accept a --level option to target either the user or project config.

# User config path (default)
cxg config path

# Project config path
cxg config path --level project

View current settings

# Show merged config from all levels
cxg config list

# Show only user-level config
cxg config list --level user

# Show only project-level config
cxg config list --level project

Read a specific value

Use dot-notation to access nested keys:

# Read from merged config (default)
cxg config get defaults.organism

# Read from a specific level
cxg config get defaults.organism --level user

Set a value

# Set in user config (default)
cxg config set display.output json
cxg config set cache.ttl 3600

# Set in project config (writes cxg.yml in current directory)
cxg config set defaults.organism "Homo sapiens" --level project

# Set a single-element list (filter defaults)
cxg config set defaults.organism "Mus musculus"

# Set multiple values with commas
cxg config set defaults.organism "Mus musculus,Homo sapiens"

The set command creates the config file if it doesn't exist.

Environment variables

Environment variables override config file values but are overridden by CLI flags.

CXG_CONFIG_FILE

Path to the user config file. Overrides the default OS-appropriate location. Does not affect project config discovery.

export CXG_CONFIG_FILE=~/my-cxg-config.yml

CXG_CACHE_TTL

Cache time-to-live in seconds. Default: 86400 (24 hours).

Set to 0 to disable caching entirely and always fetch fresh data from the API.

export CXG_CACHE_TTL=86400

CXG_CACHE_DIR

Override the cache directory.

export CXG_CACHE_DIR=~/.my-cxg-cache

CXG_API_BASE_URL

Override the CELLxGene API base URL.

export CXG_API_BASE_URL=https://custom-api.example.com/v1

NO_COLOR

Disable colored output. Follows the NO_COLOR convention.

export NO_COLOR=1