Skip to content

Latest commit

 

History

History
243 lines (178 loc) · 6.22 KB

File metadata and controls

243 lines (178 loc) · 6.22 KB

v5 Migration Guide

A guide to migrating the Auth0 Python SDK from v4 to v5.

Overall changes

Python versions

v5 supports Python 3.8 and above.

Authentication API

This major version change does not affect the Authentication API. Any code written for the Authentication API in v4 should work in v5.

Management API

v5 introduces significant improvements to the Management API by migrating to Fern as our code generation tool. This brings several benefits:

  • Type safety: All responses are now Pydantic models with full type hints.
  • IDE support: Autocomplete and inline documentation for all API methods and response fields.
  • Automatic token management: Built-in support for client credentials with automatic token caching and refresh.
  • Improved pagination: New SyncPager and AsyncPager classes for easy iteration across paginated results.
  • Better resource organization: Sub-resources are organized into sub-clients for a more intuitive API structure.

Specific changes to the Management API

Client initialization

v5 introduces a ManagementClient class with support for both token-based and client credentials authentication.

Token-based authentication

# v4
from auth0.management import Auth0

domain = 'your-tenant.auth0.com'
token = 'MGMT_API_TOKEN'
auth0 = Auth0(domain, token)

# Access users
user = auth0.users.get('user_id')
# v5
from auth0.management import ManagementClient

client = ManagementClient(
    domain="your-tenant.auth0.com",
    token="MGMT_API_TOKEN",
)

# Access users
user = client.users.get("user_id")

Client credentials authentication (new in v5)

v5 supports automatic token management when using client credentials. The token is automatically fetched, cached, and refreshed before expiration:

# v5 with client credentials
from auth0.management import ManagementClient

client = ManagementClient(
    domain="your-tenant.auth0.com",
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

# Token is automatically fetched and cached
# No need to manually obtain or refresh tokens
user = client.users.get("user_id")

Configuration options

# v4
from auth0.management import Auth0
from auth0.rest import RestClientOptions

options = RestClientOptions(
    telemetry=True,
    timeout=5.0,
    retries=3
)
auth0 = Auth0(domain, token, rest_options=options)
# v5
from auth0.management import ManagementClient

client = ManagementClient(
    domain="your-tenant.auth0.com",
    token="MGMT_API_TOKEN",
    timeout=60.0,  # Timeout in seconds
    headers={"X-Custom-Header": "value"},  # Custom headers
)

Return types: Pydantic models

The most significant change is that all API responses are now Pydantic models instead of raw dictionaries. This provides type safety, IDE autocomplete, and validation.

Accessing response data

# v4: Dictionary access
user = auth0.users.get('user_id')
print(user['email'])           # Dict key access
print(user.get('nickname'))    # Safe access with .get()

# Check if key exists
if 'app_metadata' in user:
    print(user['app_metadata'])
# v5: Attribute access
user = client.users.get("user_id")
print(user.email)              # Attribute access
print(user.nickname)           # Direct attribute access (None if not present)

# Access nested data
if user.app_metadata:
    print(user.app_metadata)

Converting to dictionaries

If you need dictionary access for compatibility with existing code, use model_dump():

# v5: Convert to dict
user = client.users.get("user_id")
user_dict = user.model_dump()  # Returns a dictionary

# Now you can use dict-style access
print(user_dict['email'])

Benefits of Pydantic models

  1. IDE autocomplete: Type user. and see all available fields
  2. Type checking: Catch errors at development time with mypy or pyright
  3. Validation: Data is validated against the schema
  4. Immutability: Response objects are frozen by default

Pagination

v5 introduces SyncPager (and AsyncPager for async) to simplify working with paginated endpoints.

v4 pagination pattern

# v4: Manual pagination
all_users = []
page = 0

while True:
    result = auth0.users.list(page=page, per_page=50, include_totals=True)
    all_users.extend(result['users'])

    if len(all_users) >= result['total']:
        break
    page += 1

# Process all users
for user in all_users:
    print(user['email'])

v5 pagination patterns

Automatic iteration - The simplest approach, iterates across all pages automatically:

# v5: Automatic iteration across all pages
for user in client.users.list():
    print(user.email)

Page-by-page iteration - When you need to process pages individually:

# v5: Page-by-page iteration
for page in client.users.list().iter_pages():
    print(f"Processing {len(page.items)} users")
    for user in page.items:
        print(user.email)

Manual pagination - For explicit control over pagination:

# v5: Manual pagination with explicit parameters
pager = client.users.list(page=0, per_page=50)

# Access current page items
for user in pager.items:
    print(user.email)

# Check if there are more pages
if pager.has_next:
    next_pager = pager.next_page()
    for user in next_pager.items:
        print(user.email)

Async pagination

For async code, use AsyncManagementClient with async iteration:

# v5: Async pagination
from auth0.management import AsyncManagementClient

client = AsyncManagementClient(
    domain="your-tenant.auth0.com",
    token="MGMT_API_TOKEN",
)

# Async iteration
async for user in client.users.list():
    print(user.email)

# Async page-by-page
async for page in client.users.list().iter_pages():
    for user in page.items:
        print(user.email)