Exemplos Python
Exemplos completos utilizando a biblioteca requests. Compativel com Python 3.8+.
Instalacao
pip install requests
Cliente API Completo
import os
import time
import requests
from typing import Optional
class TesselysApiClient:
"""Cliente para a API Externa Tesselys."""
def __init__(self, api_key: str, secret: str):
self.base_url = "https://api.tesselys.com.br/external/v1"
self.api_key = api_key
self.secret = secret
self.access_token: Optional[str] = None
self.company_token: Optional[str] = None
self.expires_at: float = 0
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json"})
def authenticate(self) -> dict:
"""Autentica com API Key e Secret. Armazena tokens para uso subsequente."""
response = requests.post(
f"{self.base_url}/auth",
json={"secret": self.secret},
headers={
"Content-Type": "application/json",
"x-api-key": self.api_key,
},
)
response.raise_for_status()
data = response.json()
self.access_token = data["accessToken"]
self.company_token = data["companyToken"]
self.expires_at = time.time() + data["expiresIn"]
self.session.headers.update({
"Authorization": f"Bearer {self.access_token}",
"x-company-token": self.company_token,
})
return data
def _ensure_auth(self):
"""Verifica se o token esta valido. Renova se necessario."""
if not self.access_token or time.time() >= self.expires_at - 60:
self.authenticate()
def _request(self, method: str, path: str, **kwargs) -> dict:
"""Executa uma requisicao com retry automatico para 401."""
self._ensure_auth()
url = f"{self.base_url}{path}"
response = self.session.request(method, url, **kwargs)
# Se 401, tenta renovar token e repetir
if response.status_code == 401:
self.authenticate()
response = self.session.request(method, url, **kwargs)
# Se 429, aguarda e tenta novamente
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
response = self.session.request(method, url, **kwargs)
response.raise_for_status()
return response.json()
# ─── Pessoas ──────────────────────────────────────────────
def list_persons(self, **params) -> dict:
"""Lista pessoas com paginacao e filtros."""
return self._request("GET", "/persons", params=params)
def get_person(self, person_id: str) -> dict:
"""Busca uma pessoa por ID."""
return self._request("GET", f"/persons/{person_id}")
def create_person(self, data: dict) -> dict:
"""Cria uma nova pessoa."""
return self._request("POST", "/persons", json=data)
def update_person(self, person_id: str, data: dict) -> dict:
"""Atualiza uma pessoa existente."""
return self._request("PUT", f"/persons/{person_id}", json=data)
# ─── Negocios ─────────────────────────────────────────────
def list_deals(self, **params) -> dict:
"""Lista negocios com paginacao e filtros."""
return self._request("GET", "/deals", params=params)
def get_deal(self, deal_id: str) -> dict:
"""Busca um negocio por ID."""
return self._request("GET", f"/deals/{deal_id}")
def create_deal(self, data: dict) -> dict:
"""Cria um novo negocio."""
return self._request("POST", "/deals", json=data)
def update_deal(self, deal_id: str, data: dict) -> dict:
"""Atualiza um negocio existente."""
return self._request("PUT", f"/deals/{deal_id}", json=data)
# ─── Lancamentos Financeiros ──────────────────────────────
def list_financial_entries(self, **params) -> dict:
"""Lista lancamentos financeiros com paginacao e filtros."""
return self._request("GET", "/financial-entries", params=params)
def get_financial_entry(self, entry_id: str) -> dict:
"""Busca um lancamento financeiro por ID."""
return self._request("GET", f"/financial-entries/{entry_id}")
def create_financial_entry(self, data: dict) -> dict:
"""Cria um novo lancamento financeiro."""
return self._request("POST", "/financial-entries", json=data)
# ─── Produtos ─────────────────────────────────────────────
def list_products(self, **params) -> dict:
"""Lista produtos com paginacao e filtros."""
return self._request("GET", "/products", params=params)
def create_product(self, data: dict) -> dict:
"""Cria um novo produto."""
return self._request("POST", "/products", json=data)
def update_product(self, product_id: str, data: dict) -> dict:
"""Atualiza um produto existente."""
return self._request("PUT", f"/products/{product_id}", json=data)
# ─── Projetos ─────────────────────────────────────────────
def list_projects(self, **params) -> dict:
"""Lista projetos com paginacao e filtros."""
return self._request("GET", "/projects", params=params)
def create_project(self, data: dict) -> dict:
"""Cria um novo projeto."""
return self._request("POST", "/projects", json=data)
Uso Basico
import os
from tesselys_client import TesselysApiClient
def main():
client = TesselysApiClient(
api_key=os.environ["TESSELYS_API_KEY"], # tesselys_ak_...
secret=os.environ["TESSELYS_API_SECRET"], # base64url string
)
# 1. Autenticar
client.authenticate()
print("Autenticado com sucesso!")
# 2. Criar uma pessoa
person = client.create_person({
"name": "Empresa Exemplo Ltda",
"documentNumber": "12345678000190",
"personType": "COMPANY",
"email": "contato@exemplo.com.br",
"classifications": ["CUSTOMER"],
"tags": ["novo-cliente"],
})
print(f"Pessoa criada: {person['id']}")
# 3. Criar um negocio vinculado
deal = client.create_deal({
"title": "Proposta Comercial - Empresa Exemplo",
"customerId": person["id"],
"dealType": "COMMERCIAL",
"dealPipelineId": "seu-pipeline-id",
"amount": 25000.00,
"expectedCloseDate": "2026-06-30",
})
print(f"Negocio criado: {deal['id']} ({deal['code']})")
# 4. Listar clientes PJ
customers = client.list_persons(
personType="COMPANY",
classification="CUSTOMER",
page=1,
limit=10,
)
print(f"Total de clientes PJ: {customers['meta']['total']}")
# 5. Criar lancamento financeiro
entry = client.create_financial_entry({
"personId": person["id"],
"title": "Fatura de Servico - Abril/2026",
"typeCategory": "REVENUE",
"originalAmount": 12500.00,
"originalDueDate": "2026-04-15",
"financialCategoryId": "sua-categoria-id",
"bankAccountId": "sua-conta-id",
"paymentMethod": "BANK_SLIP",
})
print(f"Lancamento criado: {entry['id']} ({entry['code']})")
# 6. Listar lancamentos pendentes do mes
entries = client.list_financial_entries(
typeCategory="REVENUE",
status="PENDING",
dueDateFrom="2026-04-01",
dueDateTo="2026-04-30",
)
total_pending = sum(e["originalAmount"] for e in entries["data"])
print(f"Receitas pendentes em abril: R$ {total_pending:,.2f}")
if __name__ == "__main__":
main()
Tratamento de Erros
import os
from requests.exceptions import HTTPError, ConnectionError, Timeout
from tesselys_client import TesselysApiClient
def safe_operation():
client = TesselysApiClient(
api_key=os.environ["TESSELYS_API_KEY"],
secret=os.environ["TESSELYS_API_SECRET"],
)
try:
client.authenticate()
person = client.create_person({
"name": "Teste",
"personType": "INDIVIDUAL",
"documentNumber": "00000000000", # CPF invalido
})
except HTTPError as e:
response = e.response
status = response.status_code
try:
error_data = response.json()
except ValueError:
print(f"Erro {status}: resposta nao e JSON")
return
friendly_message = error_data.get("friendlyMessage", "Erro desconhecido")
error_code = error_data.get("message", "")
if status == 400:
print(f"Dados invalidos: {friendly_message}")
# Verificar erros de campo
field_errors = error_data.get("errors", [])
for err in field_errors:
print(f" Campo '{err['field']}': {err['message']}")
elif status == 401:
print(f"Nao autorizado: {friendly_message}")
elif status == 404:
print(f"Nao encontrado: {friendly_message}")
elif status == 429:
retry_after = response.headers.get("Retry-After", "60")
print(f"Rate limit excedido. Tente novamente em {retry_after}s.")
elif status >= 500:
print(f"Erro interno do servidor: {friendly_message}")
print("Tente novamente em alguns segundos.")
else:
print(f"Erro {status}: {friendly_message}")
except ConnectionError:
print("Erro de conexao. Verifique sua rede e tente novamente.")
except Timeout:
print("Timeout na requisicao. Tente novamente.")
if __name__ == "__main__":
safe_operation()
Paginacao Automatica
def fetch_all_persons(client: TesselysApiClient, **filters) -> list:
"""Busca todas as pessoas iterando por todas as paginas."""
all_persons = []
page = 1
limit = 100
while True:
result = client.list_persons(page=page, limit=limit, **filters)
all_persons.extend(result["data"])
if page >= result["meta"]["totalPages"]:
break
page += 1
return all_persons
# Uso
client = TesselysApiClient(os.environ["TESSELYS_API_KEY"], os.environ["TESSELYS_API_SECRET"])
client.authenticate()
all_customers = fetch_all_persons(client, personType="COMPANY", classification="CUSTOMER")
print(f"Total de clientes PJ: {len(all_customers)}")