Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bitrix24-python-sdk

Python Testes Dependências Licença

SDK Python para a API REST do Bitrix24, escrito do zero — sem nenhuma biblioteca de terceiros além de requests. Resolve, de fábrica, os três problemas que toda integração séria com o Bitrix24 encontra na prática: rate limit, paginação de bases grandes e operações em massa.

from bitrix24 import Bitrix24Client, CRM, fetch_all, batch

client = Bitrix24Client("https://seuportal.bitrix24.com.br/rest/1/seutoken")
crm = CRM(client)

lead_id = crm.leads.add({"TITLE": "Lead do site", "NAME": "Helena"})
crm.deals.move_stage(42, "WON")

todos = fetch_all(client, "crm.deal.list", {"filter": {"STAGE_ID": "NEW"}})
batch(client, {f"up_{d['ID']}": ("crm.deal.update",
      {"id": d["ID"], "fields": {"OPPORTUNITY": 1000}}) for d in todos})

Dez linhas: cria lead, move negócio no funil, extrai a base inteira e atualiza tudo em massa — com throttle, retry e paginação acontecendo por baixo, sem você pensar neles.


Por que este SDK existe

A API do Bitrix24 é poderosa, mas tem três armadilhas que código ingênuo só descobre em produção:

1. Rate limit: 2 requisições por segundo

O portal corta quem passa de ~2 req/s com QUERY_LIMIT_EXCEEDED (HTTP 503). Scripts sem controle funcionam no teste com 10 registros e quebram na base real. O Bitrix24Client faz throttle automático (espaça as chamadas) e, se ainda assim o corte vier, retenta com backoff exponencial (1s, 2s, 4s...) antes de desistir. Erros de autenticação (invalid_token, HTTP 401) não são retentados — falham rápido com AuthError.

2. Paginação clássica não escala: use start=-1

O jeito óbvio de paginar (start=0, 50, 100...) esconde um custo: a cada página o servidor roda um SELECT COUNT(*) para devolver o campo total. Em uma base com 200 mil negócios, as últimas páginas ficam ordens de grandeza mais lentas que as primeiras.

A solução documentada (e pouco conhecida) é start=-1: desliga a contagem e pagina por cursor de ID — ordena por ID crescente e pede filter[">ID"] = último_id_visto a cada página. Tempo de página constante do primeiro ao último registro. É exatamente o que fetch_all() faz por padrão, com fallback automático para a paginação clássica se o método não suportar.

3. Operações em massa: batch com 50 comandos por chamada

O método batch aceita até 50 comandos numa única requisição HTTP — 50 operações pelo custo (e pela cota de rate limit) de 1. Atualizar 500 negócios um a um custa 500 requisições (~4 minutos só de throttle); com batch(), 10. O SDK monta as querystrings no formato da API (fields[TITLE]=...), divide lotes maiores que 50 automaticamente e suporta encadeamento com $result[nome][campo] dentro do mesmo lote.


Instalação

git clone https://github.com/matheusraull99/bitrix24-python-sdk.git
cd bitrix24-python-sdk
python -m venv .venv
.venv\Scripts\activate          # Windows  (Linux/macOS: source .venv/bin/activate)
pip install -r requirements.txt

Conectando num portal Bitrix24 (gratuito)

  1. Crie uma conta gratuita em bitrix24.com.br — o plano free já inclui CRM e API REST.
  2. No portal: Recursos para desenvolvedores → Outros → Webhook de entrada.
  3. Marque as permissões (crm é suficiente para este SDK) e copie a URL gerada (https://seuportal.bitrix24.com.br/rest/1/token...).
  4. copy .env.example .env e cole a URL em B24_WEBHOOK_URL.

Sem portal? Sem problema. O SDK tem um modo mock completo (create_mock_client()): um portal fake em memória, semeado com 120 negócios, 40 leads, 30 contatos e 15 itens de Smart Process, que responde no formato exato da API (result/total/next/time), incluindo batch com resolução de $result[...]. CLI, exemplos e a suíte de testes inteira rodam offline.

CLI

python cli.py deals list --stage NEW          # lista negócios por estágio
python cli.py leads export --csv saida.csv    # exporta todos os leads
python cli.py call crm.deal.fields            # qualquer método REST cru
python cli.py --mock deals list               # força o portal fake

Exemplos comentados

Script O que demonstra
examples/01_exportar_negocios_csv.py extrair a base inteira de negócios para CSV com paginação start=-1
examples/02_criar_lead_e_mover_funil.py criar lead, converter e mover o negócio de estágio no funil
examples/03_batch_atualizacao_massa.py reajuste em massa: dezenas de updates em pouquíssimas requisições via batch

Testes

pip install -r requirements-dev.txt
pytest -v

30 testes, todos contra o mock (zero rede), cobrindo: retry com backoff exponencial e rate limit com relógio fake (nenhum teste dorme de verdade), paginação start=-1 com verificação do cursor >ID requisição a requisição, divisão de lotes do batch, encadeamento $result e os helpers de CRM.

Estrutura

bitrix24/
├── client.py        # Bitrix24Client: HTTP, rate limit, retry, exceções tipadas
├── exceptions.py    # Bitrix24Error, RateLimitError, AuthError
├── pagination.py    # fetch_all: start=-1 (cursor por ID) + fallback clássico
├── batch.py         # batch: lotes de 50, querystring PHP-style, $result
├── crm.py           # helpers: leads, deals, contacts, crm.item.* (Smart Process)
└── mock.py          # portal fake em memória (fixtures realistas)
cli.py               # linha de comando
examples/            # 3 cenários reais comentados
tests/               # pytest, 100% offline

Decisões de engenharia

  • Transporte injetável. O client depende de um callable (url, payload) -> (status, dict), não de requests diretamente. É isso que torna o modo mock trivial e os testes 100% determinísticos — e permite trocar a stack HTTP sem tocar na lógica de retry/throttle.
  • Tempo injetável. sleep e clock são parâmetros do client. Os testes de rate limit e backoff usam um relógio fake que "dorme" instantaneamente — a suíte inteira roda em ~1 segundo mesmo testando esperas de vários segundos.
  • Exceções tipadas em vez de dicionário de erro. AuthError (não retentável), RateLimitError (retentável, já retentada) e Bitrix24Error (genérica) carregam code e description da API. O chamador decide por tipo, sem parse de string.
  • call() devolve o payload completo, não só result. total, next e time são metadados necessários para paginação e diagnóstico; esconder isso atrás de um retorno "conveniente" força gambiarras depois.
  • Mock com a semântica real, não stubs soltos. O MockTransport reproduz os formatos do CRM clássico (valores string, "ID": "17") e do crm.item.* (camelCase, envelope items), a diferença entre start=-1 e paginação com total/next, o limite de 50 comandos do batch e a substituição server-side de $result. Testar contra a semântica certa é o que dá confiança de que o código funciona no portal de verdade.
  • Sem dependências além de requests. Paginação, batch e rate limit são regras de negócio da API — implementá-las é o objetivo do projeto, não algo a terceirizar.

Licença

MIT — use à vontade.

About

SDK Python para a API REST do Bitrix24: batch de 50 comandos, paginação rápida start=-1, rate limit com retry e CLI — com portal mock para testes offline

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages