Skip to content

Conversation

@codeflash-ai
Copy link
Contributor

@codeflash-ai codeflash-ai bot commented Oct 30, 2025

⚡️ This pull request contains optimizations for PR #10347

If you approve this dependent PR, these changes will be merged into the original PR branch cz/fix-mcptimeout-1.6.5.

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


📄 137% (1.37x) speedup for MCPComposerService._obfuscate_command_secrets in src/backend/base/langflow/services/mcp_composer/service.py

⏱️ Runtime : 2.63 milliseconds 1.11 milliseconds (best of 114 runs)

📝 Explanation and details

The optimization achieves a 136% speedup (2.63ms → 1.11ms) by eliminating expensive Python operations in a tight loop through several key improvements:

What was optimized:

  • Method lookup elimination: Cached safe_cmd.append and safe_cmd.extend as local variables to avoid repeated attribute lookups on each iteration
  • Length computation caching: Stored len(cmd) as cmd_len to avoid recalculating the list length on every loop condition check
  • Generator expression removal: Replaced the any() generator expression with direct or comparisons to eliminate the overhead of creating a generator object and calling any()
  • String lowercasing optimization: Moved env_key.lower() outside the comparison chain to avoid multiple calls

Why this leads to speedup:
The original code's bottleneck was the any() generator expression (35.6% of total time), which creates a temporary generator object and performs function calls for each secret check. The optimized version uses direct boolean or operations that are much faster in Python. Additionally, caching method references eliminates Python's attribute lookup overhead, which is significant in tight loops.

Test case performance:
These optimizations are particularly effective for the large-scale test cases (test_large_* functions) that process 500+ command arguments, where the loop overhead compounds. The optimization maintains identical behavior while being most beneficial when processing commands with many --env arguments, especially those containing secret keys that trigger the substring matching logic.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 132 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import asyncio

# imports
import pytest  # used for our unit tests
from langflow.services.base import Service
from langflow.services.mcp_composer.service import MCPComposerService

# unit tests

@pytest.fixture
def service():
    # Fixture to provide a fresh MCPComposerService instance
    return MCPComposerService()

# ---------------- BASIC TEST CASES ----------------

def test_basic_no_env(service):
    # No --env, nothing should be changed
    cmd = ["python", "run.py", "--debug"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_env_non_secret(service):
    # --env with non-secret key/value should be unchanged
    cmd = ["--env", "USER", "alice"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_env_secret_key(service):
    # --env with a key containing "secret" should redact value
    cmd = ["--env", "API_SECRET", "mysecret"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_env_token_key(service):
    # --env with a key containing "token" should redact value
    cmd = ["--env", "access_token", "tokval"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_env_key_key(service):
    # --env with a key containing "key" should redact value
    cmd = ["--env", "auth_key", "somekey"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_mixed_args(service):
    # Mixed args, only redact secret keys
    cmd = [
        "python", "run.py",
        "--env", "USER", "alice",
        "--env", "API_SECRET", "mysecret",
        "--env", "access_token", "tokval",
        "--env", "auth_key", "somekey",
        "--verbose"
    ]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_basic_case_insensitivity(service):
    # Key should be matched case-insensitively
    cmd = ["--env", "SeCrEt_Token", "val"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

# ---------------- EDGE TEST CASES ----------------

def test_edge_empty_list(service):
    # Empty command list should return empty list
    cmd = []
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_at_end(service):
    # --env at end with missing key/value should be left as-is
    cmd = ["python", "run.py", "--env"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_only_key(service):
    # --env at end with only key, missing value
    cmd = ["--env", "API_SECRET"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_non_secret_key_partial(service):
    # --env with key but value missing, non-secret key
    cmd = ["--env", "USER"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_secret_key_partial(service):
    # --env with secret key but value missing
    cmd = ["--env", "API_SECRET"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_multiple_envs_in_row(service):
    # Multiple --env blocks, some secret, some not
    cmd = [
        "--env", "USER", "alice",
        "--env", "API_SECRET", "mysecret",
        "--env", "DEBUG", "true",
        "--env", "access_token", "tokval"
    ]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_secret_key_substring(service):
    # Secret substring anywhere in key should redact
    cmd = ["--env", "notasecretkey", "shouldredact"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_secret_key_at_start(service):
    # Secret substring at start
    cmd = ["--env", "secret_sauce", "hidden"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_secret_key_at_end(service):
    # Secret substring at end
    cmd = ["--env", "sauce_secret", "hidden"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_non_env_secret_key(service):
    # "secret" in arg, but not as --env, should NOT redact
    cmd = ["--secret", "mysecret"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_empty_value(service):
    # --env with secret key and empty value should still redact
    cmd = ["--env", "API_SECRET", ""]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_spaces_in_key(service):
    # --env with spaces in key, still redact if substring matches
    cmd = ["--env", "my secret key", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_special_chars(service):
    # --env with special characters in key, still redact if substring matches
    cmd = ["--env", "API_SECRET@123", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_multiple_secrets(service):
    # --env with key containing multiple secret substrings
    cmd = ["--env", "token_secret_key", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_uppercase_key(service):
    # --env with uppercase secret substring
    cmd = ["--env", "API_KEY", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_mixed_case_key(service):
    # --env with mixed case secret substring
    cmd = ["--env", "Api_KeY", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_key_only(service):
    # --env with key only, no value
    cmd = ["--env", "API_KEY"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_value_only(service):
    # --env with value only, no key
    cmd = ["--env", "", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_edge_env_with_empty_key_and_secret(service):
    # --env with empty key, should not redact
    cmd = ["--env", "", "value"]
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

# ---------------- LARGE SCALE TEST CASES ----------------

def test_large_many_non_secret_envs(service):
    # Large number of --env blocks, none secret
    cmd = []
    expected = []
    for i in range(500):
        cmd.extend(["--env", f"USER{i}", f"value{i}"])
        expected.extend(["--env", f"USER{i}", f"value{i}"])
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_large_many_secret_envs(service):
    # Large number of --env blocks, all secret
    cmd = []
    expected = []
    for i in range(500):
        cmd.extend(["--env", f"API_SECRET_{i}", f"value{i}"])
        expected.extend(["--env", f"API_SECRET_{i}", "***REDACTED***"])
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_large_mixed_envs(service):
    # Large number of mixed --env blocks (half secret, half not)
    cmd = []
    expected = []
    for i in range(250):
        cmd.extend(["--env", f"USER{i}", f"value{i}"])
        expected.extend(["--env", f"USER{i}", f"value{i}"])
        cmd.extend(["--env", f"API_SECRET_{i}", f"value{i}"])
        expected.extend(["--env", f"API_SECRET_{i}", "***REDACTED***"])
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_large_args_with_non_env(service):
    # Large list with many non-env args and some secret envs
    cmd = ["python"] + [f"--flag{i}" for i in range(100)]
    for i in range(100):
        cmd.extend(["--env", f"API_KEY_{i}", f"value{i}"])
    expected = ["python"] + [f"--flag{i}" for i in range(100)]
    for i in range(100):
        expected.extend(["--env", f"API_KEY_{i}", "***REDACTED***"])
    codeflash_output = service._obfuscate_command_secrets(cmd); result = codeflash_output

def test_large_args_with_interleaved_envs(service):
    # Large list with interleaved env and non-env args
    cmd = []
    expected = []
    for i in range(100):
        cmd.append(f"--flag{i}")
        expected.append(f"--flag{i}")
        cmd.extend(["--env", f"API_SECRET_{i}", f"value{i}"])
        expected.extend(["--env", f"API_SECRET_{i}", "***REDACTED***"])
        cmd.append(f"--option{i}")
        expected.append(f"--option{i}")
    codeflash_output = service._obfuscate_command_secrets(cmd); 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.
#------------------------------------------------
import asyncio
from typing import List

# imports
import pytest
from langflow.services.mcp_composer.service import MCPComposerService

# unit tests

@pytest.fixture
def service():
    return MCPComposerService()

# 1. Basic Test Cases

def test_no_env_arguments(service):
    # Command with no --env arguments should remain unchanged
    cmd = ["python", "main.py", "--port", "8080"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_non_secret_key(service):
    # --env with a non-secret key should not be obfuscated
    cmd = ["run", "--env", "DEBUG", "1"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_secret_key(service):
    # --env with a key containing "secret" should redact the value
    cmd = ["run", "--env", "MY_SECRET", "hunter2"]
    expected = ["run", "--env", "MY_SECRET", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_key(service):
    # --env with a key containing "key" should redact the value
    cmd = ["run", "--env", "api_key", "12345"]
    expected = ["run", "--env", "api_key", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_token_key(service):
    # --env with a key containing "token" should redact the value
    cmd = ["run", "--env", "access_token", "abcdef"]
    expected = ["run", "--env", "access_token", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_multiple_envs_with_and_without_secrets(service):
    # Multiple --env arguments, some with secrets, some without
    cmd = [
        "start", "--env", "DEBUG", "1",
        "--env", "SECRET_KEY", "s3cr3t",
        "--env", "LOG_LEVEL", "INFO",
        "--env", "api_token", "xyz"
    ]
    expected = [
        "start", "--env", "DEBUG", "1",
        "--env", "SECRET_KEY", "***REDACTED***",
        "--env", "LOG_LEVEL", "INFO",
        "--env", "api_token", "***REDACTED***"
    ]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_case_insensitivity(service):
    # Key with mixed case containing "Secret", "Key", or "Token"
    cmd = ["run", "--env", "SeCrEt", "v1"]
    expected = ["run", "--env", "SeCrEt", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_key_as_substring(service):
    # Key where "key" is a substring, not the whole word
    cmd = ["run", "--env", "monkey", "banana"]
    expected = ["run", "--env", "monkey", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_token_as_substring(service):
    # Key where "token" is a substring
    cmd = ["run", "--env", "mytokenvalue", "banana"]
    expected = ["run", "--env", "mytokenvalue", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_key_at_start_of_word(service):
    # Key where "key" is at the start
    cmd = ["run", "--env", "keyvalue", "banana"]
    expected = ["run", "--env", "keyvalue", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_key_at_end_of_word(service):
    # Key where "key" is at the end
    cmd = ["run", "--env", "valuekey", "banana"]
    expected = ["run", "--env", "valuekey", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

# 2. Edge Test Cases

def test_empty_command(service):
    # Empty command should return empty list
    cmd = []
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_only_env(service):
    # Only --env, no key or value (malformed)
    cmd = ["--env"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_key_only(service):
    # --env with only key, no value (malformed)
    cmd = ["--env", "SECRET_KEY"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_at_end(service):
    # --env at the end of the command, with not enough elements after
    cmd = ["run", "--env"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_key_at_end(service):
    # --env followed by key but no value
    cmd = ["run", "--env", "SECRET_KEY"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_multiple_secret_types(service):
    # --env keys with "secret", "key", "token" in various positions
    cmd = [
        "--env", "SECRET", "a",
        "--env", "mykey", "b",
        "--env", "token", "c",
        "--env", "notasecret", "d"
    ]
    expected = [
        "--env", "SECRET", "***REDACTED***",
        "--env", "mykey", "***REDACTED***",
        "--env", "token", "***REDACTED***",
        "--env", "notasecret", "***REDACTED***"
    ]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_empty_value(service):
    # --env with a secret key but empty value
    cmd = ["run", "--env", "SECRET_KEY", ""]
    expected = ["run", "--env", "SECRET_KEY", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_space_value(service):
    # --env with a secret key and value that is just spaces
    cmd = ["run", "--env", "SECRET_KEY", "   "]
    expected = ["run", "--env", "SECRET_KEY", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_special_characters(service):
    # --env with a secret key and value with special characters
    cmd = ["run", "--env", "SECRET_KEY", "!@#$%^&*()"]
    expected = ["run", "--env", "SECRET_KEY", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_unicode_value(service):
    # --env with a secret key and unicode value
    cmd = ["run", "--env", "SECRET_KEY", "密码"]
    expected = ["run", "--env", "SECRET_KEY", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_numeric_value(service):
    # --env with a secret key and numeric value
    cmd = ["run", "--env", "SECRET_KEY", "123456"]
    expected = ["run", "--env", "SECRET_KEY", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_command_with_env_and_mixedcase_key(service):
    # --env with a secret key in mixed case
    cmd = ["run", "--env", "SeCrEt_TokEn", "hunter2"]
    expected = ["run", "--env", "SeCrEt_TokEn", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_not_followed_by_key_value(service):
    # --env appears, but not followed by enough arguments
    cmd = ["run", "--env"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_containing_secret_as_substring(service):
    # --env with a key that contains "secret" as a substring
    cmd = ["run", "--env", "notasecret", "foo"]
    expected = ["run", "--env", "notasecret", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_containing_key_as_substring(service):
    # --env with a key that contains "key" as a substring
    cmd = ["run", "--env", "monkeybusiness", "foo"]
    expected = ["run", "--env", "monkeybusiness", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_containing_token_as_substring(service):
    # --env with a key that contains "token" as a substring
    cmd = ["run", "--env", "tokentastic", "foo"]
    expected = ["run", "--env", "tokentastic", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_is_just_secret(service):
    # --env with a key that is exactly "secret"
    cmd = ["run", "--env", "secret", "foo"]
    expected = ["run", "--env", "secret", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_is_just_key(service):
    # --env with a key that is exactly "key"
    cmd = ["run", "--env", "key", "foo"]
    expected = ["run", "--env", "key", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_env_with_key_is_just_token(service):
    # --env with a key that is exactly "token"
    cmd = ["run", "--env", "token", "foo"]
    expected = ["run", "--env", "token", "***REDACTED***"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

# 3. Large Scale Test Cases

def test_large_number_of_non_secret_envs(service):
    # 500 --env pairs, none of them secrets
    cmd = []
    expected = []
    for i in range(500):
        cmd.extend(["--env", f"VAR{i}", f"value{i}"])
        expected.extend(["--env", f"VAR{i}", f"value{i}"])
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_large_number_of_secret_envs(service):
    # 500 --env pairs, all secrets
    cmd = []
    expected = []
    for i in range(500):
        key = f"SECRET_KEY_{i}"
        value = f"value{i}"
        cmd.extend(["--env", key, value])
        expected.extend(["--env", key, "***REDACTED***"])
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_large_mixed_envs(service):
    # 250 secret, 250 non-secret --env pairs, interleaved
    cmd = []
    expected = []
    for i in range(250):
        # non-secret
        cmd.extend(["--env", f"VAR{i}", f"value{i}"])
        expected.extend(["--env", f"VAR{i}", f"value{i}"])
        # secret
        key = f"SECRET_KEY_{i}"
        value = f"value{i}"
        cmd.extend(["--env", key, value])
        expected.extend(["--env", key, "***REDACTED***"])
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_large_command_with_non_env_args(service):
    # Large command with --env and other arguments
    cmd = ["python", "main.py"]
    expected = ["python", "main.py"]
    for i in range(400):
        cmd.extend(["--env", f"VAR{i}", f"value{i}"])
        expected.extend(["--env", f"VAR{i}", f"value{i}"])
    cmd += ["--port", "8080", "--debug"]
    expected += ["--port", "8080", "--debug"]
    codeflash_output = service._obfuscate_command_secrets(cmd)

def test_large_command_with_secrets_and_non_secrets_and_other_args(service):
    # Large command mixing secrets, non-secrets, and other arguments
    cmd = ["start", "--log", "info"]
    expected = ["start", "--log", "info"]
    for i in range(200):
        cmd.extend(["--env", f"VAR{i}", f"value{i}"])
        expected.extend(["--env", f"VAR{i}", f"value{i}"])
        cmd.extend(["--env", f"SECRET_{i}", f"secret{i}"])
        expected.extend(["--env", f"SECRET_{i}", "***REDACTED***"])
    cmd += ["--port", "8080", "--debug"]
    expected += ["--port", "8080", "--debug"]
    codeflash_output = service._obfuscate_command_secrets(cmd)
# 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-pr10347-2025-10-30T14.41.06 and push.

Codeflash

The optimization achieves a **136% speedup** (2.63ms → 1.11ms) by eliminating expensive Python operations in a tight loop through several key improvements:

**What was optimized:**
- **Method lookup elimination**: Cached `safe_cmd.append` and `safe_cmd.extend` as local variables to avoid repeated attribute lookups on each iteration
- **Length computation caching**: Stored `len(cmd)` as `cmd_len` to avoid recalculating the list length on every loop condition check
- **Generator expression removal**: Replaced the `any()` generator expression with direct `or` comparisons to eliminate the overhead of creating a generator object and calling `any()`
- **String lowercasing optimization**: Moved `env_key.lower()` outside the comparison chain to avoid multiple calls

**Why this leads to speedup:**
The original code's bottleneck was the `any()` generator expression (35.6% of total time), which creates a temporary generator object and performs function calls for each secret check. The optimized version uses direct boolean `or` operations that are much faster in Python. Additionally, caching method references eliminates Python's attribute lookup overhead, which is significant in tight loops.

**Test case performance:**
These optimizations are particularly effective for the large-scale test cases (`test_large_*` functions) that process 500+ command arguments, where the loop overhead compounds. The optimization maintains identical behavior while being most beneficial when processing commands with many `--env` arguments, especially those containing secret keys that trigger the substring matching logic.
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Oct 30, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant