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,1199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: identity
|
|
3
|
+
description: "Auth0 Python SDK for OAuth, OIDC, and identity management in server-side applications"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "python"
|
|
6
|
+
versions: "4.7.2"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "auth0,identity,oauth,oidc,authentication"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Auth0 Python SDK Coding Guidelines
|
|
13
|
+
|
|
14
|
+
You are an Auth0 API expert. Help me with writing code using the Auth0 SDK for Python applications.
|
|
15
|
+
|
|
16
|
+
You can find the official SDK documentation here:
|
|
17
|
+
https://auth0-python.readthedocs.io/en/latest/
|
|
18
|
+
|
|
19
|
+
## Golden Rule: Use the Correct Auth0 SDK
|
|
20
|
+
|
|
21
|
+
Always use the official Auth0 Python SDK for server-side authentication and user management operations. This is the standard library for all Auth0 Management API and Authentication API interactions in Python.
|
|
22
|
+
|
|
23
|
+
- **Library Name:** Auth0 Python SDK
|
|
24
|
+
- **PyPI Package:** `auth0-python`
|
|
25
|
+
- **Current Version:** 4.13.0
|
|
26
|
+
- **Minimum Python Version:** 3.7+
|
|
27
|
+
|
|
28
|
+
**Installation:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install auth0-python
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Correct Usage:**
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from auth0.management import Auth0
|
|
38
|
+
from auth0.authentication import GetToken, Database
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Incorrect:**
|
|
42
|
+
- Using unofficial Auth0 packages
|
|
43
|
+
- Using deprecated versions of the SDK
|
|
44
|
+
|
|
45
|
+
## Environment Variables
|
|
46
|
+
|
|
47
|
+
Set up your environment variables for Auth0:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
AUTH0_DOMAIN=your-tenant.us.auth0.com
|
|
51
|
+
AUTH0_CLIENT_ID=your_client_id
|
|
52
|
+
AUTH0_CLIENT_SECRET=your_client_secret
|
|
53
|
+
AUTH0_MANAGEMENT_API_AUDIENCE=https://your-tenant.us.auth0.com/api/v2/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Installation and Setup
|
|
57
|
+
|
|
58
|
+
Install the Auth0 Python SDK:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install auth0-python
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For specific versions:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install auth0-python==4.13.0
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Initialization
|
|
71
|
+
|
|
72
|
+
### Management API Client Initialization
|
|
73
|
+
|
|
74
|
+
The Management API client is used for administrative operations like user management, role assignment, and configuration.
|
|
75
|
+
|
|
76
|
+
**Basic initialization with token:**
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from auth0.management import Auth0
|
|
80
|
+
import os
|
|
81
|
+
|
|
82
|
+
domain = os.getenv('AUTH0_DOMAIN')
|
|
83
|
+
mgmt_api_token = os.getenv('AUTH0_MANAGEMENT_API_TOKEN')
|
|
84
|
+
|
|
85
|
+
auth0 = Auth0(domain, mgmt_api_token)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Initialization with client credentials (recommended):**
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from auth0.authentication import GetToken
|
|
92
|
+
from auth0.management import Auth0
|
|
93
|
+
import os
|
|
94
|
+
|
|
95
|
+
domain = os.getenv('AUTH0_DOMAIN')
|
|
96
|
+
client_id = os.getenv('AUTH0_CLIENT_ID')
|
|
97
|
+
client_secret = os.getenv('AUTH0_CLIENT_SECRET')
|
|
98
|
+
|
|
99
|
+
# Get Management API token
|
|
100
|
+
get_token = GetToken(domain, client_id, client_secret=client_secret)
|
|
101
|
+
token = get_token.client_credentials(f'https://{domain}/api/v2/')
|
|
102
|
+
mgmt_api_token = token['access_token']
|
|
103
|
+
|
|
104
|
+
# Initialize Management client
|
|
105
|
+
auth0 = Auth0(domain, mgmt_api_token)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Authentication API Client Initialization
|
|
109
|
+
|
|
110
|
+
The Authentication API provides methods for login, signup, and password management.
|
|
111
|
+
|
|
112
|
+
**Database authentication:**
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from auth0.authentication import Database
|
|
116
|
+
import os
|
|
117
|
+
|
|
118
|
+
domain = os.getenv('AUTH0_DOMAIN')
|
|
119
|
+
client_id = os.getenv('AUTH0_CLIENT_ID')
|
|
120
|
+
|
|
121
|
+
database = Database(domain, client_id)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Token authentication:**
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from auth0.authentication import GetToken
|
|
128
|
+
import os
|
|
129
|
+
|
|
130
|
+
domain = os.getenv('AUTH0_DOMAIN')
|
|
131
|
+
client_id = os.getenv('AUTH0_CLIENT_ID')
|
|
132
|
+
client_secret = os.getenv('AUTH0_CLIENT_SECRET')
|
|
133
|
+
|
|
134
|
+
get_token = GetToken(domain, client_id, client_secret=client_secret)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## User Management
|
|
138
|
+
|
|
139
|
+
### Creating Users
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from auth0.management import Auth0
|
|
143
|
+
|
|
144
|
+
auth0 = Auth0(domain, mgmt_api_token)
|
|
145
|
+
|
|
146
|
+
def create_user(email, password):
|
|
147
|
+
user = auth0.users.create({
|
|
148
|
+
'email': email,
|
|
149
|
+
'password': password,
|
|
150
|
+
'connection': 'Username-Password-Authentication',
|
|
151
|
+
'email_verified': False,
|
|
152
|
+
'user_metadata': {
|
|
153
|
+
'plan': 'premium',
|
|
154
|
+
'preferences': {'theme': 'dark'}
|
|
155
|
+
},
|
|
156
|
+
'app_metadata': {
|
|
157
|
+
'role': 'user'
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
print(f"User created: {user['user_id']}")
|
|
162
|
+
return user
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Getting User by ID
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
def get_user(user_id):
|
|
169
|
+
user = auth0.users.get(user_id)
|
|
170
|
+
print(f"User: {user}")
|
|
171
|
+
return user
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Getting User by Email
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
def get_user_by_email(email):
|
|
178
|
+
users = auth0.users_by_email.search_users_by_email(email)
|
|
179
|
+
|
|
180
|
+
if users:
|
|
181
|
+
print(f"User found: {users[0]}")
|
|
182
|
+
return users[0]
|
|
183
|
+
|
|
184
|
+
return None
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Updating User
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
def update_user(user_id, updates):
|
|
191
|
+
updated_user = auth0.users.update(user_id, {
|
|
192
|
+
'email': 'newemail@example.com',
|
|
193
|
+
'user_metadata': {
|
|
194
|
+
'plan': 'enterprise'
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
return updated_user
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Deleting User
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
def delete_user(user_id):
|
|
205
|
+
auth0.users.delete(user_id)
|
|
206
|
+
print('User deleted')
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Listing Users
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
def list_users(page=0, per_page=50):
|
|
213
|
+
users = auth0.users.list(page=page, per_page=per_page)
|
|
214
|
+
return users
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Searching Users
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
def search_users(query):
|
|
221
|
+
users = auth0.users.list(
|
|
222
|
+
q=query,
|
|
223
|
+
search_engine='v3'
|
|
224
|
+
)
|
|
225
|
+
return users
|
|
226
|
+
|
|
227
|
+
# Example usage
|
|
228
|
+
users = search_users('email:"*@example.com"')
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Getting All Users (with pagination)
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
def get_all_users():
|
|
235
|
+
all_users = []
|
|
236
|
+
page = 0
|
|
237
|
+
per_page = 100
|
|
238
|
+
|
|
239
|
+
while True:
|
|
240
|
+
users = auth0.users.list(page=page, per_page=per_page)
|
|
241
|
+
|
|
242
|
+
if not users['users']:
|
|
243
|
+
break
|
|
244
|
+
|
|
245
|
+
all_users.extend(users['users'])
|
|
246
|
+
|
|
247
|
+
# Check if there are more pages
|
|
248
|
+
if len(users['users']) < per_page:
|
|
249
|
+
break
|
|
250
|
+
|
|
251
|
+
page += 1
|
|
252
|
+
|
|
253
|
+
return all_users
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Authentication Operations
|
|
257
|
+
|
|
258
|
+
### User Signup
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
from auth0.authentication import Database
|
|
262
|
+
|
|
263
|
+
database = Database(domain, client_id)
|
|
264
|
+
|
|
265
|
+
def signup_user(email, password):
|
|
266
|
+
result = database.signup(
|
|
267
|
+
email=email,
|
|
268
|
+
password=password,
|
|
269
|
+
connection='Username-Password-Authentication'
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
print(f"User signed up: {result}")
|
|
273
|
+
return result
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### User Login (Resource Owner Password Grant)
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
from auth0.authentication import GetToken
|
|
280
|
+
|
|
281
|
+
get_token = GetToken(domain, client_id, client_secret=client_secret)
|
|
282
|
+
|
|
283
|
+
def login_user(username, password):
|
|
284
|
+
token_response = get_token.login(
|
|
285
|
+
username=username,
|
|
286
|
+
password=password,
|
|
287
|
+
realm='Username-Password-Authentication',
|
|
288
|
+
scope='openid profile email',
|
|
289
|
+
audience='https://api.example.com'
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
print(f"Access Token: {token_response['access_token']}")
|
|
293
|
+
print(f"ID Token: {token_response.get('id_token')}")
|
|
294
|
+
|
|
295
|
+
return token_response
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Client Credentials Grant
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
def get_client_credentials_token(audience):
|
|
302
|
+
token = get_token.client_credentials(audience)
|
|
303
|
+
|
|
304
|
+
print(f"Access Token: {token['access_token']}")
|
|
305
|
+
return token
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Authorization Code Exchange
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
def exchange_authorization_code(code, redirect_uri):
|
|
312
|
+
token = get_token.authorization_code(
|
|
313
|
+
code=code,
|
|
314
|
+
redirect_uri=redirect_uri
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
return token
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Refresh Token
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
def refresh_access_token(refresh_token):
|
|
324
|
+
token = get_token.refresh_token(refresh_token)
|
|
325
|
+
|
|
326
|
+
print(f"New Access Token: {token['access_token']}")
|
|
327
|
+
return token
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Password Reset
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
def request_password_reset(email):
|
|
334
|
+
database.change_password(
|
|
335
|
+
email=email,
|
|
336
|
+
connection='Username-Password-Authentication'
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
print('Password reset email sent')
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Password Realm Grant
|
|
343
|
+
|
|
344
|
+
```python
|
|
345
|
+
def password_realm_grant(username, password, realm):
|
|
346
|
+
token = get_token.login(
|
|
347
|
+
username=username,
|
|
348
|
+
password=password,
|
|
349
|
+
realm=realm,
|
|
350
|
+
scope='openid profile email'
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
return token
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Role and Permission Management
|
|
357
|
+
|
|
358
|
+
### Creating a Role
|
|
359
|
+
|
|
360
|
+
```python
|
|
361
|
+
def create_role(name, description):
|
|
362
|
+
role = auth0.roles.create({
|
|
363
|
+
'name': name,
|
|
364
|
+
'description': description
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
print(f"Role created: {role['id']}")
|
|
368
|
+
return role
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Getting All Roles
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
def get_all_roles():
|
|
375
|
+
roles = auth0.roles.list()
|
|
376
|
+
return roles
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Getting Role by ID
|
|
380
|
+
|
|
381
|
+
```python
|
|
382
|
+
def get_role(role_id):
|
|
383
|
+
role = auth0.roles.get(role_id)
|
|
384
|
+
return role
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Updating a Role
|
|
388
|
+
|
|
389
|
+
```python
|
|
390
|
+
def update_role(role_id, name, description):
|
|
391
|
+
role = auth0.roles.update(role_id, {
|
|
392
|
+
'name': name,
|
|
393
|
+
'description': description
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
return role
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Deleting a Role
|
|
400
|
+
|
|
401
|
+
```python
|
|
402
|
+
def delete_role(role_id):
|
|
403
|
+
auth0.roles.delete(role_id)
|
|
404
|
+
print('Role deleted')
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Assigning Roles to User
|
|
408
|
+
|
|
409
|
+
```python
|
|
410
|
+
def assign_roles_to_user(user_id, role_ids):
|
|
411
|
+
auth0.users.add_roles(user_id, {'roles': role_ids})
|
|
412
|
+
print('Roles assigned to user')
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Getting User Roles
|
|
416
|
+
|
|
417
|
+
```python
|
|
418
|
+
def get_user_roles(user_id):
|
|
419
|
+
roles = auth0.users.list_roles(user_id)
|
|
420
|
+
print(f"User Roles: {roles}")
|
|
421
|
+
return roles
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Removing Roles from User
|
|
425
|
+
|
|
426
|
+
```python
|
|
427
|
+
def remove_roles_from_user(user_id, role_ids):
|
|
428
|
+
auth0.users.remove_roles(user_id, {'roles': role_ids})
|
|
429
|
+
print('Roles removed from user')
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Adding Permissions to Role
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
def add_permissions_to_role(role_id, permissions):
|
|
436
|
+
auth0.roles.add_permissions(role_id, {
|
|
437
|
+
'permissions': [
|
|
438
|
+
{
|
|
439
|
+
'permission_name': 'read:messages',
|
|
440
|
+
'resource_server_identifier': 'https://api.example.com'
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
'permission_name': 'write:messages',
|
|
444
|
+
'resource_server_identifier': 'https://api.example.com'
|
|
445
|
+
}
|
|
446
|
+
]
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
print('Permissions added to role')
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Getting Role Permissions
|
|
453
|
+
|
|
454
|
+
```python
|
|
455
|
+
def get_role_permissions(role_id):
|
|
456
|
+
permissions = auth0.roles.get_permissions(role_id)
|
|
457
|
+
return permissions
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Removing Permissions from Role
|
|
461
|
+
|
|
462
|
+
```python
|
|
463
|
+
def remove_permissions_from_role(role_id, permissions):
|
|
464
|
+
auth0.roles.remove_permissions(role_id, {'permissions': permissions})
|
|
465
|
+
print('Permissions removed from role')
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Getting User Permissions
|
|
469
|
+
|
|
470
|
+
```python
|
|
471
|
+
def get_user_permissions(user_id):
|
|
472
|
+
permissions = auth0.users.list_permissions(user_id)
|
|
473
|
+
print(f"User Permissions: {permissions}")
|
|
474
|
+
return permissions
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Assigning Permissions to User
|
|
478
|
+
|
|
479
|
+
```python
|
|
480
|
+
def assign_permissions_to_user(user_id):
|
|
481
|
+
auth0.users.add_permissions(user_id, {
|
|
482
|
+
'permissions': [
|
|
483
|
+
{
|
|
484
|
+
'permission_name': 'read:messages',
|
|
485
|
+
'resource_server_identifier': 'https://api.example.com'
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
print('Permissions assigned to user')
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Removing Permissions from User
|
|
494
|
+
|
|
495
|
+
```python
|
|
496
|
+
def remove_permissions_from_user(user_id, permissions):
|
|
497
|
+
auth0.users.remove_permissions(user_id, {'permissions': permissions})
|
|
498
|
+
print('Permissions removed from user')
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## Organization Management
|
|
502
|
+
|
|
503
|
+
### Creating an Organization
|
|
504
|
+
|
|
505
|
+
```python
|
|
506
|
+
def create_organization(name, display_name):
|
|
507
|
+
org = auth0.organizations.create({
|
|
508
|
+
'name': name,
|
|
509
|
+
'display_name': display_name
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
print(f"Organization created: {org['id']}")
|
|
513
|
+
return org
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Getting All Organizations
|
|
517
|
+
|
|
518
|
+
```python
|
|
519
|
+
def get_all_organizations():
|
|
520
|
+
orgs = auth0.organizations.list()
|
|
521
|
+
return orgs
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Getting Organization by ID
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
def get_organization(org_id):
|
|
528
|
+
org = auth0.organizations.get(org_id)
|
|
529
|
+
return org
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Updating an Organization
|
|
533
|
+
|
|
534
|
+
```python
|
|
535
|
+
def update_organization(org_id, updates):
|
|
536
|
+
org = auth0.organizations.update(org_id, updates)
|
|
537
|
+
return org
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Deleting an Organization
|
|
541
|
+
|
|
542
|
+
```python
|
|
543
|
+
def delete_organization(org_id):
|
|
544
|
+
auth0.organizations.delete(org_id)
|
|
545
|
+
print('Organization deleted')
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Adding Members to Organization
|
|
549
|
+
|
|
550
|
+
```python
|
|
551
|
+
def add_member_to_organization(org_id, user_ids):
|
|
552
|
+
auth0.organizations.create_members(org_id, {'members': user_ids})
|
|
553
|
+
print('Members added to organization')
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Getting Organization Members
|
|
557
|
+
|
|
558
|
+
```python
|
|
559
|
+
def get_organization_members(org_id):
|
|
560
|
+
members = auth0.organizations.list_members(org_id)
|
|
561
|
+
return members
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Removing Members from Organization
|
|
565
|
+
|
|
566
|
+
```python
|
|
567
|
+
def remove_members_from_organization(org_id, user_ids):
|
|
568
|
+
for user_id in user_ids:
|
|
569
|
+
auth0.organizations.delete_member(org_id, user_id)
|
|
570
|
+
|
|
571
|
+
print('Members removed from organization')
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Assigning Roles to Organization Member
|
|
575
|
+
|
|
576
|
+
```python
|
|
577
|
+
def assign_org_roles(org_id, user_id, role_ids):
|
|
578
|
+
auth0.organizations.create_member_roles(
|
|
579
|
+
org_id,
|
|
580
|
+
user_id,
|
|
581
|
+
{'roles': role_ids}
|
|
582
|
+
)
|
|
583
|
+
|
|
584
|
+
print('Organization roles assigned')
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Getting Organization Member Roles
|
|
588
|
+
|
|
589
|
+
```python
|
|
590
|
+
def get_org_member_roles(org_id, user_id):
|
|
591
|
+
roles = auth0.organizations.list_member_roles(org_id, user_id)
|
|
592
|
+
return roles
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
## Connection Management
|
|
596
|
+
|
|
597
|
+
### Getting All Connections
|
|
598
|
+
|
|
599
|
+
```python
|
|
600
|
+
def get_all_connections():
|
|
601
|
+
connections = auth0.connections.all()
|
|
602
|
+
return connections
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Getting Connection by ID
|
|
606
|
+
|
|
607
|
+
```python
|
|
608
|
+
def get_connection(connection_id):
|
|
609
|
+
connection = auth0.connections.get(connection_id)
|
|
610
|
+
return connection
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Creating a Database Connection
|
|
614
|
+
|
|
615
|
+
```python
|
|
616
|
+
def create_database_connection(name):
|
|
617
|
+
connection = auth0.connections.create({
|
|
618
|
+
'name': name,
|
|
619
|
+
'strategy': 'auth0',
|
|
620
|
+
'enabled_clients': [client_id]
|
|
621
|
+
})
|
|
622
|
+
|
|
623
|
+
return connection
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Updating a Connection
|
|
627
|
+
|
|
628
|
+
```python
|
|
629
|
+
def update_connection(connection_id, updates):
|
|
630
|
+
connection = auth0.connections.update(connection_id, updates)
|
|
631
|
+
return connection
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Deleting a Connection
|
|
635
|
+
|
|
636
|
+
```python
|
|
637
|
+
def delete_connection(connection_id):
|
|
638
|
+
auth0.connections.delete(connection_id)
|
|
639
|
+
print('Connection deleted')
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
## Client Application Management
|
|
643
|
+
|
|
644
|
+
### Getting All Clients
|
|
645
|
+
|
|
646
|
+
```python
|
|
647
|
+
def get_all_clients():
|
|
648
|
+
clients = auth0.clients.all()
|
|
649
|
+
return clients
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### Getting Client by ID
|
|
653
|
+
|
|
654
|
+
```python
|
|
655
|
+
def get_client(client_id):
|
|
656
|
+
client = auth0.clients.get(client_id)
|
|
657
|
+
return client
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Creating a Client
|
|
661
|
+
|
|
662
|
+
```python
|
|
663
|
+
def create_client(name, app_type):
|
|
664
|
+
client = auth0.clients.create({
|
|
665
|
+
'name': name,
|
|
666
|
+
'app_type': app_type, # 'native', 'spa', 'regular_web', 'non_interactive'
|
|
667
|
+
'callbacks': ['http://localhost:3000/callback'],
|
|
668
|
+
'allowed_logout_urls': ['http://localhost:3000']
|
|
669
|
+
})
|
|
670
|
+
|
|
671
|
+
return client
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Updating a Client
|
|
675
|
+
|
|
676
|
+
```python
|
|
677
|
+
def update_client(client_id, updates):
|
|
678
|
+
client = auth0.clients.update(client_id, updates)
|
|
679
|
+
return client
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### Deleting a Client
|
|
683
|
+
|
|
684
|
+
```python
|
|
685
|
+
def delete_client(client_id):
|
|
686
|
+
auth0.clients.delete(client_id)
|
|
687
|
+
print('Client deleted')
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
## Email and Verification
|
|
691
|
+
|
|
692
|
+
### Sending Email Verification
|
|
693
|
+
|
|
694
|
+
```python
|
|
695
|
+
def send_verification_email(user_id):
|
|
696
|
+
job = auth0.jobs.send_verification_email({
|
|
697
|
+
'user_id': user_id
|
|
698
|
+
})
|
|
699
|
+
|
|
700
|
+
print(f"Verification email job created: {job}")
|
|
701
|
+
return job
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Creating Email Verification Ticket
|
|
705
|
+
|
|
706
|
+
```python
|
|
707
|
+
def create_email_verification_ticket(user_id):
|
|
708
|
+
ticket = auth0.tickets.create_email_verification({
|
|
709
|
+
'user_id': user_id,
|
|
710
|
+
'result_url': 'https://example.com/verified'
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
print(f"Verification URL: {ticket['ticket']}")
|
|
714
|
+
return ticket
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Creating Password Change Ticket
|
|
718
|
+
|
|
719
|
+
```python
|
|
720
|
+
def create_password_change_ticket(user_id):
|
|
721
|
+
ticket = auth0.tickets.create_pswd_change({
|
|
722
|
+
'user_id': user_id,
|
|
723
|
+
'result_url': 'https://example.com/password-changed'
|
|
724
|
+
})
|
|
725
|
+
|
|
726
|
+
print(f"Password change URL: {ticket['ticket']}")
|
|
727
|
+
return ticket
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
## Logs and Monitoring
|
|
731
|
+
|
|
732
|
+
### Getting Logs
|
|
733
|
+
|
|
734
|
+
```python
|
|
735
|
+
def get_logs(page=0, per_page=100):
|
|
736
|
+
logs = auth0.logs.search(page=page, per_page=per_page)
|
|
737
|
+
return logs
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
### Getting Logs with Query
|
|
741
|
+
|
|
742
|
+
```python
|
|
743
|
+
def get_login_logs():
|
|
744
|
+
logs = auth0.logs.search(q='type:s', per_page=100) # 's' = successful login
|
|
745
|
+
return logs
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Getting Log by ID
|
|
749
|
+
|
|
750
|
+
```python
|
|
751
|
+
def get_log_by_id(log_id):
|
|
752
|
+
log = auth0.logs.get(log_id)
|
|
753
|
+
return log
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
## Guardian (MFA) Management
|
|
757
|
+
|
|
758
|
+
### Getting User Enrollments
|
|
759
|
+
|
|
760
|
+
```python
|
|
761
|
+
def get_user_mfa_enrollments(user_id):
|
|
762
|
+
enrollments = auth0.users.get_guardian_enrollments(user_id)
|
|
763
|
+
return enrollments
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Deleting User Enrollment
|
|
767
|
+
|
|
768
|
+
```python
|
|
769
|
+
def delete_mfa_enrollment(user_id, enrollment_id):
|
|
770
|
+
auth0.guardian.delete_enrollment(enrollment_id)
|
|
771
|
+
print('MFA enrollment deleted')
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### Getting Guardian Factors
|
|
775
|
+
|
|
776
|
+
```python
|
|
777
|
+
def get_guardian_factors():
|
|
778
|
+
factors = auth0.guardian.all_factors()
|
|
779
|
+
return factors
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Updating Guardian Factor
|
|
783
|
+
|
|
784
|
+
```python
|
|
785
|
+
def update_guardian_factor(factor_name, enabled):
|
|
786
|
+
auth0.guardian.update_factor(factor_name, {'enabled': enabled})
|
|
787
|
+
print(f"Guardian factor {factor_name} updated")
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
## User Blocking
|
|
791
|
+
|
|
792
|
+
### Getting User Blocks by Identifier
|
|
793
|
+
|
|
794
|
+
```python
|
|
795
|
+
def get_user_blocks(identifier):
|
|
796
|
+
blocks = auth0.user_blocks.get_by_identifier(identifier)
|
|
797
|
+
return blocks
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
### Unblocking User by Identifier
|
|
801
|
+
|
|
802
|
+
```python
|
|
803
|
+
def unblock_user(identifier):
|
|
804
|
+
auth0.user_blocks.unblock_by_identifier(identifier)
|
|
805
|
+
print('User unblocked')
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Getting User Blocks by ID
|
|
809
|
+
|
|
810
|
+
```python
|
|
811
|
+
def get_user_blocks_by_id(user_id):
|
|
812
|
+
blocks = auth0.user_blocks.get(user_id)
|
|
813
|
+
return blocks
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Unblocking User by ID
|
|
817
|
+
|
|
818
|
+
```python
|
|
819
|
+
def unblock_user_by_id(user_id):
|
|
820
|
+
auth0.user_blocks.unblock(user_id)
|
|
821
|
+
print('User unblocked')
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
## Grants Management
|
|
825
|
+
|
|
826
|
+
### Getting All Grants
|
|
827
|
+
|
|
828
|
+
```python
|
|
829
|
+
def get_all_grants():
|
|
830
|
+
grants = auth0.grants.all()
|
|
831
|
+
return grants
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
### Getting Grants by User ID
|
|
835
|
+
|
|
836
|
+
```python
|
|
837
|
+
def get_user_grants(user_id):
|
|
838
|
+
grants = auth0.grants.all(user_id=user_id)
|
|
839
|
+
return grants
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### Deleting Grant
|
|
843
|
+
|
|
844
|
+
```python
|
|
845
|
+
def delete_grant(grant_id):
|
|
846
|
+
auth0.grants.delete(grant_id)
|
|
847
|
+
print('Grant deleted')
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
## Resource Servers (APIs)
|
|
851
|
+
|
|
852
|
+
### Getting All Resource Servers
|
|
853
|
+
|
|
854
|
+
```python
|
|
855
|
+
def get_all_resource_servers():
|
|
856
|
+
apis = auth0.resource_servers.get_all()
|
|
857
|
+
return apis
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
### Creating a Resource Server
|
|
861
|
+
|
|
862
|
+
```python
|
|
863
|
+
def create_resource_server(identifier, name):
|
|
864
|
+
api = auth0.resource_servers.create({
|
|
865
|
+
'identifier': identifier,
|
|
866
|
+
'name': name,
|
|
867
|
+
'signing_alg': 'RS256',
|
|
868
|
+
'scopes': [
|
|
869
|
+
{'value': 'read:messages', 'description': 'Read messages'},
|
|
870
|
+
{'value': 'write:messages', 'description': 'Write messages'}
|
|
871
|
+
]
|
|
872
|
+
})
|
|
873
|
+
|
|
874
|
+
return api
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
### Getting Resource Server by ID
|
|
878
|
+
|
|
879
|
+
```python
|
|
880
|
+
def get_resource_server(resource_server_id):
|
|
881
|
+
api = auth0.resource_servers.get(resource_server_id)
|
|
882
|
+
return api
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### Updating Resource Server
|
|
886
|
+
|
|
887
|
+
```python
|
|
888
|
+
def update_resource_server(resource_server_id, updates):
|
|
889
|
+
api = auth0.resource_servers.update(resource_server_id, updates)
|
|
890
|
+
return api
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
### Deleting Resource Server
|
|
894
|
+
|
|
895
|
+
```python
|
|
896
|
+
def delete_resource_server(resource_server_id):
|
|
897
|
+
auth0.resource_servers.delete(resource_server_id)
|
|
898
|
+
print('Resource server deleted')
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
## Error Handling
|
|
902
|
+
|
|
903
|
+
The SDK raises exceptions for API errors that should be handled appropriately.
|
|
904
|
+
|
|
905
|
+
```python
|
|
906
|
+
from auth0.exceptions import Auth0Error
|
|
907
|
+
|
|
908
|
+
def safe_get_user(user_id):
|
|
909
|
+
try:
|
|
910
|
+
user = auth0.users.get(user_id)
|
|
911
|
+
return user
|
|
912
|
+
except Auth0Error as e:
|
|
913
|
+
print(f"Auth0 Error: {e}")
|
|
914
|
+
print(f"Status Code: {e.status_code}")
|
|
915
|
+
print(f"Error Code: {e.error_code}")
|
|
916
|
+
print(f"Message: {e.message}")
|
|
917
|
+
return None
|
|
918
|
+
except Exception as e:
|
|
919
|
+
print(f"Unexpected error: {e}")
|
|
920
|
+
return None
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
### Common Error Handling Patterns
|
|
924
|
+
|
|
925
|
+
```python
|
|
926
|
+
def handle_user_creation(email, password):
|
|
927
|
+
try:
|
|
928
|
+
user = auth0.users.create({
|
|
929
|
+
'email': email,
|
|
930
|
+
'password': password,
|
|
931
|
+
'connection': 'Username-Password-Authentication'
|
|
932
|
+
})
|
|
933
|
+
return {'success': True, 'user': user}
|
|
934
|
+
except Auth0Error as e:
|
|
935
|
+
if e.status_code == 409:
|
|
936
|
+
return {'success': False, 'error': 'User already exists'}
|
|
937
|
+
elif e.status_code == 400:
|
|
938
|
+
return {'success': False, 'error': 'Invalid request'}
|
|
939
|
+
elif e.status_code == 429:
|
|
940
|
+
return {'success': False, 'error': 'Rate limit exceeded'}
|
|
941
|
+
else:
|
|
942
|
+
return {'success': False, 'error': str(e)}
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
## Rate Limiting
|
|
946
|
+
|
|
947
|
+
Handle rate limits with exponential backoff:
|
|
948
|
+
|
|
949
|
+
```python
|
|
950
|
+
import time
|
|
951
|
+
|
|
952
|
+
def retry_with_backoff(func, max_retries=3):
|
|
953
|
+
for attempt in range(max_retries):
|
|
954
|
+
try:
|
|
955
|
+
return func()
|
|
956
|
+
except Auth0Error as e:
|
|
957
|
+
if e.status_code == 429 and attempt < max_retries - 1:
|
|
958
|
+
wait_time = 2 ** attempt
|
|
959
|
+
print(f"Rate limited. Waiting {wait_time} seconds...")
|
|
960
|
+
time.sleep(wait_time)
|
|
961
|
+
continue
|
|
962
|
+
raise
|
|
963
|
+
|
|
964
|
+
raise Exception("Max retries exceeded")
|
|
965
|
+
|
|
966
|
+
# Usage
|
|
967
|
+
result = retry_with_backoff(lambda: auth0.users.get(user_id))
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
## Complete Example: User Registration and Login Flow
|
|
971
|
+
|
|
972
|
+
```python
|
|
973
|
+
from auth0.authentication import Database, GetToken
|
|
974
|
+
from auth0.management import Auth0
|
|
975
|
+
import os
|
|
976
|
+
|
|
977
|
+
# Configuration
|
|
978
|
+
domain = os.getenv('AUTH0_DOMAIN')
|
|
979
|
+
client_id = os.getenv('AUTH0_CLIENT_ID')
|
|
980
|
+
client_secret = os.getenv('AUTH0_CLIENT_SECRET')
|
|
981
|
+
|
|
982
|
+
# Initialize clients
|
|
983
|
+
database = Database(domain, client_id)
|
|
984
|
+
get_token = GetToken(domain, client_id, client_secret=client_secret)
|
|
985
|
+
|
|
986
|
+
# Get Management API token
|
|
987
|
+
token = get_token.client_credentials(f'https://{domain}/api/v2/')
|
|
988
|
+
mgmt_api_token = token['access_token']
|
|
989
|
+
auth0 = Auth0(domain, mgmt_api_token)
|
|
990
|
+
|
|
991
|
+
def register_and_login(email, password):
|
|
992
|
+
# 1. Sign up user
|
|
993
|
+
signup_result = database.signup(
|
|
994
|
+
email=email,
|
|
995
|
+
password=password,
|
|
996
|
+
connection='Username-Password-Authentication'
|
|
997
|
+
)
|
|
998
|
+
print(f"User signed up: {signup_result}")
|
|
999
|
+
|
|
1000
|
+
# 2. Get user by email
|
|
1001
|
+
users = auth0.users_by_email.search_users_by_email(email)
|
|
1002
|
+
user = users[0] if users else None
|
|
1003
|
+
|
|
1004
|
+
if not user:
|
|
1005
|
+
raise Exception("User not found after signup")
|
|
1006
|
+
|
|
1007
|
+
print(f"User ID: {user['user_id']}")
|
|
1008
|
+
|
|
1009
|
+
# 3. Update user metadata
|
|
1010
|
+
auth0.users.update(user['user_id'], {
|
|
1011
|
+
'user_metadata': {
|
|
1012
|
+
'first_name': 'John',
|
|
1013
|
+
'last_name': 'Doe'
|
|
1014
|
+
}
|
|
1015
|
+
})
|
|
1016
|
+
|
|
1017
|
+
# 4. Send verification email
|
|
1018
|
+
auth0.jobs.send_verification_email({
|
|
1019
|
+
'user_id': user['user_id']
|
|
1020
|
+
})
|
|
1021
|
+
print("Verification email sent")
|
|
1022
|
+
|
|
1023
|
+
# 5. Login user (after email verification)
|
|
1024
|
+
token_response = get_token.login(
|
|
1025
|
+
username=email,
|
|
1026
|
+
password=password,
|
|
1027
|
+
realm='Username-Password-Authentication',
|
|
1028
|
+
scope='openid profile email',
|
|
1029
|
+
audience=f'https://{domain}/api/v2/'
|
|
1030
|
+
)
|
|
1031
|
+
|
|
1032
|
+
print(f"Access Token: {token_response['access_token']}")
|
|
1033
|
+
print(f"ID Token: {token_response.get('id_token')}")
|
|
1034
|
+
|
|
1035
|
+
return {
|
|
1036
|
+
'user': user,
|
|
1037
|
+
'tokens': token_response
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
# Usage
|
|
1041
|
+
if __name__ == '__main__':
|
|
1042
|
+
result = register_and_login('john.doe@example.com', 'SecurePassword123!')
|
|
1043
|
+
print(f"Registration and login complete: {result}")
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
## Advanced Patterns
|
|
1047
|
+
|
|
1048
|
+
### Batch User Creation
|
|
1049
|
+
|
|
1050
|
+
```python
|
|
1051
|
+
def batch_create_users(users_data):
|
|
1052
|
+
created_users = []
|
|
1053
|
+
errors = []
|
|
1054
|
+
|
|
1055
|
+
for user_data in users_data:
|
|
1056
|
+
try:
|
|
1057
|
+
user = auth0.users.create(user_data)
|
|
1058
|
+
created_users.append(user)
|
|
1059
|
+
except Auth0Error as e:
|
|
1060
|
+
errors.append({
|
|
1061
|
+
'email': user_data.get('email'),
|
|
1062
|
+
'error': str(e)
|
|
1063
|
+
})
|
|
1064
|
+
|
|
1065
|
+
return {
|
|
1066
|
+
'created': created_users,
|
|
1067
|
+
'errors': errors
|
|
1068
|
+
}
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
### User Search with Filters
|
|
1072
|
+
|
|
1073
|
+
```python
|
|
1074
|
+
def search_users_advanced(email_domain=None, created_after=None, metadata_filters=None):
|
|
1075
|
+
queries = []
|
|
1076
|
+
|
|
1077
|
+
if email_domain:
|
|
1078
|
+
queries.append(f'email:"*@{email_domain}"')
|
|
1079
|
+
|
|
1080
|
+
if created_after:
|
|
1081
|
+
queries.append(f'created_at:[{created_after} TO *]')
|
|
1082
|
+
|
|
1083
|
+
if metadata_filters:
|
|
1084
|
+
for key, value in metadata_filters.items():
|
|
1085
|
+
queries.append(f'user_metadata.{key}:"{value}"')
|
|
1086
|
+
|
|
1087
|
+
query = ' AND '.join(queries) if queries else None
|
|
1088
|
+
|
|
1089
|
+
users = auth0.users.list(q=query, search_engine='v3')
|
|
1090
|
+
return users
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
### Token Management Helper
|
|
1094
|
+
|
|
1095
|
+
```python
|
|
1096
|
+
class TokenManager:
|
|
1097
|
+
def __init__(self, domain, client_id, client_secret):
|
|
1098
|
+
self.domain = domain
|
|
1099
|
+
self.client_id = client_id
|
|
1100
|
+
self.client_secret = client_secret
|
|
1101
|
+
self.get_token = GetToken(domain, client_id, client_secret=client_secret)
|
|
1102
|
+
self._token = None
|
|
1103
|
+
self._token_expiry = 0
|
|
1104
|
+
|
|
1105
|
+
def get_management_token(self):
|
|
1106
|
+
import time
|
|
1107
|
+
|
|
1108
|
+
# Check if token is still valid (with 5-minute buffer)
|
|
1109
|
+
if self._token and time.time() < self._token_expiry - 300:
|
|
1110
|
+
return self._token
|
|
1111
|
+
|
|
1112
|
+
# Get new token
|
|
1113
|
+
token_response = self.get_token.client_credentials(
|
|
1114
|
+
f'https://{self.domain}/api/v2/'
|
|
1115
|
+
)
|
|
1116
|
+
|
|
1117
|
+
self._token = token_response['access_token']
|
|
1118
|
+
self._token_expiry = time.time() + token_response.get('expires_in', 86400)
|
|
1119
|
+
|
|
1120
|
+
return self._token
|
|
1121
|
+
|
|
1122
|
+
# Usage
|
|
1123
|
+
token_manager = TokenManager(domain, client_id, client_secret)
|
|
1124
|
+
auth0 = Auth0(domain, token_manager.get_management_token())
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
## Important Notes
|
|
1128
|
+
|
|
1129
|
+
### Security Best Practices
|
|
1130
|
+
|
|
1131
|
+
1. **Never expose client secrets** - Keep credentials secure on the server side
|
|
1132
|
+
2. **Use environment variables** - Store sensitive data in environment variables
|
|
1133
|
+
3. **Validate tokens** - Always validate tokens on the server side
|
|
1134
|
+
4. **Use HTTPS** - Always use HTTPS in production
|
|
1135
|
+
5. **Implement rate limiting** - Protect against brute force attacks
|
|
1136
|
+
6. **Rotate credentials** - Regularly rotate API tokens and secrets
|
|
1137
|
+
|
|
1138
|
+
### Management API Token Lifecycle
|
|
1139
|
+
|
|
1140
|
+
- Management API tokens expire after 24 hours by default
|
|
1141
|
+
- Use client credentials grant for long-running applications
|
|
1142
|
+
- Cache tokens and refresh before expiration
|
|
1143
|
+
- Implement token refresh logic in production applications
|
|
1144
|
+
|
|
1145
|
+
### Python Version Support
|
|
1146
|
+
|
|
1147
|
+
The SDK follows Python's official support schedule:
|
|
1148
|
+
- Python 3.12: Supported through October 2028
|
|
1149
|
+
- Python 3.11: Supported through October 2027
|
|
1150
|
+
- Python 3.10: Supported through October 2026
|
|
1151
|
+
- Python 3.9: Supported through October 2025
|
|
1152
|
+
- Python 3.8: End of life October 2024
|
|
1153
|
+
- Python 3.7: End of life October 2023
|
|
1154
|
+
|
|
1155
|
+
### User Search Syntax
|
|
1156
|
+
|
|
1157
|
+
Use Lucene query syntax for user searches:
|
|
1158
|
+
|
|
1159
|
+
```python
|
|
1160
|
+
# Search by email domain
|
|
1161
|
+
q = 'email:"*@example.com"'
|
|
1162
|
+
|
|
1163
|
+
# Search by metadata
|
|
1164
|
+
q = 'user_metadata.plan:"premium"'
|
|
1165
|
+
|
|
1166
|
+
# Search by multiple fields
|
|
1167
|
+
q = 'email:"*@example.com" AND user_metadata.plan:"premium"'
|
|
1168
|
+
|
|
1169
|
+
# Search by created date
|
|
1170
|
+
q = 'created_at:[2024-01-01 TO 2024-12-31]'
|
|
1171
|
+
|
|
1172
|
+
# Complex query
|
|
1173
|
+
q = '(email:"*@example.com" OR email:"*@test.com") AND user_metadata.active:true'
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
### Common Status Codes
|
|
1177
|
+
|
|
1178
|
+
| Status Code | Description |
|
|
1179
|
+
|-------------|-------------|
|
|
1180
|
+
| 200 | Success |
|
|
1181
|
+
| 201 | Created |
|
|
1182
|
+
| 204 | No Content (Success) |
|
|
1183
|
+
| 400 | Bad Request |
|
|
1184
|
+
| 401 | Unauthorized |
|
|
1185
|
+
| 403 | Forbidden |
|
|
1186
|
+
| 404 | Not Found |
|
|
1187
|
+
| 409 | Conflict (e.g., user already exists) |
|
|
1188
|
+
| 429 | Too Many Requests (Rate Limited) |
|
|
1189
|
+
| 500 | Internal Server Error |
|
|
1190
|
+
|
|
1191
|
+
## Useful Links
|
|
1192
|
+
|
|
1193
|
+
- Official Documentation: https://auth0.com/docs
|
|
1194
|
+
- Python SDK Documentation: https://auth0-python.readthedocs.io/
|
|
1195
|
+
- GitHub Repository: https://github.com/auth0/auth0-python
|
|
1196
|
+
- Example Code: https://github.com/auth0/auth0-python/blob/master/EXAMPLES.md
|
|
1197
|
+
- Community Forum: https://community.auth0.com/
|
|
1198
|
+
- Auth0 Dashboard: https://manage.auth0.com/
|
|
1199
|
+
- API Rate Limits: https://auth0.com/docs/troubleshoot/customer-support/operational-policies/rate-limit-policy
|