Skip to content

Modules

Modules are the main extension mechanism in ChaCC API. A module contributes models, routes, services, configuration, and tests while the backbone handles startup, migration, dependency resolution, and mounting.

Module layout

my_module/
  module_meta.json
  requirements.txt
  my_module_src/
    __init__.py
    main.py
    models.py
    routes.py
    context_factory.py
    run_tests.py
    tests/
      __init__.py
      test_module.py
  README.md
  .gitignore

module_meta.json

Field Required Description
name Yes Machine-readable module name.
display_name No Human-readable name shown in module records.
version No Module version.
author No Author or organization.
description No Module description.
entry_point Yes Python path to setup function, for example my_module_src.main:setup_plugin.
base_path_prefix No Default API prefix, for example /billing.
tags No FastAPI documentation tags.
dependencies_file No Requirements file name, usually requirements.txt.
required_chacc_version No Minimum ChaCC version.
license No Module license.
homepage No Module homepage.

Setup function

A module entry point must expose a callable setup function.

from fastapi import APIRouter
from chacc_api import BackboneContext


def setup_plugin(context: BackboneContext):
    router = APIRouter(prefix="/items", tags=["Items"])

    @router.get("/")
    async def list_items():
        return {"items": []}

    return router

The setup function may be synchronous or asynchronous. It receives BackboneContext and must return a FastAPI APIRouter.

Models

Models should inherit from ChaCCBaseModel and use @register_model.

from chacc_api import ChaCCBaseModel, register_model
from sqlalchemy import Column, String


@register_model
class Item(ChaCCBaseModel):
    __tablename__ = "items"
    name = Column(String, nullable=False)

ChaCCBaseModel adds:

Field Type Purpose
id Integer Primary key.
uuid GUID Cross-database UUID value.
created_at DateTime Creation timestamp.
updated_at DateTime Last update timestamp.
deleted_at DateTime Soft-delete timestamp.

Routes

Use the database dependency from the module context or directly from ChaCC API.

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from chacc_api import get_db

router = APIRouter()


@router.get("/ping")
async def ping(db: Session = Depends(get_db)):
    return {"ok": True}

Services

Modules can share behavior through BackboneContext.

def verify_token(token: str):
    return token == "example"


def setup_plugin(context):
    context.register_service("token_verifier", verify_token)
    return router

Another module can retrieve it:

verifier = context.get_service("token_verifier")

Dependencies

Put Python dependencies in requirements.txt. ChaCC resolves dependencies before extracting or enabling modules.

requests
pydantic==2.7.0

Build and deploy

chacc create my_module
chacc run server --dev
chacc build plugins/my_module
chacc deploy my_module.chacc

The build command creates a ZIP archive named after the module unless an output filename is provided.

Development mode vs production mode

Mode Source directory Behavior
Development plugins/ Loads modules from source directories with optional hot reload.
Production .modules_installed/ Loads enabled modules from extracted archives.

Best practices

  • Keep module names lowercase with underscores.
  • Use one APIRouter per module.
  • Put database models in importable Python files so model discovery can find @register_model.
  • Avoid circular imports by using context.get_service() instead of direct module imports.
  • Store module-specific secrets as {MODULE_NAME}_{KEY} in .env.
  • Restart the backbone after installing, enabling, disabling, or uninstalling a module.