JiuwenMemory 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jiuwen_memory/__init__.py +23 -0
- jiuwen_memory/common/__init__.py +13 -0
- jiuwen_memory/common/clients/__init__.py +6 -0
- jiuwen_memory/common/clients/client_registry.py +238 -0
- jiuwen_memory/common/exception/__init__.py +0 -0
- jiuwen_memory/common/exception/codes.py +968 -0
- jiuwen_memory/common/exception/errors.py +332 -0
- jiuwen_memory/common/exception/status_mapping.py +133 -0
- jiuwen_memory/common/logging/__init__.py +243 -0
- jiuwen_memory/common/logging/base_impl.py +164 -0
- jiuwen_memory/common/logging/default/__init__.py +29 -0
- jiuwen_memory/common/logging/default/config_provider.py +209 -0
- jiuwen_memory/common/logging/default/constant.py +26 -0
- jiuwen_memory/common/logging/default/default_impl.py +532 -0
- jiuwen_memory/common/logging/events.py +953 -0
- jiuwen_memory/common/logging/log_config.py +166 -0
- jiuwen_memory/common/logging/log_levels.py +65 -0
- jiuwen_memory/common/logging/loguru/__init__.py +8 -0
- jiuwen_memory/common/logging/loguru/config_provider.py +326 -0
- jiuwen_memory/common/logging/loguru/constant.py +68 -0
- jiuwen_memory/common/logging/loguru/loguru_impl.py +501 -0
- jiuwen_memory/common/logging/manager.py +214 -0
- jiuwen_memory/common/logging/protocol.py +75 -0
- jiuwen_memory/common/logging/utils.py +127 -0
- jiuwen_memory/common/schema/__init__.py +8 -0
- jiuwen_memory/common/schema/card.py +25 -0
- jiuwen_memory/common/schema/param.py +248 -0
- jiuwen_memory/common/security/__init__.py +0 -0
- jiuwen_memory/common/security/crypt_utils.py +114 -0
- jiuwen_memory/common/security/path_checker.py +68 -0
- jiuwen_memory/common/security/ssl_utils.py +128 -0
- jiuwen_memory/common/security/url_utils.py +148 -0
- jiuwen_memory/common/security/user_config.py +105 -0
- jiuwen_memory/common/utils/__init__.py +0 -0
- jiuwen_memory/common/utils/header_utils.py +32 -0
- jiuwen_memory/common/utils/schema_utils.py +526 -0
- jiuwen_memory/common/utils/singleton.py +16 -0
- jiuwen_memory/foundation/llm/__init__.py +93 -0
- jiuwen_memory/foundation/llm/headers_helper.py +46 -0
- jiuwen_memory/foundation/llm/model.py +368 -0
- jiuwen_memory/foundation/llm/model_clients/__init__.py +81 -0
- jiuwen_memory/foundation/llm/model_clients/base_model_client.py +518 -0
- jiuwen_memory/foundation/llm/model_clients/dashscope_model_client.py +579 -0
- jiuwen_memory/foundation/llm/model_clients/deepseek_model_client.py +83 -0
- jiuwen_memory/foundation/llm/model_clients/inference_affinity_model_client.py +846 -0
- jiuwen_memory/foundation/llm/model_clients/intelli_router_model_client.py +482 -0
- jiuwen_memory/foundation/llm/model_clients/openai_model_client.py +714 -0
- jiuwen_memory/foundation/llm/model_clients/openrouter_model_client.py +46 -0
- jiuwen_memory/foundation/llm/model_clients/siliconflow_model_client.py +662 -0
- jiuwen_memory/foundation/llm/output_parsers/__init__.py +11 -0
- jiuwen_memory/foundation/llm/output_parsers/json_output_parser.py +239 -0
- jiuwen_memory/foundation/llm/output_parsers/markdown_output_parser.py +481 -0
- jiuwen_memory/foundation/llm/output_parsers/output_parser.py +33 -0
- jiuwen_memory/foundation/llm/schema/__init__.py +20 -0
- jiuwen_memory/foundation/llm/schema/config.py +87 -0
- jiuwen_memory/foundation/llm/schema/generation_response.py +45 -0
- jiuwen_memory/foundation/llm/schema/message.py +126 -0
- jiuwen_memory/foundation/llm/schema/message_chunk.py +274 -0
- jiuwen_memory/foundation/llm/schema/mode_info.py +33 -0
- jiuwen_memory/foundation/llm/schema/tool_call.py +22 -0
- jiuwen_memory/foundation/prompt/__init__.py +13 -0
- jiuwen_memory/foundation/prompt/assemble/__init__.py +0 -0
- jiuwen_memory/foundation/prompt/assemble/assembler.py +149 -0
- jiuwen_memory/foundation/prompt/assemble/variables/__init__.py +0 -0
- jiuwen_memory/foundation/prompt/assemble/variables/dictable.py +100 -0
- jiuwen_memory/foundation/prompt/assemble/variables/textable.py +74 -0
- jiuwen_memory/foundation/prompt/assemble/variables/variable.py +37 -0
- jiuwen_memory/foundation/prompt/template.py +80 -0
- jiuwen_memory/foundation/store/__init__.py +210 -0
- jiuwen_memory/foundation/store/base_db_store.py +28 -0
- jiuwen_memory/foundation/store/base_embedding.py +45 -0
- jiuwen_memory/foundation/store/base_kv_store.py +214 -0
- jiuwen_memory/foundation/store/base_memory_index.py +273 -0
- jiuwen_memory/foundation/store/base_message_store.py +172 -0
- jiuwen_memory/foundation/store/base_reranker.py +71 -0
- jiuwen_memory/foundation/store/base_vector_store.py +601 -0
- jiuwen_memory/foundation/store/db/__init__.py +0 -0
- jiuwen_memory/foundation/store/db/default_db_store.py +13 -0
- jiuwen_memory/foundation/store/db/gauss_db_store.py +30 -0
- jiuwen_memory/foundation/store/db/gauss_dialect.py +117 -0
- jiuwen_memory/foundation/store/graph/__init__.py +31 -0
- jiuwen_memory/foundation/store/graph/base.py +95 -0
- jiuwen_memory/foundation/store/graph/base_graph_store.py +202 -0
- jiuwen_memory/foundation/store/graph/config.py +80 -0
- jiuwen_memory/foundation/store/graph/constants.py +19 -0
- jiuwen_memory/foundation/store/graph/database_config.py +52 -0
- jiuwen_memory/foundation/store/graph/graph_object.py +134 -0
- jiuwen_memory/foundation/store/graph/index_field.py +480 -0
- jiuwen_memory/foundation/store/graph/milvus/__init__.py +35 -0
- jiuwen_memory/foundation/store/graph/milvus/generate_milvus_schema.py +156 -0
- jiuwen_memory/foundation/store/graph/milvus/milvus_support.py +696 -0
- jiuwen_memory/foundation/store/graph/result_ranking.py +107 -0
- jiuwen_memory/foundation/store/graph/utils.py +242 -0
- jiuwen_memory/foundation/store/index/simple_memory_index.py +488 -0
- jiuwen_memory/foundation/store/kv/__init__.py +8 -0
- jiuwen_memory/foundation/store/kv/db_based_kv_store.py +348 -0
- jiuwen_memory/foundation/store/kv/in_memory_kv_store.py +161 -0
- jiuwen_memory/foundation/store/kv/shelve_store.py +235 -0
- jiuwen_memory/foundation/store/query/__init__.py +72 -0
- jiuwen_memory/foundation/store/query/base.py +270 -0
- jiuwen_memory/foundation/store/query/chroma_query_func.py +198 -0
- jiuwen_memory/foundation/store/query/milvus_query_func.py +131 -0
- jiuwen_memory/foundation/store/query/registry.py +21 -0
- jiuwen_memory/foundation/store/vector/__init__.py +0 -0
- jiuwen_memory/foundation/store/vector/chroma_vector_store.py +798 -0
- jiuwen_memory/foundation/store/vector/es_vector_store.py +614 -0
- jiuwen_memory/foundation/store/vector/gauss_vector_store.py +832 -0
- jiuwen_memory/foundation/store/vector/milvus_vector_store.py +1067 -0
- jiuwen_memory/foundation/store/vector/utils.py +369 -0
- jiuwen_memory/foundation/tool/__init__.py +3 -0
- jiuwen_memory/foundation/tool/schema.py +14 -0
- jiuwen_memory/memory_core/__init__.py +18 -0
- jiuwen_memory/memory_core/codec/__init__.py +0 -0
- jiuwen_memory/memory_core/codec/aes_storage_codec.py +57 -0
- jiuwen_memory/memory_core/common/__init__.py +1 -0
- jiuwen_memory/memory_core/common/base.py +24 -0
- jiuwen_memory/memory_core/common/distributed_lock.py +45 -0
- jiuwen_memory/memory_core/common/kv_prefix_registry.py +86 -0
- jiuwen_memory/memory_core/config/__init__.py +8 -0
- jiuwen_memory/memory_core/config/config.py +74 -0
- jiuwen_memory/memory_core/config/graph.py +94 -0
- jiuwen_memory/memory_core/external/__init__.py +15 -0
- jiuwen_memory/memory_core/external/agentarts_memory_provider.py +321 -0
- jiuwen_memory/memory_core/external/mem0_provider.py +303 -0
- jiuwen_memory/memory_core/external/openjiuwen_memory_provider.py +351 -0
- jiuwen_memory/memory_core/external/provider.py +53 -0
- jiuwen_memory/memory_core/graph/__init__.py +11 -0
- jiuwen_memory/memory_core/graph/extraction/__init__.py +7 -0
- jiuwen_memory/memory_core/graph/extraction/base.py +113 -0
- jiuwen_memory/memory_core/graph/extraction/custom_types.py +11 -0
- jiuwen_memory/memory_core/graph/extraction/entity_type_definition.py +56 -0
- jiuwen_memory/memory_core/graph/extraction/extraction_models.py +108 -0
- jiuwen_memory/memory_core/graph/extraction/extraction_prompts.py +290 -0
- jiuwen_memory/memory_core/graph/extraction/parse_response.py +93 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/__init__.py +10 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/__init__.py +7 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_check_missing_cn.pr.md +12 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_conversation_cn.pr.md +37 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_dedupe_entity_cn.pr.md +23 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_dedupe_relation_cn.pr.md +33 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_document_cn.pr.md +38 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_entity_merge_cn.pr.md +40 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_json_cn.pr.md +30 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_relation_cn.pr.md +49 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_relation_filter_cn.pr.md +26 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_summary_create_cn.pr.md +39 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/entity_extraction_timezone_cn.pr.md +14 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/cn/prompts.yaml +32 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/__init__.py +7 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_check_missing_en.pr.md +12 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_conversation_en.pr.md +37 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_dedupe_entity_en.pr.md +23 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_dedupe_relation_en.pr.md +35 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_document_en.pr.md +38 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_entity_merge_en.pr.md +40 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_json_en.pr.md +30 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_relation_en.pr.md +49 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_relation_filter_en.pr.md +26 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_summary_create_en.pr.md +39 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/entity_extraction_timezone_en.pr.md +14 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/en/prompts.yaml +32 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/entity_extraction/__init__.py +15 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/entity_extraction/base.py +142 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/entity_extraction/cn.py +91 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/entity_extraction/en.py +96 -0
- jiuwen_memory/memory_core/graph/extraction/prompts/manager.py +109 -0
- jiuwen_memory/memory_core/graph/graph_memory/__init__.py +0 -0
- jiuwen_memory/memory_core/graph/graph_memory/base.py +1139 -0
- jiuwen_memory/memory_core/graph/graph_memory/local_storage/__init__.py +10 -0
- jiuwen_memory/memory_core/graph/graph_memory/parse_llm_response.py +282 -0
- jiuwen_memory/memory_core/graph/graph_memory/postprocess_graph_objects.py +190 -0
- jiuwen_memory/memory_core/graph/graph_memory/states.py +338 -0
- jiuwen_memory/memory_core/graph/graph_memory/utils.py +86 -0
- jiuwen_memory/memory_core/graph/graph_memory/validate_input.py +82 -0
- jiuwen_memory/memory_core/long_term_memory.py +2339 -0
- jiuwen_memory/memory_core/manage/__init__.py +0 -0
- jiuwen_memory/memory_core/manage/index/__init__.py +0 -0
- jiuwen_memory/memory_core/manage/index/base_memory_manager.py +155 -0
- jiuwen_memory/memory_core/manage/index/fragment_memory_manager.py +449 -0
- jiuwen_memory/memory_core/manage/index/middle_mem_manager.py +199 -0
- jiuwen_memory/memory_core/manage/index/summary_manager.py +230 -0
- jiuwen_memory/memory_core/manage/index/variable_manager.py +246 -0
- jiuwen_memory/memory_core/manage/index/write_manager.py +94 -0
- jiuwen_memory/memory_core/manage/mem_model/__init__.py +0 -0
- jiuwen_memory/memory_core/manage/mem_model/data_id_manager.py +17 -0
- jiuwen_memory/memory_core/manage/mem_model/db_model.py +110 -0
- jiuwen_memory/memory_core/manage/mem_model/memory_unit.py +66 -0
- jiuwen_memory/memory_core/manage/mem_model/message_manager.py +105 -0
- jiuwen_memory/memory_core/manage/mem_model/scope_user_mapping_manager.py +41 -0
- jiuwen_memory/memory_core/manage/mem_model/semantic_store.py +310 -0
- jiuwen_memory/memory_core/manage/mem_model/sql_db_store.py +226 -0
- jiuwen_memory/memory_core/manage/mem_model/sql_message_store.py +306 -0
- jiuwen_memory/memory_core/manage/mem_model/user_mem_store.py +260 -0
- jiuwen_memory/memory_core/manage/search/__init__.py +0 -0
- jiuwen_memory/memory_core/manage/search/search_manager.py +232 -0
- jiuwen_memory/memory_core/manage/update/__init__.py +0 -0
- jiuwen_memory/memory_core/manage/update/mem_update_checker.py +297 -0
- jiuwen_memory/memory_core/migration/__init__.py +0 -0
- jiuwen_memory/memory_core/migration/migration_plan.py +136 -0
- jiuwen_memory/memory_core/migration/migrator/__init__.py +0 -0
- jiuwen_memory/memory_core/migration/migrator/index_version_migrator.py +209 -0
- jiuwen_memory/memory_core/migration/migrator/kv_migrator.py +291 -0
- jiuwen_memory/memory_core/migration/migrator/memory_meta_manager.py +43 -0
- jiuwen_memory/memory_core/migration/migrator/message_migrator.py +233 -0
- jiuwen_memory/memory_core/migration/migrator/sql_migrator.py +338 -0
- jiuwen_memory/memory_core/migration/migrator/vector_migrator.py +98 -0
- jiuwen_memory/memory_core/migration/operation/__init__.py +0 -0
- jiuwen_memory/memory_core/migration/operation/base_operation.py +35 -0
- jiuwen_memory/memory_core/migration/operation/operation_registry.py +152 -0
- jiuwen_memory/memory_core/migration/operation/operations.py +206 -0
- jiuwen_memory/memory_core/migration/run_migrations.py +162 -0
- jiuwen_memory/memory_core/process/__init__.py +0 -0
- jiuwen_memory/memory_core/process/dreaming/__init__.py +27 -0
- jiuwen_memory/memory_core/process/dreaming/orchestrator.py +100 -0
- jiuwen_memory/memory_core/process/dreaming/source.py +108 -0
- jiuwen_memory/memory_core/process/dreaming/store.py +127 -0
- jiuwen_memory/memory_core/process/dreaming/sweeper.py +159 -0
- jiuwen_memory/memory_core/process/extract/__init__.py +0 -0
- jiuwen_memory/memory_core/process/extract/common.py +25 -0
- jiuwen_memory/memory_core/process/extract/generation.py +447 -0
- jiuwen_memory/memory_core/process/extract/long_term_memory_extractor.py +122 -0
- jiuwen_memory/memory_core/process/extract/memory_analyzer.py +139 -0
- jiuwen_memory/memory_core/process/refine/__init__.py +0 -0
- jiuwen_memory/memory_core/prompts/__init__.py +0 -0
- jiuwen_memory/memory_core/prompts/continuity_check_system_prompt.md +16 -0
- jiuwen_memory/memory_core/prompts/dreaming_extraction.md +23 -0
- jiuwen_memory/memory_core/prompts/fragment_memory_prompt.md +109 -0
- jiuwen_memory/memory_core/prompts/memory_analysis_prompt.md +61 -0
- jiuwen_memory/memory_core/prompts/memory_update_check.md +53 -0
- jiuwen_memory/memory_core/prompts/prompt_applier.py +131 -0
- jiuwen_memory/memory_core/prompts/semantic_validation.md +43 -0
- jiuwen_memory/retrieval/__init__.py +0 -0
- jiuwen_memory/retrieval/common/__init__.py +0 -0
- jiuwen_memory/retrieval/common/callbacks.py +61 -0
- jiuwen_memory/retrieval/common/config.py +81 -0
- jiuwen_memory/retrieval/embedding/__init__.py +0 -0
- jiuwen_memory/retrieval/embedding/api_embedding.py +358 -0
- jiuwen_memory/retrieval/embedding/base.py +11 -0
- jiuwen_memory/server/__init__.py +0 -0
- jiuwen_memory/server/memory_server.py +459 -0
- jiuwen_memory/server/store_factory.py +144 -0
- jiuwenmemory-0.1.0.dist-info/METADATA +545 -0
- jiuwenmemory-0.1.0.dist-info/RECORD +247 -0
- jiuwenmemory-0.1.0.dist-info/WHEEL +5 -0
- jiuwenmemory-0.1.0.dist-info/entry_points.txt +2 -0
- jiuwenmemory-0.1.0.dist-info/licenses/LICENSE +202 -0
- jiuwenmemory-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
|
|
3
|
+
|
|
4
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
# Wheel installation should include package metadata
|
|
8
|
+
__version__ = version("JiuwenMemory")
|
|
9
|
+
except PackageNotFoundError:
|
|
10
|
+
# Only developer working with source code directly may not have package metadata
|
|
11
|
+
import tomllib
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
__version__ = "unknown"
|
|
15
|
+
pyproject = Path(__file__).parents[1] / "pyproject.toml"
|
|
16
|
+
if pyproject.exists():
|
|
17
|
+
project_metadata = tomllib.loads(pyproject.read_text(encoding="utf-8")).get("project", {})
|
|
18
|
+
package_name = project_metadata.get("name")
|
|
19
|
+
version_parsed = project_metadata.get("version")
|
|
20
|
+
if package_name == "JiuwenMemory" and version_parsed:
|
|
21
|
+
__version__ = version_parsed
|
|
22
|
+
|
|
23
|
+
__all__ = ["__version__"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
|
|
3
|
+
from jiuwen_memory.common.schema import Param
|
|
4
|
+
from jiuwen_memory.common.schema.card import BaseCard
|
|
5
|
+
|
|
6
|
+
_SCHEMA_CLASSES = [
|
|
7
|
+
"BaseCard",
|
|
8
|
+
"Param"
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
_SCHEMA_CLASSES
|
|
13
|
+
)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
3
|
+
from typing import Dict, List, Optional, Any, Callable, Type
|
|
4
|
+
from jiuwen_memory.common.logging import logger
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ClientRegistry:
|
|
8
|
+
"""Registry for managing client classes and factories.
|
|
9
|
+
|
|
10
|
+
This class provides a central registry for client classes, their factories.
|
|
11
|
+
It supports both decorator-based and class-based registration.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
"""Initialize an empty registry."""
|
|
16
|
+
self._factories: Dict[str, Callable] = {}
|
|
17
|
+
self._client_classes: Dict[str, Type] = {}
|
|
18
|
+
|
|
19
|
+
def register_client(self, name: str, client_type: Optional[str] = "common"):
|
|
20
|
+
"""Decorator to register client factory functions.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
name: Primary name of the client.
|
|
24
|
+
client_type: Type category of the client (e.g., 'database', 'cache').
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Decorator function that registers the factory.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
ValueError: If the client name is already registered.
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
@registry.register_client('redis', client_type='cache')
|
|
35
|
+
def create_redis_client(**kwargs):
|
|
36
|
+
return RedisClient(**kwargs)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def decorator(factory_func: Callable) -> Callable:
|
|
40
|
+
full_name = f'{client_type}_{name}' if client_type else name
|
|
41
|
+
|
|
42
|
+
if full_name in self._factories:
|
|
43
|
+
raise ValueError(f"Client type '{full_name}' already registered")
|
|
44
|
+
|
|
45
|
+
self._factories[full_name] = factory_func
|
|
46
|
+
return factory_func
|
|
47
|
+
|
|
48
|
+
return decorator
|
|
49
|
+
|
|
50
|
+
def register_class(self, client_class: Type['BaseClient']) -> None:
|
|
51
|
+
"""Register a client class.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
client_class: The client class to register. Must have __client_name__
|
|
55
|
+
and __client_type__ attributes.
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ValueError: If the class doesn't define required attributes or if
|
|
59
|
+
the client name is already registered.
|
|
60
|
+
|
|
61
|
+
Example:
|
|
62
|
+
class MySQLClient(BaseClient):
|
|
63
|
+
__client_name__ = 'mysql'
|
|
64
|
+
__client_type__ = 'database'
|
|
65
|
+
"""
|
|
66
|
+
if not hasattr(client_class, '__client_name__'):
|
|
67
|
+
raise ValueError(f"Client class {client_class.__name__} must define __client_name__")
|
|
68
|
+
|
|
69
|
+
if not hasattr(client_class, '__client_type__'):
|
|
70
|
+
raise ValueError(f"Client class {client_class.__name__} must define __client_type__")
|
|
71
|
+
|
|
72
|
+
names = client_class.__client_name__ if isinstance(client_class.__client_name__, list) else [
|
|
73
|
+
client_class.__client_name__]
|
|
74
|
+
client_type = client_class.__client_type__
|
|
75
|
+
|
|
76
|
+
if not client_type:
|
|
77
|
+
raise ValueError(f"Client class {client_class.__name__} __client_type__ cannot be empty, register failed")
|
|
78
|
+
for name in names:
|
|
79
|
+
full_name = f'{client_type}_{name}'
|
|
80
|
+
|
|
81
|
+
if full_name in self._factories or full_name in self._client_classes:
|
|
82
|
+
logger.warning(f"Client type '{full_name}' already registered")
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
# Store the client class
|
|
86
|
+
self._client_classes[full_name] = client_class
|
|
87
|
+
|
|
88
|
+
# Create factory function
|
|
89
|
+
def factory(**kwargs):
|
|
90
|
+
return client_class(**kwargs)
|
|
91
|
+
|
|
92
|
+
self._factories[full_name] = factory
|
|
93
|
+
|
|
94
|
+
def get_client(self, name: str, client_type: Optional[str] = "common", **kwargs) -> Any:
|
|
95
|
+
"""Get a client instance.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
name: Name of the client.
|
|
99
|
+
client_type: Optional type category to narrow down the search.
|
|
100
|
+
**kwargs: Additional arguments to pass to the client constructor.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
An instance of the requested client.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
ValueError: If the client name is empty or unknown.
|
|
107
|
+
RuntimeError: If client creation fails.
|
|
108
|
+
|
|
109
|
+
Example:
|
|
110
|
+
client = registry.get_client('mysql', client_type='database', host='localhost')
|
|
111
|
+
"""
|
|
112
|
+
if not name:
|
|
113
|
+
raise ValueError("Client name cannot be empty")
|
|
114
|
+
|
|
115
|
+
lookup_name = name
|
|
116
|
+
if client_type:
|
|
117
|
+
full_name = f'{client_type}_{name}'
|
|
118
|
+
if full_name in self._factories:
|
|
119
|
+
lookup_name = full_name
|
|
120
|
+
|
|
121
|
+
factory = self._factories.get(lookup_name)
|
|
122
|
+
if not factory:
|
|
123
|
+
available = list(self._factories.keys())
|
|
124
|
+
search_key = f'{client_type}_{name}' if client_type else name
|
|
125
|
+
raise ValueError(f"Unknown client type: '{search_key}'. Available: {available}")
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
return factory(**kwargs)
|
|
129
|
+
except Exception as e:
|
|
130
|
+
raise RuntimeError(f"Failed to create client '{lookup_name}': {e}") from e
|
|
131
|
+
|
|
132
|
+
def unregister(self, name: str, client_type: Optional[str] = None) -> None:
|
|
133
|
+
"""Unregister a client.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
name: Name of the client to unregister.
|
|
137
|
+
client_type: Optional type category of the client.
|
|
138
|
+
|
|
139
|
+
Raises:
|
|
140
|
+
ValueError: If the client is not registered.
|
|
141
|
+
"""
|
|
142
|
+
full_name = f'{client_type}_{name}' if client_type else name
|
|
143
|
+
|
|
144
|
+
if full_name not in self._factories:
|
|
145
|
+
raise ValueError(f"Client type '{full_name}' not registered")
|
|
146
|
+
|
|
147
|
+
del self._factories[full_name]
|
|
148
|
+
self._client_classes.pop(full_name, None)
|
|
149
|
+
|
|
150
|
+
def list_clients(self) -> List[str]:
|
|
151
|
+
"""List all registered clients.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List of registered client full names.
|
|
155
|
+
"""
|
|
156
|
+
return list(self._factories.keys())
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
_client_registry = ClientRegistry()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def get_client_registry():
|
|
163
|
+
return _client_registry
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class BaseClient:
|
|
167
|
+
"""Abstract base class for asynchronous clients.
|
|
168
|
+
|
|
169
|
+
This class serves as a template for creating client classes. Subclasses
|
|
170
|
+
must define __client_name__ and __client_type__ class attributes, and
|
|
171
|
+
implement all abstract methods.
|
|
172
|
+
|
|
173
|
+
Attributes:
|
|
174
|
+
__client_name__: Primary name of the client type.
|
|
175
|
+
__client_type__: Type category (e.g., 'database', 'cache', 'api').
|
|
176
|
+
config: Configuration dictionary passed during initialization.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
__client_name__: str = None
|
|
180
|
+
__client_type__: str = "common"
|
|
181
|
+
|
|
182
|
+
def __init_subclass__(cls, **kwargs):
|
|
183
|
+
"""Initialize subclass and register it if it's a client class.
|
|
184
|
+
|
|
185
|
+
This method is called whenever a class inherits from BaseClient.
|
|
186
|
+
It automatically registers any class that defines __client_name__
|
|
187
|
+
and __client_type__ attributes with the global client registry.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
**kwargs: Additional keyword arguments passed to the subclass.
|
|
191
|
+
"""
|
|
192
|
+
super().__init_subclass__(**kwargs)
|
|
193
|
+
|
|
194
|
+
# Skip registration for BaseClient itself (though this method won't be called for BaseClient)
|
|
195
|
+
# Check if client name and type are defined
|
|
196
|
+
if hasattr(cls, '__client_name__') and hasattr(cls, '__client_type__'):
|
|
197
|
+
# Automatically register with the global registry
|
|
198
|
+
if cls.__client_name__ is not None: # Ensure it's actually set
|
|
199
|
+
get_client_registry().register_class(cls)
|
|
200
|
+
|
|
201
|
+
def __init__(self, **kwargs):
|
|
202
|
+
"""Initialize the client with configuration.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
**kwargs: Configuration parameters for the client.
|
|
206
|
+
"""
|
|
207
|
+
self.config = kwargs
|
|
208
|
+
|
|
209
|
+
async def close(self) -> bool:
|
|
210
|
+
"""Asynchronously close connection to the service.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
True if disconnection successful, False otherwise.
|
|
214
|
+
"""
|
|
215
|
+
pass
|
|
216
|
+
|
|
217
|
+
async def __aenter__(self):
|
|
218
|
+
"""Async context manager entry point.
|
|
219
|
+
|
|
220
|
+
Automatically connects when entering the context.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
The client instance.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
return self
|
|
227
|
+
|
|
228
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
229
|
+
"""Async context manager exit point.
|
|
230
|
+
|
|
231
|
+
Automatically disconnects when exiting the context.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
exc_type: Exception type if an exception was raised.
|
|
235
|
+
exc_val: Exception value if an exception was raised.
|
|
236
|
+
exc_tb: Exception traceback if an exception was raised.
|
|
237
|
+
"""
|
|
238
|
+
await self.close()
|
|
File without changes
|