Skip to main content

CLI harness for Odoo 12 ERP — CRUD, modules, DB management, reports via XML-RPC. Requires: running Odoo 12 instance

Project description

cli-anything-odoo_12

CLI para Odoo 12 ERP — consulte dados, gerencie módulos, exporte relatórios e faça perguntas em linguagem natural, tudo pelo terminal.

Instalação

pip install cli-anything-odoo-12

Após instalar, o comando cli-anything-odoo_12 fica disponível no terminal.

Pré-requisitos

  • Python 3.10+
  • Odoo 12 rodando (acessível via rede, ex: http://localhost:8069)

Quick Start

1. Connect to Odoo

The CLI supports two backend protocols:

Backend Flag Auth Requisitos
REST (padrão) --backend rest OAuth2 (client_credentials) Módulo REST API instalado no Odoo
XML-RPC --backend xmlrpc Usuário/senha Nenhum (nativo do Odoo)

Opção A: REST API (recomendado)

Requer configuração única do OAuth2:

Passo 1 — Criar Client OAuth2 no Odoo:

  1. Acesse Configurações > REST API > OAuth2
  2. Crie um novo client:
    • Nome: ex. "CLI API"
    • Tipo OAuth: Client Credentials
    • Usuário: selecione o usuário Odoo que o client vai operar
  3. Copie o Client Key e Client Secret

Passo 2 — Configurar o CLI:

cli-anything-odoo_12 config setup-rest \
  --client-id <CLIENT_KEY> \
  --client-secret <CLIENT_SECRET> \
  --url http://localhost:8069 \
  --db mydb

Passo 3 — Verificar:

cli-anything-odoo_12 record search res.partner --domain "[('is_company','=',True)]" --limit 5

Opção B: XML-RPC (sem configuração extra)

# Connect via XML-RPC and save credentials
cli-anything-odoo_12 connect \
  --url http://localhost:8069 --db mydb --user admin --password admin \
  --backend xmlrpc --save

Após configurar (ambos os backends)

# As credenciais são reutilizadas automaticamente nos próximos comandos:
cli-anything-odoo_12 record search res.partner --limit 5
cli-anything-odoo_12 ask "empresas"

# Trocar backend por comando:
cli-anything-odoo_12 --backend xmlrpc record search res.partner --limit 5

# Ou passar credenciais por comando (sobrescreve config salva):
cli-anything-odoo_12 --url http://localhost:8069 --db mydb --user admin --password admin record search res.partner

2. Record Operations (CRUD)

# Search partners (companies only)
cli-anything-odoo_12 record search res.partner --domain "[('is_company','=',True)]" --fields name,email --limit 10

# Example output:
#   Found 10 record(s) in res.partner
#   [0]
#     id: 1
#     name: My Company
#     email: info@mycompany.com
#   [1]
#     id: 14
#     name: Azure Interior
#     email: azure@example.com

# Read specific record
cli-anything-odoo_12 record read res.partner 1 --fields name,email,phone

# Create record
cli-anything-odoo_12 record create res.partner --values '{"name":"New Company","is_company":true}'
# Output: Created res.partner record id=42

# Update record
cli-anything-odoo_12 record write res.partner 42 --values '{"phone":"+55 11 99999-0000"}'

# Delete record
cli-anything-odoo_12 record unlink res.partner 42

# Count records
cli-anything-odoo_12 record count res.partner --domain "[('is_company','=',True)]"
# Output: res.partner: 15 record(s)

# List model fields
cli-anything-odoo_12 record fields res.partner
# Output: res.partner: 143 fields

3. Module Management

cli-anything-odoo_12 module list --installed
# Output: Found 254 module(s)

cli-anything-odoo_12 module list --search sale
cli-anything-odoo_12 module info sale
cli-anything-odoo_12 module install sale
cli-anything-odoo_12 module update sale

4. Database Operations

cli-anything-odoo_12 db list
# Output: Found 3 database(s)
#   - erp-production
#   - erp-staging
#   - test_cli

cli-anything-odoo_12 db create new_db --lang pt_BR
cli-anything-odoo_12 db backup mydb /tmp/mydb_backup.zip
cli-anything-odoo_12 db restore new_db /tmp/mydb_backup.zip
cli-anything-odoo_12 db drop old_db --confirm

5. Reports

cli-anything-odoo_12 report list --model account.invoice
# Output: Found 63 report(s)

cli-anything-odoo_12 report render account.report_invoice 42 --output invoice.pdf
# Output: Report saved: invoice.pdf (45,231 bytes)

6. Data Export

# Export all partners to CSV
cli-anything-odoo_12 export csv res.partner --output partners.csv --fields name,email,phone
# Output: Exported 920 records to partners.csv

# Export with domain filter
cli-anything-odoo_12 export csv res.partner --output companies.csv --fields name,email --domain "[('is_company','=',True)]"
# Output: Exported 15 records to companies.csv

# Export to JSON with limit
cli-anything-odoo_12 export json res.partner --output partners.json --fields name,email --limit 100
# Output: Exported 100 records to partners.json

# Export to stdout (omit --output)
cli-anything-odoo_12 export json res.partner --fields name --limit 3

7. Natural Language Query (NLQ)

The ask command translates free-text queries (PT-BR, EN, ES) into Odoo search domains using regex patterns. No external dependencies or LLM required.

Simple Queries

# List companies
cli-anything-odoo_12 ask "liste todas as empresas"

# Example output:
#   ━━━ Empresas ━━━
#     Consulta: res.company | 3 registro(s)
#
#     ID   Nome                  E-mail              Telefone
#     ───  ────────────────────  ──────────────────  ──────────
#     1    The Cookiery          info@cookiery.com   (11) 3333-4444
#     3    Filial Centro         centro@cookiery.com —
#     5    Filial Shopping       shop@cookiery.com   —
#
#     Total: 3 registro(s)

# Search with filters
cli-anything-odoo_12 ask "faturas de entrada pagas em janeiro/2024"

# Example output:
#   ━━━ Faturas de Entrada — Paid — Janeiro/2024 ━━━
#     Consulta: account.invoice | 8 registro(s)
#
#     ID    Numero    Parceiro           Data         Total (R$)  Status
#     ────  ────────  ─────────────────  ──────────   ──────────  ──────
#     1042  INV/001   Fornecedor ABC     2024-01-05   15.230,00   paid
#     1043  INV/002   Fornecedor XYZ     2024-01-12    8.500,00   paid
#     ...
#
#     Total: 8 registro(s) | Soma: R$ 87.430,00

# Active customers with limit
cli-anything-odoo_12 ask "clientes ativos" --limit 10

Cross-Model Grouping (Analytical Queries)

Group orders by product category or individual products — the CLI automatically traverses related models (order > line > product > category).

# POS orders grouped by product category
cli-anything-odoo_12 ask "vendas do pos de janeiro/2026 agrupado por categoria de produto"

# Example output:
#   ━━━ Vendas do POS — Janeiro/2026 — por Categoria de Produto ━━━
#     Consulta: pos.order | 229 itens de linha
#
#     Categoria de Produto  Itens  Qtd   Total (R$)   %
#     ────────────────────  ─────  ────  ──────────   ────
#     Cookies               98     156   2.376,50     67.4%
#     Bebidas               45     89      534,20     15.1%
#     Salgados              38     62      312,80      8.9%
#     Doces                 28     45      198,34      5.6%
#     Sem Categoria         20     32      106,00      3.0%
#
#     Total: 229 itens | Qtd: 384 | Soma: R$ 3.527,84

# POS orders grouped by individual product
cli-anything-odoo_12 ask "vendas do pos agrupado por produto"

# Invoice grouped by product category
cli-anything-odoo_12 ask "faturas agrupado por categoria de produto"

# Purchase orders grouped by product category
cli-anything-odoo_12 ask "pedidos de compra agrupado por categoria de produto"

Supported Cross-Model Groupings

Model Group Key Traversal Path
pos.order categoria de produto pos.order > pos.order.line > product.product > product.category
pos.order categoria pos pos.order > pos.order.line > product.product > pos.category
pos.order produto pos.order > pos.order.line > product.product
account.invoice categoria de produto account.invoice > account.invoice.line > product.product > product.category
account.invoice produto account.invoice > account.invoice.line > product.product
sale.order categoria de produto sale.order > sale.order.line > product.product > product.category
sale.order produto sale.order > sale.order.line > product.product
purchase.order categoria de produto purchase.order > purchase.order.line > product.product > product.category

Simple Field Grouping

# POS orders grouped by point-of-sale terminal
cli-anything-odoo_12 ask "vendas do pos agrupado por pdv"

# Example output:
#   ━━━ Vendas do POS ━━━
#     Consulta: pos.order | 50 registro(s)
#
#     Grupo              Qtd  Total (R$)   %
#     ─────────────────  ───  ──────────   ────
#     Loja Centro        28   4.520,00     65.2%
#     Loja Shopping      22   2.410,00     34.8%
#
#     Total: 50 registro(s) | Soma: R$ 6.930,00

With Export

# Export to CSV
cli-anything-odoo_12 ask "faturas de entrada em janeiro/2024 e exporte para csv em /tmp/faturas.csv"
# Output: ... Exportado para /tmp/faturas.csv

# Export to JSON
cli-anything-odoo_12 ask "empresas e exporte para json em /tmp/empresas.json"

# Complex combined query with export
cli-anything-odoo_12 ask "faturas de entrada pagas em janeiro/2024 acima de R$ 5.000 e exporte para csv em /tmp/fat.csv"

Other Query Examples

# Birthdays in a specific month
cli-anything-odoo_12 ask "aniversariantes de marco"

# Date range
cli-anything-odoo_12 ask "faturas de 01/03 a 15/03"

# Relative dates
cli-anything-odoo_12 ask "pedidos de compra este mes"
cli-anything-odoo_12 ask "faturas ultimo mes"

# Amount filters (BRL format)
cli-anything-odoo_12 ask "faturas acima de R$ 10.000"
cli-anything-odoo_12 ask "pedidos de venda abaixo de 5000"

# English queries
cli-anything-odoo_12 ask "invoices above 5000"
cli-anything-odoo_12 ask "active customers"
cli-anything-odoo_12 ask "paid invoices in january/2024"

# Spanish queries
cli-anything-odoo_12 ask "facturas pagadas"

Supported Aliases (Multilingual)

PT-BR EN ES Odoo Model
empresas companies res.company
parceiros, contatos partners, contacts socios res.partner
clientes customers res.partner (customer=True)
fornecedores suppliers res.partner (supplier=True)
faturas, notas fiscais invoices facturas account.invoice
pedidos de venda sale orders pedido de venta sale.order
pedidos de compra purchase orders orden de compra purchase.order
produtos products product.product
pagamentos payments account.payment
vendas do pos, pedidos pos pos.order
usuarios users res.users
aniversariantes res.partner (birthday)

Supported Filters

Filter PT-BR EN
Status pagas, em aberto, rascunho, canceladas, confirmadas paid, open, draft, cancelled, done
Type de entrada, de saida incoming, outgoing
Date em janeiro/2024, este mes, ultimo mes in january/2024, this month, last month
Range de 01/03 a 15/03 from 01/03 to 15/03
Amount acima de R$ 10.000, abaixo de 5000 above 5000, below 1000
Boolean ativos, inativos, arquivados active, inactive, archived
Document CPF 123.456.789-00
Group agrupado por categoria de produto grouped by product category
Export exporte para csv em /tmp/f.csv
Limit top 10, limitar a 5 limit 10

8. Configuration Management

# Show saved config (passwords/tokens are masked)
cli-anything-odoo_12 config show

# Example output:
#   url: http://localhost:8069
#   db: erp-thecookiery
#   user: nexuz@nexuz.com.br
#   password: adm***
#   backend: rest
#   grant_type: client_credentials
#   client_id: vjVaBgp7...
#   client_secret: 4EIwDzsN***
#   access_token: eyJhbGci***
#   token_expiry: 1742060400.0

# Delete a specific key
cli-anything-odoo_12 config delete --key access_token

# Delete all config
cli-anything-odoo_12 config delete

9. JSON Output (for agents)

# Any command with --json produces machine-readable output
cli-anything-odoo_12 --json record search res.partner --limit 3

# Example output:
# {
#   "model": "res.partner",
#   "count": 3,
#   "records": [
#     {"id": 1, "name": "My Company", "email": "info@co.com"},
#     ...
#   ]
# }

cli-anything-odoo_12 --json ask "empresas"

# Cross-group JSON output
cli-anything-odoo_12 --json ask "vendas do pos agrupado por categoria de produto"

# Example output:
# {
#   "model": "pos.order",
#   "title": "Vendas do POS",
#   "group_by": "Categoria de Produto",
#   "groups": [
#     {"name": "Cookies", "count": 98, "qty": 156.0, "total": 2376.50, "pct": 67.4},
#     ...
#   ],
#   "grand_count": 229,
#   "grand_qty": 384.0,
#   "grand_total": 3527.84
# }

cli-anything-odoo_12 --json module list --installed
cli-anything-odoo_12 --json db list

10. Interactive REPL

# Start REPL (just run without subcommand)
cli-anything-odoo_12 --url http://localhost:8069 --db mydb --user admin --password admin

# Example session:
#   cli-anything-odoo_12  v1.0.0
#   Connected to http://localhost:8069 db=mydb uid=2
#
#   odoo_12 [mydb] > record search res.partner --limit 5
#   Found 5 record(s) in res.partner
#   ...
#
#   odoo_12 [mydb] > ask "faturas pagas em janeiro/2024"
#   ━━━ Faturas — Paid — Janeiro/2024 ━━━
#   ...
#
#   odoo_12 [mydb] > quit

Global Flags

Flag Effect
--json Machine-readable JSON output (all commands)
--url Odoo server URL (overrides saved config)
--db Database name (overrides saved config)
--user Username (overrides saved config)
--password Password (overrides saved config)
--backend Backend protocol: rest (default) or xmlrpc

Architecture

cli_anything/odoo_12/
├── odoo_12_cli.py              # Main CLI entry point (Click framework)
├── core/
│   ├── aliases.py              # Multilingual model/status/type alias registry
│   ├── connection.py           # Config management + backend factory (get_rpc)
│   ├── cross_group.py          # Cross-model grouping engine
│   ├── database.py             # Database operations (list, create, backup, etc.)
│   ├── export.py               # CSV/JSON export
│   ├── formatters.py           # Business-friendly output formatting
│   ├── module.py               # Module management
│   ├── nlq.py                  # Natural Language Query parser (regex-based)
│   ├── record.py               # CRUD operations
│   ├── report.py               # Report generation
│   └── session.py              # Undo/redo + command history
├── utils/
│   ├── odoo_backend_base.py    # ABC OdooBackend (21 abstract methods) + config I/O
│   ├── odoo_backend.py         # OdooRPC (XML-RPC) + backward-compat re-exports
│   ├── odoo_rest.py            # OdooREST (REST API, OAuth2, urllib — zero deps)
│   └── repl_skin.py            # Terminal UI (tables, colors, prompts)
└── tests/
    ├── TEST.md                 # Test plan + results
    ├── test_core.py            # Unit tests (82 tests, no Odoo needed)
    ├── test_rest.py            # REST backend unit tests (24 tests, mock HTTP)
    └── test_full_e2e.py        # E2E tests (27 tests, requires running Odoo)

Backend Architecture

All commands work identically regardless of backend. The OdooBackend ABC defines 21 methods implemented by both OdooRPC (XML-RPC) and OdooREST (REST API):

                     OdooBackend (ABC)
                    21 abstract methods
                   /                   \
            OdooRPC                   OdooREST
         (xmlrpc.client)          (urllib — REST API)
         Built-in Odoo API        OAuth2 + JSON/HTTP

The connection.py factory (get_rpc()) selects the backend based on saved config or --backend flag. REST is the default; XML-RPC is available as fallback via --backend xmlrpc.

OAuth2

O CLI utiliza o grant type client_credentials. O client OAuth2 é vinculado a um usuário no Odoo, e a autenticação usa apenas client_id + client_secret.

O ciclo de vida do token é automático: tokens são persistidos em config.json, renovados na expiração e re-autenticados em caso de falha (retry em 401).

Troubleshooting

Problema Causa Solucao
Connection refused Odoo offline ou URL errada Verificar se Odoo esta rodando: curl http://localhost:8069/web/login
Access Denied Credenciais invalidas Verificar usuario/senha: cli-anything-odoo_12 connect --url ... --save
OAuth2 authentication failed client_id/secret incorretos Verificar OAuth2 client no Odoo (Settings > REST API > OAuth2)
unauthorized_client OAuth Type do client incorreto No Odoo, verificar se o OAuth Type esta como Client Credentials
REST API error 500: AccessError Usuario REST sem permissoes suficientes Alterar tipo do usuario para "Usuario Interno" (Settings > Users)
Modelo nao reconhecido na query Alias NLQ nao existe Usar alias suportado (ver tabela de aliases) ou record search <model>
command not found CLI nao instalado Executar pip install cli-anything-odoo-12 e verificar which cli-anything-odoo_12
404 on /api/* Modulo REST API nao instalado Instalar modulo REST API no Odoo ou usar --backend xmlrpc
NLQ retorna 0 registros Filtros muito restritivos Simplificar a query (remover filtro de data) e testar incrementalmente
Export CSV vazio Domain sem resultados Testar a mesma query sem export primeiro para confirmar resultados

Running Tests

pip install -e ".[dev]"

# Unit tests (no Odoo needed)
python3 -m pytest cli_anything/odoo_12/tests/test_core.py -v

# REST backend unit tests (no Odoo needed — uses mock HTTP)
python3 -m pytest cli_anything/odoo_12/tests/test_rest.py -v

# E2E tests (requires running Odoo)
ODOO_URL=http://localhost:8069 ODOO_DB=mydb ODOO_USER=admin ODOO_PASSWORD=admin \
  python3 -m pytest cli_anything/odoo_12/tests/test_full_e2e.py -v -s

# All tests
CLI_ANYTHING_FORCE_INSTALLED=1 python3 -m pytest cli_anything/odoo_12/tests/ -v -s

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

cli_anything_odoo_12-1.0.2.tar.gz (56.6 kB view details)

Uploaded Source

Built Distribution

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

cli_anything_odoo_12-1.0.2-py3-none-any.whl (66.6 kB view details)

Uploaded Python 3

File details

Details for the file cli_anything_odoo_12-1.0.2.tar.gz.

File metadata

  • Download URL: cli_anything_odoo_12-1.0.2.tar.gz
  • Upload date:
  • Size: 56.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for cli_anything_odoo_12-1.0.2.tar.gz
Algorithm Hash digest
SHA256 9ff066864be452cc9c88abf0ae056b4841a31c8fd97e7ec21221d5fffa5e36e9
MD5 f5fbbc312f9098b8c35778f38a1c2379
BLAKE2b-256 9e4e6ee4bb25cb21daea7a626412a5a95e30fb45b123ba40df3e745cbc9efdba

See more details on using hashes here.

File details

Details for the file cli_anything_odoo_12-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for cli_anything_odoo_12-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0bd4e8d22606ccee783d02bdf8fd1ad3dad5859c830bafc218563c6e57995950
MD5 83b1833363a4bb9cbc8874066c376ef8
BLAKE2b-256 9e1be10b121dd8522e86d81846a61d7e5f4d80f3a1a3457e7b73ad5a807ad815

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