From c2fdfdc5044a46e193674f3ae06da85fca6fe287 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 07:08:47 +0000 Subject: [PATCH] [autofix.ci] apply automated fixes --- api/controllers/service_api/wraps.py | 6 +++--- api/libs/api_token_cache.py | 4 ++-- api/tasks/update_api_token_last_used_task.py | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api/controllers/service_api/wraps.py b/api/controllers/service_api/wraps.py index 19bf089539..b1b143c6d1 100644 --- a/api/controllers/service_api/wraps.py +++ b/api/controllers/service_api/wraps.py @@ -358,18 +358,18 @@ def validate_and_get_api_token(scope: str | None = None): def _async_update_token_last_used_at(auth_token: str, scope: str | None): """ Asynchronously update the last_used_at timestamp for a token. - + This schedules a Celery task to update the database without blocking the current request. The start time is passed to ensure only older records are updated, providing natural concurrency control. """ try: from tasks.update_api_token_last_used_task import update_api_token_last_used_task - + # Record the request start time for concurrency control start_time = naive_utc_now() start_time_iso = start_time.isoformat() - + # Fire and forget - don't wait for result update_api_token_last_used_task.delay(auth_token, scope, start_time_iso) logger.debug("Scheduled async update for last_used_at (scope: %s, start_time: %s)", scope, start_time_iso) diff --git a/api/libs/api_token_cache.py b/api/libs/api_token_cache.py index 06399826c1..dc4d25f128 100644 --- a/api/libs/api_token_cache.py +++ b/api/libs/api_token_cache.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) class CachedApiToken: """ Simple data class to represent a cached API token. - + This is NOT a SQLAlchemy model instance, but a plain Python object that mimics the ApiToken model interface for read-only access. """ @@ -110,7 +110,7 @@ class ApiTokenCache: try: data = json.loads(cached_data) - + # Create a simple data object (NOT a SQLAlchemy model instance) # This is safe because it's just a plain Python object with attributes token_obj = CachedApiToken( diff --git a/api/tasks/update_api_token_last_used_task.py b/api/tasks/update_api_token_last_used_task.py index 291a0a7794..488158e6b0 100644 --- a/api/tasks/update_api_token_last_used_task.py +++ b/api/tasks/update_api_token_last_used_task.py @@ -20,10 +20,10 @@ logger = logging.getLogger(__name__) def update_api_token_last_used_task(self, token: str, scope: str | None, start_time_iso: str): """ Asynchronously update the last_used_at timestamp for an API token. - + Uses timestamp comparison to ensure only updates when last_used_at is older than the request start time, providing natural concurrency control. - + Args: token: The API token string scope: The token type/scope (e.g., 'app', 'dataset') @@ -31,10 +31,10 @@ def update_api_token_last_used_task(self, token: str, scope: str | None, start_t """ try: # Parse start_time from ISO format - start_time = datetime.fromisoformat(start_time_iso) + start_time = datetime.fromisoformat(start_time_iso) # Update database current_time = naive_utc_now() - + with Session(db.engine, expire_on_commit=False) as session: update_stmt = ( update(ApiToken) @@ -46,7 +46,7 @@ def update_api_token_last_used_task(self, token: str, scope: str | None, start_t .values(last_used_at=current_time) ) result = session.execute(update_stmt) - + if hasattr(result, "rowcount") and result.rowcount > 0: session.commit() logger.info("Updated last_used_at for token (async): %s... (scope: %s)", token[:10], scope) @@ -54,7 +54,7 @@ def update_api_token_last_used_task(self, token: str, scope: str | None, start_t else: logger.debug("No update needed for token: %s... (already up-to-date)", token[:10]) return {"status": "no_update_needed", "reason": "last_used_at >= start_time"} - + except Exception as e: logger.warning("Failed to update last_used_at for token (async): %s", e) # Don't retry on failure to avoid blocking the queue