Skip to content

Getting Started

Install the project in editable mode with development dependencies:

uv sync --extra dev

Or with pip:

python -m pip install -e ".[dev]"

The project-level FastAPI surface is optional. Install it only for public API work:

uv sync --extra public_api

Verify that the import package is available:

import msm

Install ms-markets agent skills into a host project only through the explicit CLI command:

msm copy-msm-skills --path .

This copies the packaged skill bundle into .agents/skills/ms_markets/. Importing msm does not write files, create .agents/, or auto-install skills.

Run this command only from a separate host project. The CLI blocks msm copy-msm-skills --path . inside the ms-markets source checkout because the destination would overlap the package's own skill source.

Documentation

Serve the documentation locally:

mkdocs serve

Build the static documentation site:

mkdocs build

Architecture Decisions

Implementation decisions should be recorded under docs/ADR.

First Market Setup

Start with the typed row API for simple workflows:

mainsequence migrations upgrade --provider migrations:migration head
import msm

from msm.api.assets import Asset, AssetCategory, AssetType

msm.start_engine(models=["AssetType", "Asset", "AssetCategory"])

AssetType.upsert(asset_type="crypto", display_name="Crypto")

asset = Asset.upsert(unique_identifier="example-asset-btc", asset_type="crypto")
assets = Asset.filter(asset_type="crypto")

category = AssetCategory.upsert(
    unique_identifier="example-crypto",
    display_name="Example Crypto",
)

This follows the library-wide convention: user code works with Pydantic row objects, while schema code works with SQLAlchemy *Table declarations. Asset.upsert(...) and Asset.filter(...) use the active markets runtime. They do not attach to MetaTables or create schemas on first use.

For application startup that wants a controlled runtime preflight, attach directly:

import msm

runtime = msm.start_engine()
context = runtime.context
asset_table = runtime.table("Asset")

That startup preflight resolves already-registered backend MetaTable and TimeIndexMetaTable resources by each selected model's SQLAlchemy table name. Missing backend tables fail startup and should be fixed through the SDK migration upgrade flow.

For development examples that should use an example namespace, set MSM_AUTO_REGISTER_NAMESPACE before importing msm.api, then call msm.start_engine(...) during startup. That namespace also becomes the default namespace for markets DataNode identifiers and hash_namespace values created in the same process.

Every markets MetaTable now has a user-facing row model under msm.api.*. Legacy imports such as from msm.models import Asset have been removed; use from msm.api.assets import Asset for row operations and from msm.models import AssetTable for SQLAlchemy schema declarations.

Treat explicit runtime attachment as process startup work: run it once during application initialization after admin migrations are current. Repeated calls with the same arguments return the cached runtime; different arguments are rejected for that process. See MetaTable Registration, Migrations, and Market Workflows.