with one click
cli-sdk-guide
// Guide for implementing Backend.AI client SDK and CLI (Session, BaseFunction, @api_function, Click commands, Pydantic models, FieldSpec, output handlers, APIConfig, testing)
// Guide for implementing Backend.AI client SDK and CLI (Session, BaseFunction, @api_function, Click commands, Pydantic models, FieldSpec, output handlers, APIConfig, testing)
Guide for implementing Backend.AI repository patterns (create, get, search, update, delete, purge, batch operations, Querier, BatchQuerier, Creator, Updater, Purger, SearchScope, with_tables)
Diagnose and fix Docker Compose halfstack issues — config mapping, service health, DB/Redis/etcd inspection, supergraph regeneration
Local development tools — service management (./dev) and v2 CLI testing (./bai)
Guide for implementing REST and GraphQL APIs (create, get, search, update, delete, purge, scope prefix patterns, admin_ prefix, SearchScope, BaseFilterAdapter, @api_function, Click CLI)
Complete submission workflow - quality checks, commit, PR creation, changelog generation, and final push. Use after finishing implementation work.
Guide the Backend.AI release process - run release.sh, generate changelog via towncrier, consolidate RC entries for final releases with subsection grouping.
| name | cli-sdk-guide |
| description | Guide for implementing Backend.AI client SDK and CLI (Session, BaseFunction, @api_function, Click commands, Pydantic models, FieldSpec, output handlers, APIConfig, testing) |
| version | 1.0.0 |
| dependencies | ["api-guide","tdd-guide"] |
| tags | ["client-sdk","cli","session","api-function","click","pydantic","output-handler"] |
Guide for implementing Backend.AI client SDK and CLI with session management, API functions, and Click commands.
SDK (Software Development Kit):
CLI (Command Line Interface):
When to use:
Layers: CLI → SDK → REST API → Manager
Flow: CLI commands call SDK functions through Session, which makes HTTP requests to REST API endpoints.
CLI Layer:
ExtendedCommandGroup - Command groups with aliases and interrupt handlingLazyGroup - Lazy loading for faster startupCLIContext - Shared state (config, output mode)@pass_ctx_obj - CLIContext injection decoratorFieldSpec - Output field definitionsBaseOutputHandler - Console/JSON formattersSDK Layer:
BaseFunction - Metaclass for API function classes@api_function - Decorator for API methodsAsyncSession - Primary async HTTP sessionSession - Sync wrapper for CLIapi_session - ContextVar for session contextData Layer:
client/cli/types.py)common/dto/)Config Layer:
APIConfig - Environment variables and .env fileCLIContext - CLI state and output handlerAsyncSession (Primary):
api_session ContextVar for context propagationSession (Sync Wrapper):
See:
client/session.py - Session and AsyncSession implementationclient/request.py - HTTP request handlingclient/config.py - APIConfig for environment variables@api_function decorator:
api_session ContextVarBaseFunction metaclass:
session.FairShare, session.AdminStandard operations:
create_* - POST requestsget_* - GET single itemsearch_* - GET collection with filtersupdate_* - PATCH requestsdelete_* - DELETE requestspurge_* - Permanent deletionSee:
client/func/base.py - BaseFunction and @api_functionclient/func/fair_share.py - Complete implementation exampleCurrent state:
client/cli/types.pycommon/dto/Why Pydantic:
Usage:
model_dump(mode="json", exclude_none=True) - To JSON dictmodel_validate(data) - From JSON dictSee:
client/func/fair_share.py - Pydantic usage in SDKcommon/dto/fair_share.py - Shared DTO definitionsStandard pattern:
Response.model_validate(data)See complete example:
client/func/fair_share.py - All standard operations (create, get, search, update, delete)Command organization:
ExtendedCommandGroup - Enhanced Click group with interrupt handlingLazyGroup - Defers module imports until needed@pass_ctx_obj - Type-safe CLIContext injectionSee:
client/cli/main.py - Main entry and command groupsclient/cli/extensions.py - @pass_ctx_obj decoratorclient/cli/fair_share/__init__.py - LazyGroup usageFieldSpec:
BaseOutputHandler:
print_item() - Single item displayprint_list() - Collection displayprint_error() - Error messagesSee:
client/output/types.py - FieldSpec and BaseOutputHandler protocolclient/output/fields.py - Field utilitiesclient/cli/fair_share/commands.py - FieldSpec definitions and usagePattern:
BackendAIError exceptionsctx.output.print_error() for consistent formattingError handling:
BackendAIErrorExitCode enum (OK=0, FAILURE=1, INVALID_ARGUMENT=2, PERMISSION_DENIED=3)ctx.output.print_error() handles both console and JSON modesSee:
client/cli/fair_share/commands.py - Complete CLI integrationclient/cli/types.py - CLIContext and ExitCodeclient/exceptions.py - Exception hierarchy| Pattern | SDK | CLI |
|---|---|---|
| Session | async with AsyncSession() | with Session() (sync wrapper) |
| Request | Request("POST", "/endpoint", json={...}) | SDK handles internally |
| Response | Response.model_validate(data) | SDK returns parsed model |
| Output | Return Pydantic model | ctx.output.print_item() or print_list() |
| Error | Raise BackendAIError subclass | print_error() + sys.exit(ExitCode) |
| Config | APIConfig() reads environment | Passed via CLIContext |
| Async | Always async (async def, await) | Sync wrapper handles internally |
When implementing new CLI/SDK feature:
✅ Implement REST API (/api-guide)
✅ Define Pydantic models
common/dto/✅ Implement SDK function
@api_function decorator✅ Define FieldSpec
✅ Implement CLI commands
✅ Write tests (/tdd-guide)
✅ Update documentation
SDK tests:
pytest-aiohttpCLI tests:
CliRunner for command invocationSee:
/tdd-guide skill for testing workflowtests/unit/client/ - Test examplesComplete implementations:
client/func/fair_share.py - Full SDK with Pydantic modelsclient/cli/fair_share/commands.py - Full CLI with all patternsArchitecture components:
client/session.py - Session and AsyncSessionclient/func/base.py - @api_function and BaseFunctionclient/cli/main.py - CLI entry pointclient/cli/extensions.py - @pass_ctx_obj decoratorclient/output/types.py - FieldSpec and output handlersclient/config.py - APIConfigclient/cli/types.py - CLIContext and ExitCodeclient/exceptions.py - Exception hierarchyAll new SDK/CLI work MUST use the v2 pattern.
client/v2/domains_v2/)BaseDomainClient, receives BackendAIAuthClient via constructorcommon/dto/manager/v2/ exclusivelytyped_request() handles serialization and response parsingV2ClientRegistry (client/v2/v2_registry.py) with @cached_property per domainclient/cli/v2/)Command pattern: ./bai [admin] {entity} [{sub-entity}] {operation}
admin_ SDK methods → commands under ./bai admin {entity} ..../bai {entity} ...__init__.py + commands.pyadmin/{entity}.py--name-contains, --status, etc.)--order-by field:direction supports multiple values~/.backend.ai/ via load_v2_config() → V2ConnectionConfig dataclass~/.backend.ai/)config.toml — endpoint, endpoint_type, api_versioncredentials.toml — access_key, secret_keysession/cookie.dat — webserver session cookie (login/logout)Related skills:
/api-guide - REST API implementation (prerequisite)/tdd-guide - Testing workflow/local-dev - Service management and CLI testing