Skip to content

Commit d52265f

Browse files
committed
feat: simply code
1 parent d900b22 commit d52265f

27 files changed

+140
-435
lines changed

.env

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Elasticsearch connection settings
2-
ELASTICSEARCH_HOST=https://localhost:9200
2+
ELASTICSEARCH_HOSTS=https://localhost:9200
33
ELASTICSEARCH_USERNAME=elastic
44
ELASTICSEARCH_PASSWORD=test123
55

66
# OpenSearch connection settings
7-
OPENSEARCH_HOST=https://localhost:9200
7+
OPENSEARCH_HOSTS=https://localhost:9200
88
OPENSEARCH_USERNAME=elastic
99
OPENSEARCH_PASSWORD=test123

src/clients/__init__.py

+31-19
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,45 @@
1-
from typing import Dict
2-
from .elasticsearch.client import ElasticsearchClient
3-
from .opensearch.client import OpenSearchClient
4-
from .interfaces import SearchClient
1+
# Python 内置包
2+
import os
53

6-
def create_search_client(config: Dict, engine_type: str) -> SearchClient:
4+
# 第三方包
5+
from dotenv import load_dotenv
6+
7+
# 本项目包
8+
from src.clients.common.client import SearchClient
9+
from src.clients.exceptions import handle_search_exceptions
10+
11+
def create_search_client(engine_type: str) -> SearchClient:
712
"""
8-
Factory function to create the appropriate search client.
13+
Create a search client for the specified engine type.
914
1015
Args:
11-
config: Configuration dictionary with connection parameters
1216
engine_type: Type of search engine to use ("elasticsearch" or "opensearch")
1317
1418
Returns:
15-
SearchClient: An instance of the appropriate search client
16-
17-
Raises:
18-
ValueError: If an invalid engine type is specified
19+
A search client instance
1920
"""
20-
if engine_type.lower() == "elasticsearch":
21-
return ElasticsearchClient(config)
22-
elif engine_type.lower() == "opensearch":
23-
return OpenSearchClient(config)
24-
else:
25-
raise ValueError(f"Invalid engine type: {engine_type}. Must be 'elasticsearch' or 'opensearch'")
21+
# Load configuration from environment variables
22+
load_dotenv()
23+
24+
# Get configuration from environment variables
25+
prefix = engine_type.upper()
26+
hosts_str = os.environ.get(f"{prefix}_HOSTS", "https://localhost:9200")
27+
hosts = [host.strip() for host in hosts_str.split(",")]
28+
username = os.environ.get(f"{prefix}_USERNAME")
29+
password = os.environ.get(f"{prefix}_PASSWORD")
30+
verify_certs = os.environ.get(f"{prefix}_VERIFY_CERTS", "false").lower() == "true"
31+
32+
config = {
33+
"hosts": hosts,
34+
"username": username,
35+
"password": password,
36+
"verify_certs": verify_certs
37+
}
38+
39+
return SearchClient(config, engine_type)
2640

2741
__all__ = [
2842
'create_search_client',
2943
'handle_search_exceptions',
3044
'SearchClient',
31-
'ElasticsearchClient',
32-
'OpenSearchClient',
3345
]

src/clients/base.py

+44-14
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,54 @@
1-
"""
2-
Base classes and interfaces for search clients.
3-
"""
4-
from abc import ABC, abstractmethod
1+
from abc import ABC
52
import logging
3+
import warnings
64
from typing import Dict
75

86
class SearchClientBase(ABC):
9-
"""Base abstract class for search clients with common functionality."""
10-
11-
def __init__(self, config: Dict):
7+
def __init__(self, config: Dict, engine_type: str):
128
"""
13-
Initialize the base search client.
9+
Initialize the search client.
1410
1511
Args:
1612
config: Configuration dictionary with connection parameters
13+
engine_type: Type of search engine to use ("elasticsearch" or "opensearch")
1714
"""
18-
self.logger = logging.getLogger(self.__class__.__name__)
15+
self.logger = logging.getLogger()
1916
self.config = config
20-
21-
@abstractmethod
22-
def close(self):
23-
"""Close the client connection."""
24-
pass
17+
self.engine_type = engine_type
18+
19+
# Extract common configuration
20+
hosts = config.get("hosts")
21+
username = config.get("username")
22+
password = config.get("password")
23+
verify_certs = config.get("verify_certs", False)
24+
25+
# Disable insecure request warnings if verify_certs is False
26+
if not verify_certs:
27+
warnings.filterwarnings("ignore", message=".*TLS with verify_certs=False is insecure.*")
28+
warnings.filterwarnings("ignore", message=".*Unverified HTTPS request is being made to host.*")
29+
30+
try:
31+
import urllib3
32+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
33+
except ImportError:
34+
pass
35+
36+
# Initialize client based on engine type
37+
if engine_type == "elasticsearch":
38+
from elasticsearch import Elasticsearch
39+
self.client = Elasticsearch(
40+
hosts=hosts,
41+
basic_auth=(username, password) if username and password else None,
42+
verify_certs=verify_certs
43+
)
44+
self.logger.info(f"Elasticsearch client initialized with hosts: {hosts}")
45+
elif engine_type == "opensearch":
46+
from opensearchpy import OpenSearch
47+
self.client = OpenSearch(
48+
hosts=hosts,
49+
http_auth=(username, password) if username and password else None,
50+
verify_certs=verify_certs
51+
)
52+
self.logger.info(f"OpenSearch client initialized with hosts: {hosts}")
53+
else:
54+
raise ValueError(f"Unsupported engine type: {engine_type}")

src/clients/common/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .index import IndexClient
2+
from .document import DocumentClient
3+
from .cluster import ClusterClient
4+
from .alias import AliasClient
5+
6+
__all__ = ['IndexClient', 'DocumentClient', 'ClusterClient', 'AliasClient']

src/clients/opensearch/alias.py src/clients/common/alias.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Dict
2-
from .base import BaseOpenSearchClient
3-
from ..interfaces.alias import AliasClientInterface
42

5-
class OpenSearchAliasClient(BaseOpenSearchClient, AliasClientInterface):
3+
from src.clients.base import SearchClientBase
4+
5+
class AliasClient(SearchClientBase):
66
def list_aliases(self) -> Dict:
77
"""Get all aliases."""
88
return self.client.cat.aliases()

src/clients/common/client.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Dict
2+
3+
from src.clients.common.alias import AliasClient
4+
from src.clients.common.cluster import ClusterClient
5+
from src.clients.common.document import DocumentClient
6+
from src.clients.common.index import IndexClient
7+
8+
class SearchClient(IndexClient, DocumentClient, ClusterClient, AliasClient):
9+
"""
10+
Unified search client that combines all search functionality.
11+
12+
This class uses multiple inheritance to combine all specialized client implementations
13+
(index, document, cluster, alias) into a single unified client.
14+
"""
15+
16+
def __init__(self, config: Dict, engine_type: str):
17+
"""
18+
Initialize the search client.
19+
20+
Args:
21+
config: Configuration dictionary with connection parameters
22+
engine_type: Type of search engine to use ("elasticsearch" or "opensearch")
23+
"""
24+
super().__init__(config, engine_type)
25+
self.logger.info(f"Initialized the {engine_type} client")

src/clients/common/cluster.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import Dict
2+
3+
from src.clients.base import SearchClientBase
4+
5+
class ClusterClient(SearchClientBase):
6+
def get_cluster_health(self) -> Dict:
7+
"""Get cluster health information from OpenSearch."""
8+
return self.client.cluster.health()
9+
10+
def get_cluster_stats(self) -> Dict:
11+
"""Get cluster statistics from OpenSearch."""
12+
return self.client.cluster.stats()

src/clients/opensearch/document.py src/clients/common/document.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Dict, Optional
2-
from .base import BaseOpenSearchClient
3-
from ..interfaces.document import DocumentClientInterface
42

5-
class OpenSearchDocumentClient(BaseOpenSearchClient, DocumentClientInterface):
3+
from src.clients.base import SearchClientBase
4+
5+
class DocumentClient(SearchClientBase):
66
def search_documents(self, index: str, body: Dict) -> Dict:
77
"""Search for documents in the index."""
88
return self.client.search(index=index, body=body)
@@ -25,3 +25,4 @@ def delete_document(self, index: str, id: str) -> Dict:
2525
def delete_by_query(self, index: str, body: Dict) -> Dict:
2626
"""Deletes documents matching the provided query."""
2727
return self.client.delete_by_query(index=index, body=body)
28+

src/clients/opensearch/index.py src/clients/common/index.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Dict, Optional
2-
from .base import BaseOpenSearchClient
3-
from ..interfaces.index import IndexClientInterface
42

5-
class OpenSearchIndexClient(BaseOpenSearchClient, IndexClientInterface):
3+
from src.clients.base import SearchClientBase
4+
5+
class IndexClient(SearchClientBase):
66
def list_indices(self) -> Dict:
77
"""List all indices."""
88
return self.client.cat.indices()

src/clients/elasticsearch/__init__.py

-3
This file was deleted.

src/clients/elasticsearch/alias.py

-20
This file was deleted.

src/clients/elasticsearch/base.py

-40
This file was deleted.

src/clients/elasticsearch/client.py

-28
This file was deleted.

src/clients/elasticsearch/cluster.py

-12
This file was deleted.

src/clients/elasticsearch/document.py

-27
This file was deleted.

src/clients/elasticsearch/index.py

-20
This file was deleted.

0 commit comments

Comments
 (0)