SDK cliente (Python) para a API Maps to Lead — prospecção de leads a partir do Google Maps. De maneira nenhuma apoiamos ou incentivamos a prática de SPAM.
Project description
maps-to-lead (Python)
SDK cliente (Python 3) para a API Maps to Lead — prospecção de leads a partir do Google Maps: nome, telefone, WhatsApp, site, endereço e (opcional) email/redes.
⚠️ Não apoiamos nem incentivamos a prática de SPAM. Utilize com sabedoria e respeite a LGPD/GDPR e os termos de uso das plataformas.
- Zero dependências — usa só a biblioteca padrão (
urllib). - Tipado (
py.typed) — dataclasses de entrada eTypedDictnas respostas. - Cobre
POST /api/finde todo o painel/manager(state, jobs, leads, export.xlsx, stream ao vivo por SSE).
Este pacote é um cliente HTTP: ele fala com um servidor Maps to Lead que você mesmo hospeda (via Docker ou código). Ele não faz o scraping localmente. Suba o servidor primeiro — veja o README do projeto.
Requisitos
- Python >= 3.8
- Uma instância da API Maps to Lead acessível (ex.:
http://localhost:9000). - O
MANAGER_TOKENdo servidor — necessário apenas para os endpoints do painel.
Instalação
pip install maps-to-lead
Início rápido
from maps_to_lead import MapsToLead
client = MapsToLead("http://localhost:9000", token="MANAGER_TOKEN") # token só p/ o painel
# Inicia a busca — responde na hora com o jobId. Os leads chegam no webhook.
job = client.find(
query={"type": "software", "city": "centro", "state": "rio de janeiro"},
webhook={"url": "https://webhook.site/seu-id", "retry": False, "timeout": 6000},
options={"only_with_phone": True, "only_repeat": False, "only_infos_extras": True},
)
print(job["jobId"]) # ex.: "job_1737500000000_1"
Prefere entrada tipada? Use as dataclasses:
from maps_to_lead import MapsToLead, FindQuery, FindWebhook, FindOptions
client.find(
query=FindQuery(type="restaurante", city="savassi", state="MG"),
webhook=FindWebhook(url="https://meu-endpoint/webhook"),
options=FindOptions(only_with_phone=True),
)
Configuração do cliente
MapsToLead(
"https://seu-host:9000", # base_url (obrigatório)
token="MANAGER_TOKEN", # opcional — exigido pelos endpoints /manager
timeout=30.0, # opcional — timeout padrão por request, em segundos (None desliga)
headers={"X-Custom": "1"}, # opcional — headers extras em toda request
opener=None, # opcional — urllib OpenerDirector (ex.: proxy)
)
API
As respostas são dicts JSON crus (chaves em camelCase, como a API envia). Cada método aceita timeout= (segundos) por chamada.
find(query, webhook, options=None) — inicia uma busca
Não exige token. Responde na hora; a extração roda em segundo plano e cada lead é entregue via POST no seu webhook["url"].
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
query.type |
str | ✅ | ramo/palavra-chave (software, restaurante…) |
query.city / state |
str | ❌ | localização |
webhook.url |
str | ✅ | URL que recebe os leads (um POST por lead) |
webhook.retry |
bool | ❌ | False = sem retentativas. Padrão True |
webhook.timeout |
int | ❌ | timeout por POST ao webhook, em ms (1000–120000) |
options.only_with_phone |
bool | ❌ | ignora lugares sem telefone. Padrão False |
options.only_repeat |
bool | ❌ | False = sem telefones repetidos (dedupe). Padrão True |
options.only_infos_extras |
bool | ❌ | visita o site do lead p/ email/redes. Padrão False |
Painel /manager (exigem token)
state = client.get_state() # snapshot ao vivo (KPIs, jobs, leads)
jobs = client.get_jobs(limit=50) # {"jobs": [...]}
page = client.get_leads(limit=12, offset=0) # {"leads": [...], "total", "limit", "offset"}
job_leads = client.get_job_leads("job_123", limit=50)
xlsx = client.export_leads_xlsx() # bytes (.xlsx)
with open("leads.xlsx", "wb") as f:
f.write(xlsx)
Stream ao vivo (SSE)
# 1) Gerador — encerra com break
for snap in client.stream_snapshots():
print("leads:", snap["totals"]["leads"], "ativos:", snap["totals"]["activeJobs"])
if snap["totals"]["activeJobs"] == 0:
break
# 2) Callback numa thread de fundo + função de parada
stop = client.on_snapshot(
lambda snap: print(snap["totals"]["leads"]),
on_error=lambda e: print("erro:", e),
)
# ...depois: stop()
Tratamento de erros
Toda falha de HTTP/rede vira uma MapsToLeadError:
from maps_to_lead import MapsToLead, MapsToLeadError
try:
client.get_state()
except MapsToLeadError as e:
print(e.status) # 401, 429, 500… (0 = rede/timeout)
print(e.body) # corpo cru da resposta
if e.is_unauthorized: ... # token inválido/ausente
if e.is_rate_limited: ... # 429 — respeite o rate limit
if e.is_network_error: ... # servidor fora do ar / timeout
Payload recebido no seu webhook
Cada lead chega como um POST com o corpo {"lead": {...}}. O tipo é LeadPayload (veja maps_to_lead.models). Exemplo com Flask:
from flask import Flask, request
app = Flask(__name__)
@app.post("/webhook")
def webhook():
lead = request.json["lead"]
print(lead["name"], lead["contacts"]["phone"])
return "", 200
Exemplos
Veja a pasta examples/.
Licença
MIT. faz parte do projeto maps-to-lead.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maps_to_lead-0.0.1.tar.gz.
File metadata
- Download URL: maps_to_lead-0.0.1.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75f278bf67a73e937b45950c618ce26eb3a268d91d2835c1742e8acce9913b24
|
|
| MD5 |
e2d4a4e8764762319e168b04385f79a2
|
|
| BLAKE2b-256 |
0005dea47daa5ed4994131ccc02b384460d65f427ac8a405c40bad812a27b658
|
File details
Details for the file maps_to_lead-0.0.1-py3-none-any.whl.
File metadata
- Download URL: maps_to_lead-0.0.1-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d12608a25a73c1b41d3af8fe0e2e7f4cab887e5b30685c1859e163140ceb37e
|
|
| MD5 |
98cdfc92e94e7a7f62b4e61c1167993c
|
|
| BLAKE2b-256 |
8de50417a21abfb26b4df443111896f378cca93c4819a7ad1ff60e5243e8717f
|