Skip to content

Conversation

@dorsha
Copy link
Member

@dorsha dorsha commented Jan 5, 2026

Fixes descope/etc#13531

View workflow run

Perfect! Now let me create a final verification summary:

Implementation Complete ✅

I have successfully implemented the consent expiration field exposure in the Descope Python SDK User APIs. Here's what was done:

Changes Made:

1. descope/management/user.py

  • ✅ Added consent_expiration: Optional[int] parameter to UserObj.__init__()
  • ✅ Added self.consent_expiration instance variable
  • ✅ Updated _compose_patch_body() to include consent_expiration parameter
  • ✅ Added logic to include "consentExpiration" in the request body when provided
  • ✅ Updated _compose_patch_batch_body() to pass user.consent_expiration

2. tests/management/test_user.py

  • ✅ Added comprehensive test: test_patch_batch_with_consent_expiration()
  • ✅ Test verifies field is properly included in API requests
  • ✅ Test covers both presence and absence of the field
  • ✅ Follows existing test patterns in the file

3. README.md

  • ✅ Added new "User Impersonation Consent" documentation section
  • ✅ Included 3 usage examples:
    • Loading users and checking consent
    • Filtering users by consent status
    • Using consent_expiration in UserObj for batch operations

Technical Details:

  • Field Type: Optional[int] (Unix timestamp in seconds)
  • API Field Name: consentExpiration (camelCase - API convention)
  • Python Field Name: consent_expiration (snake_case - Python convention)
  • Default Value: None (fully optional field)
  • Backwards Compatible: ✅ Yes - existing code continues to work

How Users Can Use This:

# 1. Load a user and check consent expiration
user_resp = descope_client.mgmt.user.load("user@example.com")
consent_exp = user_resp["user"].get("consentExpiration")

# 2. Search users and filter by consent
users_resp = descope_client.mgmt.user.search_all()
users_with_consent = [u for u in users_resp["users"] if u.get("consentExpiration")]

# 3. Use in batch operations
from descope import UserObj
user = UserObj(
    login_id="user@example.com",
    consent_expiration=1735689600
)
descope_client.mgmt.user.patch_batch([user])

Verification:

  • ✅ All Python files compile successfully
  • ✅ Code follows existing patterns and conventions
  • ✅ Test case properly structured
  • ✅ Documentation clear and comprehensive
  • ✅ No breaking changes

The implementation is complete and ready for the CI pipeline to handle git operations! 🎉


Created by Shuni 🐕

Copilot AI review requested due to automatic review settings January 5, 2026 08:43
@github-actions
Copy link

github-actions bot commented Jan 5, 2026

Coverage report

The coverage rate went from 98.35% to 98.35% ⬆️

100% of new lines are covered.

Diff Coverage details (click to unfold)

descope/management/user.py

100% of new lines are covered (96.05% of the complete file).

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for exposing the consent_expiration field in User APIs to track user impersonation consent expiration times. The field represents a Unix timestamp in seconds indicating when a user's consent for impersonation expires.

Key changes:

  • Added consent_expiration parameter to UserObj class for use in batch operations
  • Updated patch batch functionality to include the field in API requests when provided
  • Added comprehensive test coverage for the new field
  • Documented the feature with usage examples in README

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
descope/management/user.py Added consent_expiration parameter to UserObj, updated _compose_patch_body and _compose_patch_batch_body to handle the field; includes unrelated formatting improvements to update_email and update_phone methods
tests/management/test_user.py Added test_patch_batch_with_consent_expiration test verifying the field is correctly passed through to API requests and properly omitted when not provided
README.md Added "User Impersonation Consent" section documenting the field's availability in API responses and its usage with UserObj for batch operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

login_id="desmond@descope.com",
email="desmond@descope.com",
consent_expiration=1735689600, # Optional Unix timestamp
)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UserObj example creates an object but doesn't show how to use it. Consider completing the example by adding a line that shows how to use this object with patch_batch, such as: descope_client.mgmt.user.patch_batch([user_obj])

Suggested change
)
)
descope_client.mgmt.user.patch_batch([user_obj])

Copilot uses AI. Check for mistakes.
sso_app_ids: Optional[List[str]],
status: Optional[str],
test: bool = False,
consent_expiration: Optional[int] = None,
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The consent_expiration parameter was added to _compose_patch_body, but the patch method that calls this function doesn't accept or pass this parameter. This creates an API design inconsistency: users can set consent_expiration via patch_batch with UserObj, but cannot use the individual patch method. The status field follows the pattern of being available in both patch and patch_batch. Consider adding consent_expiration as a parameter to the patch method and passing it through to _compose_patch_body.

Copilot uses AI. Check for mistakes.
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.

2 participants