Skip to content

Conversation

@brianfeucht
Copy link

This PR introduces a thread-safe and async-safe way to access HTTP response headers (especially rate-limit information) from Auth0's Management API responses.

Changes

  • Added ContextVar for thread-safe header storage (auth0/rest.py)

    • Response headers are now stored in a per-execution-context variable
    • Each thread or async task gets its own isolated copy
    • Headers persist for the lifetime of the execution context
  • Added last_response_headers property to RestClient

    • New read-only property on RestClient class
    • Returns dict[str, str] containing rate-limit and other response headers
    • Available after every API call (GET, POST, PATCH, DELETE, etc.)
  • Updated EmptyResponse to preserve headers from 204 responses

    • 204 No Content responses now preserve headers
    • Rate-limit information is available even on success-with-no-content responses
  • Test suite (auth0/test/test_rest_headers_contextvar.py)

    • 8 new tests covering various scenarios
    • Specific verification of thread isolation
    • Tests for POST, PATCH, DELETE, and GET methods

References

Testing

This PR includes comprehensive testing:

Unit Tests Added: 8 Tests (All Passing ✅)

  1. test_headers_accessible_after_request - Verifies headers are stored and accessible after successful API calls
  2. test_headers_on_204_response - Confirms headers are preserved on 204 No Content responses
  3. test_headers_updated_on_successive_requests - Validates headers are updated with each new request
  4. test_headers_empty_initially - Confirms empty dict before any API calls
  5. test_thread_isolation - KEY TEST: Verifies each thread sees its own headers (not contaminated by other threads)
  6. test_headers_in_same_context_reflect_latest_request - Confirms context-specific behavior
  7. test_post_request_headers - Headers work on POST requests
  8. test_patch_request_headers - Headers work on PATCH requests

Test Coverage

  • Unit test coverage: 8 new tests specifically for this feature
  • Integration testing: Tests verify integration with existing RestClient workflow
  • Thread-safety verification: Specific test confirms thread isolation works correctly
  • Async-safety: ContextVars properly support asyncio tasks
  • HTTP methods covered: GET, POST, PATCH, DELETE, all tested
  • Response types covered: JSON (200, 201), Empty (204)

Existing Tests

  • ✅ All 301 management API tests pass
  • ✅ All 109 authentication tests pass
  • Zero regressions - 410 existing tests unaffected

Checklist

@brianfeucht brianfeucht requested a review from a team as a code owner December 17, 2025 19:25
Implement a thread-safe and async-safe way to access response headers using Python's contextvars module.

Changes:
- Add ContextVar to store response headers isolated per execution context (thread/async task)
- Add last_response_headers property to RestClient for accessing rate-limit and other response metadata
- Update EmptyResponse to preserve headers from 204 responses
- Comprehensive tests covering thread isolation, successive requests, and various HTTP methods

Benefits:
- Zero breaking changes - fully backwards compatible
- Minimal code footprint - only rest.py modified
- Thread-safe and async-safe via contextvars (Python 3.7+)
- No per-class boilerplate (eliminates need for 32 duplicate properties)

Usage:
    users = Users(domain="tenant.auth0.com", token="token")
    users.create({"email": "user@example.com"})
    headers = users.client.last_response_headers
    remaining = int(headers.get("X-RateLimit-Remaining", 0))
@brianfeucht brianfeucht force-pushed the feature/context-var-headers branch from 6de0387 to 4b7c793 Compare December 18, 2025 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant