Command Palette

Search for a command to run...

Python

Python SDK with asyncio support and comprehensive data analysis

Installation & Setup
Required dependencies and project setup for Python

Package Installation

pip install requests aiohttp

pip install requests aiohttp python-dotenv

python -m venv leakzero-env
source leakzero-env/bin/activate

pip install requests aiohttp python-dotenv

requirements.txt

requests>=2.31.0
aiohttp>=3.8.0
python-dotenv>=1.0.0

pandas>=2.0.0
numpy>=1.24.0

structlog>=23.0.0

.env

LEAKZERO_API_KEY=your_api_key_here
LEAKZERO_BASE_URL=https://api.leakzero.io/api/v1
LOG_LEVEL=INFO
Python Version: This example requires Python 3.7+ for asyncio support and dataclasses. For older versions, install the dataclasses backport.
Quick Start Example
Simple example to get you started with Python

basic_usage.py

#!/usr/bin/env python3

import os
from leakzero_client import LeakZeroClient, SearchOptions

def basic_search():
    client = LeakZeroClient(os.getenv('LEAKZERO_API_KEY'))

    try:
        result = client.regular_search(SearchOptions(
            field='email',
            value='[email protected]',
            row_limit=100
        ))

        print(f"Found {result.total_results} records")
        print(f"Cost: {result.cost:.6f}")

        for record in result.data[:5]:
            breach = record.get('breach_name', 'Unknown')
            date = record.get('breach_date', 'Unknown')
            print(f"Breach: {breach}, Date: {date}")

        analysis = client.analyze_breaches(result.data)
        print(f"\nUnique breaches: {analysis['unique_breaches']}")

    except Exception as e:
        print(f"Search failed: {e}")

if __name__ == "__main__":
    basic_search()
Production ReadyComplete Python Implementation
Full-featured client with async support, data analysis, and enterprise features

leakzero_client.py

#!/usr/bin/env python3

import asyncio
import logging
import os
import time
from datetime import datetime
from typing import Dict, List, Optional, Union, Any
from dataclasses import dataclass, field
import json

import aiohttp
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry


@dataclass
class SearchOptions:
    field: str
    value: str
    option: str = 'exact'
    row_limit: int = 1000
    auto_export: Optional[Dict[str, Any]] = None


@dataclass
class SearchResult:
    data: List[Dict[str, Any]]
    total_results: int
    cost: float
    request_id: str
    processing_time: int
    analysis: Optional[Dict[str, Any]] = field(default_factory=dict)


@dataclass
class ApiError(Exception):
    error: str
    message: str
    status_code: int
    retry_after: Optional[int] = None


class LeakZeroClient:

    def __init__(
        self,
        api_key: str,
        base_url: str = "https://api.leakzero.io/api/v1",
        max_retries: int = 3,
        timeout: int = 120,
        log_level: str = "INFO"
    ):
        if not api_key:
            raise ValueError("API key is required")

        self.api_key = api_key
        self.base_url = base_url.rstrip('/')
        self.max_retries = max_retries
        self.timeout = timeout

        logging.basicConfig(level=getattr(logging, log_level.upper()))
        self.logger = logging.getLogger(__name__)

        self.session = self._setup_session()

        self._async_session = None

    def _setup_session(self) -> requests.Session:
        session = requests.Session()

        retry_strategy = Retry(
            total=self.max_retries,
            backoff_factor=1,
            status_forcelist=[429, 500, 502, 503, 504],
            allowed_methods=["GET", "POST"]
        )

        adapter = HTTPAdapter(max_retries=retry_strategy)
        session.mount("http://", adapter)
        session.mount("https://", adapter)

        return session

    def _get_headers(self) -> Dict[str, str]:
        return {
            'x-api-key': self.api_key,
            'x-timestamp': datetime.utcnow().isoformat() + 'Z',
            'x-request-id': self._generate_request_id(),
            'Content-Type': 'application/json',
            'User-Agent': 'LeakZero-Python-SDK/1.0.0'
        }

    def _generate_request_id(self) -> str:
        import uuid
        return f"req_{int(time.time())}_{str(uuid.uuid4())[:8]}"

    def _format_error(self, response: requests.Response) -> ApiError:
        try:
            data = response.json()
            error = data.get('error', 'API_ERROR')
            message = data.get('message', f'HTTP {response.status_code}')
        except:
            error = 'HTTP_ERROR'
            message = f'HTTP {response.status_code}: {response.reason}'

        return ApiError(
            error=error,
            message=message,
            status_code=response.status_code,
            retry_after=response.headers.get('Retry-After')
        )

    def _make_request(
        self,
        method: str,
        endpoint: str,
        data: Optional[Dict] = None
    ) -> requests.Response:
        url = f"{self.base_url}{endpoint}"
        headers = self._get_headers()

        try:
            if method.upper() == 'POST' and data:
                response = self.session.post(
                    url,
                    json=data,
                    headers=headers,
                    timeout=self.timeout
                )
            else:
                response = self.session.get(
                    url,
                    headers=headers,
                    timeout=self.timeout
                )

            self.logger.info(f"API Request successful: {method.upper()} {endpoint}")

            if response.status_code == 429:
                retry_after = int(response.headers.get('Retry-After', 5))
                self.logger.warning(f"Rate limited. Waiting {retry_after}s")
                time.sleep(min(retry_after, 30))
                return self._make_request(method, endpoint, data)

            response.raise_for_status()
            return response

        except requests.RequestException as e:
            if hasattr(e, 'response') and e.response is not None:
                raise self._format_error(e.response)
            raise ApiError('REQUEST_ERROR', str(e), 0)

    def get_balance(self) -> Dict[str, Any]:
        try:
            response = self._make_request('GET', '/public/balance')
            return response.json()
        except Exception as e:
            self.logger.error(f"Failed to get balance: {e}")
            raise

    def regular_search(self, options: Union[SearchOptions, Dict]) -> SearchResult:
        if isinstance(options, dict):
            options = SearchOptions(**options)

        try:
            payload = {
                'field': options.field,
                'value': options.value,
                'option': options.option,
                'rowLimit': min(options.row_limit, 10000)
            }

            if options.auto_export:
                payload['autoExport'] = json.dumps(options.auto_export)

            self.logger.info(f"Searching for {options.field}: {options.value}")

            response = self._make_request('POST', '/public/search/regular', payload)

            result = SearchResult(
                data=response.json().get('data', []),
                total_results=int(response.headers.get('x-rows-returned', 0)),
                cost=int(response.headers.get('x-charge', 0)) / 1_000_000_000,
                request_id=response.headers.get('x-request-id', 'unknown'),
                processing_time=int(response.headers.get('x-processing-time', 0))
            )

            self.logger.info(f"Found {result.total_results} records (Cost: {result.cost:.6f})")
            return result

        except Exception as e:
            self.logger.error(f"Regular search failed: {e}")
            raise


if __name__ == "__main__":
    api_key = os.getenv('LEAKZERO_API_KEY')
    client = LeakZeroClient(api_key)

    options = SearchOptions(field='email', value='[email protected]')
    result = client.regular_search(options)
    print(f"Found {result.total_results} records")
Type Hints: Full type annotations with dataclasses for better IDE support
Async Support: Both synchronous and asynchronous operations supported
Data Science: Built-in analysis tools with Counter and statistics
Key Features

Core Features

  • • Synchronous and asynchronous API support
  • • Automatic retry with exponential backoff
  • • Rate limit handling with intelligent delays
  • • Comprehensive error handling and logging
  • • Context manager support for resource cleanup

Data Analysis Tools

  • • Built-in breach data analysis utilities
  • • Statistical analysis with Counter collections
  • • Date range and distribution analysis
  • • Bulk search operations with batching
  • • Export functionality for large datasets
Best Practices:
  • • Always use environment variables for API keys
  • • Implement proper error handling for production use
  • • Use async operations for better performance with multiple requests
  • • Monitor your API usage and balance regularly
  • • Use virtual environments to manage dependencies
Documentation - LeakZero | LeakZero