Python SDK for the LeadsDB API
Project description
leadsdb
Python SDK for the LeadsDB API.
Features:
- Sync and async clients
- Pydantic models with validation
- Fluent filter API
- Automatic pagination
- Retry with exponential backoff
- Full type hints
Installation
pip install leadsdb
Requires Python 3.10+.
Quick Start
from leadsdb import LeadsDB, Lead
client = LeadsDB("your-api-key")
# Create a lead
lead = client.create(Lead(
name="Acme Corporation",
source="website",
city="San Francisco",
email="contact@acme.com",
rating=4.5,
tags=["enterprise", "saas"],
))
print(f"Created: {lead.name} ({lead.id})")
Async Client
import asyncio
from leadsdb import AsyncLeadsDB, Lead
async def main():
async with AsyncLeadsDB("your-api-key") as client:
lead = await client.create(Lead(
name="Acme Corporation",
source="website",
))
print(f"Created: {lead.name}")
asyncio.run(main())
Client Options
client = LeadsDB(
api_key,
base_url="https://custom.api.com",
timeout=30.0,
max_retries=5,
)
CRUD Operations
Create
from leadsdb import Lead, text_attr, number_attr, bool_attr, list_attr
lead = client.create(Lead(
name="Acme Corporation",
source="website",
description="Leading provider of innovative solutions",
address="123 Main Street",
city="San Francisco",
state="CA",
country="USA",
postal_code="94105",
latitude=37.7749,
longitude=-122.4194,
phone="+1-555-123-4567",
email="contact@acme.com",
website="https://acme.com",
rating=4.5,
review_count=128,
category="Technology",
tags=["enterprise", "saas", "b2b"],
source_id="acme-001",
logo_url="https://acme.com/logo.png",
attributes=[
text_attr("industry", "Software"),
number_attr("employees", 500),
bool_attr("verified", True),
list_attr("products", ["CRM", "ERP", "Analytics"]),
],
))
Get
lead = client.get("lead-id")
Update
from leadsdb import UpdateLeadInput
lead = client.update("lead-id", UpdateLeadInput(
rating=4.8,
city="New York",
tags=["enterprise", "saas", "b2b", "updated"],
))
Delete
client.delete("lead-id")
Listing Leads
Basic List
from leadsdb import city, rating, SortField, SortOrder
result = client.list(
city().eq("Berlin"),
rating().gte(4.0),
sort_by=SortField.NAME,
sort_order=SortOrder.ASC,
limit=20,
)
for lead in result.leads:
print(f"{lead.name} ({lead.city})")
# Pagination
if result.has_more:
next_result = client.list(
city().eq("Berlin"),
cursor=result.next_cursor,
)
Iterator (Automatic Pagination)
for lead in client.iterate(city().eq("Berlin"), sort_by=SortField.NAME):
print(lead.name)
Async Iterator
async for lead in client.iterate(city().eq("Berlin")):
print(lead.name)
Filters
All filters default to AND logic. Use or_() for OR logic.
Text Fields
Available for: name(), city(), country(), state(), category(), source(), email(), phone(), website()
| Method | Description |
|---|---|
eq(value) |
Equals |
neq(value) |
Not equals |
contains(value) |
Contains substring |
not_contains(value) |
Does not contain substring |
is_empty() |
Field is empty |
is_not_empty() |
Field is not empty |
from leadsdb import city, name, email
city().eq("Berlin")
name().contains("Tech")
email().is_not_empty()
Number Fields
Available for: rating(), review_count()
| Method | Description |
|---|---|
eq(value) |
Equals |
neq(value) |
Not equals |
gt(value) |
Greater than |
gte(value) |
Greater than or equal |
lt(value) |
Less than |
lte(value) |
Less than or equal |
from leadsdb import rating, review_count
rating().gte(4.0)
review_count().gt(100)
Array Fields
Available for: tags()
| Method | Description |
|---|---|
contains(value) |
Array contains value |
not_contains(value) |
Array does not contain value |
is_empty() |
Array is empty |
is_not_empty() |
Array is not empty |
from leadsdb import tags
tags().contains("enterprise")
tags().is_not_empty()
Location
| Method | Description |
|---|---|
within_radius(lat, lon, km) |
Within radius in kilometers |
is_set() |
Coordinates are set |
is_not_set() |
Coordinates are not set |
from leadsdb import location
# Find leads within 50km of Berlin
location().within_radius(52.52, 13.405, 50)
Custom Attributes
Use attr(name) for custom attribute filters:
from leadsdb import attr
attr("industry").eq("Software")
attr("employees").gte(100)
OR Logic
from leadsdb import or_, rating
# City is Berlin OR Paris
result = client.list(
rating().gte(4.0), # AND
or_().city().eq("Berlin"), # OR
or_().city().eq("Paris"), # OR
)
Sorting
from leadsdb import SortField, SortOrder, attr_sort_field
# Sort by field
result = client.list(sort_by=SortField.NAME, sort_order=SortOrder.ASC)
result = client.list(sort_by=SortField.RATING, sort_order=SortOrder.DESC)
# Sort by custom attribute
result = client.list(sort_by=attr_sort_field("employees"), sort_order=SortOrder.DESC)
Available sort fields:
SortField.NAME,SortField.CITY,SortField.COUNTRY,SortField.STATESortField.CATEGORY,SortField.SOURCE,SortField.EMAIL,SortField.PHONE,SortField.WEBSITESortField.RATING,SortField.REVIEW_COUNTSortField.CREATED_AT,SortField.UPDATED_AT
Bulk Operations
Bulk Create (up to 100 leads)
result = client.bulk_create([
Lead(name="Lead 1", source="import", city="Athens"),
Lead(name="Lead 2", source="import", city="London"),
Lead(name="Lead 3", source="import", city="Paris"),
])
print(f"Created: {result.success}, Failed: {result.failed}")
for created in result.created:
print(f"ID: {created.id} (index {created.index})")
Notes
# Create a note
note = client.create_note("lead-id", "Initial contact made")
# List notes
notes = client.list_notes("lead-id")
# Update a note
note = client.update_note("note-id", "Updated content")
# Delete a note
client.delete_note("note-id")
Export
from leadsdb import ExportFormat
# Export as CSV
data = client.export(ExportFormat.CSV)
with open("leads.csv", "wb") as f:
f.write(data)
# Export as JSON
data = client.export(ExportFormat.JSON)
Error Handling
from leadsdb import NotFoundError, APIError
try:
lead = client.get("non-existent-id")
except NotFoundError:
print("Lead not found")
except APIError as e:
print(f"Status: {e.status_code}, Message: {e.message}")
Exception types:
NotFoundError- Resource not found (404)UnauthorizedError- Invalid API key (401)ForbiddenError- Access denied (403)RateLimitedError- Too many requests (429)BadRequestError- Invalid request (400)ValidationError- Client-side validation error
Using ListOptions
For more complex queries, you can use ListOptions:
from leadsdb import ListOptions, city, rating, SortField, SortOrder
opts = (
ListOptions()
.with_limit(50)
.with_sort(SortField.RATING, SortOrder.DESC)
.with_filter(city().eq("Berlin"))
.with_filter(rating().gte(4.0))
)
result = client.list(options=opts)
License
MIT
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 leadsdb-0.9.0.tar.gz.
File metadata
- Download URL: leadsdb-0.9.0.tar.gz
- Upload date:
- Size: 15.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95c10209feae5d670df54f24650b43bce9f0ff11e2a2ac82d52909bcd9d9492d
|
|
| MD5 |
4e9df8ea7e45a9ee6ce5d5d5858dd431
|
|
| BLAKE2b-256 |
23f55f97d7c35f61cb6bd721c5eea2b57dbb964c3b796a92b6bb41de99a10b91
|
Provenance
The following attestation bundles were made for leadsdb-0.9.0.tar.gz:
Publisher:
publish.yml on gosom/py-leadsdb
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leadsdb-0.9.0.tar.gz -
Subject digest:
95c10209feae5d670df54f24650b43bce9f0ff11e2a2ac82d52909bcd9d9492d - Sigstore transparency entry: 779840849
- Sigstore integration time:
-
Permalink:
gosom/py-leadsdb@0bf88674ffcc0d683438910f1463de31e456dfc3 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/gosom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0bf88674ffcc0d683438910f1463de31e456dfc3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file leadsdb-0.9.0-py3-none-any.whl.
File metadata
- Download URL: leadsdb-0.9.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
379e15b2109efb17d93a1de0660f4f8e522563f4f3c6b9f6efa21d84d1be90d0
|
|
| MD5 |
91027f2fbee74b6a3ee47a3a9d69dd70
|
|
| BLAKE2b-256 |
4d12a2e8248182bd601909785b54f6217e9fe13d75aabf9183ae7ef1a757a2fa
|
Provenance
The following attestation bundles were made for leadsdb-0.9.0-py3-none-any.whl:
Publisher:
publish.yml on gosom/py-leadsdb
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leadsdb-0.9.0-py3-none-any.whl -
Subject digest:
379e15b2109efb17d93a1de0660f4f8e522563f4f3c6b9f6efa21d84d1be90d0 - Sigstore transparency entry: 779840850
- Sigstore integration time:
-
Permalink:
gosom/py-leadsdb@0bf88674ffcc0d683438910f1463de31e456dfc3 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/gosom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0bf88674ffcc0d683438910f1463de31e456dfc3 -
Trigger Event:
release
-
Statement type: