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

Em distros Linux modernas (PEP 668), a solução mais simples é usar pipx, que instala CLIs em ambientes isolados automaticamente:

# Instalar pipx (se ainda não tiver)
sudo apt install pipx
pipx ensurepath

# Instalar o CLI
pipx install cli-anything-odoo-12

# Atualizar para nova versão
pipx upgrade cli-anything-odoo-12

Alternativa com pip (em virtualenv ou sistemas sem PEP 668):

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)

Início Rápido

1. Conectar ao Odoo

O CLI suporta dois protocolos de comunicação:

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)

# Conectar via XML-RPC e salvar credenciais
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. Operações de Registros (CRUD)

# Buscar parceiros (somente empresas)
cli-anything-odoo_12 record search res.partner --domain "[('is_company','=',True)]" --fields name,email --limit 10

# Exemplo de saída:
#   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

# Ler um registro específico
cli-anything-odoo_12 record read res.partner 1 --fields name,email,phone

# Criar registro
cli-anything-odoo_12 record create res.partner --values '{"name":"New Company","is_company":true}'
# Saída: Created res.partner record id=42

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

# Excluir registro
cli-anything-odoo_12 record unlink res.partner 42

# Contar registros
cli-anything-odoo_12 record count res.partner --domain "[('is_company','=',True)]"
# Saída: res.partner: 15 record(s)

# Listar campos do modelo
cli-anything-odoo_12 record fields res.partner
# Saída: res.partner: 143 fields

3. Gerenciamento de Módulos

cli-anything-odoo_12 module list --installed
# Saída: 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. Operações de Banco de Dados

cli-anything-odoo_12 db list
# Saída: 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. Relatórios

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

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

6. Exportação de Dados

# Exportar todos os parceiros para CSV
cli-anything-odoo_12 export csv res.partner --output partners.csv --fields name,email,phone
# Saída: Exported 920 records to partners.csv

# Exportar com filtro de domínio
cli-anything-odoo_12 export csv res.partner --output companies.csv --fields name,email --domain "[('is_company','=',True)]"
# Saída: Exported 15 records to companies.csv

# Exportar para JSON com limite
cli-anything-odoo_12 export json res.partner --output partners.json --fields name,email --limit 100
# Saída: Exported 100 records to partners.json

# Exportar para stdout (omitir --output)
cli-anything-odoo_12 export json res.partner --fields name --limit 3

7. Consulta em Linguagem Natural (NLQ)

O comando ask traduz perguntas em texto livre (PT-BR, EN, ES) em domínios de busca do Odoo usando padrões regex. Sem dependências externas ou LLM.

Consultas Simples

# Listar empresas
cli-anything-odoo_12 ask "liste todas as empresas"

# Exemplo de saída:
#   ━━━ 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)

# Buscar com filtros
cli-anything-odoo_12 ask "faturas de entrada pagas em janeiro/2024"

# Exemplo de saída:
#   ━━━ 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

# Clientes ativos com limite
cli-anything-odoo_12 ask "clientes ativos" --limit 10

# Faturas de fornecedor (resolve para account.invoice com type=in_invoice)
cli-anything-odoo_12 ask "faturas de fornecedor abertas em janeiro/2026"

# Faturas de cliente (resolve para account.invoice com type=out_invoice)
cli-anything-odoo_12 ask "faturas de cliente pagas"

Filtro por Empresa (Multi-Company)

Em ambientes multi-company, o CLI filtra automaticamente pela empresa do usuário logado. Você pode sobrescrever com --company ou diretamente na query:

# Usar empresa do usuário logado (padrão — não precisa especificar nada)
cli-anything-odoo_12 ask "faturas abertas"

# Filtrar por empresa específica via flag --company (ID, nome ou CNPJ)
cli-anything-odoo_12 ask "faturas abertas" --company 3
cli-anything-odoo_12 ask "pedidos de venda" --company "The Cookiery"
cli-anything-odoo_12 ask "produtos" --company "12.345.678/0001-90"

# Filtrar por empresa diretamente na query (hint em linguagem natural)
cli-anything-odoo_12 ask "faturas da empresa The Cookiery"
cli-anything-odoo_12 ask "pedidos de compra da companhia 3"

# Exemplo de saída:
#   ━━━ Faturas — Open ━━━
#     Consulta: account.invoice | company_id=3 | 12 registro(s)
#     ...

Prioridade de resolução do company_id:

  1. Hint na query ("da empresa X") — maior prioridade
  2. Flag --company na linha de comando
  3. Valor salvo no config (config set company_id 3)
  4. Empresa do usuário logado — fallback padrão

Agrupamento entre Modelos (Consultas Analíticas)

Agrupe pedidos por categoria de produto ou produtos individuais — o CLI percorre automaticamente modelos relacionados (pedido > linha > produto > categoria).

# Vendas POS agrupadas por categoria de produto
cli-anything-odoo_12 ask "vendas do pos de janeiro/2026 agrupado por categoria de produto"

# Exemplo de saída:
#   ━━━ 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

# Vendas POS agrupadas por produto individual
cli-anything-odoo_12 ask "vendas do pos agrupado por produto"

# Faturas agrupadas por categoria de produto
cli-anything-odoo_12 ask "faturas agrupado por categoria de produto"

# Pedidos de compra agrupados por categoria de produto
cli-anything-odoo_12 ask "pedidos de compra agrupado por categoria de produto"

Agrupamentos entre Modelos Suportados

Modelo Chave de Agrupamento Caminho de Travessia
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

Agrupamento por Campo Simples

# Vendas POS agrupadas por terminal de ponto de venda
cli-anything-odoo_12 ask "vendas do pos agrupado por pdv"

# Exemplo de saída:
#   ━━━ 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

Com Exportação

# Exportar para CSV
cli-anything-odoo_12 ask "faturas de entrada em janeiro/2024 e exporte para csv em /tmp/faturas.csv"
# Saída: ... Exportado para /tmp/faturas.csv

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

# Consulta combinada com exportação
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"

Outros Exemplos de Consulta

# Aniversariantes de um mês específico
cli-anything-odoo_12 ask "aniversariantes de marco"

# Intervalo de datas
cli-anything-odoo_12 ask "faturas de 01/03 a 15/03"

# Datas relativas
cli-anything-odoo_12 ask "pedidos de compra este mes"
cli-anything-odoo_12 ask "faturas ultimo mes"

# Filtros por valor (formato BRL)
cli-anything-odoo_12 ask "faturas acima de R$ 10.000"
cli-anything-odoo_12 ask "pedidos de venda abaixo de 5000"

# Consultas em inglês
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"

# Consultas em espanhol
cli-anything-odoo_12 ask "facturas pagadas"

Aliases Suportados (Multilíngue)

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 proveedores res.partner (supplier=True)
faturas, notas fiscais invoices facturas account.invoice
faturas de fornecedor supplier invoices account.invoice (type=in_invoice)
faturas de cliente customer invoices account.invoice (type=out_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)

Filtros Suportados

Filtro 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
Company da empresa X, da companhia Y company X

8. Gerenciamento de Configuração

# Mostrar configuração salva (senhas/tokens são mascarados)
cli-anything-odoo_12 config show

# Exemplo de saída:
#   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

# Excluir uma chave específica
cli-anything-odoo_12 config delete --key access_token

# Excluir toda a configuração
cli-anything-odoo_12 config delete

9. Saída JSON (para automação)

O flag --json pode ser usado globalmente ou por comando:

# Qualquer comando com --json produz saída legível por máquina
cli-anything-odoo_12 record search res.partner --limit 3 --json

# Exemplo de saída:
# {
#   "model": "res.partner",
#   "count": 3,
#   "records": [
#     {"id": 1, "name": "My Company", "email": "info@co.com"},
#     ...
#   ]
# }

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

# Saída JSON com agrupamento entre modelos
cli-anything-odoo_12 ask "vendas do pos agrupado por categoria de produto" --json

# Exemplo de saída:
# {
#   "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 module list --installed --json
cli-anything-odoo_12 db list --json

10. REPL Interativo

# Iniciar o REPL (execute sem subcomando)
cli-anything-odoo_12 --url http://localhost:8069 --db mydb --user admin --password admin

# Exemplo de sessão:
#   cli-anything-odoo_12  v1.0.6
#   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

Flags Globais

Flag Efeito
--json Saída JSON legível por máquina (disponível em todos os comandos)
--version Exibe a versão do pacote instalado
--url URL do servidor Odoo (sobrescreve config salva)
--db Nome do banco de dados (sobrescreve config salva)
--user Nome de usuário (sobrescreve config salva)
--password Senha (sobrescreve config salva)
--backend Protocolo de comunicação: rest (padrão) ou xmlrpc
--company, -c Filtro de empresa no ask: ID, nome ou CNPJ (padrão: empresa do usuário logado)

Arquitetura

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)

Arquitetura de Backend

Todos os comandos funcionam de forma idêntica independentemente do backend. O OdooBackend ABC define 21 métodos implementados por OdooRPC (XML-RPC) e OdooREST (REST API):

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

O factory connection.py (get_rpc()) seleciona o backend com base na config salva ou no flag --backend. REST é o padrão; XML-RPC está disponível como 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).

Solução de Problemas

Problema Causa Solução
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

Executando Testes

pip install -e ".[dev]"

# Testes unitários (não precisa de Odoo)
python3 -m pytest cli_anything/odoo_12/tests/test_core.py -v

# Testes do backend REST (não precisa de Odoo — usa mock HTTP)
python3 -m pytest cli_anything/odoo_12/tests/test_rest.py -v

# Testes E2E (requer Odoo rodando)
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

# Todos os testes
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.1.0.tar.gz (60.8 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.1.0-py3-none-any.whl (71.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for cli_anything_odoo_12-1.1.0.tar.gz
Algorithm Hash digest
SHA256 dc88cff1ecbcb8a30c72f5d1284045b2a09f2e6845d895d542ba729c314b36ca
MD5 28d5548596202a8d0cfd67cdc1e1f7c4
BLAKE2b-256 f8a1fe4b9fef227cff9f55aad8fbe8ece3e17ec9b146e9484d4bc66a5707701b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cli_anything_odoo_12-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b24de3ecea24cd66490c4f9af1ca54a657ebdf2c03fa56584f66080861017466
MD5 9874a6ddf2153cbadf2492191d973dd1
BLAKE2b-256 84c1863ca34968e7b15f6ecf05a70b09d3b422e587dc256ece01449a4751f41a

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