Skip to main content

CLI for the Dattos platform

Project description

dattos

CLI for the Dattos reconciliation platform — designed as an agent-native interface for AI agents (Claude Code, custom agents) to operate Dattos programmatically.

All output is JSON to stdout, errors go to stderr, making it trivially parseable by both humans and machines.

Installation

Requires Python 3.11+.

pip install dattos

# Verify
dattos version
# {"version": "0.3.0"}

From source (development)

git clone git@bitbucket.org:dattos/dattos-cli.git
cd dattos-cli
pip install -e .

Authentication

The CLI authenticates via API key + organization ID. Configure using environment variables or the config file (~/.dattos/config.json).

Environment Variables

export DATTOS_API_URL="https://your-instance.dattos.com.br/dattos.api"
export DATTOS_API_KEY="api-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export DATTOS_ORG_ID="1"
export DATTOS_FOLDER_ID="2473"  # optional, default folder for all commands

Config File

dattos config set api-url "https://your-instance.dattos.com.br/dattos.api"
dattos config set api-key "api-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
dattos config set org-id "1"

Saved to ~/.dattos/config.json. Environment variables take precedence over the config file.

Folder ID

Most Dattos API endpoints require a folder context. There are three ways to set it (in priority order):

# 1. Per-command flag (highest priority)
dattos analyses list --folder-id 2473

# 2. Environment variable
export DATTOS_FOLDER_ID="2473"
dattos analyses list

# 3. Config file (persistent, recommended)
dattos config set folder-id "2473"
dattos analyses list

To discover available folder IDs, use dattos folders list:

# Full tree (raw JSON)
dattos folders list

# Flat list with id, name, and full path (easier to read)
dattos folders list --flat

Commands

dattos analyses — Manage analyses

# List analyses (with pagination and search)
dattos analyses list --page-size 10
# {"data": [{"analysisId": 5192, "analysisCode": "PRD-7728", "analysisName": "Reconciliação Bancária", ...}], "totalItems": 42}

dattos analyses list --search "RECON-001" --folder-id 2473
dattos analyses list --inactive  # include inactive/archived

# Get analysis by ID
dattos analyses get 5192 --folder-id 2473
# {"analysisId": 5192, "analysisCode": "PRD-7728", "analysisName": "Reconciliação Bancária", "isActive": true, ...}

# Get analysis by code
dattos analyses get-by-code "ETL-1" --folder-id 2473
# {"analysisId": 4137, "analysisCode": "ETL-1", ...}

# List data sources and connector info
dattos analyses datasources 5192 --folder-id 2473
# [{"id": 101, "name": "Extrato Bancário", "connectorType": "Excel", ...}]

# Check execution status at a reference date
dattos analyses execution-status 5192 --date 2025-12-20 --folder-id 2473
# {"executionJobId": "89625", "status": "Loaded", "completedPercent": 100.0, ...}
# Status values: NoLoad, Loading, Loaded, Error, Inactive, InvalidPreparation

# Start an analysis execution (default: replace mode)
dattos analyses start 5192 --date 2026-03-08
# {"status": "started", "analysisId": 5192, "referenceDate": "2026-03-08"}

# Start with file upload (auto-uploads, then starts)
dattos analyses start 5192 --date 2026-03-08 --file data.csv
# Supported: .csv, .edi, .ofx, .pdf, .rem, .ret, .txt, .xlsx, .xls, .xlsb, .xml

# Start and wait for completion (polls every 5s)
dattos analyses start 5192 --date 2026-03-08 --wait

# Incremental import (preserves existing data, adds new)
dattos analyses start 5192 --date 2026-03-08 --incremental

dattos loads — Query analysis loads

# Get load details for a reference date (returns load ID + dataset IDs)
dattos loads get 5192 2025-12-20 --folder-id 2473
# {"id": 3248, "referenceDate": "2025-12-20", "datasets": [{"id": 2476, "name": "Extrato", "columns": [...]}]}

# List all reference dates with loaded data
dattos loads list-dates 4137 --from 2025-01-01 --to 2026-12-31 --folder-id 2473
# ["2025-12-09T00:00:00", "2025-12-10T00:00:00", "2025-12-11T00:00:00"]

# List available views for a load
dattos loads views 5192 3248 --folder-id 2473
# [{"id": 1, "name": "Summary"}, {"id": 2, "name": "Detail"}]

dattos datasets — Query dataset rows

# Search rows in a dataset (requires analysis ID, load ID, dataset ID)
dattos datasets search 5192 3248 2476 --page-size 10 --folder-id 2473
# {"rows": {"data": [{"id": 1, "valor": 1500.00, "data": "2025-12-20", ...}]}, "totalRows": 1523}

# With pagination (default page-size is 50)
dattos datasets search 5192 3248 2476 --page-size 50 --page 2

# With filter (JSON string)
dattos datasets search 5192 3248 2476 --filter '{"column": "status", "value": "active"}'

dattos matching — Reconciliation results

# Get matching execution info
dattos matching get 5192 3248 2475 --folder-id 2473
# {"id": 1, "status": "Completed", "matchedCount": 1523, ...}

# Get totals by status (matched, unmatched, pending)
dattos matching status 5192 3248 2475 --folder-id 2473
# {"Matched": 1523, "Unmatched": 47, "Pending": 0}

# Get matching summary report
dattos matching summary 5192 3248 2475 --folder-id 2473
# [{"column": "Account", "matched": 100, "unmatched": 5}, ...]

dattos reports — Generate and download reports

# Generate a report (async — returns report ID to poll)
dattos reports generate 5192 --load-id 3248 --dataset-id 2476 --format csv
# {"id": 99, "status": "Processing"}

dattos reports generate 5192 --load-id 3248 --dataset-id 2476 --format xlsx
# Note: >1M rows only supports CSV format

# Check report generation status
dattos reports status 5192 --load-id 3248 --dataset-id 2476
# {"id": 99, "status": "Completed", "downloadUrl": "..."}

# Download a generated report
dattos reports download 5192 99 --output report.csv
# {"status": "downloaded", "file": "report.csv"}

dattos workflows — Manage and execute workflows

# List workflows
dattos workflows list --page-size 10
dattos workflows list --name "Daily Recon"
# {"data": [{"Workflow": {"Id": 1, "Name": "Daily Recon"}, "ExecutionWorkflow": {...}}, ...], "totalItems": 5}

# Get workflow details
dattos workflows get 1
# {"Workflow": {"Id": 1, "Name": "Daily Recon", "IsActive": true}, "ExecutionWorkflow": {"Status": "Done", ...}}

# Start a workflow for a reference date
dattos workflows start 1 --date 2026-03-08
# {"status": "started", "workflowId": 1, "referenceDate": "2026-03-08"}

# Stop a running workflow execution
dattos workflows stop 10  # uses execution ID, not workflow ID
# {"status": "stopped", "executionId": 10}

# View execution history
dattos workflows history 1 --page-size 20
# {"data": [{"Id": 10, "Status": "Done", "ReferenceDate": "2026-03-07"}, ...], "totalItems": 15}

# View task logs
dattos workflows logs 55  # uses task ID from execution
# [{"message": "Starting import", "timestamp": "2026-03-07T10:00:00"}, ...]

dattos imports — Monitor and manage imports

# List imports (with optional filters)
dattos imports list
dattos imports list --from 2026-01-01 --to 2026-03-31
dattos imports list --status Error
dattos imports list --include-canceled
# {"data": [{"Id": 1, "Status": "Success", "TotalSuccess": 100, ...}], "totalItems": 25}

# Get import details
dattos imports get 1
# {"Id": 1, "Status": "Success", "TotalSuccess": 100, "TotalRejections": 0, ...}

# View rejection details
dattos imports results 1
# {"data": [{"line": 5, "reason": "Invalid date format"}], "totalItems": 1}

# View import logs
dattos imports logs 1
# {"data": [{"message": "Processing started", "timestamp": "..."}], "totalItems": 3}

# Cancel an import
dattos imports cancel 1
# {"status": "canceled", "importId": 1}

dattos folders — List and inspect folders

# List all folders as a tree (raw JSON)
dattos folders list

# Flat list — easier to find folder IDs
dattos folders list --flat
# [{"id": 2473, "code": "SIR", "name": "sirio", "fullPath": "Engenharia / sirio", "depth": 1}, ...]

dattos users — Manage users

# List all users (flat array)
dattos users list
dattos users list --search "john" --page-size 20
# [{"Id": 4, "UserCode": "david.barouh", "FullName": "David Barouh", "EmailAddress": "...", "Blocked": false, ...}]

# Get a user by ID
dattos users get 4
# {"Id": 4, "UserCode": "david.barouh", "FullName": "David Barouh", ...}

# List available Privacy Profiles (roles)
dattos users list-roles
# [{"Id": 1, "Name": "Administradores", ...}, {"Id": 2, "Name": "Engenharia", ...}]

# Get roles assigned to a user
dattos users roles 4
# [{"Id": 1, "Name": "Administradores", ...}, ...]

# Create a new user — Dattos sends an invitation email automatically
dattos users create --code "JDOE" --name "John Doe" --email "john.doe@company.com"
dattos users create --code "JDOE" --name "John Doe" --email "john.doe@company.com" --culture "en-US"
# {"Id": 80, "UserCode": "JDOE", "FullName": "John Doe", ...}

# Update a user (read-modify-write — only provided fields change)
dattos users update 80 --name "John P. Doe"
dattos users update 80 --culture "en-US"
dattos users update 80 --blocked   # block the user
dattos users update 80 --active    # unblock the user

# Assign Privacy Profiles — REPLACES all existing roles
dattos users set-roles 80 --role-id 1 --role-id 2
# {} (success)

# Delete a user — requires --yes (irreversible)
dattos users delete 80 --yes
# {"status": "deleted", "userId": 80}

dattos config — Manage configuration

# Set config values (saved to ~/.dattos/config.json)
dattos config set api-url "https://your-instance.dattos.com.br/dattos.api"
dattos config set api-key "api-xxxxxxxx"
dattos config set org-id "1"
dattos config set folder-id "2473"
# {"key": "folder-id", "status": "saved"}

# Show current resolved configuration (API key is masked)
dattos config show
# {"api_url": "https://your-instance.dattos.com.br/dattos.api", "api_key": "api-xxxx...", "org_id": "1", "folder_id": "2473"}

dattos version

dattos version
# {"version": "0.3.0"}

Usage Examples

Example 1: First-time setup

# Configure credentials
dattos config set api-url "https://your-instance.dattos.com.br/dattos.api"
dattos config set api-key "api-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
dattos config set org-id "1"

# Discover your folders
dattos folders list --flat | jq '.[] | "\(.id) — \(.fullPath)"'
# "2473 — Engenharia / sirio"
# "2474 — Engenharia / delta"

# Set a default folder
dattos config set folder-id "2473"

# Verify everything works
dattos config show
dattos analyses list --page-size 5

Example 2: Inspect reconciliation results

# Find the analysis by code
dattos analyses get-by-code "RECON-BANK"
# Note the analysisId (e.g., 5192)

# Check if data is loaded for a date
dattos analyses execution-status 5192 --date 2026-03-01
# {"status": "Loaded", "completedPercent": 100.0, ...}

# Get the load (returns load ID and dataset IDs)
dattos loads get 5192 2026-03-01
# Note loadId (3248) and datasetId (2476)

# Browse the data
dattos datasets search 5192 3248 2476 --page-size 10

# Check matching results
dattos matching status 5192 3248 2475
# {"Matched": 1523, "Unmatched": 47, "Pending": 0}

Example 3: Export data for external analysis

# Generate a CSV report
dattos reports generate 5192 --load-id 3248 --dataset-id 2476 --format csv
# {"id": 99, "status": "Processing"}

# Wait for it to complete
dattos reports status 5192 --load-id 3248 --dataset-id 2476
# {"id": 99, "status": "Completed"}

# Download the file
dattos reports download 5192 99 --output reconciliation_2026-03-01.csv
# {"status": "downloaded", "file": "reconciliation_2026-03-01.csv"}

Example 4: Find loaded dates for an analysis

# Which dates have data loaded?
dattos loads list-dates 4137 --from 2026-01-01 --to 2026-03-31 | jq -r '.[]'
# 2026-01-15T00:00:00
# 2026-02-15T00:00:00
# 2026-03-15T00:00:00

Example 5: Composing with jq

# List analysis names and codes
dattos analyses list --page-size 100 | jq '.data[] | {code: .analysisCode, name: .analysisName}'

# Count unmatched items
dattos matching status 5192 3248 2475 | jq '.Unmatched'

# Get dataset column names
dattos loads get 5192 2026-03-01 | jq '.datasets[].columns[].name'

# Check if execution is done (useful in scripts)
STATUS=$(dattos analyses execution-status 5192 --date 2026-03-01 | jq -r '.status')
if [ "$STATUS" = "Loaded" ]; then echo "Ready"; fi

Typical Agent Workflow

A typical AI agent workflow to inspect reconciliation results:

# 0. First time: discover folders and set default
dattos folders list --flat
dattos config set folder-id "2473"

# 1. List analyses
dattos analyses list --page-size 10

# 2. Check execution status
dattos analyses execution-status 5192 --date 2025-12-20

# 3. Get load details (returns load ID + dataset IDs)
dattos loads get 5192 2025-12-20

# 4. Search dataset rows
dattos datasets search 5192 3248 2476 --page-size 50

# 5. Check matching results
dattos matching status 5192 3248 2475

# 6. Export a report
dattos reports generate 5192 --load-id 3248 --dataset-id 2476 --format csv

Output Format

All commands output JSON to stdout. Errors output structured JSON to stderr.

# Success — JSON to stdout
dattos analyses get 5192
# {"analysisId": 5192, "analysisCode": "PRD-7728", ...}

# Error — JSON to stderr, non-zero exit code
dattos analyses get 99999
# {"error": "not_found", "message": "A entidade procurada não existe.", "status": 404}

Exit Codes

Code Meaning
0 Success
1 API error (4xx/5xx)
2 Auth/config error (missing API key, invalid credentials)

Piping and Filtering

Because output is JSON, it composes naturally with jq:

# Get just the analysis names
dattos analyses list --folder-id 2473 | jq '.data[].analysisName'

# Get loaded dates as plain text
dattos loads list-dates 4137 --from 2025-01-01 --to 2026-12-31 --folder-id 2473 | jq -r '.[]'

# Check if execution is complete
dattos analyses execution-status 5192 --date 2025-12-20 | jq -r '.status'

Error Handling

The CLI handles common API errors with descriptive messages:

HTTP Status Error Type Description
401 auth_error Invalid or expired API key
403 forbidden Insufficient permissions
404 not_found Resource does not exist
429 rate_limited Too many requests (auto-retried up to 3 times)
Other api_error General API error

Rate limiting (HTTP 429) is handled automatically with exponential backoff (5s, 10s, 20s, max 30s).

Project Structure

dattos-cli/
├── src/dattos_cli/
│   ├── __init__.py          # Version
│   ├── main.py              # Typer app, client factory, error handling
│   ├── client.py            # HTTP client (httpx) with retry logic
│   ├── config.py            # Config loading (env vars + ~/.dattos/config.json)
│   ├── output.py            # JSON output helpers (stdout/stderr)
│   └── commands/
│       ├── analyses.py      # dattos analyses *
│       ├── loads.py          # dattos loads *
│       ├── datasets.py       # dattos datasets *
│       ├── matching.py       # dattos matching *
│       ├── reports.py        # dattos reports *
│       ├── folders.py        # dattos folders *
│       ├── workflows.py      # dattos workflows *
│       ├── imports.py         # dattos imports *
│       ├── users.py           # dattos users *
│       ├── etl.py             # dattos etl *
│       └── config_cmd.py     # dattos config *
├── tests/                   # 67 unit + integration tests
├── docs/plans/              # Design and implementation docs
├── pyproject.toml
└── .gitignore

Development

Branch Workflow

All development happens on develop. The main branch is protected — changes require a PR.

git checkout develop
# make changes...
git push origin develop
# create PR: develop → main

Setup

pip install -e .
pip install pytest

# Run tests
pytest -v

# Run a specific test
pytest tests/test_analyses.py -v

Tech Stack

  • Python 3.11+
  • Typer — CLI framework with type hints and auto-generated help
  • httpx — HTTP client with MockTransport for testing
  • hatchling — Build backend

Roadmap

  • v0.2 — Execution commands ✅ Done (analyses start, workflows, imports)
  • v0.3 — User management ✅ Done (users list/get/create/update/delete/set-roles)
  • v0.4 — Configuration commands (create/edit analyses, datasources, connectors)
  • Future — Database connection info, interactive login, shell completion, table output format

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dattos-0.4.2.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dattos-0.4.2-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file dattos-0.4.2.tar.gz.

File metadata

  • Download URL: dattos-0.4.2.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for dattos-0.4.2.tar.gz
Algorithm Hash digest
SHA256 bfcd98b6f685cdd93f93adb481b74ffc75175fddb6ed2cf8541c585b19d7705b
MD5 5431f10f3f5bc248272c5db4774ec625
BLAKE2b-256 572bad693dec4aedb38f4380679d74c80434373f8c532e659e474b8c6c51d193

See more details on using hashes here.

File details

Details for the file dattos-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: dattos-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for dattos-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7592bf7fa33983f77b4c67b345e0ad4078cbd3bc5d7ced3634cc63f8694af427
MD5 553aa02d233e02bcc3afabb1ce06bdc5
BLAKE2b-256 0bc5b81ad0112765d48a2e0a9e828c04095e70d9c4c15efadf35564c41aba550

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page