chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workers
|
|
3
|
+
description: "Cloudflare Workers SDK for building edge functions with KV and R2 storage in Python"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "python"
|
|
6
|
+
versions: "4.3.1"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "cloudflare,workers,edge,kv,r2"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Cloudflare API Coding Guidelines (Python)
|
|
13
|
+
|
|
14
|
+
You are a Cloudflare API coding expert. Help me with writing code using the Cloudflare API calling the official libraries and SDKs.
|
|
15
|
+
|
|
16
|
+
You can find the official SDK documentation and code samples here:
|
|
17
|
+
https://developers.cloudflare.com/api/
|
|
18
|
+
|
|
19
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
20
|
+
|
|
21
|
+
Always use the official Cloudflare Python SDK to interact with the Cloudflare API, which is the standard library for all Cloudflare API interactions. Do not use unofficial libraries or deprecated packages.
|
|
22
|
+
|
|
23
|
+
- **Library Name:** Cloudflare Python SDK
|
|
24
|
+
- **PyPI Package:** `cloudflare`
|
|
25
|
+
- **Legacy Libraries:** Avoid `python-cloudflare` (archived) or unofficial packages
|
|
26
|
+
|
|
27
|
+
**Installation:**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install cloudflare
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**APIs and Usage:**
|
|
34
|
+
|
|
35
|
+
- **Correct:** `from cloudflare import Cloudflare`
|
|
36
|
+
- **Correct:** `client = Cloudflare()`
|
|
37
|
+
- **Correct:** `client.zones.create(...)`
|
|
38
|
+
- **Correct:** `from cloudflare import AsyncCloudflare`
|
|
39
|
+
- **Incorrect:** `CloudflareAPI` or `CloudFlare`
|
|
40
|
+
- **Incorrect:** Using the archived `python-cloudflare` package
|
|
41
|
+
- **Incorrect:** `CloudflareClient`
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
Install the Cloudflare SDK:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install cloudflare
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Set your API token as an environment variable:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export CLOUDFLARE_API_TOKEN='your_api_token_here'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Initialization
|
|
58
|
+
|
|
59
|
+
The `cloudflare` library requires creating a `Cloudflare` instance for all API calls.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import os
|
|
63
|
+
from cloudflare import Cloudflare
|
|
64
|
+
|
|
65
|
+
# Uses the CLOUDFLARE_API_TOKEN environment variable if api_token not specified
|
|
66
|
+
client = Cloudflare()
|
|
67
|
+
|
|
68
|
+
# Or pass the API token directly
|
|
69
|
+
# client = Cloudflare(api_token=os.environ.get("CLOUDFLARE_API_TOKEN"))
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Alternative Authentication
|
|
73
|
+
|
|
74
|
+
You can also authenticate with API email and key (legacy method):
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
client = Cloudflare(
|
|
78
|
+
api_email=os.environ.get("CLOUDFLARE_API_EMAIL"),
|
|
79
|
+
api_key=os.environ.get("CLOUDFLARE_API_KEY"),
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Async Client
|
|
84
|
+
|
|
85
|
+
The SDK provides an async client for asynchronous operations:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import asyncio
|
|
89
|
+
import os
|
|
90
|
+
from cloudflare import AsyncCloudflare
|
|
91
|
+
|
|
92
|
+
client = AsyncCloudflare(
|
|
93
|
+
api_token=os.environ.get("CLOUDFLARE_API_TOKEN"),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
async def main():
|
|
97
|
+
zone = await client.zones.create(
|
|
98
|
+
account={"id": "023e105f4ecef8ad9ca31a8372d0c353"},
|
|
99
|
+
name="example.com",
|
|
100
|
+
type="full",
|
|
101
|
+
)
|
|
102
|
+
print(zone.id)
|
|
103
|
+
|
|
104
|
+
asyncio.run(main())
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Zone Management
|
|
108
|
+
|
|
109
|
+
Zones are the foundation of Cloudflare - each zone represents a domain.
|
|
110
|
+
|
|
111
|
+
### Create a Zone
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from cloudflare import Cloudflare
|
|
115
|
+
|
|
116
|
+
client = Cloudflare()
|
|
117
|
+
|
|
118
|
+
zone = client.zones.create(
|
|
119
|
+
account={"id": "023e105f4ecef8ad9ca31a8372d0c353"},
|
|
120
|
+
name="example.com",
|
|
121
|
+
type="full",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
print(zone.id)
|
|
125
|
+
print(zone.name)
|
|
126
|
+
print(zone.status)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Get Zone Details
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
zone = client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
133
|
+
|
|
134
|
+
print(zone.name)
|
|
135
|
+
print(zone.status)
|
|
136
|
+
print(zone.name_servers)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### List Zones
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
# List all zones with auto-pagination
|
|
143
|
+
all_zones = []
|
|
144
|
+
for zone in client.zones.list():
|
|
145
|
+
all_zones.append(zone)
|
|
146
|
+
print(f"{zone.id}: {zone.name}")
|
|
147
|
+
|
|
148
|
+
# Or with filtering
|
|
149
|
+
zones = client.zones.list(
|
|
150
|
+
account={"id": "023e105f4ecef8ad9ca31a8372d0c353"},
|
|
151
|
+
status="active",
|
|
152
|
+
)
|
|
153
|
+
for zone in zones:
|
|
154
|
+
print(zone.name)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Edit a Zone
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
client.zones.edit(
|
|
161
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
162
|
+
paused=False,
|
|
163
|
+
type="full",
|
|
164
|
+
)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Delete a Zone
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
client.zones.delete(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## DNS Records Management
|
|
174
|
+
|
|
175
|
+
Manage DNS records for your zones.
|
|
176
|
+
|
|
177
|
+
### Create DNS Record
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from cloudflare import Cloudflare
|
|
181
|
+
|
|
182
|
+
client = Cloudflare()
|
|
183
|
+
|
|
184
|
+
record = client.dns.records.create(
|
|
185
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
186
|
+
type="A",
|
|
187
|
+
name="www",
|
|
188
|
+
content="192.0.2.1",
|
|
189
|
+
ttl=3600,
|
|
190
|
+
proxied=True,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
print(record.id)
|
|
194
|
+
print(record.name)
|
|
195
|
+
print(record.type)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### List DNS Records
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
# List all DNS records for a zone
|
|
202
|
+
records = client.dns.records.list(
|
|
203
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
for record in records:
|
|
207
|
+
print(f"{record.type} {record.name} -> {record.content}")
|
|
208
|
+
|
|
209
|
+
# Filter by record type
|
|
210
|
+
a_records = client.dns.records.list(
|
|
211
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
212
|
+
type="A",
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
for record in a_records:
|
|
216
|
+
print(f"{record.name}: {record.content}")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Update DNS Record
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
client.dns.records.update(
|
|
223
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
224
|
+
dns_record_id="372e67954025e0ba6aaa6d586b9e0b59",
|
|
225
|
+
type="A",
|
|
226
|
+
name="www",
|
|
227
|
+
content="192.0.2.2",
|
|
228
|
+
ttl=3600,
|
|
229
|
+
proxied=True,
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Delete DNS Record
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
client.dns.records.delete(
|
|
237
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
238
|
+
dns_record_id="372e67954025e0ba6aaa6d586b9e0b59",
|
|
239
|
+
)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Workers Management
|
|
243
|
+
|
|
244
|
+
Cloudflare Workers allows you to run code at the edge.
|
|
245
|
+
|
|
246
|
+
### Upload a Worker Script
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from cloudflare import Cloudflare
|
|
250
|
+
|
|
251
|
+
client = Cloudflare()
|
|
252
|
+
|
|
253
|
+
# Read worker script from file
|
|
254
|
+
with open("worker.js", "r") as f:
|
|
255
|
+
script_content = f.read()
|
|
256
|
+
|
|
257
|
+
client.workers.scripts.update(
|
|
258
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
259
|
+
script_name="my-worker",
|
|
260
|
+
**{"<any part name>": script_content},
|
|
261
|
+
metadata={
|
|
262
|
+
"main_module": "worker.js",
|
|
263
|
+
"compatibility_date": "2025-01-01",
|
|
264
|
+
},
|
|
265
|
+
)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### List Worker Scripts
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
scripts = client.workers.scripts.list(
|
|
272
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
for script in scripts:
|
|
276
|
+
print(script.id)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Get Worker Script
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
script = client.workers.scripts.get(
|
|
283
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
284
|
+
script_name="my-worker",
|
|
285
|
+
)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Delete Worker Script
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
client.workers.scripts.delete(
|
|
292
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
293
|
+
script_name="my-worker",
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Workers KV Storage
|
|
298
|
+
|
|
299
|
+
Workers KV is a global, low-latency key-value data store.
|
|
300
|
+
|
|
301
|
+
### Create KV Namespace
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
namespace = client.kv.namespaces.create(
|
|
305
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
306
|
+
title="my-kv-namespace",
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
print(namespace.id)
|
|
310
|
+
print(namespace.title)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### List KV Namespaces
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
namespaces = client.kv.namespaces.list(
|
|
317
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
for ns in namespaces:
|
|
321
|
+
print(f"{ns.id}: {ns.title}")
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Write KV Value
|
|
325
|
+
|
|
326
|
+
```python
|
|
327
|
+
client.kv.namespaces.values.update(
|
|
328
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
329
|
+
namespace_id="0f2ac74b498b48028cb68387c421e279",
|
|
330
|
+
key_name="my-key",
|
|
331
|
+
value="my-value",
|
|
332
|
+
metadata='{"someMetadata": "value"}',
|
|
333
|
+
)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Read KV Value
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
value = client.kv.namespaces.values.get(
|
|
340
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
341
|
+
namespace_id="0f2ac74b498b48028cb68387c421e279",
|
|
342
|
+
key_name="my-key",
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
print(value)
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Delete KV Value
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
client.kv.namespaces.values.delete(
|
|
352
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
353
|
+
namespace_id="0f2ac74b498b48028cb68387c421e279",
|
|
354
|
+
key_name="my-key",
|
|
355
|
+
)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Delete KV Namespace
|
|
359
|
+
|
|
360
|
+
```python
|
|
361
|
+
client.kv.namespaces.delete(
|
|
362
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
363
|
+
namespace_id="0f2ac74b498b48028cb68387c421e279",
|
|
364
|
+
)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## R2 Object Storage
|
|
368
|
+
|
|
369
|
+
R2 is S3-compatible object storage without egress fees.
|
|
370
|
+
|
|
371
|
+
### Create R2 Bucket
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
bucket = client.r2.buckets.create(
|
|
375
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
376
|
+
name="my-bucket",
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
print(bucket.name)
|
|
380
|
+
print(bucket.creation_date)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### List R2 Buckets
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
buckets = client.r2.buckets.list(
|
|
387
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
for bucket in buckets.buckets:
|
|
391
|
+
print(bucket.name)
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Delete R2 Bucket
|
|
395
|
+
|
|
396
|
+
```python
|
|
397
|
+
client.r2.buckets.delete(
|
|
398
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
399
|
+
bucket_name="my-bucket",
|
|
400
|
+
)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## D1 Database
|
|
404
|
+
|
|
405
|
+
D1 is Cloudflare's native serverless SQL database.
|
|
406
|
+
|
|
407
|
+
### Create D1 Database
|
|
408
|
+
|
|
409
|
+
```python
|
|
410
|
+
database = client.d1.database.create(
|
|
411
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
412
|
+
name="my-database",
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
print(database.uuid)
|
|
416
|
+
print(database.name)
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### List D1 Databases
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
databases = client.d1.database.list(
|
|
423
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
for db in databases:
|
|
427
|
+
print(f"{db.uuid}: {db.name}")
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Query D1 Database
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
result = client.d1.database.query(
|
|
434
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
435
|
+
database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
436
|
+
sql="SELECT * FROM users WHERE id = ?",
|
|
437
|
+
params=["123"],
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
print(result)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Delete D1 Database
|
|
444
|
+
|
|
445
|
+
```python
|
|
446
|
+
client.d1.database.delete(
|
|
447
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
448
|
+
database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
449
|
+
)
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Pages Projects
|
|
453
|
+
|
|
454
|
+
Cloudflare Pages allows you to deploy static sites and full-stack applications.
|
|
455
|
+
|
|
456
|
+
### Create Pages Project
|
|
457
|
+
|
|
458
|
+
```python
|
|
459
|
+
project = client.pages.projects.create(
|
|
460
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
461
|
+
name="my-project",
|
|
462
|
+
production_branch="main",
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
print(project.name)
|
|
466
|
+
print(project.subdomain)
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### List Pages Projects
|
|
470
|
+
|
|
471
|
+
```python
|
|
472
|
+
projects = client.pages.projects.list(
|
|
473
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
for project in projects:
|
|
477
|
+
print(f"{project.name}: {project.subdomain}")
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Get Pages Project
|
|
481
|
+
|
|
482
|
+
```python
|
|
483
|
+
project = client.pages.projects.get(
|
|
484
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
485
|
+
project_name="my-project",
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
print(project.name)
|
|
489
|
+
print(project.production_branch)
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Delete Pages Project
|
|
493
|
+
|
|
494
|
+
```python
|
|
495
|
+
client.pages.projects.delete(
|
|
496
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
497
|
+
project_name="my-project",
|
|
498
|
+
)
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## Account Management
|
|
502
|
+
|
|
503
|
+
### List Accounts
|
|
504
|
+
|
|
505
|
+
```python
|
|
506
|
+
# Auto-pagination
|
|
507
|
+
all_accounts = []
|
|
508
|
+
for account in client.accounts.list():
|
|
509
|
+
all_accounts.append(account)
|
|
510
|
+
print(f"{account.id}: {account.name}")
|
|
511
|
+
|
|
512
|
+
# Manual pagination
|
|
513
|
+
page = client.accounts.list(per_page=20)
|
|
514
|
+
for account in page.result:
|
|
515
|
+
print(account.name)
|
|
516
|
+
|
|
517
|
+
if page.has_next_page():
|
|
518
|
+
next_page = page.get_next_page()
|
|
519
|
+
for account in next_page.result:
|
|
520
|
+
print(account.name)
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Get Account Details
|
|
524
|
+
|
|
525
|
+
```python
|
|
526
|
+
account = client.accounts.get(
|
|
527
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
print(account.name)
|
|
531
|
+
print(account.settings)
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## Load Balancers
|
|
535
|
+
|
|
536
|
+
### Create Load Balancer
|
|
537
|
+
|
|
538
|
+
```python
|
|
539
|
+
load_balancer = client.load_balancers.create(
|
|
540
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
541
|
+
name="my-load-balancer",
|
|
542
|
+
default_pools=["17b5962d775c646f3f9725cbc7a53df4"],
|
|
543
|
+
fallback_pool="17b5962d775c646f3f9725cbc7a53df4",
|
|
544
|
+
ttl=30,
|
|
545
|
+
steering_policy="random",
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
print(load_balancer.id)
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### List Load Balancers
|
|
552
|
+
|
|
553
|
+
```python
|
|
554
|
+
load_balancers = client.load_balancers.list(
|
|
555
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
for lb in load_balancers:
|
|
559
|
+
print(f"{lb.id}: {lb.name}")
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Create Load Balancer Pool
|
|
563
|
+
|
|
564
|
+
```python
|
|
565
|
+
pool = client.load_balancers.pools.create(
|
|
566
|
+
account_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
567
|
+
name="my-pool",
|
|
568
|
+
origins=[
|
|
569
|
+
{
|
|
570
|
+
"name": "origin-1",
|
|
571
|
+
"address": "192.0.2.1",
|
|
572
|
+
"enabled": True,
|
|
573
|
+
"weight": 1,
|
|
574
|
+
},
|
|
575
|
+
],
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
print(pool.id)
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
## Cache Management
|
|
582
|
+
|
|
583
|
+
### Purge Cache
|
|
584
|
+
|
|
585
|
+
```python
|
|
586
|
+
# Purge everything
|
|
587
|
+
client.cache.purge(
|
|
588
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
589
|
+
purge_everything=True,
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
# Purge by URLs
|
|
593
|
+
client.cache.purge(
|
|
594
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
595
|
+
files=[
|
|
596
|
+
"https://example.com/file1.jpg",
|
|
597
|
+
"https://example.com/file2.jpg",
|
|
598
|
+
],
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
# Purge by tags
|
|
602
|
+
client.cache.purge(
|
|
603
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
604
|
+
tags=["tag1", "tag2"],
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
# Purge by prefix
|
|
608
|
+
client.cache.purge(
|
|
609
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
610
|
+
prefixes=["https://example.com/images/"],
|
|
611
|
+
)
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
## WAF and Firewall Rules
|
|
615
|
+
|
|
616
|
+
### Create Firewall Rule
|
|
617
|
+
|
|
618
|
+
```python
|
|
619
|
+
rule = client.firewall.rules.create(
|
|
620
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
621
|
+
filter={
|
|
622
|
+
"expression": "(ip.src eq 192.0.2.1)",
|
|
623
|
+
},
|
|
624
|
+
action="block",
|
|
625
|
+
description="Block specific IP",
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
print(rule.id)
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### List Firewall Rules
|
|
632
|
+
|
|
633
|
+
```python
|
|
634
|
+
rules = client.firewall.rules.list(
|
|
635
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
for rule in rules:
|
|
639
|
+
print(f"{rule.id}: {rule.description}")
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
## SSL/TLS Certificate Management
|
|
643
|
+
|
|
644
|
+
### List SSL Certificates
|
|
645
|
+
|
|
646
|
+
```python
|
|
647
|
+
certificates = client.ssl.certificates.list(
|
|
648
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
649
|
+
)
|
|
650
|
+
|
|
651
|
+
for cert in certificates:
|
|
652
|
+
print(cert.id)
|
|
653
|
+
print(cert.hosts)
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Get SSL Settings
|
|
657
|
+
|
|
658
|
+
```python
|
|
659
|
+
settings = client.ssl.settings.get(
|
|
660
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
print(settings)
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
## File Uploads
|
|
667
|
+
|
|
668
|
+
The SDK supports multiple file input formats for endpoints that require file uploads:
|
|
669
|
+
|
|
670
|
+
```python
|
|
671
|
+
from pathlib import Path
|
|
672
|
+
from cloudflare import Cloudflare
|
|
673
|
+
|
|
674
|
+
client = Cloudflare()
|
|
675
|
+
|
|
676
|
+
# Using Path objects (recommended)
|
|
677
|
+
client.api_gateway.user_schemas.create(
|
|
678
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
679
|
+
file=Path("/path/to/file"),
|
|
680
|
+
kind="openapi_v3",
|
|
681
|
+
)
|
|
682
|
+
|
|
683
|
+
# Using file-like objects
|
|
684
|
+
with open("/path/to/file", "rb") as f:
|
|
685
|
+
client.api_gateway.user_schemas.create(
|
|
686
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
687
|
+
file=f,
|
|
688
|
+
kind="openapi_v3",
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
# Using bytes
|
|
692
|
+
with open("/path/to/file", "rb") as f:
|
|
693
|
+
file_bytes = f.read()
|
|
694
|
+
client.api_gateway.user_schemas.create(
|
|
695
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
696
|
+
file=file_bytes,
|
|
697
|
+
kind="openapi_v3",
|
|
698
|
+
)
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
## Error Handling
|
|
702
|
+
|
|
703
|
+
The SDK provides comprehensive error handling with specific error types:
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
import cloudflare
|
|
707
|
+
from cloudflare import Cloudflare
|
|
708
|
+
|
|
709
|
+
client = Cloudflare()
|
|
710
|
+
|
|
711
|
+
try:
|
|
712
|
+
zone = client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
713
|
+
except cloudflare.APIConnectionError as e:
|
|
714
|
+
print("Server unreachable")
|
|
715
|
+
print(e.__cause__)
|
|
716
|
+
except cloudflare.RateLimitError as e:
|
|
717
|
+
print("429 rate limit error")
|
|
718
|
+
print(e.status_code)
|
|
719
|
+
print(e.response)
|
|
720
|
+
except cloudflare.APIStatusError as e:
|
|
721
|
+
print(f"Error {e.status_code}")
|
|
722
|
+
print(e.response)
|
|
723
|
+
except Exception as e:
|
|
724
|
+
print(f"Unexpected error: {e}")
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Error Types
|
|
728
|
+
|
|
729
|
+
- `APIConnectionError` - Server unreachable or connection issues
|
|
730
|
+
- `RateLimitError` - 429 rate limit exceeded
|
|
731
|
+
- `APIStatusError` - Any HTTP error status (400, 401, 403, 404, etc.)
|
|
732
|
+
- `APITimeoutError` - Request timeout
|
|
733
|
+
|
|
734
|
+
All errors have access to:
|
|
735
|
+
- `e.status_code` - HTTP status code (if available)
|
|
736
|
+
- `e.response` - Raw response object
|
|
737
|
+
- `e.body` - Response body
|
|
738
|
+
|
|
739
|
+
## Advanced Configuration
|
|
740
|
+
|
|
741
|
+
### Retries
|
|
742
|
+
|
|
743
|
+
Configure automatic retry behavior:
|
|
744
|
+
|
|
745
|
+
```python
|
|
746
|
+
from cloudflare import Cloudflare
|
|
747
|
+
|
|
748
|
+
# Configure default retries for all requests
|
|
749
|
+
client = Cloudflare(max_retries=3) # default is 2
|
|
750
|
+
|
|
751
|
+
# Or configure per-request
|
|
752
|
+
client.with_options(max_retries=5).zones.get(
|
|
753
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
754
|
+
)
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
The SDK automatically retries:
|
|
758
|
+
- Connection errors
|
|
759
|
+
- 408 Request Timeout
|
|
760
|
+
- 409 Conflict
|
|
761
|
+
- 429 Rate Limit
|
|
762
|
+
- >=500 Internal errors
|
|
763
|
+
|
|
764
|
+
### Timeouts
|
|
765
|
+
|
|
766
|
+
Set custom timeout values:
|
|
767
|
+
|
|
768
|
+
```python
|
|
769
|
+
from cloudflare import Cloudflare
|
|
770
|
+
import httpx
|
|
771
|
+
|
|
772
|
+
# Simple timeout (20 seconds)
|
|
773
|
+
client = Cloudflare(timeout=20.0) # default is 1 minute
|
|
774
|
+
|
|
775
|
+
# Granular timeout control
|
|
776
|
+
client = Cloudflare(
|
|
777
|
+
timeout=httpx.Timeout(
|
|
778
|
+
60.0, # total timeout
|
|
779
|
+
read=5.0, # read timeout
|
|
780
|
+
write=10.0, # write timeout
|
|
781
|
+
connect=2.0, # connect timeout
|
|
782
|
+
),
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
# Override per-request
|
|
786
|
+
client.with_options(timeout=5.0).zones.edit(
|
|
787
|
+
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
|
|
788
|
+
)
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
### Custom HTTP Client
|
|
792
|
+
|
|
793
|
+
Provide a custom HTTP client for proxies or custom configuration:
|
|
794
|
+
|
|
795
|
+
```python
|
|
796
|
+
import httpx
|
|
797
|
+
from cloudflare import Cloudflare, DefaultHttpxClient
|
|
798
|
+
|
|
799
|
+
client = Cloudflare(
|
|
800
|
+
http_client=DefaultHttpxClient(
|
|
801
|
+
proxy="http://my.test.proxy.example.com",
|
|
802
|
+
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
|
|
803
|
+
),
|
|
804
|
+
)
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### Base URL Override
|
|
808
|
+
|
|
809
|
+
Override the base API URL:
|
|
810
|
+
|
|
811
|
+
```python
|
|
812
|
+
client = Cloudflare(
|
|
813
|
+
base_url="http://my.test.server.example.com:8083",
|
|
814
|
+
)
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Accessing Raw Response Data
|
|
818
|
+
|
|
819
|
+
Access underlying HTTP response data:
|
|
820
|
+
|
|
821
|
+
```python
|
|
822
|
+
from cloudflare import Cloudflare
|
|
823
|
+
|
|
824
|
+
client = Cloudflare()
|
|
825
|
+
|
|
826
|
+
# Get raw response
|
|
827
|
+
response = client.zones.with_raw_response.create(
|
|
828
|
+
account={"id": "023e105f4ecef8ad9ca31a8372d0c353"},
|
|
829
|
+
name="example.com",
|
|
830
|
+
type="full",
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
print(response.headers.get("X-Request-ID"))
|
|
834
|
+
print(response.status_code)
|
|
835
|
+
|
|
836
|
+
# Parse the response
|
|
837
|
+
zone = response.parse()
|
|
838
|
+
print(zone.id)
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Streaming Responses
|
|
842
|
+
|
|
843
|
+
Stream large responses:
|
|
844
|
+
|
|
845
|
+
```python
|
|
846
|
+
with client.zones.with_streaming_response.create(
|
|
847
|
+
account={"id": "023e105f4ecef8ad9ca31a8372d0c353"},
|
|
848
|
+
name="example.com",
|
|
849
|
+
type="full",
|
|
850
|
+
) as response:
|
|
851
|
+
print(response.headers.get("X-My-Header"))
|
|
852
|
+
for line in response.iter_lines():
|
|
853
|
+
print(line)
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
## Pagination
|
|
857
|
+
|
|
858
|
+
Handle paginated responses automatically or manually:
|
|
859
|
+
|
|
860
|
+
```python
|
|
861
|
+
from cloudflare import Cloudflare
|
|
862
|
+
|
|
863
|
+
client = Cloudflare()
|
|
864
|
+
|
|
865
|
+
# Auto-pagination (recommended)
|
|
866
|
+
all_zones = []
|
|
867
|
+
for zone in client.zones.list():
|
|
868
|
+
all_zones.append(zone)
|
|
869
|
+
print(zone.name)
|
|
870
|
+
|
|
871
|
+
# Manual pagination
|
|
872
|
+
first_page = client.zones.list(per_page=20)
|
|
873
|
+
for zone in first_page.result:
|
|
874
|
+
print(zone.name)
|
|
875
|
+
|
|
876
|
+
if first_page.has_next_page():
|
|
877
|
+
print(f"Next page info: {first_page.next_page_info()}")
|
|
878
|
+
next_page = first_page.get_next_page()
|
|
879
|
+
for zone in next_page.result:
|
|
880
|
+
print(zone.name)
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
### Async Pagination
|
|
884
|
+
|
|
885
|
+
```python
|
|
886
|
+
import asyncio
|
|
887
|
+
from cloudflare import AsyncCloudflare
|
|
888
|
+
|
|
889
|
+
client = AsyncCloudflare()
|
|
890
|
+
|
|
891
|
+
async def main():
|
|
892
|
+
# Auto-pagination
|
|
893
|
+
all_accounts = []
|
|
894
|
+
async for account in client.accounts.list():
|
|
895
|
+
all_accounts.append(account)
|
|
896
|
+
print(all_accounts)
|
|
897
|
+
|
|
898
|
+
# Manual pagination
|
|
899
|
+
first_page = await client.accounts.list()
|
|
900
|
+
if first_page.has_next_page():
|
|
901
|
+
next_page = await first_page.get_next_page()
|
|
902
|
+
print(f"Items: {len(next_page.result)}")
|
|
903
|
+
|
|
904
|
+
asyncio.run(main())
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
## Context Manager Usage
|
|
908
|
+
|
|
909
|
+
Use context managers to ensure proper resource cleanup:
|
|
910
|
+
|
|
911
|
+
```python
|
|
912
|
+
from cloudflare import Cloudflare
|
|
913
|
+
|
|
914
|
+
with Cloudflare() as client:
|
|
915
|
+
zone = client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
916
|
+
print(zone.name)
|
|
917
|
+
# HTTP client is automatically closed
|
|
918
|
+
|
|
919
|
+
# Async context manager
|
|
920
|
+
import asyncio
|
|
921
|
+
from cloudflare import AsyncCloudflare
|
|
922
|
+
|
|
923
|
+
async def main():
|
|
924
|
+
async with AsyncCloudflare() as client:
|
|
925
|
+
zone = await client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
926
|
+
print(zone.name)
|
|
927
|
+
|
|
928
|
+
asyncio.run(main())
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
## Type Checking
|
|
932
|
+
|
|
933
|
+
The SDK includes full type annotations for use with mypy or other type checkers:
|
|
934
|
+
|
|
935
|
+
```python
|
|
936
|
+
from cloudflare import Cloudflare
|
|
937
|
+
from cloudflare.types import Zone
|
|
938
|
+
|
|
939
|
+
client: Cloudflare = Cloudflare()
|
|
940
|
+
|
|
941
|
+
zone: Zone = client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
942
|
+
print(zone.id)
|
|
943
|
+
print(zone.name)
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
## Custom/Undocumented Endpoints
|
|
947
|
+
|
|
948
|
+
Make requests to endpoints not yet in the typed SDK:
|
|
949
|
+
|
|
950
|
+
```python
|
|
951
|
+
import httpx
|
|
952
|
+
|
|
953
|
+
# POST request to custom endpoint
|
|
954
|
+
response = client.post(
|
|
955
|
+
"/some/path",
|
|
956
|
+
cast_to=httpx.Response,
|
|
957
|
+
body={"some_prop": "foo"},
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
print(response.headers.get("x-foo"))
|
|
961
|
+
|
|
962
|
+
# GET request
|
|
963
|
+
response = client.get(
|
|
964
|
+
"/custom/endpoint",
|
|
965
|
+
cast_to=httpx.Response,
|
|
966
|
+
options={"params": {"filter": "active"}},
|
|
967
|
+
)
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
## Checking for Null vs. Missing Fields
|
|
971
|
+
|
|
972
|
+
Distinguish between null values and missing fields:
|
|
973
|
+
|
|
974
|
+
```python
|
|
975
|
+
response = client.zones.get(zone_id="023e105f4ecef8ad9ca31a8372d0c353")
|
|
976
|
+
|
|
977
|
+
if response.my_field is None:
|
|
978
|
+
if "my_field" not in response.model_fields_set:
|
|
979
|
+
print("Field was missing entirely")
|
|
980
|
+
else:
|
|
981
|
+
print("Field was explicitly null")
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
## Useful Links
|
|
985
|
+
|
|
986
|
+
- Documentation: https://developers.cloudflare.com/api/
|
|
987
|
+
- SDK GitHub: https://github.com/cloudflare/cloudflare-python
|
|
988
|
+
- API Keys: https://dash.cloudflare.com/profile/api-tokens
|
|
989
|
+
- Workers Docs: https://developers.cloudflare.com/workers/
|
|
990
|
+
- R2 Docs: https://developers.cloudflare.com/r2/
|
|
991
|
+
- D1 Docs: https://developers.cloudflare.com/d1/
|
|
992
|
+
- KV Docs: https://developers.cloudflare.com/kv/
|
|
993
|
+
- Pages Docs: https://developers.cloudflare.com/pages/
|
|
994
|
+
- Rate Limits: https://developers.cloudflare.com/fundamentals/api/reference/limits/
|