Deployment & CI/CD
Deploy Python Workers globally in 30 seconds with Wrangler, or automate your entire deployment pipeline with the Python SDK.
Quick Deploy with Wrangler
# Install wrangler (once)
bun install -g wrangler
# Local development with hot reload
wrangler dev main.py
# Deploy to production
wrangler deploy # 30 seconds to global deployment CI/CD Automation with the Python SDK
Automate your entire deployment pipeline programmatically:
from cloudflare import Cloudflare
import os
import hashlib
from pathlib import Path
from typing import Dict
class CloudflareDeployment:
"""CI/CD deployment automation"""
def __init__(self, api_token: str):
self.client = Cloudflare(api_token=api_token)
def deploy_worker(
self,
script_name: str,
script_path: str,
env_vars: Dict[str, str]
):
"""Deploy a Worker script"""
with open(script_path, 'r') as f:
script_content = f.read()
# Calculate hash for versioning
script_hash = hashlib.sha256(
script_content.encode()
).hexdigest()[:8]
# Upload with environment variables as secrets
bindings = [
{
"type": "secret_text",
"name": key,
"text": value,
}
for key, value in env_vars.items()
]
result = self.client.workers.scripts.update(
script_name,
account_id=os.environ["CLOUDFLARE_ACCOUNT_ID"],
metadata={
"main_module": "index.js",
"bindings": bindings,
"compatibility_date": "2024-01-01",
"tags": [
f"version:{script_hash}",
"env:production"
],
},
files={
"index.js": (
"index.js",
script_content.encode(),
"application/javascript",
)
},
)
print(f"Deployed {script_name} version {script_hash}")
return result Static Site Deployment
def deploy_pages_project(
self,
project_name: str,
build_directory: str
):
"""Deploy a Pages project"""
deployment = self.client.pages.projects.deployments.create(
account_id=os.environ["CLOUDFLARE_ACCOUNT_ID"],
project_name=project_name,
)
# Upload files
for file_path in Path(build_directory).rglob("*"):
if file_path.is_file():
relative_path = file_path.relative_to(build_directory)
# Upload each file to the deployment
print(f"Uploading: {relative_path}")
return deployment Rollbacks
Roll back to a previous version by tag:
def rollback(self, script_name: str, version_tag: str):
"""Rollback to a previous version"""
versions = self.client.workers.scripts.versions.list(
account_id=os.environ["CLOUDFLARE_ACCOUNT_ID"],
script_name=script_name,
)
# Find the version to rollback to
for version in versions:
if version_tag in version.tags:
# Deploy this version
self.client.workers.scripts.versions.deployment.create(
account_id=os.environ["CLOUDFLARE_ACCOUNT_ID"],
script_name=script_name,
version_id=version.id,
)
print(f"Rolled back to version {version_tag}")
return
raise ValueError(f"Version {version_tag} not found") Cache Management
def purge_cache(self, zone_id: str):
"""Purge CDN cache after deployment"""
self.client.cache.purge(
zone_id=zone_id,
purge_everything=True,
)
print("Cache purged") GitHub Actions Example
# Usage in a CI/CD pipeline
if __name__ == "__main__":
deployer = CloudflareDeployment(
os.environ["CLOUDFLARE_API_TOKEN"]
)
# Deploy Worker
deployer.deploy_worker(
"api-worker",
"dist/worker.js",
{
"DATABASE_URL": os.environ["DATABASE_URL"],
"API_KEY": os.environ["API_KEY"],
}
)
# Deploy static site
deployer.deploy_pages_project("my-site", "build/")
# Clear cache
deployer.purge_cache(os.environ["CLOUDFLARE_ZONE_ID"]) Wrangler Configuration Reference
# wrangler.toml
name = "my-python-worker"
main = "main.py"
compatibility_date = "2024-01-01"
# Bindings
[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id"
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-database-id"
[ai]
binding = "AI"
# Queues
[[queues.producers]]
binding = "TASK_QUEUE"
queue = "my-task-queue"
[[queues.consumers]]
queue = "my-task-queue"
max_batch_size = 10
# Cron Triggers
[triggers]
crons = ["*/5 * * * *"] # Every 5 minutes