The Cloudflare Python SDK

The Cloudflare Python SDK (pip install cloudflare) gives you programmatic control over Cloudflare's entire platform from your existing Python applications. Think of it as boto3 for Cloudflare — but cleaner, type-safe, and covering everything from DNS to AI.

Installation & Setup

# Install with your favorite package manager
pip install cloudflare
# or
uv pip install cloudflare
# or
poetry add cloudflare
import os
from cloudflare import Cloudflare
# Async support built-in
from cloudflare import AsyncCloudflare

client = Cloudflare(
    api_token=os.environ.get("CLOUDFLARE_API_TOKEN"),  # Recommended
    # or use api_email + api_key (legacy)
)

Type Safety & Auto-completion

Every API call is fully typed with TypedDicts for requests and Pydantic models for responses:

# Your IDE knows exactly what fields are available
zone = client.zones.create(
    account={"id": "your-account-id"},
    name="example.com",
    type="full",  # IDE autocompletes: "full" | "partial" | "secondary"
)

# Response objects are Pydantic models
print(zone.id)               # Fully typed!
print(zone.to_json(indent=2))  # Easy serialization
zone_dict = zone.to_dict()   # Convert to dict

Pagination

The SDK handles pagination automatically, or you can control it manually:

# Automatic pagination
all_zones = []
for zone in client.zones.list():
    all_zones.append(zone)
    print(f"Processing zone: {zone.name}")

# Manual pagination for more control
page = client.zones.list(per_page=50)
while True:
    for zone in page.result:
        print(zone.name)
    if not page.has_next_page():
        break
    page = page.get_next_page()

Async Operations

Use AsyncCloudflare for concurrent API calls:

import asyncio
from cloudflare import AsyncCloudflare

async def process_zones():
    async with AsyncCloudflare() as client:
        # Concurrent API calls
        tasks = []
        async for zone in client.zones.list():
            task = process_zone(client, zone)
            tasks.append(task)

        # Process all zones concurrently
        results = await asyncio.gather(*tasks)
        return results

async def process_zone(client: AsyncCloudflare, zone):
    # Get DNS records concurrently
    records = await client.dns.records.list(zone_id=zone.id)
    return {
        "zone": zone.name,
        "record_count": len(list(records))
    }

# Run
results = asyncio.run(process_zones())

Error Handling

import cloudflare
from cloudflare import Cloudflare
import time

client = Cloudflare()

try:
    zone = client.zones.get(zone_id="invalid-id")
except cloudflare.NotFoundError:
    print("Zone not found")
except cloudflare.RateLimitError as e:
    print(f"Rate limited. Retry after {e.response.headers.get('Retry-After')} seconds")
    time.sleep(int(e.response.headers.get('Retry-After', 60)))
except cloudflare.APIStatusError as e:
    print(f"API error {e.status_code}: {e.response}")
except cloudflare.APIConnectionError:
    print("Network connection failed")

DNS Management

Manage DNS records programmatically — infrastructure as code:

from cloudflare import Cloudflare
from typing import List, Dict

client = Cloudflare()

def sync_dns_records(zone_id: str, desired_records: List[Dict]):
    """Declarative DNS management — define desired state"""

    # Get current records
    current_records = list(client.dns.records.list(zone_id=zone_id))

    # Create a map for easy lookup
    current_map = {(r.type, r.name): r for r in current_records}

    for desired in desired_records:
        key = (desired["type"], desired["name"])
        if key in current_map:
            # Update existing record
            record = current_map[key]
            client.dns.records.update(
                zone_id=zone_id,
                dns_record_id=record.id,
                **desired
            )
            print(f"Updated: {desired['name']} ({desired['type']})")
        else:
            # Create new record
            client.dns.records.create(zone_id=zone_id, **desired)
            print(f"Created: {desired['name']} ({desired['type']})")

# Define your DNS configuration
my_dns_config = [
    {
        "type": "A",
        "name": "api.example.com",
        "content": "192.0.2.1",
        "proxied": True,
    },
    {
        "type": "CNAME",
        "name": "www.example.com",
        "content": "example.com",
        "proxied": True,
    },
    {
        "type": "MX",
        "name": "example.com",
        "content": "mail.example.com",
        "priority": 10,
        "proxied": False,  # MX records can't be proxied
    },
]

sync_dns_records("your-zone-id", my_dns_config)

SDK Coverage

The SDK covers the full Cloudflare platform. Key modules include: