diff --git a/enterprise/server/auth/saas_user_auth.py b/enterprise/server/auth/saas_user_auth.py index 42bdd9f640..72138c268a 100644 --- a/enterprise/server/auth/saas_user_auth.py +++ b/enterprise/server/auth/saas_user_auth.py @@ -35,6 +35,7 @@ from storage.user_authorization_store import UserAuthorizationStore from storage.user_store import UserStore from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import ( PROVIDER_TOKEN_TYPE, ProviderToken, @@ -43,7 +44,6 @@ from openhands.integrations.provider import ( from openhands.server.settings import Settings from openhands.server.user_auth.user_auth import AuthType, UserAuth from openhands.storage.data_models.secrets import Secrets -from openhands.storage.settings.settings_store import SettingsStore token_manager = TokenManager() diff --git a/enterprise/storage/saas_secrets_store.py b/enterprise/storage/saas_secrets_store.py index 14d1fb524c..9df72241e1 100644 --- a/enterprise/storage/saas_secrets_store.py +++ b/enterprise/storage/saas_secrets_store.py @@ -10,10 +10,10 @@ from storage.database import a_session_maker from storage.stored_custom_secrets import StoredCustomSecrets from storage.user_store import UserStore +from openhands.app_server.secrets.secrets_store import SecretsStore from openhands.core.config.openhands_config import OpenHandsConfig from openhands.core.logger import openhands_logger as logger from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.secrets_store import SecretsStore @dataclass diff --git a/enterprise/storage/saas_settings_store.py b/enterprise/storage/saas_settings_store.py index e73c3e62ba..44c40b2813 100644 --- a/enterprise/storage/saas_settings_store.py +++ b/enterprise/storage/saas_settings_store.py @@ -21,9 +21,9 @@ from storage.user import User from storage.user_settings import UserSettings from storage.user_store import UserStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.core.config.openhands_config import OpenHandsConfig from openhands.server.settings import Settings -from openhands.storage.settings.settings_store import SettingsStore from openhands.utils.jsonpatch_compat import deep_merge from openhands.utils.llm import is_openhands_model diff --git a/openhands/storage/secrets/file_secrets_store.py b/openhands/app_server/secrets/file_secrets_store.py similarity index 96% rename from openhands/storage/secrets/file_secrets_store.py rename to openhands/app_server/secrets/file_secrets_store.py index 9e9d744424..3c2093cecc 100644 --- a/openhands/storage/secrets/file_secrets_store.py +++ b/openhands/app_server/secrets/file_secrets_store.py @@ -3,11 +3,11 @@ from __future__ import annotations import json from dataclasses import dataclass +from openhands.app_server.secrets.secrets_store import SecretsStore from openhands.core.config.openhands_config import OpenHandsConfig from openhands.storage import get_file_store from openhands.storage.data_models.secrets import Secrets from openhands.storage.files import FileStore -from openhands.storage.secrets.secrets_store import SecretsStore from openhands.utils.async_utils import call_sync_from_async diff --git a/openhands/app_server/secrets/secrets_router.py b/openhands/app_server/secrets/secrets_router.py index 97269b7f49..82abb79a9b 100644 --- a/openhands/app_server/secrets/secrets_router.py +++ b/openhands/app_server/secrets/secrets_router.py @@ -13,6 +13,7 @@ from openhands.app_server.secrets.secrets_models import ( CustomSecretPage, CustomSecretWithoutValue, ) +from openhands.app_server.secrets.secrets_store import SecretsStore from openhands.app_server.utils.dependencies import get_dependencies from openhands.app_server.utils.models import EditResponse from openhands.integrations.provider import ( @@ -30,7 +31,6 @@ from openhands.server.user_auth import ( get_secrets_store, ) from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.secrets_store import SecretsStore # Create router with /api/v1/secrets prefix router = APIRouter( diff --git a/openhands/storage/secrets/secrets_store.py b/openhands/app_server/secrets/secrets_store.py similarity index 100% rename from openhands/storage/secrets/secrets_store.py rename to openhands/app_server/secrets/secrets_store.py diff --git a/openhands/storage/settings/file_settings_store.py b/openhands/app_server/settings/file_settings_store.py similarity index 96% rename from openhands/storage/settings/file_settings_store.py rename to openhands/app_server/settings/file_settings_store.py index 66820fb5cc..361c91becc 100644 --- a/openhands/storage/settings/file_settings_store.py +++ b/openhands/app_server/settings/file_settings_store.py @@ -3,11 +3,11 @@ from __future__ import annotations import json from dataclasses import dataclass +from openhands.app_server.settings.settings_store import SettingsStore from openhands.core.config.openhands_config import OpenHandsConfig from openhands.storage import get_file_store from openhands.storage.data_models.settings import Settings from openhands.storage.files import FileStore -from openhands.storage.settings.settings_store import SettingsStore from openhands.utils.async_utils import call_sync_from_async diff --git a/openhands/app_server/settings/settings_router.py b/openhands/app_server/settings/settings_router.py index 90b556ea8f..4163cb5992 100644 --- a/openhands/app_server/settings/settings_router.py +++ b/openhands/app_server/settings/settings_router.py @@ -9,6 +9,8 @@ from typing import Any from fastapi import APIRouter, Depends, status from fastapi.responses import JSONResponse +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.app_server.utils.dependencies import get_dependencies from openhands.core.logger import openhands_logger as logger from openhands.integrations.provider import ( @@ -28,8 +30,6 @@ from openhands.server.user_auth import ( ) from openhands.storage.data_models.secrets import Secrets from openhands.storage.data_models.settings import Settings -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.settings_store import SettingsStore from openhands.utils.llm import ( get_provider_api_base, is_openhands_model, diff --git a/openhands/storage/settings/settings_store.py b/openhands/app_server/settings/settings_store.py similarity index 100% rename from openhands/storage/settings/settings_store.py rename to openhands/app_server/settings/settings_store.py diff --git a/openhands/server/config/server_config.py b/openhands/server/config/server_config.py index 25caa8d5ee..2ca48453a3 100644 --- a/openhands/server/config/server_config.py +++ b/openhands/server/config/server_config.py @@ -22,10 +22,10 @@ class ServerConfig(ServerConfigInterface): hide_llm_settings = os.environ.get('HIDE_LLM_SETTINGS', 'false') == 'true' # This config is used to hide the microagent management page from the users for now. We will remove this once we release the new microagent management page. settings_store_class: str = ( - 'openhands.storage.settings.file_settings_store.FileSettingsStore' + 'openhands.app_server.settings.file_settings_store.FileSettingsStore' ) secret_store_class: str = ( - 'openhands.storage.secrets.file_secrets_store.FileSecretsStore' + 'openhands.app_server.secrets.file_secrets_store.FileSecretsStore' ) user_auth_class: str = ( 'openhands.server.user_auth.default_user_auth.DefaultUserAuth' diff --git a/openhands/server/shared.py b/openhands/server/shared.py index 994c4685f4..a5e0e44eb8 100644 --- a/openhands/server/shared.py +++ b/openhands/server/shared.py @@ -11,14 +11,14 @@ import os import socketio from dotenv import load_dotenv +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.core.config import load_openhands_config from openhands.core.config.openhands_config import OpenHandsConfig from openhands.server.config.server_config import ServerConfig, load_server_config from openhands.server.types import ServerConfigInterface from openhands.storage import get_file_store from openhands.storage.files import FileStore -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.settings_store import SettingsStore from openhands.utils.import_utils import get_impl load_dotenv() diff --git a/openhands/server/user_auth/__init__.py b/openhands/server/user_auth/__init__.py index d6a4c58e3f..59dc67185a 100644 --- a/openhands/server/user_auth/__init__.py +++ b/openhands/server/user_auth/__init__.py @@ -2,12 +2,12 @@ from fastapi import Depends, Request from fastapi.security import APIKeyHeader from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import PROVIDER_TOKEN_TYPE from openhands.server.settings import Settings from openhands.server.user_auth.user_auth import AuthType, get_user_auth from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.settings_store import SettingsStore async def get_provider_tokens(request: Request) -> PROVIDER_TOKEN_TYPE | None: diff --git a/openhands/server/user_auth/default_user_auth.py b/openhands/server/user_auth/default_user_auth.py index 70d8e177f4..1fb0cb8a54 100644 --- a/openhands/server/user_auth/default_user_auth.py +++ b/openhands/server/user_auth/default_user_auth.py @@ -11,13 +11,13 @@ from dataclasses import dataclass from fastapi import Request from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import PROVIDER_TOKEN_TYPE from openhands.server import shared from openhands.server.settings import Settings from openhands.server.user_auth.user_auth import UserAuth from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.settings_store import SettingsStore @dataclass diff --git a/openhands/server/user_auth/user_auth.py b/openhands/server/user_auth/user_auth.py index 7ebc94593b..922069d6e7 100644 --- a/openhands/server/user_auth/user_auth.py +++ b/openhands/server/user_auth/user_auth.py @@ -14,13 +14,13 @@ from enum import Enum from fastapi import Request from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import PROVIDER_TOKEN_TYPE, ProviderHandler from openhands.integrations.service_types import UserGitInfo from openhands.server.settings import Settings from openhands.server.shared import server_config from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.settings_store import SettingsStore from openhands.utils.import_utils import get_impl diff --git a/openhands/utils/import_utils.py b/openhands/utils/import_utils.py index 7dc25b918f..108db46fca 100644 --- a/openhands/utils/import_utils.py +++ b/openhands/utils/import_utils.py @@ -52,7 +52,7 @@ def get_impl(cls: type[T], impl_name: str | None) -> type[T]: Args: cls: The base class that defines the interface impl_name: Fully qualified name of the implementation class, or None to use the base class - e.g. 'openhands.storage.settings.file_settings_store.FileSettingsStore' + e.g. 'openhands.app_server.settings.file_settings_store.FileSettingsStore' Returns: The implementation class, which is guaranteed to be a subclass of cls diff --git a/tests/unit/app_server/test_secrets_api.py b/tests/unit/app_server/test_secrets_api.py index 401a4114ff..78fc7f564f 100644 --- a/tests/unit/app_server/test_secrets_api.py +++ b/tests/unit/app_server/test_secrets_api.py @@ -9,6 +9,7 @@ from fastapi import FastAPI from fastapi.testclient import TestClient from pydantic import SecretStr +from openhands.app_server.secrets.file_secrets_store import FileSecretsStore from openhands.app_server.secrets.secrets_router import ( router as secrets_router, ) @@ -19,7 +20,6 @@ from openhands.integrations.provider import ( ) from openhands.storage import get_file_store from openhands.storage.data_models.secrets import Secrets -from openhands.storage.secrets.file_secrets_store import FileSecretsStore @pytest.fixture @@ -45,7 +45,7 @@ def file_secrets_store(temp_dir): file_store = get_file_store('local', temp_dir) store = FileSecretsStore(file_store) with patch( - 'openhands.storage.secrets.file_secrets_store.FileSecretsStore.get_instance', + 'openhands.app_server.secrets.file_secrets_store.FileSecretsStore.get_instance', AsyncMock(return_value=store), ): yield store diff --git a/tests/unit/app_server/test_settings_api.py b/tests/unit/app_server/test_settings_api.py index d4e7cf9b8c..42a822a77a 100644 --- a/tests/unit/app_server/test_settings_api.py +++ b/tests/unit/app_server/test_settings_api.py @@ -6,6 +6,9 @@ from fastapi import Request from fastapi.testclient import TestClient from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.file_settings_store import FileSettingsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import ProviderToken, ProviderType from openhands.integrations.service_types import UserGitInfo from openhands.sdk.llm import LLM @@ -19,9 +22,6 @@ from openhands.server.user_auth.user_auth import UserAuth from openhands.storage.data_models.secrets import Secrets from openhands.storage.data_models.settings import Settings from openhands.storage.memory import InMemoryFileStore -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.file_settings_store import FileSettingsStore -from openhands.storage.settings.settings_store import SettingsStore _EXPOSE = {'expose_secrets': True} @@ -103,7 +103,7 @@ def test_client(): return_value=MockUserAuth(), ), patch( - 'openhands.storage.settings.file_settings_store.FileSettingsStore.get_instance', + 'openhands.app_server.settings.file_settings_store.FileSettingsStore.get_instance', AsyncMock(return_value=FileSettingsStore(InMemoryFileStore())), ), ): diff --git a/tests/unit/mcp/test_mcp_integration.py b/tests/unit/mcp/test_mcp_integration.py index 4c2fd439fa..62e84d045a 100644 --- a/tests/unit/mcp/test_mcp_integration.py +++ b/tests/unit/mcp/test_mcp_integration.py @@ -4,12 +4,12 @@ from unittest.mock import AsyncMock, patch import pytest +from openhands.app_server.settings.file_settings_store import FileSettingsStore from openhands.core.config.mcp_config import MCPConfig, RemoteMCPServer from openhands.sdk.llm import LLM from openhands.sdk.settings import AgentSettings from openhands.server.user_auth.default_user_auth import DefaultUserAuth from openhands.storage.data_models.settings import Settings -from openhands.storage.settings.file_settings_store import FileSettingsStore def _sdk_mcp_config(settings: Settings) -> MCPConfig | None: diff --git a/tests/unit/server/routes/test_skills_api.py b/tests/unit/server/routes/test_skills_api.py index b1daa1bee0..47940c86d4 100644 --- a/tests/unit/server/routes/test_skills_api.py +++ b/tests/unit/server/routes/test_skills_api.py @@ -7,15 +7,15 @@ from fastapi import Request from fastapi.testclient import TestClient from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.file_settings_store import FileSettingsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import ProviderToken, ProviderType from openhands.integrations.service_types import UserGitInfo from openhands.server.app import app from openhands.server.user_auth.user_auth import UserAuth from openhands.storage.data_models.secrets import Secrets from openhands.storage.memory import InMemoryFileStore -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.file_settings_store import FileSettingsStore -from openhands.storage.settings.settings_store import SettingsStore class MockUserAuth(UserAuth): @@ -75,7 +75,7 @@ def test_client(): return_value=MockUserAuth(), ), patch( - 'openhands.storage.settings.file_settings_store.FileSettingsStore.get_instance', + 'openhands.app_server.settings.file_settings_store.FileSettingsStore.get_instance', AsyncMock(return_value=FileSettingsStore(InMemoryFileStore())), ), ): diff --git a/tests/unit/server/test_openapi_schema_generation.py b/tests/unit/server/test_openapi_schema_generation.py index 8a3f8ad8f7..feb0dcd884 100644 --- a/tests/unit/server/test_openapi_schema_generation.py +++ b/tests/unit/server/test_openapi_schema_generation.py @@ -6,15 +6,15 @@ from fastapi import Request from fastapi.testclient import TestClient from pydantic import SecretStr +from openhands.app_server.secrets.secrets_store import SecretsStore +from openhands.app_server.settings.file_settings_store import FileSettingsStore +from openhands.app_server.settings.settings_store import SettingsStore from openhands.integrations.provider import ProviderToken, ProviderType from openhands.integrations.service_types import UserGitInfo from openhands.server.app import app from openhands.server.user_auth.user_auth import UserAuth from openhands.storage.data_models.secrets import Secrets from openhands.storage.memory import InMemoryFileStore -from openhands.storage.secrets.secrets_store import SecretsStore -from openhands.storage.settings.file_settings_store import FileSettingsStore -from openhands.storage.settings.settings_store import SettingsStore class MockUserAuth(UserAuth): @@ -71,7 +71,7 @@ def test_client(): return_value=MockUserAuth(), ), patch( - 'openhands.storage.settings.file_settings_store.FileSettingsStore.get_instance', + 'openhands.app_server.settings.file_settings_store.FileSettingsStore.get_instance', AsyncMock(return_value=FileSettingsStore(InMemoryFileStore())), ), ): diff --git a/tests/unit/storage/settings/test_file_settings_store.py b/tests/unit/storage/settings/test_file_settings_store.py index 38500db701..12b093a09f 100644 --- a/tests/unit/storage/settings/test_file_settings_store.py +++ b/tests/unit/storage/settings/test_file_settings_store.py @@ -4,12 +4,12 @@ from unittest.mock import MagicMock, patch import pytest from pydantic import SecretStr +from openhands.app_server.settings.file_settings_store import FileSettingsStore from openhands.core.config.openhands_config import OpenHandsConfig from openhands.sdk.llm import LLM from openhands.sdk.settings import AgentSettings, ConversationSettings from openhands.storage.data_models.settings import Settings from openhands.storage.files import FileStore -from openhands.storage.settings.file_settings_store import FileSettingsStore @pytest.fixture @@ -106,7 +106,7 @@ async def test_get_instance(): config = OpenHandsConfig(file_store='local', file_store_path='/test/path') with patch( - 'openhands.storage.settings.file_settings_store.get_file_store' + 'openhands.app_server.settings.file_settings_store.get_file_store' ) as mock_get_store: mock_store = MagicMock(spec=FileStore) mock_get_store.return_value = mock_store