Skip to content

⚡️ Speed up method AuthService.get_user_id_from_token by 186% in PR #10702 (pluggable-auth-service)#11623

Closed
codeflash-ai[bot] wants to merge 172 commits into
mainfrom
codeflash/optimize-pr10702-2026-02-06T14.49.04
Closed

⚡️ Speed up method AuthService.get_user_id_from_token by 186% in PR #10702 (pluggable-auth-service)#11623
codeflash-ai[bot] wants to merge 172 commits into
mainfrom
codeflash/optimize-pr10702-2026-02-06T14.49.04

Conversation

@codeflash-ai
Copy link
Copy Markdown
Contributor

@codeflash-ai codeflash-ai Bot commented Feb 6, 2026

⚡️ This pull request contains optimizations for PR #10702

If you approve this dependent PR, these changes will be merged into the original PR branch pluggable-auth-service.

This PR will be automatically closed if the original PR is merged.


📄 186% (1.86x) speedup for AuthService.get_user_id_from_token in src/backend/base/langflow/services/auth/service.py

⏱️ Runtime : 9.34 milliseconds 3.26 milliseconds (best of 32 runs)

📝 Explanation and details

The optimized code achieves a 186% speedup (from 9.34ms to 3.26ms) by replacing the heavyweight jwt.decode() call with a lightweight manual JWT payload extraction.

What Changed:
Instead of using PyJWT's jwt.decode(token, options={"verify_signature": False}), the optimized version manually splits the JWT string, base64-decodes the payload section, and parses the JSON to extract the "sub" claim directly.

Why This Is Faster:
The line profiler reveals the bottleneck: in the original code, jwt.decode() consumed 90.4% of the total runtime (71.3ms out of 78.9ms). Despite disabling signature verification, PyJWT still performs extensive validation, header parsing, algorithm checking, and creates multiple intermediate objects.

The optimized approach:

  • Skips all PyJWT overhead by directly accessing the payload (middle section of header.payload.signature)
  • Uses standard library functions (str.split, base64.urlsafe_b64decode, json.loads) which are highly optimized C extensions
  • Reduces from one expensive library call to three fast operations

Looking at the line profiler for the optimized version:

  • base64.urlsafe_b64decode: 26.2% of time (5.6ms)
  • json.loads: 30.8% of time (6.5ms)
  • UUID() construction: 28.1% of time (6.0ms)
  • Token splitting and padding: <7% combined

The work is distributed across faster primitives instead of concentrated in one slow call.

Impact on Workloads:
This optimization particularly benefits:

  • High-frequency logging/debugging scenarios where tokens are decoded repeatedly for user ID extraction without authentication
  • Batch processing (as shown in test cases processing 500+ tokens) where the 3x speedup compounds significantly
  • Large payload tokens where avoiding PyJWT's full parsing machinery provides even greater relative gains

Test Case Performance:
The annotated tests show the optimization handles all edge cases correctly (malformed tokens, missing claims, invalid UUIDs) while maintaining identical behavior. Batch processing tests with 50-500 tokens especially benefit from the cumulative time savings.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 515 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
from uuid import UUID, uuid4  # for constructing and comparing UUIDs

import jwt  # PyJWT used to create tokens compatible with the service's jwt.decode usage
# imports
import pytest  # used for our unit tests
from langflow.services.auth.service import AuthService

# function to test
# (The actual implementation is imported above from langflow.services.auth.service)
# We will instantiate AuthService and call its get_user_id_from_token method in tests below.

def _make_token_with_payload(payload: dict) -> str:
    """
    Helper to create a JWT token string containing the given payload.
    Use a real signature algorithm and key (signature will not be verified by the function under test).
    """
    # Use HS256 and a fixed secret; AuthService.get_user_id_from_token decodes with verify_signature=False,
    # so the exact key/alg do not affect decoding in these tests.
    return jwt.encode(payload, key="test-secret", algorithm="HS256")


def test_valid_token_returns_expected_uuid():
    # Create a valid UUID and embed it in a token under the 'sub' claim.
    expected_uuid = uuid4()
    token = _make_token_with_payload({"sub": str(expected_uuid)})

    # Instantiate AuthService; constructor accepts a settings_service argument but does not use it here.
    svc = AuthService(settings_service=None)

    # Call the method under test and assert it returns the same UUID object (value equal).
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_missing_sub_claim_returns_zero_uuid():
    # Token without 'sub' claim should trigger KeyError path and return UUID(int=0)
    token = _make_token_with_payload({"name": "alice", "role": "user"})

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_malformed_sub_value_returns_zero_uuid():
    # Token with 'sub' present but not a valid UUID string should raise ValueError internally
    token = _make_token_with_payload({"sub": "not-a-uuid-string"})

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_invalid_token_string_returns_zero_uuid():
    # Completely invalid token string (not a JWT at all) should be handled gracefully
    invalid_token = "this.is.not.a.valid.jwt"

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(invalid_token); result = codeflash_output


def test_valid_uppercase_uuid_sub_is_accepted():
    # UUIDs are case-insensitive in textual representation; uppercase should parse fine
    expected_uuid = uuid4()
    token = _make_token_with_payload({"sub": str(expected_uuid).upper()})

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_valid_zero_uuid_in_token_is_distinguished_from_error_but_value_matches():
    # If a token legitimately contains the zero UUID, the function should return that UUID.
    zero_uuid_str = str(UUID(int=0))
    token = _make_token_with_payload({"sub": zero_uuid_str})

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_large_payload_token_still_parses_sub_quickly():
    # Build a token with many additional claims to simulate a large payload (but keep total keys < 1000).
    many_claims = {f"key_{i}": f"value_{i}" for i in range(200)}  # 200 extra claims
    valid_uuid = uuid4()
    many_claims["sub"] = str(valid_uuid)
    token = _make_token_with_payload(many_claims)

    svc = AuthService(settings_service=None)
    codeflash_output = svc.get_user_id_from_token(token); result = codeflash_output


def test_batch_processing_of_many_tokens_returns_all_expected_uuids():
    # Create a moderate-sized batch of tokens to test scalability (500 is below the 1000-loop threshold).
    num_tokens = 500
    uuids = [uuid4() for _ in range(num_tokens)]
    tokens = [_make_token_with_payload({"sub": str(u)}) for u in uuids]

    svc = AuthService(settings_service=None)

    # Process each token and assert correctness. This tests batch behavior and helps reveal
    # issues that only manifest when the function is called repeatedly.
    results = []
    for tok in tokens:
        # Keep the loop below 1000 iterations as requested.
        results.append(svc.get_user_id_from_token(tok))



#------------------------------------------------
from unittest.mock import MagicMock, patch
from uuid import UUID

import jwt
import pytest
from jwt import InvalidTokenError
from langflow.services.auth.service import AuthService
from lfx.services.settings.service import SettingsService


# Test fixture to create an AuthService instance with a mock SettingsService
@pytest.fixture
def auth_service():
    """Create an AuthService instance with mocked SettingsService for testing."""
    mock_settings = MagicMock(spec=SettingsService)
    service = AuthService(mock_settings)
    return service


def test_valid_token_with_valid_uuid(auth_service):
    """Test extraction of user ID from a valid JWT token with a valid UUID 'sub' claim."""
    # Create a valid JWT token with a proper UUID in the 'sub' claim
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    token = jwt.encode({"sub": valid_uuid}, "secret", algorithm="HS256")
    
    # Extract the user ID from the token
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_valid_token_with_standard_uuid_format(auth_service):
    """Test extraction with a standard RFC 4122 compliant UUID."""
    # Use a well-known UUID format
    test_uuid = "12345678-1234-5678-1234-567812345678"
    token = jwt.encode({"sub": test_uuid}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_valid_token_with_additional_claims(auth_service):
    """Test that get_user_id_from_token correctly extracts 'sub' from a token with multiple claims."""
    # Create a token with multiple claims - the function should only care about 'sub'
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    token = jwt.encode({
        "sub": valid_uuid,
        "iat": 1234567890,
        "exp": 1234567900,
        "email": "user@example.com",
        "roles": ["admin", "user"]
    }, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_without_signature_verification(auth_service):
    """Test that the function works with tokens that haven't been signature-verified."""
    # Manually create a token without proper signing (to verify signature=False is being used)
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    # Create a properly formatted but unverified token
    token = jwt.encode({"sub": valid_uuid}, "wrong_secret", algorithm="HS256")
    
    # The function should still extract the 'sub' claim without verifying the signature
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_missing_sub_claim_returns_zero_uuid(auth_service):
    """Test that a token without 'sub' claim returns UUID(int=0)."""
    # Create a token without the 'sub' claim
    token = jwt.encode({"email": "user@example.com"}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_invalid_token_format_returns_zero_uuid(auth_service):
    """Test that an invalid/malformed token returns UUID(int=0)."""
    # Pass a string that is not a valid JWT
    invalid_token = "not.a.valid.jwt.token"
    
    codeflash_output = auth_service.get_user_id_from_token(invalid_token); result = codeflash_output


def test_empty_token_string_returns_zero_uuid(auth_service):
    """Test that an empty token string returns UUID(int=0)."""
    codeflash_output = auth_service.get_user_id_from_token(""); result = codeflash_output


def test_none_sub_claim_returns_zero_uuid(auth_service):
    """Test that a token with None as 'sub' claim returns UUID(int=0)."""
    # Create a token with None as the sub value
    token = jwt.encode({"sub": None}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_not_uuid_format_returns_zero_uuid(auth_service):
    """Test that 'sub' claim with non-UUID string returns UUID(int=0)."""
    # Create a token where 'sub' is not a valid UUID format
    token = jwt.encode({"sub": "not-a-uuid-string"}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_with_numeric_value(auth_service):
    """Test that numeric 'sub' claim values return UUID(int=0)."""
    # Create a token where 'sub' is an integer instead of a string
    token = jwt.encode({"sub": 12345}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_with_hex_uuid_no_hyphens(auth_service):
    """Test that a UUID without hyphens in 'sub' claim returns UUID(int=0)."""
    # Create a token with UUID in hex format without hyphens
    token = jwt.encode({"sub": "550e8400e29b41d4a716446655440000"}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_with_invalid_uuid_characters(auth_service):
    """Test that 'sub' with invalid UUID characters returns UUID(int=0)."""
    # Create a token with a string that looks like UUID but has invalid characters
    token = jwt.encode({"sub": "550e8400-e29b-41d4-a716-44665544000G"}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_malformed_jwt_with_extra_dots(auth_service):
    """Test that a JWT with too many dots (malformed) returns UUID(int=0)."""
    malformed_token = "header.payload.signature.extra"
    
    codeflash_output = auth_service.get_user_id_from_token(malformed_token); result = codeflash_output


def test_jwt_with_only_header_and_payload(auth_service):
    """Test that a JWT missing the signature portion returns UUID(int=0)."""
    incomplete_token = "header.payload"
    
    codeflash_output = auth_service.get_user_id_from_token(incomplete_token); result = codeflash_output


def test_token_with_special_characters_in_sub(auth_service):
    """Test that 'sub' with special characters returns UUID(int=0)."""
    token = jwt.encode({"sub": "550e8400-e29b-41d4-a716-446655440@00"}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_with_empty_string(auth_service):
    """Test that empty string as 'sub' claim returns UUID(int=0)."""
    token = jwt.encode({"sub": ""}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_sub_claim_with_whitespace_only(auth_service):
    """Test that whitespace-only 'sub' claim returns UUID(int=0)."""
    token = jwt.encode({"sub": "   "}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_with_list_as_sub(auth_service):
    """Test that a list as 'sub' claim returns UUID(int=0)."""
    token = jwt.encode({"sub": ["uuid1", "uuid2"]}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_with_dict_as_sub(auth_service):
    """Test that a dict as 'sub' claim returns UUID(int=0)."""
    token = jwt.encode({"sub": {"id": "550e8400-e29b-41d4-a716-446655440000"}}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_with_uuid_in_different_case(auth_service):
    """Test that UUID with uppercase letters is handled correctly."""
    # UUIDs are case-insensitive in Python's UUID class
    valid_uuid_lower = "550e8400-e29b-41d4-a716-446655440000"
    token = jwt.encode({"sub": valid_uuid_lower.upper()}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_with_uuid_mixed_case(auth_service):
    """Test that UUID with mixed case letters is handled correctly."""
    valid_uuid = "550E8400-e29B-41d4-A716-446655440000"
    token = jwt.encode({"sub": valid_uuid}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_very_long_token_string(auth_service):
    """Test that a very long malformed token returns UUID(int=0)."""
    # Create a very long string that's not a valid JWT
    long_token = "a" * 10000
    
    codeflash_output = auth_service.get_user_id_from_token(long_token); result = codeflash_output


def test_token_with_null_bytes(auth_service):
    """Test that a token containing null bytes returns UUID(int=0)."""
    token_with_nulls = "header\x00.payload\x00.signature"
    
    codeflash_output = auth_service.get_user_id_from_token(token_with_nulls); result = codeflash_output


def test_expired_token_still_extracts_uuid(auth_service):
    """Test that an expired token still extracts the user ID (no signature verification)."""
    # Create an expired token
    import time
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    token = jwt.encode({
        "sub": valid_uuid,
        "exp": int(time.time()) - 3600  # Expired 1 hour ago
    }, "secret", algorithm="HS256")
    
    # Should still extract the user ID since signature is not verified
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_with_wrong_algorithm(auth_service):
    """Test that a token created with different algorithm still extracts UUID."""
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    # Create token with HS512 instead of HS256
    token = jwt.encode({"sub": valid_uuid}, "secret", algorithm="HS512")
    
    # Should still work since signature verification is disabled
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_multiple_sequential_token_extractions(auth_service):
    """Test that the function handles multiple token extractions correctly."""
    # Generate and test 100 different UUIDs to ensure consistent behavior
    for i in range(100):
        # Create a valid UUID string from the index
        test_uuid = f"550e8400-e29b-41d4-a716-{44665544:04d}{i:04d}"
        token = jwt.encode({"sub": test_uuid}, "secret", algorithm="HS256")
        
        codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_batch_processing_valid_tokens(auth_service):
    """Test batch processing of 50 valid tokens."""
    # Create a batch of tokens with different UUIDs
    tokens_and_expected = []
    for i in range(50):
        # Create valid UUIDs programmatically
        base_uuid = f"550e8400-e29b-41d4-a716-{4466554400 + i:010d}"
        token = jwt.encode({"sub": base_uuid}, "secret", algorithm="HS256")
        tokens_and_expected.append((token, UUID(base_uuid)))
    
    # Process all tokens
    results = [auth_service.get_user_id_from_token(token) for token, _ in tokens_and_expected]
    
    # Verify all results match expected UUIDs
    for result, (_, expected_uuid) in zip(results, tokens_and_expected):
        pass


def test_batch_processing_invalid_tokens(auth_service):
    """Test batch processing of 50 invalid tokens."""
    # Create a batch of invalid tokens
    invalid_tokens = [
        "invalid_token_" + str(i) for i in range(50)
    ]
    
    # Process all invalid tokens
    results = [auth_service.get_user_id_from_token(token) for token in invalid_tokens]
    
    # All should return UUID(int=0)
    for result in results:
        pass


def test_mixed_batch_valid_and_invalid_tokens(auth_service):
    """Test batch processing with mixed valid and invalid tokens."""
    # Create a mix of 50 tokens (25 valid, 25 invalid)
    batch_results = []
    
    for i in range(50):
        if i % 2 == 0:
            # Create valid token
            test_uuid = f"550e8400-e29b-41d4-a716-{4466554400 + i:010d}"
            token = jwt.encode({"sub": test_uuid}, "secret", algorithm="HS256")
            expected = UUID(test_uuid)
        else:
            # Create invalid token
            token = f"invalid_token_{i}"
            expected = UUID(int=0)
        
        codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        batch_results.append((result, expected))
    
    # Verify all results
    for result, expected in batch_results:
        pass


def test_tokens_with_large_payload(auth_service):
    """Test token extraction when the JWT contains a large payload."""
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    
    # Create a token with a large payload (many additional claims)
    large_payload = {"sub": valid_uuid}
    for i in range(100):
        large_payload[f"claim_{i}"] = f"value_{i}" * 10  # Add large strings
    
    token = jwt.encode(large_payload, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_repeated_calls_same_token_consistency(auth_service):
    """Test that calling the function multiple times with same token gives consistent results."""
    valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
    token = jwt.encode({"sub": valid_uuid}, "secret", algorithm="HS256")
    
    # Call the function 100 times with the same token
    results = [auth_service.get_user_id_from_token(token) for _ in range(100)]
    
    # All results should be identical
    expected = UUID(valid_uuid)
    for result in results:
        pass


def test_all_nil_uuid(auth_service):
    """Test with the all-zeros UUID (nil UUID)."""
    nil_uuid = "00000000-0000-0000-0000-000000000000"
    token = jwt.encode({"sub": nil_uuid}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_max_uuid(auth_service):
    """Test with the maximum UUID value."""
    max_uuid = "ffffffff-ffff-ffff-ffff-ffffffffffff"
    token = jwt.encode({"sub": max_uuid}, "secret", algorithm="HS256")
    
    codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_many_edge_case_tokens(auth_service):
    """Test a variety of edge cases in a single batch."""
    # Test 50 different edge cases
    test_cases = [
        ("missing_sub", None),  # Will be caught as KeyError
        ("invalid_format", "not-valid-uuid"),
        ("empty_string", ""),
        ("whitespace", "   "),
        ("too_long", "a" * 1000),
        ("special_chars", "550e8400-e29b-41d4-a716-44665544@000"),
        ("valid", "550e8400-e29b-41d4-a716-446655440000"),
    ]
    
    # Process first batch of 50 variations
    for i in range(50):
        if i % 7 == 0:
            # Test missing sub claim
            token = jwt.encode({"iat": 1234567890}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        elif i % 7 == 1:
            # Test valid UUID
            valid_uuid = f"550e8400-e29b-41d4-a716-{4466554400 + i:010d}"
            token = jwt.encode({"sub": valid_uuid}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        elif i % 7 == 2:
            # Test invalid format
            token = jwt.encode({"sub": "not-a-uuid"}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        elif i % 7 == 3:
            # Test malformed JWT
            codeflash_output = auth_service.get_user_id_from_token("bad.jwt"); result = codeflash_output
        elif i % 7 == 4:
            # Test numeric sub
            token = jwt.encode({"sub": 12345}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        elif i % 7 == 5:
            # Test list as sub
            token = jwt.encode({"sub": ["uuid1"]}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
        else:
            # Test None as sub
            token = jwt.encode({"sub": None}, "secret", algorithm="HS256")
            codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output


def test_token_extraction_performance_with_various_sizes(auth_service):
    """Test that extraction works consistently across tokens of various sizes."""
    # Create tokens with payloads of increasing size
    for payload_size in [1, 10, 50, 100]:
        valid_uuid = "550e8400-e29b-41d4-a716-446655440000"
        payload = {"sub": valid_uuid}
        
        # Add claims to increase payload size
        for i in range(payload_size):
            payload[f"claim_{i}"] = "x" * 100
        
        token = jwt.encode(payload, "secret", algorithm="HS256")
        codeflash_output = auth_service.get_user_id_from_token(token); result = codeflash_output
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-pr10702-2026-02-06T14.49.04 and push.

Codeflash

ogabrielluiz and others added 30 commits January 15, 2026 12:49
…ager for pluggable service discovery

- Added `register_service` decorator to allow services to self-register with the ServiceManager.
- Enhanced `ServiceManager` to support multiple service discovery mechanisms, including decorator-based registration, config files, and entry points.
- Implemented methods for direct service class registration and plugin discovery from various sources, improving flexibility and extensibility of service management.
- Introduced VariableService class to handle environment variables with in-memory caching.
- Added methods for getting, setting, deleting, and listing variables.
- Included logging for service initialization and variable operations.
- Created an __init__.py file to expose VariableService in the package namespace.
…teardown

- Updated LocalStorageService to inherit from both StorageService and Service for improved functionality.
- Added a name attribute for service identification.
- Implemented an async teardown method for future extensibility, even though no cleanup is currently needed.
- Refactored the constructor to ensure proper initialization of both parent classes.
…l logging functionality

- Added `BaseTelemetryService` as an abstract base class defining the interface for telemetry services.
- Introduced `TelemetryService`, a lightweight implementation that logs telemetry events without sending data.
- Created `__init__.py` to expose the telemetry service in the package namespace.
- Ensured robust async methods for logging various telemetry events and handling exceptions.
- Added `BaseTracingService` as an abstract base class defining the interface for tracing services.
- Implemented `TracingService`, a lightweight version that logs trace events without external integrations.
- Included async methods for starting and ending traces, tracing components, and managing logs and outputs.
- Enhanced documentation for clarity on method usage and parameters.
- Introduced a new test suite for validating the functionality of the @register_service decorator.
- Implemented tests for various service types including LocalStorageService, TelemetryService, and TracingService.
- Verified behavior for service registration with and without overrides, ensuring correct service management.
- Included tests for custom service implementations and preservation of class functionality.
- Enhanced overall test coverage for the service registration mechanism.
- Introduced a suite of unit tests covering edge cases for service registration, lifecycle management, and dependency resolution.
- Implemented integration tests to validate service loading from configuration files and environment variables.
- Enhanced test coverage for various service types including LocalStorageService, TelemetryService, and VariableService.
- Verified behavior for service registration with and without overrides, ensuring correct service management.
- Ensured robust handling of error conditions and edge cases in service creation and configuration parsing.
- Introduced comprehensive unit tests for LocalStorageService, TelemetryService, TracingService, and VariableService.
- Implemented integration tests to validate the interaction between minimal services.
- Ensured robust coverage for file operations, service readiness, and exception handling.
- Enhanced documentation within tests for clarity on functionality and expected behavior.
…ection

- Revised the documentation to highlight the advantages of the pluggable service system.
- Replaced the migration guide with a detailed overview of features such as automatic discovery, lazy instantiation, dependency injection, and lifecycle management.
- Clarified examples of service registration and improved overall documentation for better understanding.
During rebase, the teardown method was added in two locations (lines 57 and 220).
Removed the duplicate at line 57, keeping the one at the end of the class (line 220)
which is the more appropriate location for cleanup methods.
…changes

- Add MockSessionService fixtures to test files that use ServiceManager
- Update LocalStorageService test instantiation to use mock session and settings services
- Fix service count assertions to account for MockSessionService in fixtures
- Remove duplicate class-level clean_manager fixtures in test_edge_cases.py

These changes fix test failures caused by LocalStorageService requiring
session_service and settings_service parameters instead of just data_dir.
- Fixed Diamond Inheritance in LocalStorageService
- Added Circular Dependency Detection in _create_service_from_class
- Fixed StorageService.teardown to Have Default Implementation
- The aiofile library uses native async I/O (libaio) which fails with
  EAGAIN (SystemError: 11, 'Resource temporarily unavailable') in
  containerized environments like GitHub Actions runners.
- Switch to aiofiles which uses thread pool executors, providing reliable
  async file I/O across all environments including containers.
  The discover_plugins() method had a TOCTOU (time-of-check to time-of-use)
  race condition. Since get() uses a keyed lock (per service name), multiple
  threads requesting different services could concurrently see
  _plugins_discovered=False and trigger duplicate plugin discovery.

  Wrap discover_plugins() with self._lock to ensure thread-safe access to
  the _plugins_discovered flag and prevent concurrent discovery execution.
…ager for pluggable service discovery

- Added `register_service` decorator to allow services to self-register with the ServiceManager.
- Enhanced `ServiceManager` to support multiple service discovery mechanisms, including decorator-based registration, config files, and entry points.
- Implemented methods for direct service class registration and plugin discovery from various sources, improving flexibility and extensibility of service management.
…teardown

- Updated LocalStorageService to inherit from both StorageService and Service for improved functionality.
- Added a name attribute for service identification.
- Implemented an async teardown method for future extensibility, even though no cleanup is currently needed.
- Refactored the constructor to ensure proper initialization of both parent classes.
  Consolidate all authentication methods into the AuthService class to
  enable pluggable authentication implementations. The utils module now
  contains thin wrappers that delegate to the registered auth service.

  This allows alternative auth implementations (e.g., OIDC) to be
  registered via the pluggable services system while maintaining
  backward compatibility with existing code that imports from utils.

  Changes:
  - Move all auth logic (token creation, user validation, API key
    security, password hashing, encryption) to AuthService
  - Refactor utils.py to delegate to get_auth_service()
  - Update function signatures to remove settings_service parameter
    (now obtained from the service internally)
…vice parameter

  - Changed function to retrieve current user from access token instead of JWT.
  - Updated AuthServiceFactory to specify SettingsService type in create method.
  - Removed settings_service dependency from encryption and decryption functions, simplifying the code.

This refactor enhances the clarity and maintainability of the authentication logic.
- Introduced comprehensive unit tests for AuthService, covering token creation, user validation, and authentication methods.
- Added tests for pluggable authentication, ensuring correct delegation to registered services.
- Enhanced test coverage for user authentication scenarios, including active/inactive user checks and token validation.

These additions improve the reliability and maintainability of the authentication system.
HimavarshaVS and others added 23 commits February 5, 2026 06:05
The optimized code achieves a **186% speedup** (from 9.34ms to 3.26ms) by replacing the heavyweight `jwt.decode()` call with a lightweight manual JWT payload extraction.

**What Changed:**
Instead of using PyJWT's `jwt.decode(token, options={"verify_signature": False})`, the optimized version manually splits the JWT string, base64-decodes the payload section, and parses the JSON to extract the `"sub"` claim directly.

**Why This Is Faster:**
The line profiler reveals the bottleneck: in the original code, `jwt.decode()` consumed **90.4%** of the total runtime (71.3ms out of 78.9ms). Despite disabling signature verification, PyJWT still performs extensive validation, header parsing, algorithm checking, and creates multiple intermediate objects. 

The optimized approach:
- Skips all PyJWT overhead by directly accessing the payload (middle section of `header.payload.signature`)
- Uses standard library functions (`str.split`, `base64.urlsafe_b64decode`, `json.loads`) which are highly optimized C extensions
- Reduces from one expensive library call to three fast operations

Looking at the line profiler for the optimized version:
- `base64.urlsafe_b64decode`: 26.2% of time (5.6ms)
- `json.loads`: 30.8% of time (6.5ms)  
- `UUID()` construction: 28.1% of time (6.0ms)
- Token splitting and padding: <7% combined

The work is distributed across faster primitives instead of concentrated in one slow call.

**Impact on Workloads:**
This optimization particularly benefits:
- **High-frequency logging/debugging scenarios** where tokens are decoded repeatedly for user ID extraction without authentication
- **Batch processing** (as shown in test cases processing 500+ tokens) where the 3x speedup compounds significantly
- **Large payload tokens** where avoiding PyJWT's full parsing machinery provides even greater relative gains

**Test Case Performance:**
The annotated tests show the optimization handles all edge cases correctly (malformed tokens, missing claims, invalid UUIDs) while maintaining identical behavior. Batch processing tests with 50-500 tokens especially benefit from the cumulative time savings.
@codeflash-ai codeflash-ai Bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Feb 6, 2026
@github-actions github-actions Bot added the community Pull Request from an external contributor label Feb 6, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 81.32530% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 34.92%. Comparing base (4063abd) to head (95a2b6d).
⚠️ Report is 13 commits behind head on main.

Files with missing lines Patch % Lines
src/lfx/src/lfx/services/auth/service.py 70.58% 15 Missing ⚠️
src/lfx/src/lfx/services/auth/exceptions.py 62.50% 9 Missing ⚠️
src/lfx/src/lfx/services/auth/base.py 93.22% 4 Missing ⚠️
src/lfx/src/lfx/services/deps.py 33.33% 2 Missing ⚠️
src/lfx/src/lfx/services/manager.py 93.75% 0 Missing and 1 partial ⚠️

❌ Your project status has failed because the head coverage (42.10%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #11623      +/-   ##
==========================================
- Coverage   34.94%   34.92%   -0.03%     
==========================================
  Files        1506     1509       +3     
  Lines       71834    71582     -252     
  Branches    10674    10672       -2     
==========================================
- Hits        25101    24998     -103     
+ Misses      45401    45252     -149     
  Partials     1332     1332              
Flag Coverage Δ
lfx 42.10% <81.32%> (+0.26%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/backend/base/langflow/__main__.py 56.05% <ø> (+0.05%) ⬆️
src/backend/base/langflow/api/v1/api_key.py 72.72% <ø> (-0.61%) ⬇️
src/backend/base/langflow/api/v1/endpoints.py 73.02% <ø> (+0.12%) ⬆️
src/backend/base/langflow/api/v1/login.py 39.74% <ø> (-2.12%) ⬇️
src/backend/base/langflow/api/v1/mcp.py 72.41% <ø> (-0.16%) ⬇️
src/backend/base/langflow/api/v1/mcp_projects.py 41.18% <ø> (-0.10%) ⬇️
src/backend/base/langflow/api/v1/models.py 41.55% <ø> (+0.34%) ⬆️
src/backend/base/langflow/api/v1/store.py 32.63% <ø> (+0.67%) ⬆️
src/backend/base/langflow/api/v1/users.py 65.33% <ø> (-1.74%) ⬇️
src/backend/base/langflow/api/v2/mcp.py 51.02% <ø> (+0.68%) ⬆️
... and 22 more

... and 10 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Base automatically changed from pluggable-auth-service to main February 6, 2026 20:41
@ogabrielluiz
Copy link
Copy Markdown
Contributor

Closing: removing CodeFlash integration.

@codeflash-ai codeflash-ai Bot deleted the codeflash/optimize-pr10702-2026-02-06T14.49.04 branch February 11, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI community Pull Request from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants