From ec5f887debf0b554a2e4e0aaa045a9b52a93b893 Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Thu, 12 Mar 2026 10:31:04 -0700 Subject: [PATCH 1/8] chore: fix isort updated import order, applied isort to adjust the formatting of the import packages for py files --- cforge/commands/server/run.py | 1 + cforge/common/console.py | 2 ++ cforge/common/errors.py | 4 +++ cforge/common/http.py | 3 ++ cforge/common/prompting.py | 3 ++ cforge/common/render.py | 3 ++ cforge/config.py | 4 +-- cforge/credential_store.py | 2 +- cforge/main.py | 9 ++---- cforge/profile_utils.py | 6 ++-- tests/commands/resources/test_a2a.py | 4 ++- tests/commands/resources/test_mcp_servers.py | 4 ++- tests/commands/resources/test_plugins.py | 2 ++ tests/commands/resources/test_prompts.py | 4 ++- tests/commands/resources/test_resources.py | 4 ++- tests/commands/resources/test_tools.py | 4 ++- .../resources/test_virtual_servers.py | 4 ++- tests/commands/server/test_run.py | 5 +++- tests/commands/server/test_serve.py | 4 ++- tests/commands/settings/test_config_schema.py | 2 +- tests/commands/settings/test_export.py | 3 +- tests/commands/settings/test_import_cmd.py | 2 +- tests/commands/settings/test_login.py | 4 +++ tests/commands/settings/test_logout.py | 4 +++ tests/commands/settings/test_profiles.py | 11 ++++--- .../commands/settings/test_support_bundle.py | 2 +- tests/commands/settings/test_whoami.py | 15 ++++++++-- tests/common/test_http.py | 29 +++++++++++++++++++ tests/common/test_prompting.py | 4 +-- tests/common/test_render.py | 12 ++++++++ tests/conftest.py | 4 +-- tests/test_config.py | 4 +-- tests/test_credential_store.py | 4 ++- tests/test_profile_utils.py | 9 +++--- 34 files changed, 138 insertions(+), 43 deletions(-) diff --git a/cforge/commands/server/run.py b/cforge/commands/server/run.py index 23f1060..266c2a9 100644 --- a/cforge/commands/server/run.py +++ b/cforge/commands/server/run.py @@ -164,6 +164,7 @@ def run( # Import top-level translate here to avoid undesirable initialization # Third Party + # First-Party from mcpgateway.translate import main as translate_main # Launch the translation wrapper in a subprocess diff --git a/cforge/common/console.py b/cforge/common/console.py index 5e3ab60..36d050e 100644 --- a/cforge/common/console.py +++ b/cforge/common/console.py @@ -9,8 +9,10 @@ configuration without repeated construction. """ +# Standard from functools import lru_cache +# Third-Party from rich.console import Console import typer diff --git a/cforge/common/errors.py b/cforge/common/errors.py index 58e96e7..0f67f69 100644 --- a/cforge/common/errors.py +++ b/cforge/common/errors.py @@ -9,12 +9,15 @@ boundary between internal failures and surfaced command errors. """ +# Standard from enum import Enum import json from typing import Any, Optional, Tuple +# Third-Party import typer +# First-Party from cforge.common.console import get_console @@ -56,6 +59,7 @@ def split_exception_details(exception: Exception) -> Tuple[str, Any]: def handle_exception(exception: Exception) -> None: """Handle an exception and print a friendly error message.""" + # First-Party from cforge.common.render import print_json e_str, e_detail = split_exception_details(exception) diff --git a/cforge/common/http.py b/cforge/common/http.py index 0de7755..602c35f 100644 --- a/cforge/common/http.py +++ b/cforge/common/http.py @@ -9,11 +9,14 @@ helpers instead of handling auth headers and base URL resolution themselves. """ +# Standard from pathlib import Path from typing import Any, Dict, Optional +# Third-Party import requests +# First-Party from cforge.common.errors import AuthenticationError, CLIError from cforge.config import get_settings from cforge.credential_store import load_profile_credentials diff --git a/cforge/common/prompting.py b/cforge/common/prompting.py index 0e36455..a7ca455 100644 --- a/cforge/common/prompting.py +++ b/cforge/common/prompting.py @@ -10,13 +10,16 @@ commands that need structured request payloads. """ +# Standard import json from typing import Annotated, Any, Callable, Dict, get_args, get_origin, get_type_hints, List, Optional, Tuple, Union +# Third-Party from pydantic import BaseModel from rich.console import Console import typer +# First-Party from cforge.common.console import get_console from cforge.common.errors import CLIError from cforge.common.schema_validation import validate_instance, validate_instance_against_subschema, validate_schema diff --git a/cforge/common/render.py b/cforge/common/render.py index c007a0d..f80b981 100644 --- a/cforge/common/render.py +++ b/cforge/common/render.py @@ -9,9 +9,11 @@ data retrieval while sharing a consistent terminal presentation. """ +# Standard import json from typing import Any, Dict, List, Optional +# Third-Party from rich.console import Console, ConsoleOptions, RenderableType, RenderResult from rich.measure import Measurement from rich.panel import Panel @@ -19,6 +21,7 @@ from rich.syntax import Syntax from rich.table import Table +# First-Party from cforge.common.console import get_console from cforge.config import get_settings diff --git a/cforge/config.py b/cforge/config.py index e006c1a..113f5a8 100644 --- a/cforge/config.py +++ b/cforge/config.py @@ -10,16 +10,16 @@ # Standard from contextlib import contextmanager from functools import lru_cache +import os from pathlib import Path from typing import Generator, Optional, Self -import os # Third-Party from pydantic import model_validator # First-Party -from mcpgateway.config import Settings from mcpgateway.config import get_settings as cf_get_settings +from mcpgateway.config import Settings HOME_DIR_NAME = ".contextforge" DEFAULT_HOME = Path.home() / HOME_DIR_NAME diff --git a/cforge/credential_store.py b/cforge/credential_store.py index eca88f6..e6d59d6 100644 --- a/cforge/credential_store.py +++ b/cforge/credential_store.py @@ -15,7 +15,7 @@ # Third-Party from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC # First-Party diff --git a/cforge/main.py b/cforge/main.py index 2d75eb8..94a5c47 100644 --- a/cforge/main.py +++ b/cforge/main.py @@ -28,6 +28,7 @@ # Third-Party import typer +# First-Party from cforge.commands.deploy.deploy import deploy from cforge.commands.metrics.metrics import metrics_get, metrics_reset from cforge.commands.resources.a2a import ( @@ -47,11 +48,7 @@ mcp_servers_toggle, mcp_servers_update, ) -from cforge.commands.resources.plugins import ( - plugins_get, - plugins_list, - plugins_stats, -) +from cforge.commands.resources.plugins import plugins_get, plugins_list, plugins_stats from cforge.commands.resources.prompts import ( prompts_create, prompts_delete, @@ -101,8 +98,6 @@ from cforge.commands.settings.support_bundle import support_bundle from cforge.commands.settings.version import version from cforge.commands.settings.whoami import whoami - -# First-Party from cforge.common.console import get_app # Get the main app singleton diff --git a/cforge/profile_utils.py b/cforge/profile_utils.py index 208507a..b889189 100644 --- a/cforge/profile_utils.py +++ b/cforge/profile_utils.py @@ -10,14 +10,14 @@ # Standard from datetime import datetime +import json from pathlib import Path from typing import Dict, List, Optional -import json # Third-Party -from pydantic import BaseModel, Field, ValidationInfo, field_validator +from pydantic import BaseModel, Field, field_validator, ValidationInfo -# Local +# First-Party from cforge.config import get_settings # Virtual default profile ID for local development diff --git a/tests/commands/resources/test_a2a.py b/tests/commands/resources/test_a2a.py index 7f47a69..7ab431e 100644 --- a/tests/commands/resources/test_a2a.py +++ b/tests/commands/resources/test_a2a.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -28,6 +28,8 @@ a2a_toggle, a2a_update, ) + +# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_mcp_servers.py b/tests/commands/resources/test_mcp_servers.py index e3e83c2..f5b3b06 100644 --- a/tests/commands/resources/test_mcp_servers.py +++ b/tests/commands/resources/test_mcp_servers.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -27,6 +27,8 @@ mcp_servers_toggle, mcp_servers_update, ) + +# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_plugins.py b/tests/commands/resources/test_plugins.py index ad0af73..e9d603d 100644 --- a/tests/commands/resources/test_plugins.py +++ b/tests/commands/resources/test_plugins.py @@ -15,6 +15,8 @@ from cforge.commands.resources.plugins import _parse_plugin_mode, PluginMode, plugins_get, plugins_list, plugins_stats from cforge.common.errors import AuthenticationError, CLIError from cforge.main import app + +# Local from tests.conftest import invoke_typer_command, patch_functions diff --git a/tests/commands/resources/test_prompts.py b/tests/commands/resources/test_prompts.py index 87ef17e..e6cd48f 100644 --- a/tests/commands/resources/test_prompts.py +++ b/tests/commands/resources/test_prompts.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -28,6 +28,8 @@ prompts_toggle, prompts_update, ) + +# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_resources.py b/tests/commands/resources/test_resources.py index 68e5f54..8198a73 100644 --- a/tests/commands/resources/test_resources.py +++ b/tests/commands/resources/test_resources.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -28,6 +28,8 @@ resources_toggle, resources_update, ) + +# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_tools.py b/tests/commands/resources/test_tools.py index 7a6c3c8..192154f 100644 --- a/tests/commands/resources/test_tools.py +++ b/tests/commands/resources/test_tools.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -28,6 +28,8 @@ tools_toggle, tools_update, ) + +# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_virtual_servers.py b/tests/commands/resources/test_virtual_servers.py index f6b2b7f..6c0f0cd 100644 --- a/tests/commands/resources/test_virtual_servers.py +++ b/tests/commands/resources/test_virtual_servers.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import MagicMock, patch # Third-Party @@ -33,6 +33,8 @@ virtual_servers_tools, virtual_servers_update, ) + +# Local from tests.conftest import mock_mcp_server_sse, patch_functions, register_mcp_server diff --git a/tests/commands/server/test_run.py b/tests/commands/server/test_run.py index 815fc7b..7521e6c 100644 --- a/tests/commands/server/test_run.py +++ b/tests/commands/server/test_run.py @@ -12,6 +12,8 @@ # First-Party from cforge.commands.server.run import run + +# Local from tests.conftest import invoke_typer_command @@ -502,6 +504,7 @@ def test_run_register_without_source_warns(self) -> None: def test_run_health_check_connection_error_retry(self) -> None: """Test that health check retries on connection errors.""" + # Third-Party import requests as real_requests with ( @@ -542,8 +545,8 @@ def test_run_health_check_connection_error_retry(self) -> None: def test_run_health_check_timeout(self) -> None: """Test that health check timeout exits with error.""" + # Third-Party import requests as real_requests - import typer with ( diff --git a/tests/commands/server/test_serve.py b/tests/commands/server/test_serve.py index 6eebda8..501725b 100644 --- a/tests/commands/server/test_serve.py +++ b/tests/commands/server/test_serve.py @@ -8,15 +8,17 @@ """ # Standard -from unittest.mock import patch import threading import time +from unittest.mock import patch # Third-Party import requests # First-Party from cforge.commands.server.serve import serve + +# Local from tests.conftest import get_open_port, invoke_typer_command diff --git a/tests/commands/settings/test_config_schema.py b/tests/commands/settings/test_config_schema.py index a38195f..4bce6c0 100644 --- a/tests/commands/settings/test_config_schema.py +++ b/tests/commands/settings/test_config_schema.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # First-Party diff --git a/tests/commands/settings/test_export.py b/tests/commands/settings/test_export.py index 9429f1c..ea5c5af 100644 --- a/tests/commands/settings/test_export.py +++ b/tests/commands/settings/test_export.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party @@ -49,6 +49,7 @@ def test_export_with_custom_output(self, mock_base_url, mock_console) -> None: def test_export_with_default_filename(self, mock_base_url, mock_console) -> None: """Test export with auto-generated filename.""" mock_export_data = {"metadata": {"entity_counts": {}}} + # Standard import os with tempfile.TemporaryDirectory() as temp_dir: diff --git a/tests/commands/settings/test_import_cmd.py b/tests/commands/settings/test_import_cmd.py index 4d1819b..401b5ac 100644 --- a/tests/commands/settings/test_import_cmd.py +++ b/tests/commands/settings/test_import_cmd.py @@ -9,8 +9,8 @@ # Standard import json -import tempfile from pathlib import Path +import tempfile from unittest.mock import patch # Third-Party diff --git a/tests/commands/settings/test_login.py b/tests/commands/settings/test_login.py index 1aa83cb..39c66d8 100644 --- a/tests/commands/settings/test_login.py +++ b/tests/commands/settings/test_login.py @@ -144,8 +144,10 @@ class TestLoginWithProfiles: def test_login_saves_to_profile_specific_token_file(self, mock_base_url, mock_console, mock_settings) -> None: """Test that login saves token to profile-specific file when profile is active.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store mock_response = Mock() @@ -181,8 +183,10 @@ def test_login_saves_to_profile_specific_token_file(self, mock_base_url, mock_co def test_login_with_multiple_profiles(self, mock_base_url, mock_console, mock_settings) -> None: """Test that different profiles can have different tokens.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id1 = "profile-1" diff --git a/tests/commands/settings/test_logout.py b/tests/commands/settings/test_logout.py index b38e860..0787046 100644 --- a/tests/commands/settings/test_logout.py +++ b/tests/commands/settings/test_logout.py @@ -93,8 +93,10 @@ class TestLogoutWithProfiles: def test_logout_removes_profile_specific_token(self, mock_console, mock_settings) -> None: """Test that logout removes profile-specific token file.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile @@ -130,8 +132,10 @@ def test_logout_removes_profile_specific_token(self, mock_console, mock_settings def test_logout_only_removes_active_profile_token(self, mock_console, mock_settings) -> None: """Test that logout only removes the active profile's token, not others.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id1 = "profile-1" diff --git a/tests/commands/settings/test_profiles.py b/tests/commands/settings/test_profiles.py index 9b5e5cc..4bce668 100644 --- a/tests/commands/settings/test_profiles.py +++ b/tests/commands/settings/test_profiles.py @@ -9,10 +9,10 @@ # Standard from datetime import datetime -from pathlib import Path -from unittest.mock import Mock, patch import json +from pathlib import Path import tempfile +from unittest.mock import Mock, patch # Third-Party import pytest @@ -27,11 +27,11 @@ ) from cforge.profile_utils import ( AuthProfile, + DEFAULT_PROFILE_ID, + load_profile_store, ProfileMetadata, ProfileStore, save_profile_store, - load_profile_store, - DEFAULT_PROFILE_ID, ) @@ -103,6 +103,7 @@ def test_profiles_list_empty(self, mock_console, mock_settings) -> None: def test_profiles_list_with_active_profile(self, mock_console, mock_settings) -> None: """Test listing profiles when there is an active profile.""" + # Standard from datetime import datetime # Create test profiles with one active @@ -140,6 +141,7 @@ def test_profiles_list_with_active_profile(self, mock_console, mock_settings) -> def test_profiles_list_without_active_profile(self, mock_console, mock_settings) -> None: """Test listing profiles when there is not an active profile.""" + # Standard from datetime import datetime # Create test profiles with one active @@ -623,6 +625,7 @@ def test_profiles_create_enable_fails(self, mock_console, mock_settings) -> None def test_profiles_create_with_existing_store(self, mock_console, mock_settings) -> None: """Test creating a profile when a profile store already exists.""" + # First-Party from cforge.profile_utils import load_profile_store # Create an existing profile store diff --git a/tests/commands/settings/test_support_bundle.py b/tests/commands/settings/test_support_bundle.py index c7432d8..ce5d241 100644 --- a/tests/commands/settings/test_support_bundle.py +++ b/tests/commands/settings/test_support_bundle.py @@ -8,8 +8,8 @@ """ # Standard -import tempfile from pathlib import Path +import tempfile from unittest.mock import Mock, patch # Third-Party diff --git a/tests/commands/settings/test_whoami.py b/tests/commands/settings/test_whoami.py index b8cc20f..9da8d13 100644 --- a/tests/commands/settings/test_whoami.py +++ b/tests/commands/settings/test_whoami.py @@ -80,9 +80,12 @@ class TestWhoamiWithProfiles: def test_whoami_with_active_profile_and_token(self, mock_settings, mock_console) -> None: """Test whoami displays active profile information along with auth status.""" - from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store + # Standard from datetime import datetime + # First-Party + from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store + # Create and save an active profile profile_id = "test-profile-whoami" profile = AuthProfile( @@ -125,9 +128,12 @@ def test_whoami_with_active_profile_and_token(self, mock_settings, mock_console) def test_whoami_with_active_profile_with_metadata(self, mock_settings, mock_console) -> None: """Test whoami displays profile metadata when available.""" - from cforge.profile_utils import AuthProfile, ProfileMetadata, ProfileStore, save_profile_store + # Standard from datetime import datetime + # First-Party + from cforge.profile_utils import AuthProfile, ProfileMetadata, ProfileStore, save_profile_store + # Create profile with metadata profile_id = "test-profile-metadata" metadata = ProfileMetadata( @@ -165,9 +171,12 @@ def test_whoami_with_active_profile_with_metadata(self, mock_settings, mock_cons def test_whoami_with_active_profile_no_auth(self, mock_settings, mock_console) -> None: """Test whoami with active profile but no authentication.""" - from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store + # Standard from datetime import datetime + # First-Party + from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store + # Create and save an active profile profile_id = "test-profile-noauth" profile = AuthProfile( diff --git a/tests/common/test_http.py b/tests/common/test_http.py index 41c4e91..5b46c73 100644 --- a/tests/common/test_http.py +++ b/tests/common/test_http.py @@ -14,6 +14,8 @@ # First-Party from cforge.common.errors import AuthenticationError, CLIError from cforge.common.http import get_auth_token, get_token_file, load_token, make_authenticated_request, save_token + +# Local from tests.conftest import mock_client_login @@ -29,8 +31,10 @@ def test_get_token_file(self, mock_settings) -> None: def test_get_token_file_with_active_profile(self, mock_settings) -> None: """Test getting the token file path uses active profile when available.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile @@ -66,8 +70,10 @@ def test_save_and_load_token(self) -> None: def test_save_and_load_token_with_active_profile(self, mock_settings) -> None: """Test saving and loading a token with an active profile.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store test_token = "profile_token_456" @@ -100,8 +106,10 @@ def test_save_and_load_token_with_active_profile(self, mock_settings) -> None: def test_save_token_different_profiles(self, mock_settings) -> None: """Test that different profiles have separate token files.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store token1 = "token_for_profile_1" @@ -162,8 +170,10 @@ def test_load_token_nonexistent(self, tmp_path: Path) -> None: def test_load_token_nonexistent_profile(self, mock_settings) -> None: """Test loading a token for a profile that doesn't have a token file.""" + # Standard from datetime import datetime + # First-Party from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id = "nonexistent-profile" @@ -194,8 +204,10 @@ class TestBaseUrl: def test_get_base_url_with_active_profile(self, mock_settings) -> None: """Test get_base_url returns profile's API URL when active profile exists.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import get_base_url from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store @@ -220,6 +232,7 @@ def test_get_base_url_with_active_profile(self, mock_settings) -> None: def test_get_base_url_without_active_profile(self, mock_settings) -> None: """Test get_base_url returns default URL when no active profile.""" + # First-Party from cforge.common.http import get_base_url # No profile saved, should use settings @@ -261,6 +274,7 @@ class TestAutoLogin: def test_attempt_auto_login_no_profile(self, mock_settings): """Test auto-login when no profile is active.""" + # First-Party from cforge.common.http import attempt_auto_login token = attempt_auto_login() @@ -268,8 +282,10 @@ def test_attempt_auto_login_no_profile(self, mock_settings): def test_attempt_auto_login_no_credentials(self, mock_settings): """Test auto-login when credentials are not available.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -289,8 +305,10 @@ def test_attempt_auto_login_no_credentials(self, mock_settings): def test_attempt_auto_login_missing_email(self, mock_settings): """Test auto-login when email is missing from credentials.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -310,8 +328,10 @@ def test_attempt_auto_login_missing_email(self, mock_settings): def test_attempt_auto_login_missing_password(self, mock_settings): """Test auto-login when password is missing from credentials.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -332,8 +352,10 @@ def test_attempt_auto_login_missing_password(self, mock_settings): @patch("cforge.common.http.requests.post") def test_attempt_auto_login_success(self, mock_post, mock_settings): """Test successful auto-login.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login, load_token from cforge.profile_utils import AuthProfile @@ -364,8 +386,10 @@ def test_attempt_auto_login_success(self, mock_post, mock_settings): @patch("cforge.common.http.requests.post") def test_attempt_auto_login_failed_login(self, mock_post, mock_settings): """Test auto-login when login fails.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -391,8 +415,10 @@ def test_attempt_auto_login_failed_login(self, mock_post, mock_settings): @patch("cforge.common.http.requests.post") def test_attempt_auto_login_no_token_in_response(self, mock_post, mock_settings): """Test auto-login when response doesn't contain token.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -419,8 +445,10 @@ def test_attempt_auto_login_no_token_in_response(self, mock_post, mock_settings) @patch("cforge.common.http.requests.post") def test_attempt_auto_login_request_exception(self, mock_post, mock_settings): """Test auto-login when request raises exception.""" + # Standard from datetime import datetime + # First-Party from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -443,6 +471,7 @@ def test_attempt_auto_login_request_exception(self, mock_post, mock_settings): def test_get_auth_token_with_auto_login(self, mock_settings): """Test that get_auth_token attempts auto-login when no token is available.""" + # First-Party from cforge.common.http import get_auth_token # Mock no env token and no file token, but successful auto-login diff --git a/tests/common/test_prompting.py b/tests/common/test_prompting.py index 216fdb8..07bebf5 100644 --- a/tests/common/test_prompting.py +++ b/tests/common/test_prompting.py @@ -16,13 +16,13 @@ _build_prompt_text, _infer_schema_type, _INT_SENTINEL_DEFAULT, - prompt_for_json_schema, - prompt_for_schema, _resolve_effective_schema, _resolve_ref_schema, _resolve_schema_type, _schema_contains_ref, _strip_schema_internal_properties, + prompt_for_json_schema, + prompt_for_schema, ) diff --git a/tests/common/test_render.py b/tests/common/test_render.py index 44b1133..86bfe4e 100644 --- a/tests/common/test_render.py +++ b/tests/common/test_render.py @@ -15,6 +15,7 @@ class TestLineLimit: def test_line_limit_basic_truncation(self) -> None: """Test that LineLimit truncates content to max_lines.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -40,6 +41,7 @@ def test_line_limit_basic_truncation(self) -> None: def test_line_limit_no_truncation_needed(self) -> None: """Test that LineLimit doesn't truncate when content is within limit.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -60,6 +62,7 @@ def test_line_limit_no_truncation_needed(self) -> None: def test_line_limit_exact_match(self) -> None: """Test LineLimit when content exactly matches max_lines.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -81,6 +84,7 @@ def test_line_limit_exact_match(self) -> None: def test_line_limit_zero_lines(self) -> None: """Test LineLimit with max_lines=0 shows only ellipsis.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -99,6 +103,7 @@ def test_line_limit_zero_lines(self) -> None: def test_line_limit_one_line(self) -> None: """Test LineLimit with max_lines=1.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -118,6 +123,7 @@ def test_line_limit_one_line(self) -> None: def test_line_limit_with_long_single_line(self) -> None: """Test LineLimit with a single long line that wraps.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -138,6 +144,7 @@ def test_line_limit_with_long_single_line(self) -> None: def test_line_limit_measurement_passthrough(self) -> None: """Test that LineLimit passes through measurement to wrapped renderable.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -155,6 +162,7 @@ def test_line_limit_measurement_passthrough(self) -> None: def test_line_limit_with_empty_content(self) -> None: """Test LineLimit with empty content.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -172,6 +180,7 @@ def test_line_limit_with_empty_content(self) -> None: def test_line_limit_preserves_styling(self) -> None: """Test that LineLimit preserves rich styling in truncated content.""" + # Third-Party from rich.console import Console from rich.text import Text @@ -258,6 +267,7 @@ def test_print_table_missing_columns(self, mock_console) -> None: def test_print_table_wraps_all_cells_with_line_limit(self) -> None: """Test that print_table wraps all cell values with LineLimit for truncation.""" + # Standard from unittest.mock import patch # Create test data with various types @@ -284,6 +294,7 @@ def test_print_table_wraps_all_cells_with_line_limit(self) -> None: def test_print_table_with_custom_max_lines(self, mock_settings) -> None: """Test that print_table respects custom table_max_lines configuration.""" + # Standard from unittest.mock import patch # Configure mock_settings with custom max_lines value @@ -312,6 +323,7 @@ def test_print_table_with_custom_max_lines(self, mock_settings) -> None: def test_print_table_with_disabled_line_limit(self, mock_settings) -> None: """Test that print_table skips LineLimit wrapping when table_max_lines is 0 or negative.""" + # Standard from unittest.mock import patch # Configure mock_settings with disabled max_lines value (0) diff --git a/tests/conftest.py b/tests/conftest.py index 3c21f61..a703fbb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,11 +22,10 @@ from typing import Any, Callable, Generator, List, Union from unittest.mock import Mock, patch +# Third-Party from fastapi.testclient import TestClient from mcp.server.fastmcp import FastMCP from pydantic import SecretStr - -# Third-Party import pytest from typer.models import OptionInfo from typer.testing import CliRunner @@ -263,6 +262,7 @@ def test_endpoint(mock_client): response = mock_client.get("/health") assert response.status_code == 200 """ + # First-Party from mcpgateway.main import app client = TestClient(app) diff --git a/tests/test_config.py b/tests/test_config.py index 6ac9f39..63398b7 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -8,10 +8,10 @@ """ # Standard -from pathlib import Path -from unittest import mock import os +from pathlib import Path import tempfile +from unittest import mock # First-Party from cforge.config import get_settings diff --git a/tests/test_credential_store.py b/tests/test_credential_store.py index a44998d..c10e6b8 100644 --- a/tests/test_credential_store.py +++ b/tests/test_credential_store.py @@ -13,7 +13,7 @@ # Third-Party from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC # First-Party @@ -73,6 +73,7 @@ class TestCredentialDecryption: def _encrypt_data(self, data: str, encryption_key: str) -> bytes: """Helper to encrypt data using the same format as electron-store/conf.""" + # Standard import os # Generate random IV @@ -226,6 +227,7 @@ def test_load_profile_credentials_decryption_fails(self, mock_settings): def _encrypt_data(self, data: str, encryption_key: str) -> bytes: """Helper to encrypt data using the same format as electron-store/conf.""" + # Standard import os # Generate random IV diff --git a/tests/test_profile_utils.py b/tests/test_profile_utils.py index 95e5d63..1ed7106 100644 --- a/tests/test_profile_utils.py +++ b/tests/test_profile_utils.py @@ -8,21 +8,21 @@ """ # Standard -import json from datetime import datetime +import json from pathlib import Path # First-Party from cforge.profile_utils import ( AuthProfile, DEFAULT_PROFILE_ID, - ProfileMetadata, - ProfileStore, - get_all_profiles, get_active_profile, + get_all_profiles, get_profile, get_profile_store_path, load_profile_store, + ProfileMetadata, + ProfileStore, save_profile_store, set_active_profile, ) @@ -376,6 +376,7 @@ def test_save_profile_store_creates_directory(self, mock_settings) -> None: # Ensure directory doesn't exist if store_path.parent.exists(): + # Standard import shutil shutil.rmtree(store_path.parent) From 16d1c1b1efafc25bfe6cae09eb34cd1a3ca4e6cd Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Fri, 13 Mar 2026 10:18:41 -0700 Subject: [PATCH 2/8] update: added isort back into pre-commit hook to test if files pass --- .pre-commit-config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 160abd9..6d9d903 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -421,13 +421,13 @@ repos: description: The uncompromising Python code formatter. language_version: python3 - # - repo: https://github.com/pycqa/isort - # rev: 6.0.1 - # hooks: - # - id: isort - # name: 🐍 isort - Import Sorter - # description: A Python utility / library to sort imports. - # args: [--profile=black] + - repo: https://github.com/pycqa/isort + rev: 6.0.1 + hooks: + - id: isort + name: 🐍 isort - Import Sorter + description: A Python utility / library to sort imports. + args: [--profile=black] # - repo: https://github.com/asottile/pyupgrade # rev: v3.20.0 From 8f397f71c6267ef36422421b28ef49fa0edcab95 Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Fri, 13 Mar 2026 12:03:09 -0700 Subject: [PATCH 3/8] removed todo --- pyproject.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dc0c328..c68d636 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,9 +171,8 @@ target-version = "py311" [tool.ruff.lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. -# Also "D1" for docstring present checks. -# TODO: Enable "I" for import sorting as a separate PR. -select = ["E3", "E4", "E7", "E9", "F", "D1"] +# Also "D1" for docstring present checks and "I" for import sorting. +select = ["E3", "E4", "E7", "E9", "F", "D1", "I"] ignore = [] # Allow fix for all enabled rules (when `--fix`) is provided. From aa63628a450593dae805c35c47b82a231224f0ee Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Fri, 13 Mar 2026 14:37:01 -0700 Subject: [PATCH 4/8] chore: isort fix updates updated configs for isort and re-disabled the toml. --- PR_ISORT.md | 0 cforge/commands/deploy/deploy.py | 2 +- cforge/commands/metrics/metrics.py | 2 +- cforge/commands/resources/a2a.py | 7 +++- cforge/commands/resources/mcp_servers.py | 7 +++- cforge/commands/resources/plugins.py | 2 +- cforge/commands/resources/prompts.py | 7 +++- cforge/commands/resources/resources.py | 7 +++- cforge/commands/resources/tools.py | 7 +++- cforge/commands/resources/virtual_servers.py | 7 +++- cforge/commands/server/run.py | 6 ++- cforge/commands/server/serve.py | 2 +- cforge/commands/settings/config_schema.py | 5 ++- cforge/commands/settings/export.py | 5 ++- cforge/commands/settings/import_cmd.py | 5 ++- cforge/commands/settings/login.py | 2 +- cforge/commands/settings/logout.py | 2 +- cforge/commands/settings/profiles.py | 7 ++-- cforge/commands/settings/support_bundle.py | 2 +- cforge/commands/settings/version.py | 4 +- cforge/commands/settings/whoami.py | 2 +- cforge/common/console.py | 1 + cforge/common/errors.py | 7 ++-- cforge/common/http.py | 2 +- cforge/common/prompting.py | 6 ++- cforge/common/render.py | 5 ++- cforge/config.py | 3 +- cforge/credential_store.py | 5 ++- cforge/main.py | 2 +- cforge/profile_utils.py | 5 ++- pyproject.toml | 21 ++++++----- tests/commands/deploy/test_deploy.py | 2 +- tests/commands/metrics/test_metrics.py | 2 +- tests/commands/resources/test_a2a.py | 9 ++--- tests/commands/resources/test_mcp_servers.py | 9 ++--- tests/commands/resources/test_plugins.py | 4 +- tests/commands/resources/test_prompts.py | 9 ++--- tests/commands/resources/test_resources.py | 9 ++--- tests/commands/resources/test_tools.py | 9 ++--- .../resources/test_virtual_servers.py | 9 ++--- tests/commands/server/test_run.py | 4 +- tests/commands/server/test_serve.py | 7 ++-- tests/commands/settings/test_config_schema.py | 7 ++-- tests/commands/settings/test_export.py | 7 ++-- tests/commands/settings/test_import_cmd.py | 7 ++-- tests/commands/settings/test_login.py | 9 +++-- tests/commands/settings/test_logout.py | 9 +++-- tests/commands/settings/test_profiles.py | 9 +++-- .../commands/settings/test_support_bundle.py | 5 ++- tests/commands/settings/test_version.py | 4 +- tests/commands/settings/test_whoami.py | 8 ++-- tests/common/test_console.py | 2 +- tests/common/test_errors.py | 2 +- tests/common/test_http.py | 37 +++++++++---------- tests/common/test_prompting.py | 3 +- tests/common/test_render.py | 2 +- tests/common/test_schema_validation.py | 2 +- tests/conftest.py | 14 ++++--- tests/test_config.py | 7 ++-- tests/test_credential_store.py | 2 +- tests/test_main.py | 2 +- tests/test_profile_utils.py | 5 ++- 62 files changed, 200 insertions(+), 163 deletions(-) create mode 100644 PR_ISORT.md diff --git a/PR_ISORT.md b/PR_ISORT.md new file mode 100644 index 0000000..e69de29 diff --git a/cforge/commands/deploy/deploy.py b/cforge/commands/deploy/deploy.py index 4d1f578..8b0af49 100644 --- a/cforge/commands/deploy/deploy.py +++ b/cforge/commands/deploy/deploy.py @@ -10,7 +10,7 @@ # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console diff --git a/cforge/commands/metrics/metrics.py b/cforge/commands/metrics/metrics.py index 770b599..e70ab6d 100644 --- a/cforge/commands/metrics/metrics.py +++ b/cforge/commands/metrics/metrics.py @@ -10,7 +10,7 @@ # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import make_authenticated_request from cforge.common.render import print_json diff --git a/cforge/commands/resources/a2a.py b/cforge/commands/resources/a2a.py index 1dde748..64d33f1 100644 --- a/cforge/commands/resources/a2a.py +++ b/cforge/commands/resources/a2a.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import A2AAgentCreate, A2AAgentUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import A2AAgentCreate, A2AAgentUpdate def a2a_list( diff --git a/cforge/commands/resources/mcp_servers.py b/cforge/commands/resources/mcp_servers.py index 8973e26..f6ffbea 100644 --- a/cforge/commands/resources/mcp_servers.py +++ b/cforge/commands/resources/mcp_servers.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import GatewayCreate, GatewayUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import GatewayCreate, GatewayUpdate def mcp_servers_list( diff --git a/cforge/commands/resources/plugins.py b/cforge/commands/resources/plugins.py index 5baa698..f82497d 100644 --- a/cforge/commands/resources/plugins.py +++ b/cforge/commands/resources/plugins.py @@ -19,7 +19,7 @@ # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.errors import AuthenticationError, CaseInsensitiveEnum, CLIError, handle_exception from cforge.common.http import make_authenticated_request diff --git a/cforge/commands/resources/prompts.py b/cforge/commands/resources/prompts.py index b3b0d83..5616e85 100644 --- a/cforge/commands/resources/prompts.py +++ b/cforge/commands/resources/prompts.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Any, Dict, Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import PromptCreate, PromptUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import PromptCreate, PromptUpdate def prompts_list( diff --git a/cforge/commands/resources/resources.py b/cforge/commands/resources/resources.py index 05137cd..330151d 100644 --- a/cforge/commands/resources/resources.py +++ b/cforge/commands/resources/resources.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Any, Dict, Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import ResourceCreate, ResourceUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import ResourceCreate, ResourceUpdate def resources_list( diff --git a/cforge/commands/resources/tools.py b/cforge/commands/resources/tools.py index 0c88bb4..0766430 100644 --- a/cforge/commands/resources/tools.py +++ b/cforge/commands/resources/tools.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Any, Dict, Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import ToolCreate, ToolUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import CLIError, handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_json_schema, prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import ToolCreate, ToolUpdate def tools_list( diff --git a/cforge/commands/resources/virtual_servers.py b/cforge/commands/resources/virtual_servers.py index 39ecf88..9a123af 100644 --- a/cforge/commands/resources/virtual_servers.py +++ b/cforge/commands/resources/virtual_servers.py @@ -8,20 +8,23 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party import typer # First-Party +from mcpgateway.schemas import ServerCreate, ServerUpdate + +# Local from cforge.common.console import get_console from cforge.common.errors import handle_exception from cforge.common.http import make_authenticated_request from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table -from mcpgateway.schemas import ServerCreate, ServerUpdate def _fixup_payload(data: dict) -> dict: diff --git a/cforge/commands/server/run.py b/cforge/commands/server/run.py index 266c2a9..d4e090e 100644 --- a/cforge/commands/server/run.py +++ b/cforge/commands/server/run.py @@ -12,17 +12,18 @@ """ # Standard +from typing import List, Optional + import atexit import multiprocessing import os import time -from typing import List, Optional # Third-Party import requests import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import make_authenticated_request @@ -164,6 +165,7 @@ def run( # Import top-level translate here to avoid undesirable initialization # Third Party + # First-Party from mcpgateway.translate import main as translate_main diff --git a/cforge/commands/server/serve.py b/cforge/commands/server/serve.py index 76dc308..14a57d5 100644 --- a/cforge/commands/server/serve.py +++ b/cforge/commands/server/serve.py @@ -14,7 +14,7 @@ import typer import uvicorn -# First-Party +# Local from cforge.config import get_settings, set_serve_settings # --------------------------------------------------------------------------- diff --git a/cforge/commands/settings/config_schema.py b/cforge/commands/settings/config_schema.py index 1d95797..427672c 100644 --- a/cforge/commands/settings/config_schema.py +++ b/cforge/commands/settings/config_schema.py @@ -8,14 +8,15 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.render import print_json from cforge.config import get_settings diff --git a/cforge/commands/settings/export.py b/cforge/commands/settings/export.py index 3937c1e..109c91b 100644 --- a/cforge/commands/settings/export.py +++ b/cforge/commands/settings/export.py @@ -9,14 +9,15 @@ # Standard from datetime import datetime -import json from pathlib import Path from typing import Any, Dict, Optional +import json + # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import get_base_url, make_authenticated_request diff --git a/cforge/commands/settings/import_cmd.py b/cforge/commands/settings/import_cmd.py index d02b3e6..f9fafe9 100644 --- a/cforge/commands/settings/import_cmd.py +++ b/cforge/commands/settings/import_cmd.py @@ -8,14 +8,15 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import make_authenticated_request diff --git a/cforge/commands/settings/login.py b/cforge/commands/settings/login.py index 10294e1..ba238b5 100644 --- a/cforge/commands/settings/login.py +++ b/cforge/commands/settings/login.py @@ -11,7 +11,7 @@ import requests import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import get_base_url, get_token_file, save_token diff --git a/cforge/commands/settings/logout.py b/cforge/commands/settings/logout.py index c1d86da..008acfb 100644 --- a/cforge/commands/settings/logout.py +++ b/cforge/commands/settings/logout.py @@ -7,7 +7,7 @@ CLI command: logout """ -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import get_token_file diff --git a/cforge/commands/settings/profiles.py b/cforge/commands/settings/profiles.py index d39f5ae..c21faea 100644 --- a/cforge/commands/settings/profiles.py +++ b/cforge/commands/settings/profiles.py @@ -9,16 +9,17 @@ # Standard from datetime import datetime -import json from pathlib import Path +from typing import Optional + +import json import secrets import string -from typing import Optional # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.prompting import prompt_for_schema from cforge.common.render import print_json, print_table diff --git a/cforge/commands/settings/support_bundle.py b/cforge/commands/settings/support_bundle.py index da9f930..793e27d 100644 --- a/cforge/commands/settings/support_bundle.py +++ b/cforge/commands/settings/support_bundle.py @@ -14,7 +14,7 @@ # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console diff --git a/cforge/commands/settings/version.py b/cforge/commands/settings/version.py index ae63438..0ea3339 100644 --- a/cforge/commands/settings/version.py +++ b/cforge/commands/settings/version.py @@ -8,9 +8,11 @@ """ # First-Party +from mcpgateway import __version__ + +# Local from cforge.common.console import get_console from cforge.common.http import make_authenticated_request -from mcpgateway import __version__ def version() -> None: diff --git a/cforge/commands/settings/whoami.py b/cforge/commands/settings/whoami.py index ed91743..9a4d607 100644 --- a/cforge/commands/settings/whoami.py +++ b/cforge/commands/settings/whoami.py @@ -7,7 +7,7 @@ CLI command: whoami """ -# First-Party +# Local from cforge.common.console import get_console from cforge.common.http import get_token_file, load_token from cforge.config import get_settings diff --git a/cforge/common/console.py b/cforge/common/console.py index 36d050e..47723aa 100644 --- a/cforge/common/console.py +++ b/cforge/common/console.py @@ -14,6 +14,7 @@ # Third-Party from rich.console import Console + import typer diff --git a/cforge/common/errors.py b/cforge/common/errors.py index 0f67f69..5fd250b 100644 --- a/cforge/common/errors.py +++ b/cforge/common/errors.py @@ -11,13 +11,14 @@ # Standard from enum import Enum -import json from typing import Any, Optional, Tuple +import json + # Third-Party import typer -# First-Party +# Local from cforge.common.console import get_console @@ -59,7 +60,7 @@ def split_exception_details(exception: Exception) -> Tuple[str, Any]: def handle_exception(exception: Exception) -> None: """Handle an exception and print a friendly error message.""" - # First-Party + # Local from cforge.common.render import print_json e_str, e_detail = split_exception_details(exception) diff --git a/cforge/common/http.py b/cforge/common/http.py index 602c35f..7e45ae2 100644 --- a/cforge/common/http.py +++ b/cforge/common/http.py @@ -16,7 +16,7 @@ # Third-Party import requests -# First-Party +# Local from cforge.common.errors import AuthenticationError, CLIError from cforge.config import get_settings from cforge.credential_store import load_profile_credentials diff --git a/cforge/common/prompting.py b/cforge/common/prompting.py index a7ca455..af67157 100644 --- a/cforge/common/prompting.py +++ b/cforge/common/prompting.py @@ -11,15 +11,17 @@ """ # Standard -import json from typing import Annotated, Any, Callable, Dict, get_args, get_origin, get_type_hints, List, Optional, Tuple, Union +import json + # Third-Party from pydantic import BaseModel from rich.console import Console + import typer -# First-Party +# Local from cforge.common.console import get_console from cforge.common.errors import CLIError from cforge.common.schema_validation import validate_instance, validate_instance_against_subschema, validate_schema diff --git a/cforge/common/render.py b/cforge/common/render.py index f80b981..8c9f40f 100644 --- a/cforge/common/render.py +++ b/cforge/common/render.py @@ -10,9 +10,10 @@ """ # Standard -import json from typing import Any, Dict, List, Optional +import json + # Third-Party from rich.console import Console, ConsoleOptions, RenderableType, RenderResult from rich.measure import Measurement @@ -21,7 +22,7 @@ from rich.syntax import Syntax from rich.table import Table -# First-Party +# Local from cforge.common.console import get_console from cforge.config import get_settings diff --git a/cforge/config.py b/cforge/config.py index 113f5a8..a65807e 100644 --- a/cforge/config.py +++ b/cforge/config.py @@ -10,10 +10,11 @@ # Standard from contextlib import contextmanager from functools import lru_cache -import os from pathlib import Path from typing import Generator, Optional, Self +import os + # Third-Party from pydantic import model_validator diff --git a/cforge/credential_store.py b/cforge/credential_store.py index e6d59d6..ab39747 100644 --- a/cforge/credential_store.py +++ b/cforge/credential_store.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path from typing import Optional +import json + # Third-Party from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC -# First-Party +# Local from cforge.config import get_settings diff --git a/cforge/main.py b/cforge/main.py index 94a5c47..155a189 100644 --- a/cforge/main.py +++ b/cforge/main.py @@ -28,7 +28,7 @@ # Third-Party import typer -# First-Party +# Local from cforge.commands.deploy.deploy import deploy from cforge.commands.metrics.metrics import metrics_get, metrics_reset from cforge.commands.resources.a2a import ( diff --git a/cforge/profile_utils.py b/cforge/profile_utils.py index b889189..bb201e3 100644 --- a/cforge/profile_utils.py +++ b/cforge/profile_utils.py @@ -10,14 +10,15 @@ # Standard from datetime import datetime -import json from pathlib import Path from typing import Dict, List, Optional +import json + # Third-Party from pydantic import BaseModel, Field, field_validator, ValidationInfo -# First-Party +# Local from cforge.config import get_settings # Virtual default profile ID for local development diff --git a/pyproject.toml b/pyproject.toml index c68d636..6c09e88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,8 +171,9 @@ target-version = "py311" [tool.ruff.lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. -# Also "D1" for docstring present checks and "I" for import sorting. -select = ["E3", "E4", "E7", "E9", "F", "D1", "I"] +# Also "D1" for docstring present checks +# "I" for import sorting. +select = ["E3", "E4", "E7", "E9", "F", "D1"] ignore = [] # Allow fix for all enabled rules (when `--fix`) is provided. @@ -221,16 +222,16 @@ from-first = true # place all "from ... import ..." befo ############################################################################### # What belongs where ############################################################################### -known-first-party = ["cforge", "mcpgateway"] # treat "cforge" and "mcpgateway" as FIRSTPARTY -known-local-folder = ["tests", "scripts"] # treat these folders as LOCALFOLDER +known-first-party = ["mcpgateway"] # treat "cforge" and "mcpgateway" as FIRSTPARTY +known-local-folder = ["tests", "scripts","cforge"] # treat these folders as LOCALFOLDER known-third-party = ["alembic"] # treat "alembic" as THIRDPARTY # src-paths = ["src/cforge"] # uncomment only if package moves under src/ ############################################################################### # Style niceties ############################################################################### -force-sort-within-sections = true # always alphabetise names inside each block -order-by-type = false # don't group imports by "type vs. straight name" +# force_alphabetical_sort_within_sections = true # always alphabetise names inside each block +# order-by-type = true # don't group imports by "type vs. straight name" # balanced-wrapping = true # spread wrapped imports evenly between lines # lines-between-sections = 1 # exactly one blank line between the five groups # lines-between-types = 1 # one blank line between 'import X' and 'from X import ...' @@ -259,10 +260,10 @@ disallow_untyped_defs = false # Core behaviour ############################################################################### profile = "black" # inherit Black's own import-sorting profile +from_first = true # place all "from ... import ..." before plain "import ..." line_length = 200 # match Black's custom line length multi_line_output = 3 # vertical-hanging-indent style include_trailing_comma = true # keep trailing commas for Black -from_first = true # place all "from ... import ..." before plain "import ..." ############################################################################### # Section ordering & headings @@ -277,14 +278,14 @@ import_heading_localfolder = "Local" # header for ad-hoc scripts / tests ############################################################################### # What belongs where ############################################################################### -known_first_party = ["cforge", "mcpgateway"] # treat "mcpgateway.*" as FIRSTPARTY -known_local_folder = ["tests", "scripts"] # treat these folders as LOCALFOLDER +known_first_party = ["mcpgateway"] # treat "mcpgateway.*" as FIRSTPARTY +known_local_folder = ["tests", "scripts", "cforge"] # treat these folders as LOCALFOLDER # src_paths = ["src/cforge"] # uncomment only if package moves under src/ ############################################################################### # Style niceties ############################################################################### -force_sort_within_sections = true # always alphabetise names inside each block +force_alphabetical_sort_within_sections = true # always alphabetise names inside each block order_by_type = false # don't group imports by "type vs. straight name" balanced_wrapping = true # spread wrapped imports evenly between lines lines_between_sections = 1 # exactly one blank line between the five groups diff --git a/tests/commands/deploy/test_deploy.py b/tests/commands/deploy/test_deploy.py index ff57d00..2adf8f4 100644 --- a/tests/commands/deploy/test_deploy.py +++ b/tests/commands/deploy/test_deploy.py @@ -14,7 +14,7 @@ import pytest import typer -# First-Party +# Local from cforge.commands.deploy.deploy import deploy diff --git a/tests/commands/metrics/test_metrics.py b/tests/commands/metrics/test_metrics.py index 6b19cc2..87446cd 100644 --- a/tests/commands/metrics/test_metrics.py +++ b/tests/commands/metrics/test_metrics.py @@ -14,7 +14,7 @@ import pytest import typer -# First-Party +# Local from cforge.commands.metrics.metrics import metrics_get, metrics_reset diff --git a/tests/commands/resources/test_a2a.py b/tests/commands/resources/test_a2a.py index 7ab431e..13b9870 100644 --- a/tests/commands/resources/test_a2a.py +++ b/tests/commands/resources/test_a2a.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.a2a import ( a2a_create, a2a_delete, @@ -28,8 +29,6 @@ a2a_toggle, a2a_update, ) - -# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_mcp_servers.py b/tests/commands/resources/test_mcp_servers.py index f5b3b06..e068cf7 100644 --- a/tests/commands/resources/test_mcp_servers.py +++ b/tests/commands/resources/test_mcp_servers.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.mcp_servers import ( mcp_servers_create, mcp_servers_delete, @@ -27,8 +28,6 @@ mcp_servers_toggle, mcp_servers_update, ) - -# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_plugins.py b/tests/commands/resources/test_plugins.py index e9d603d..23a6540 100644 --- a/tests/commands/resources/test_plugins.py +++ b/tests/commands/resources/test_plugins.py @@ -11,12 +11,10 @@ import pytest import typer -# First-Party +# Local from cforge.commands.resources.plugins import _parse_plugin_mode, PluginMode, plugins_get, plugins_list, plugins_stats from cforge.common.errors import AuthenticationError, CLIError from cforge.main import app - -# Local from tests.conftest import invoke_typer_command, patch_functions diff --git a/tests/commands/resources/test_prompts.py b/tests/commands/resources/test_prompts.py index e6cd48f..14bf43d 100644 --- a/tests/commands/resources/test_prompts.py +++ b/tests/commands/resources/test_prompts.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.prompts import ( prompts_create, prompts_delete, @@ -28,8 +29,6 @@ prompts_toggle, prompts_update, ) - -# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_resources.py b/tests/commands/resources/test_resources.py index 8198a73..d983ed3 100644 --- a/tests/commands/resources/test_resources.py +++ b/tests/commands/resources/test_resources.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.resources import ( resources_create, resources_delete, @@ -28,8 +29,6 @@ resources_toggle, resources_update, ) - -# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_tools.py b/tests/commands/resources/test_tools.py index 192154f..d226d8c 100644 --- a/tests/commands/resources/test_tools.py +++ b/tests/commands/resources/test_tools.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.tools import ( tools_create, tools_delete, @@ -28,8 +29,6 @@ tools_toggle, tools_update, ) - -# Local from tests.conftest import patch_functions diff --git a/tests/commands/resources/test_virtual_servers.py b/tests/commands/resources/test_virtual_servers.py index 6c0f0cd..147b48e 100644 --- a/tests/commands/resources/test_virtual_servers.py +++ b/tests/commands/resources/test_virtual_servers.py @@ -8,17 +8,18 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import MagicMock, patch +import json +import tempfile + # Third-Party import click import pytest import typer -# First-Party +# Local from cforge.commands.resources.prompts import prompts_list from cforge.commands.resources.resources import resources_list from cforge.commands.resources.tools import tools_list @@ -33,8 +34,6 @@ virtual_servers_tools, virtual_servers_update, ) - -# Local from tests.conftest import mock_mcp_server_sse, patch_functions, register_mcp_server diff --git a/tests/commands/server/test_run.py b/tests/commands/server/test_run.py index 7521e6c..bfacc6f 100644 --- a/tests/commands/server/test_run.py +++ b/tests/commands/server/test_run.py @@ -10,10 +10,8 @@ # Standard from unittest.mock import MagicMock, patch -# First-Party -from cforge.commands.server.run import run - # Local +from cforge.commands.server.run import run from tests.conftest import invoke_typer_command diff --git a/tests/commands/server/test_serve.py b/tests/commands/server/test_serve.py index 501725b..2e77281 100644 --- a/tests/commands/server/test_serve.py +++ b/tests/commands/server/test_serve.py @@ -8,17 +8,16 @@ """ # Standard +from unittest.mock import patch + import threading import time -from unittest.mock import patch # Third-Party import requests -# First-Party -from cforge.commands.server.serve import serve - # Local +from cforge.commands.server.serve import serve from tests.conftest import get_open_port, invoke_typer_command diff --git a/tests/commands/settings/test_config_schema.py b/tests/commands/settings/test_config_schema.py index 4bce6c0..05f9052 100644 --- a/tests/commands/settings/test_config_schema.py +++ b/tests/commands/settings/test_config_schema.py @@ -8,12 +8,13 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch -# First-Party +import json +import tempfile + +# Local from cforge.commands.settings.config_schema import config_schema diff --git a/tests/commands/settings/test_export.py b/tests/commands/settings/test_export.py index ea5c5af..ea59735 100644 --- a/tests/commands/settings/test_export.py +++ b/tests/commands/settings/test_export.py @@ -8,16 +8,17 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import pytest import typer -# First-Party +# Local from cforge.commands.settings.export import export diff --git a/tests/commands/settings/test_import_cmd.py b/tests/commands/settings/test_import_cmd.py index 401b5ac..7fca937 100644 --- a/tests/commands/settings/test_import_cmd.py +++ b/tests/commands/settings/test_import_cmd.py @@ -8,16 +8,17 @@ """ # Standard -import json from pathlib import Path -import tempfile from unittest.mock import patch +import json +import tempfile + # Third-Party import pytest import typer -# First-Party +# Local from cforge.commands.settings.import_cmd import import_cmd diff --git a/tests/commands/settings/test_login.py b/tests/commands/settings/test_login.py index 39c66d8..d54d210 100644 --- a/tests/commands/settings/test_login.py +++ b/tests/commands/settings/test_login.py @@ -9,15 +9,16 @@ # Standard from pathlib import Path -import tempfile from unittest.mock import Mock, patch +import tempfile + # Third-Party import pytest import requests import typer -# First-Party +# Local from cforge.commands.settings.login import login from cforge.common.errors import AuthenticationError from cforge.common.http import make_authenticated_request @@ -147,7 +148,7 @@ def test_login_saves_to_profile_specific_token_file(self, mock_base_url, mock_co # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store mock_response = Mock() @@ -186,7 +187,7 @@ def test_login_with_multiple_profiles(self, mock_base_url, mock_console, mock_se # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id1 = "profile-1" diff --git a/tests/commands/settings/test_logout.py b/tests/commands/settings/test_logout.py index 0787046..4b601ef 100644 --- a/tests/commands/settings/test_logout.py +++ b/tests/commands/settings/test_logout.py @@ -9,13 +9,14 @@ # Standard from pathlib import Path -import tempfile from unittest.mock import patch +import tempfile + # Third-Party import pytest -# First-Party +# Local from cforge.commands.settings.login import login from cforge.commands.settings.logout import logout from cforge.common.errors import AuthenticationError @@ -96,7 +97,7 @@ def test_logout_removes_profile_specific_token(self, mock_console, mock_settings # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile @@ -135,7 +136,7 @@ def test_logout_only_removes_active_profile_token(self, mock_console, mock_setti # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id1 = "profile-1" diff --git a/tests/commands/settings/test_profiles.py b/tests/commands/settings/test_profiles.py index 4bce668..195cd91 100644 --- a/tests/commands/settings/test_profiles.py +++ b/tests/commands/settings/test_profiles.py @@ -9,16 +9,17 @@ # Standard from datetime import datetime -import json from pathlib import Path -import tempfile from unittest.mock import Mock, patch +import json +import tempfile + # Third-Party import pytest import typer -# First-Party +# Local from cforge.commands.settings.profiles import ( profiles_create, profiles_get, @@ -625,7 +626,7 @@ def test_profiles_create_enable_fails(self, mock_console, mock_settings) -> None def test_profiles_create_with_existing_store(self, mock_console, mock_settings) -> None: """Test creating a profile when a profile store already exists.""" - # First-Party + # Local from cforge.profile_utils import load_profile_store # Create an existing profile store diff --git a/tests/commands/settings/test_support_bundle.py b/tests/commands/settings/test_support_bundle.py index ce5d241..1e90944 100644 --- a/tests/commands/settings/test_support_bundle.py +++ b/tests/commands/settings/test_support_bundle.py @@ -9,14 +9,15 @@ # Standard from pathlib import Path -import tempfile from unittest.mock import Mock, patch +import tempfile + # Third-Party import pytest import typer -# First-Party +# Local from cforge.commands.settings.support_bundle import support_bundle diff --git a/tests/commands/settings/test_version.py b/tests/commands/settings/test_version.py index 1464703..1c6a9a0 100644 --- a/tests/commands/settings/test_version.py +++ b/tests/commands/settings/test_version.py @@ -8,9 +8,11 @@ """ # First-Party -from cforge.commands.settings.version import version from mcpgateway import __version__ +# Local +from cforge.commands.settings.version import version + class TestVersionCommand: """Tests for version command.""" diff --git a/tests/commands/settings/test_whoami.py b/tests/commands/settings/test_whoami.py index 9da8d13..12eeb68 100644 --- a/tests/commands/settings/test_whoami.py +++ b/tests/commands/settings/test_whoami.py @@ -10,7 +10,7 @@ # Standard from unittest.mock import patch -# First-Party +# Local from cforge.commands.settings.whoami import whoami @@ -83,7 +83,7 @@ def test_whoami_with_active_profile_and_token(self, mock_settings, mock_console) # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile @@ -131,7 +131,7 @@ def test_whoami_with_active_profile_with_metadata(self, mock_settings, mock_cons # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileMetadata, ProfileStore, save_profile_store # Create profile with metadata @@ -174,7 +174,7 @@ def test_whoami_with_active_profile_no_auth(self, mock_settings, mock_console) - # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile diff --git a/tests/common/test_console.py b/tests/common/test_console.py index eb5fe43..94b5c85 100644 --- a/tests/common/test_console.py +++ b/tests/common/test_console.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Tests for cforge.common.console.""" -# First-Party +# Local from cforge.common.console import get_app, get_console diff --git a/tests/common/test_errors.py b/tests/common/test_errors.py index 4884300..9bb5c87 100644 --- a/tests/common/test_errors.py +++ b/tests/common/test_errors.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Tests for cforge.common.errors.""" -# First-Party +# Local from cforge.common.errors import AuthenticationError, CLIError diff --git a/tests/common/test_http.py b/tests/common/test_http.py index 5b46c73..7d349be 100644 --- a/tests/common/test_http.py +++ b/tests/common/test_http.py @@ -3,19 +3,18 @@ # Standard from pathlib import Path +from unittest.mock import Mock, patch + import stat import tempfile -from unittest.mock import Mock, patch # Third-Party import pytest import requests -# First-Party +# Local from cforge.common.errors import AuthenticationError, CLIError from cforge.common.http import get_auth_token, get_token_file, load_token, make_authenticated_request, save_token - -# Local from tests.conftest import mock_client_login @@ -34,7 +33,7 @@ def test_get_token_file_with_active_profile(self, mock_settings) -> None: # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store # Create and save an active profile @@ -73,7 +72,7 @@ def test_save_and_load_token_with_active_profile(self, mock_settings) -> None: # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store test_token = "profile_token_456" @@ -109,7 +108,7 @@ def test_save_token_different_profiles(self, mock_settings) -> None: # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store token1 = "token_for_profile_1" @@ -173,7 +172,7 @@ def test_load_token_nonexistent_profile(self, mock_settings) -> None: # Standard from datetime import datetime - # First-Party + # Local from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store profile_id = "nonexistent-profile" @@ -207,7 +206,7 @@ def test_get_base_url_with_active_profile(self, mock_settings) -> None: # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import get_base_url from cforge.profile_utils import AuthProfile, ProfileStore, save_profile_store @@ -232,7 +231,7 @@ def test_get_base_url_with_active_profile(self, mock_settings) -> None: def test_get_base_url_without_active_profile(self, mock_settings) -> None: """Test get_base_url returns default URL when no active profile.""" - # First-Party + # Local from cforge.common.http import get_base_url # No profile saved, should use settings @@ -274,7 +273,7 @@ class TestAutoLogin: def test_attempt_auto_login_no_profile(self, mock_settings): """Test auto-login when no profile is active.""" - # First-Party + # Local from cforge.common.http import attempt_auto_login token = attempt_auto_login() @@ -285,7 +284,7 @@ def test_attempt_auto_login_no_credentials(self, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -308,7 +307,7 @@ def test_attempt_auto_login_missing_email(self, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -331,7 +330,7 @@ def test_attempt_auto_login_missing_password(self, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -355,7 +354,7 @@ def test_attempt_auto_login_success(self, mock_post, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login, load_token from cforge.profile_utils import AuthProfile @@ -389,7 +388,7 @@ def test_attempt_auto_login_failed_login(self, mock_post, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -418,7 +417,7 @@ def test_attempt_auto_login_no_token_in_response(self, mock_post, mock_settings) # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -448,7 +447,7 @@ def test_attempt_auto_login_request_exception(self, mock_post, mock_settings): # Standard from datetime import datetime - # First-Party + # Local from cforge.common.http import attempt_auto_login from cforge.profile_utils import AuthProfile @@ -471,7 +470,7 @@ def test_attempt_auto_login_request_exception(self, mock_post, mock_settings): def test_get_auth_token_with_auto_login(self, mock_settings): """Test that get_auth_token attempts auto-login when no token is available.""" - # First-Party + # Local from cforge.common.http import get_auth_token # Mock no env token and no file token, but successful auto-login diff --git a/tests/common/test_prompting.py b/tests/common/test_prompting.py index 07bebf5..d9f1220 100644 --- a/tests/common/test_prompting.py +++ b/tests/common/test_prompting.py @@ -8,9 +8,10 @@ # Third-Party from pydantic import BaseModel, Field + import pytest -# First-Party +# Local from cforge.common.errors import CLIError from cforge.common.prompting import ( _build_prompt_text, diff --git a/tests/common/test_render.py b/tests/common/test_render.py index 86bfe4e..d1a89d7 100644 --- a/tests/common/test_render.py +++ b/tests/common/test_render.py @@ -6,7 +6,7 @@ from rich.syntax import Syntax from rich.table import Table -# First-Party +# Local from cforge.common.render import LineLimit, print_json, print_table diff --git a/tests/common/test_schema_validation.py b/tests/common/test_schema_validation.py index 4d68e3a..5d1f9ba 100644 --- a/tests/common/test_schema_validation.py +++ b/tests/common/test_schema_validation.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Tests for cforge.common.schema_validation.""" -# First-Party +# Local from cforge.common.schema_validation import validate_instance, validate_instance_against_subschema, validate_schema diff --git a/tests/conftest.py b/tests/conftest.py index a703fbb..f9ba383 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,26 +9,28 @@ # Standard from contextlib import contextmanager +from pathlib import Path +from types import SimpleNamespace +from typing import Any, Callable, Generator, List, Union +from unittest.mock import Mock, patch + import inspect import logging import os -from pathlib import Path import socket import sys import tempfile import threading import time -from types import SimpleNamespace -from typing import Any, Callable, Generator, List, Union -from unittest.mock import Mock, patch # Third-Party from fastapi.testclient import TestClient from mcp.server.fastmcp import FastMCP from pydantic import SecretStr -import pytest from typer.models import OptionInfo from typer.testing import CliRunner + +import pytest import urllib3 import uvicorn @@ -38,7 +40,7 @@ os.environ["DATABASE_URL"] = f"sqlite:////{working_dir.__enter__()}/mcp.db" -# First-Party +# Local from cforge.config import CLISettings, get_settings # noqa: E402 # Suppress urllib3 retry warnings during tests diff --git a/tests/test_config.py b/tests/test_config.py index 63398b7..c9ac8d3 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -8,12 +8,13 @@ """ # Standard -import os from pathlib import Path -import tempfile from unittest import mock -# First-Party +import os +import tempfile + +# Local from cforge.config import get_settings diff --git a/tests/test_credential_store.py b/tests/test_credential_store.py index c10e6b8..d0aab5b 100644 --- a/tests/test_credential_store.py +++ b/tests/test_credential_store.py @@ -16,7 +16,7 @@ from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC -# First-Party +# Local from cforge.credential_store import ( decrypt_credential_data, get_credential_store_path, diff --git a/tests/test_main.py b/tests/test_main.py index 1b47eea..b289f48 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -10,7 +10,7 @@ # Third-Party from typer.testing import CliRunner -# First-Party +# Local from cforge.main import app diff --git a/tests/test_profile_utils.py b/tests/test_profile_utils.py index 1ed7106..2cd800f 100644 --- a/tests/test_profile_utils.py +++ b/tests/test_profile_utils.py @@ -9,10 +9,11 @@ # Standard from datetime import datetime -import json from pathlib import Path -# First-Party +import json + +# Local from cforge.profile_utils import ( AuthProfile, DEFAULT_PROFILE_ID, From 71c6570e78a40767ddb4b11b0006708aa2e0559b Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Fri, 13 Mar 2026 14:40:31 -0700 Subject: [PATCH 5/8] Update cforge/commands/server/run.py Co-authored-by: Gabe Goodhart --- cforge/commands/server/run.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cforge/commands/server/run.py b/cforge/commands/server/run.py index d4e090e..260ced2 100644 --- a/cforge/commands/server/run.py +++ b/cforge/commands/server/run.py @@ -165,7 +165,6 @@ def run( # Import top-level translate here to avoid undesirable initialization # Third Party - # First-Party from mcpgateway.translate import main as translate_main From 8c779be50055039a1bd120a94265a444c22781b8 Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Thu, 19 Mar 2026 07:41:25 -0700 Subject: [PATCH 6/8] chore: update isort config removed line between from and import types changed sorting to case sensitive --- cforge/commands/resources/a2a.py | 1 - cforge/commands/resources/mcp_servers.py | 1 - cforge/commands/resources/plugins.py | 2 +- cforge/commands/resources/prompts.py | 1 - cforge/commands/resources/resources.py | 1 - cforge/commands/resources/tools.py | 1 - cforge/commands/resources/virtual_servers.py | 1 - cforge/commands/server/run.py | 3 +-- cforge/commands/settings/config_schema.py | 1 - cforge/commands/settings/export.py | 1 - cforge/commands/settings/import_cmd.py | 1 - cforge/commands/settings/profiles.py | 3 +-- cforge/common/console.py | 1 - cforge/common/errors.py | 1 - cforge/common/prompting.py | 4 +--- cforge/common/render.py | 3 +-- cforge/config.py | 3 +-- cforge/credential_store.py | 3 +-- cforge/profile_utils.py | 3 +-- pyproject.toml | 9 +++++---- tests/commands/resources/test_a2a.py | 1 - tests/commands/resources/test_mcp_servers.py | 1 - tests/commands/resources/test_plugins.py | 2 +- tests/commands/resources/test_prompts.py | 1 - tests/commands/resources/test_resources.py | 1 - tests/commands/resources/test_tools.py | 1 - tests/commands/resources/test_virtual_servers.py | 1 - tests/commands/server/test_serve.py | 1 - tests/commands/settings/test_config_schema.py | 1 - tests/commands/settings/test_export.py | 1 - tests/commands/settings/test_import_cmd.py | 1 - tests/commands/settings/test_login.py | 1 - tests/commands/settings/test_logout.py | 1 - tests/commands/settings/test_profiles.py | 3 +-- tests/commands/settings/test_support_bundle.py | 1 - tests/common/test_http.py | 1 - tests/common/test_prompting.py | 3 +-- tests/conftest.py | 2 -- tests/test_config.py | 1 - tests/test_credential_store.py | 2 +- tests/test_profile_utils.py | 5 ++--- 41 files changed, 19 insertions(+), 57 deletions(-) diff --git a/cforge/commands/resources/a2a.py b/cforge/commands/resources/a2a.py index 64d33f1..b98b5ef 100644 --- a/cforge/commands/resources/a2a.py +++ b/cforge/commands/resources/a2a.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party diff --git a/cforge/commands/resources/mcp_servers.py b/cforge/commands/resources/mcp_servers.py index f6ffbea..4c84919 100644 --- a/cforge/commands/resources/mcp_servers.py +++ b/cforge/commands/resources/mcp_servers.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party diff --git a/cforge/commands/resources/plugins.py b/cforge/commands/resources/plugins.py index f82497d..feb4d04 100644 --- a/cforge/commands/resources/plugins.py +++ b/cforge/commands/resources/plugins.py @@ -21,7 +21,7 @@ # Local from cforge.common.console import get_console -from cforge.common.errors import AuthenticationError, CaseInsensitiveEnum, CLIError, handle_exception +from cforge.common.errors import AuthenticationError, CLIError, CaseInsensitiveEnum, handle_exception from cforge.common.http import make_authenticated_request from cforge.common.render import print_json, print_table diff --git a/cforge/commands/resources/prompts.py b/cforge/commands/resources/prompts.py index 5616e85..68d69bc 100644 --- a/cforge/commands/resources/prompts.py +++ b/cforge/commands/resources/prompts.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Any, Dict, Optional - import json # Third-Party diff --git a/cforge/commands/resources/resources.py b/cforge/commands/resources/resources.py index 330151d..e5dfa53 100644 --- a/cforge/commands/resources/resources.py +++ b/cforge/commands/resources/resources.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Any, Dict, Optional - import json # Third-Party diff --git a/cforge/commands/resources/tools.py b/cforge/commands/resources/tools.py index 0766430..557867a 100644 --- a/cforge/commands/resources/tools.py +++ b/cforge/commands/resources/tools.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Any, Dict, Optional - import json # Third-Party diff --git a/cforge/commands/resources/virtual_servers.py b/cforge/commands/resources/virtual_servers.py index 9a123af..cf80558 100644 --- a/cforge/commands/resources/virtual_servers.py +++ b/cforge/commands/resources/virtual_servers.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party diff --git a/cforge/commands/server/run.py b/cforge/commands/server/run.py index 260ced2..883ba19 100644 --- a/cforge/commands/server/run.py +++ b/cforge/commands/server/run.py @@ -13,7 +13,6 @@ # Standard from typing import List, Optional - import atexit import multiprocessing import os @@ -164,7 +163,7 @@ def run( args.append("--jsonResponse") # Import top-level translate here to avoid undesirable initialization - # Third Party + # First-Party from mcpgateway.translate import main as translate_main diff --git a/cforge/commands/settings/config_schema.py b/cforge/commands/settings/config_schema.py index 427672c..623c2fb 100644 --- a/cforge/commands/settings/config_schema.py +++ b/cforge/commands/settings/config_schema.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party diff --git a/cforge/commands/settings/export.py b/cforge/commands/settings/export.py index 109c91b..0768bba 100644 --- a/cforge/commands/settings/export.py +++ b/cforge/commands/settings/export.py @@ -11,7 +11,6 @@ from datetime import datetime from pathlib import Path from typing import Any, Dict, Optional - import json # Third-Party diff --git a/cforge/commands/settings/import_cmd.py b/cforge/commands/settings/import_cmd.py index f9fafe9..42a3522 100644 --- a/cforge/commands/settings/import_cmd.py +++ b/cforge/commands/settings/import_cmd.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party diff --git a/cforge/commands/settings/profiles.py b/cforge/commands/settings/profiles.py index c21faea..ef60cde 100644 --- a/cforge/commands/settings/profiles.py +++ b/cforge/commands/settings/profiles.py @@ -11,7 +11,6 @@ from datetime import datetime from pathlib import Path from typing import Optional - import json import secrets import string @@ -26,11 +25,11 @@ from cforge.config import get_settings from cforge.profile_utils import ( AuthProfile, + ProfileStore, get_active_profile, get_all_profiles, get_profile, load_profile_store, - ProfileStore, save_profile_store, set_active_profile, ) diff --git a/cforge/common/console.py b/cforge/common/console.py index 47723aa..36d050e 100644 --- a/cforge/common/console.py +++ b/cforge/common/console.py @@ -14,7 +14,6 @@ # Third-Party from rich.console import Console - import typer diff --git a/cforge/common/errors.py b/cforge/common/errors.py index 5fd250b..c21fe90 100644 --- a/cforge/common/errors.py +++ b/cforge/common/errors.py @@ -12,7 +12,6 @@ # Standard from enum import Enum from typing import Any, Optional, Tuple - import json # Third-Party diff --git a/cforge/common/prompting.py b/cforge/common/prompting.py index af67157..3e329f3 100644 --- a/cforge/common/prompting.py +++ b/cforge/common/prompting.py @@ -11,14 +11,12 @@ """ # Standard -from typing import Annotated, Any, Callable, Dict, get_args, get_origin, get_type_hints, List, Optional, Tuple, Union - +from typing import Annotated, Any, Callable, Dict, List, Optional, Tuple, Union, get_args, get_origin, get_type_hints import json # Third-Party from pydantic import BaseModel from rich.console import Console - import typer # Local diff --git a/cforge/common/render.py b/cforge/common/render.py index 8c9f40f..203521a 100644 --- a/cforge/common/render.py +++ b/cforge/common/render.py @@ -11,11 +11,10 @@ # Standard from typing import Any, Dict, List, Optional - import json # Third-Party -from rich.console import Console, ConsoleOptions, RenderableType, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult, RenderableType from rich.measure import Measurement from rich.panel import Panel from rich.segment import Segment diff --git a/cforge/config.py b/cforge/config.py index a65807e..e006c1a 100644 --- a/cforge/config.py +++ b/cforge/config.py @@ -12,15 +12,14 @@ from functools import lru_cache from pathlib import Path from typing import Generator, Optional, Self - import os # Third-Party from pydantic import model_validator # First-Party -from mcpgateway.config import get_settings as cf_get_settings from mcpgateway.config import Settings +from mcpgateway.config import get_settings as cf_get_settings HOME_DIR_NAME = ".contextforge" DEFAULT_HOME = Path.home() / HOME_DIR_NAME diff --git a/cforge/credential_store.py b/cforge/credential_store.py index ab39747..aa85d6b 100644 --- a/cforge/credential_store.py +++ b/cforge/credential_store.py @@ -10,13 +10,12 @@ # Standard from pathlib import Path from typing import Optional - import json # Third-Party from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC # Local diff --git a/cforge/profile_utils.py b/cforge/profile_utils.py index bb201e3..208507a 100644 --- a/cforge/profile_utils.py +++ b/cforge/profile_utils.py @@ -12,11 +12,10 @@ from datetime import datetime from pathlib import Path from typing import Dict, List, Optional - import json # Third-Party -from pydantic import BaseModel, Field, field_validator, ValidationInfo +from pydantic import BaseModel, Field, ValidationInfo, field_validator # Local from cforge.config import get_settings diff --git a/pyproject.toml b/pyproject.toml index 6c09e88..fbe56c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -222,7 +222,7 @@ from-first = true # place all "from ... import ..." befo ############################################################################### # What belongs where ############################################################################### -known-first-party = ["mcpgateway"] # treat "cforge" and "mcpgateway" as FIRSTPARTY +known-first-party = ["mcpgateway"] # treat "mcpgateway" as FIRSTPARTY known-local-folder = ["tests", "scripts","cforge"] # treat these folders as LOCALFOLDER known-third-party = ["alembic"] # treat "alembic" as THIRDPARTY # src-paths = ["src/cforge"] # uncomment only if package moves under src/ @@ -278,18 +278,19 @@ import_heading_localfolder = "Local" # header for ad-hoc scripts / tests ############################################################################### # What belongs where ############################################################################### -known_first_party = ["mcpgateway"] # treat "mcpgateway.*" as FIRSTPARTY +known_first_party = ["mcpgateway"] # treat "mcpgateway" as FIRSTPARTY known_local_folder = ["tests", "scripts", "cforge"] # treat these folders as LOCALFOLDER # src_paths = ["src/cforge"] # uncomment only if package moves under src/ ############################################################################### # Style niceties ############################################################################### -force_alphabetical_sort_within_sections = true # always alphabetise names inside each block +# force_alphabetical_sort_within_sections = true # always alphabetise names inside each block +case_sensitive = true # case sensitive sorting order_by_type = false # don't group imports by "type vs. straight name" balanced_wrapping = true # spread wrapped imports evenly between lines lines_between_sections = 1 # exactly one blank line between the five groups -lines_between_types = 1 # one blank line between 'import X' and 'from X import ...' +# lines_between_types = 1 # one blank line between 'import X' and 'from X import ...' no_lines_before = ["LOCALFOLDER"] # suppress blank line *before* the LOCALFOLDER block ensure_newline_before_comments = true # newline before any inline # comment after an import diff --git a/tests/commands/resources/test_a2a.py b/tests/commands/resources/test_a2a.py index 13b9870..7eb238a 100644 --- a/tests/commands/resources/test_a2a.py +++ b/tests/commands/resources/test_a2a.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/resources/test_mcp_servers.py b/tests/commands/resources/test_mcp_servers.py index e068cf7..53ca900 100644 --- a/tests/commands/resources/test_mcp_servers.py +++ b/tests/commands/resources/test_mcp_servers.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/resources/test_plugins.py b/tests/commands/resources/test_plugins.py index 23a6540..9bd7a54 100644 --- a/tests/commands/resources/test_plugins.py +++ b/tests/commands/resources/test_plugins.py @@ -12,7 +12,7 @@ import typer # Local -from cforge.commands.resources.plugins import _parse_plugin_mode, PluginMode, plugins_get, plugins_list, plugins_stats +from cforge.commands.resources.plugins import PluginMode, _parse_plugin_mode, plugins_get, plugins_list, plugins_stats from cforge.common.errors import AuthenticationError, CLIError from cforge.main import app from tests.conftest import invoke_typer_command, patch_functions diff --git a/tests/commands/resources/test_prompts.py b/tests/commands/resources/test_prompts.py index 14bf43d..958c400 100644 --- a/tests/commands/resources/test_prompts.py +++ b/tests/commands/resources/test_prompts.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/resources/test_resources.py b/tests/commands/resources/test_resources.py index d983ed3..0d8c54c 100644 --- a/tests/commands/resources/test_resources.py +++ b/tests/commands/resources/test_resources.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/resources/test_tools.py b/tests/commands/resources/test_tools.py index d226d8c..32c6a49 100644 --- a/tests/commands/resources/test_tools.py +++ b/tests/commands/resources/test_tools.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/resources/test_virtual_servers.py b/tests/commands/resources/test_virtual_servers.py index 147b48e..639f879 100644 --- a/tests/commands/resources/test_virtual_servers.py +++ b/tests/commands/resources/test_virtual_servers.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import MagicMock, patch - import json import tempfile diff --git a/tests/commands/server/test_serve.py b/tests/commands/server/test_serve.py index 2e77281..3bf1e27 100644 --- a/tests/commands/server/test_serve.py +++ b/tests/commands/server/test_serve.py @@ -9,7 +9,6 @@ # Standard from unittest.mock import patch - import threading import time diff --git a/tests/commands/settings/test_config_schema.py b/tests/commands/settings/test_config_schema.py index 05f9052..1647576 100644 --- a/tests/commands/settings/test_config_schema.py +++ b/tests/commands/settings/test_config_schema.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/settings/test_export.py b/tests/commands/settings/test_export.py index ea59735..6873729 100644 --- a/tests/commands/settings/test_export.py +++ b/tests/commands/settings/test_export.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/settings/test_import_cmd.py b/tests/commands/settings/test_import_cmd.py index 7fca937..ae4202f 100644 --- a/tests/commands/settings/test_import_cmd.py +++ b/tests/commands/settings/test_import_cmd.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import json import tempfile diff --git a/tests/commands/settings/test_login.py b/tests/commands/settings/test_login.py index d54d210..7d1ede8 100644 --- a/tests/commands/settings/test_login.py +++ b/tests/commands/settings/test_login.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import Mock, patch - import tempfile # Third-Party diff --git a/tests/commands/settings/test_logout.py b/tests/commands/settings/test_logout.py index 4b601ef..9f766cd 100644 --- a/tests/commands/settings/test_logout.py +++ b/tests/commands/settings/test_logout.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import patch - import tempfile # Third-Party diff --git a/tests/commands/settings/test_profiles.py b/tests/commands/settings/test_profiles.py index 195cd91..90a7be0 100644 --- a/tests/commands/settings/test_profiles.py +++ b/tests/commands/settings/test_profiles.py @@ -11,7 +11,6 @@ from datetime import datetime from pathlib import Path from unittest.mock import Mock, patch - import json import tempfile @@ -29,9 +28,9 @@ from cforge.profile_utils import ( AuthProfile, DEFAULT_PROFILE_ID, - load_profile_store, ProfileMetadata, ProfileStore, + load_profile_store, save_profile_store, ) diff --git a/tests/commands/settings/test_support_bundle.py b/tests/commands/settings/test_support_bundle.py index 1e90944..e1efea3 100644 --- a/tests/commands/settings/test_support_bundle.py +++ b/tests/commands/settings/test_support_bundle.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest.mock import Mock, patch - import tempfile # Third-Party diff --git a/tests/common/test_http.py b/tests/common/test_http.py index 7d349be..a3d74e1 100644 --- a/tests/common/test_http.py +++ b/tests/common/test_http.py @@ -4,7 +4,6 @@ # Standard from pathlib import Path from unittest.mock import Mock, patch - import stat import tempfile diff --git a/tests/common/test_prompting.py b/tests/common/test_prompting.py index d9f1220..350c227 100644 --- a/tests/common/test_prompting.py +++ b/tests/common/test_prompting.py @@ -8,15 +8,14 @@ # Third-Party from pydantic import BaseModel, Field - import pytest # Local from cforge.common.errors import CLIError from cforge.common.prompting import ( + _INT_SENTINEL_DEFAULT, _build_prompt_text, _infer_schema_type, - _INT_SENTINEL_DEFAULT, _resolve_effective_schema, _resolve_ref_schema, _resolve_schema_type, diff --git a/tests/conftest.py b/tests/conftest.py index f9ba383..43b36f9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,6 @@ from types import SimpleNamespace from typing import Any, Callable, Generator, List, Union from unittest.mock import Mock, patch - import inspect import logging import os @@ -29,7 +28,6 @@ from pydantic import SecretStr from typer.models import OptionInfo from typer.testing import CliRunner - import pytest import urllib3 import uvicorn diff --git a/tests/test_config.py b/tests/test_config.py index c9ac8d3..44b2d41 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -10,7 +10,6 @@ # Standard from pathlib import Path from unittest import mock - import os import tempfile diff --git a/tests/test_credential_store.py b/tests/test_credential_store.py index d0aab5b..df4dae4 100644 --- a/tests/test_credential_store.py +++ b/tests/test_credential_store.py @@ -13,7 +13,7 @@ # Third-Party from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC # Local diff --git a/tests/test_profile_utils.py b/tests/test_profile_utils.py index 2cd800f..749a3cf 100644 --- a/tests/test_profile_utils.py +++ b/tests/test_profile_utils.py @@ -10,20 +10,19 @@ # Standard from datetime import datetime from pathlib import Path - import json # Local from cforge.profile_utils import ( AuthProfile, DEFAULT_PROFILE_ID, + ProfileMetadata, + ProfileStore, get_active_profile, get_all_profiles, get_profile, get_profile_store_path, load_profile_store, - ProfileMetadata, - ProfileStore, save_profile_store, set_active_profile, ) From c32c15a67bc718389f231f8ff391bd01cb55c952 Mon Sep 17 00:00:00 2001 From: Christina Zhao Date: Thu, 19 Mar 2026 07:43:38 -0700 Subject: [PATCH 7/8] removed vs commented out changes in config just removed the style changes that are no longer applied from the toml file --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fbe56c6..e9a54b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -285,12 +285,10 @@ known_local_folder = ["tests", "scripts", "cforge"] # treat these folde ############################################################################### # Style niceties ############################################################################### -# force_alphabetical_sort_within_sections = true # always alphabetise names inside each block case_sensitive = true # case sensitive sorting order_by_type = false # don't group imports by "type vs. straight name" balanced_wrapping = true # spread wrapped imports evenly between lines lines_between_sections = 1 # exactly one blank line between the five groups -# lines_between_types = 1 # one blank line between 'import X' and 'from X import ...' no_lines_before = ["LOCALFOLDER"] # suppress blank line *before* the LOCALFOLDER block ensure_newline_before_comments = true # newline before any inline # comment after an import From 2ba4cecb077bc5f1384d7aa96f70bcec19d8ea02 Mon Sep 17 00:00:00 2001 From: Gabe Goodhart Date: Fri, 20 Mar 2026 08:40:31 -0600 Subject: [PATCH 8/8] fix: Remove PR_ISORT.md Branch: isort-fix AI-usage: none Signed-off-by: Gabe Goodhart --- PR_ISORT.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 PR_ISORT.md diff --git a/PR_ISORT.md b/PR_ISORT.md deleted file mode 100644 index e69de29..0000000