sedb 0.1.1__tar.gz
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.
- sedb-0.1.1/PKG-INFO +56 -0
- sedb-0.1.1/README.md +39 -0
- sedb-0.1.1/pyproject.toml +20 -0
- sedb-0.1.1/setup.cfg +4 -0
- sedb-0.1.1/src/sedb/__init__.py +2 -0
- sedb-0.1.1/src/sedb/elastic.py +54 -0
- sedb-0.1.1/src/sedb/mongo.py +123 -0
- sedb-0.1.1/src/sedb.egg-info/PKG-INFO +56 -0
- sedb-0.1.1/src/sedb.egg-info/SOURCES.txt +10 -0
- sedb-0.1.1/src/sedb.egg-info/dependency_links.txt +1 -0
- sedb-0.1.1/src/sedb.egg-info/requires.txt +3 -0
- sedb-0.1.1/src/sedb.egg-info/top_level.txt +1 -0
sedb-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: sedb
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Search Engine DataBase utils
|
|
5
|
+
Author: Hansimov
|
|
6
|
+
Project-URL: Homepage, https://github.com/Hansimov/tclogger
|
|
7
|
+
Project-URL: Issues, https://github.com/Hansimov/tclogger/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/Hansimov/tclogger/blob/main/CHANGELOG.md
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.6
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: tclogger
|
|
15
|
+
Requires-Dist: pymongo
|
|
16
|
+
Requires-Dist: elasticsearch
|
|
17
|
+
|
|
18
|
+
# sedb
|
|
19
|
+
Search Engine DataBase utils
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
```sh
|
|
25
|
+
pip install sedb --upgrade
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Run example:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
python example.py
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
See: [example.py](./example.py)
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import sys
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
|
43
|
+
|
|
44
|
+
import bldb
|
|
45
|
+
|
|
46
|
+
from bldb import MongoOperator, MongoConfigsType
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
mongo_configs = {
|
|
51
|
+
"host": "localhost",
|
|
52
|
+
"port": 27017,
|
|
53
|
+
"dbname": "test",
|
|
54
|
+
}
|
|
55
|
+
mongo = MongoOperator(configs=mongo_configs)
|
|
56
|
+
```
|
sedb-0.1.1/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# sedb
|
|
2
|
+
Search Engine DataBase utils
|
|
3
|
+
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
```sh
|
|
8
|
+
pip install sedb --upgrade
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Run example:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
python example.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
See: [example.py](./example.py)
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
import sys
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
|
26
|
+
|
|
27
|
+
import bldb
|
|
28
|
+
|
|
29
|
+
from bldb import MongoOperator, MongoConfigsType
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
mongo_configs = {
|
|
34
|
+
"host": "localhost",
|
|
35
|
+
"port": 27017,
|
|
36
|
+
"dbname": "test",
|
|
37
|
+
}
|
|
38
|
+
mongo = MongoOperator(configs=mongo_configs)
|
|
39
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sedb"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
authors = [
|
|
5
|
+
{ name="Hansimov" },
|
|
6
|
+
]
|
|
7
|
+
description = "Search Engine DataBase utils"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.6"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Operating System :: OS Independent",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [ "tclogger", "pymongo", "elasticsearch" ]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://github.com/Hansimov/tclogger"
|
|
19
|
+
Issues = "https://github.com/Hansimov/tclogger/issues"
|
|
20
|
+
Changelog = "https://github.com/Hansimov/tclogger/blob/main/CHANGELOG.md"
|
sedb-0.1.1/setup.cfg
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from elasticsearch import Elasticsearch
|
|
2
|
+
from tclogger import logger, logstr
|
|
3
|
+
from typing import TypedDict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ElasticConfigsType(TypedDict):
|
|
7
|
+
host: str
|
|
8
|
+
port: int
|
|
9
|
+
ca_certs: str
|
|
10
|
+
api_key: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ElasticOperator:
|
|
14
|
+
def __init__(self, configs: ElasticConfigsType, verbose: bool = True):
|
|
15
|
+
self.configs = configs
|
|
16
|
+
self.init_configs()
|
|
17
|
+
self.verbose = verbose
|
|
18
|
+
|
|
19
|
+
def init_configs(self):
|
|
20
|
+
self.host = self.configs["host"]
|
|
21
|
+
self.port = self.configs["port"]
|
|
22
|
+
self.ca_certs = self.configs["ca_certs"]
|
|
23
|
+
self.api_key = self.configs["api_key"]
|
|
24
|
+
self.endpoint = f"https://{self.host}:{self.port}"
|
|
25
|
+
|
|
26
|
+
def connect(self):
|
|
27
|
+
"""Connect to self-managed cluster with API Key authentication
|
|
28
|
+
* https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#auth-apikey
|
|
29
|
+
|
|
30
|
+
How to create API Key:
|
|
31
|
+
- Go to Kibana: http://<hostname>:5601/app/management/security/api_keys
|
|
32
|
+
- Create API Key, which would generated a json with keys "name", "api_key" and "encoded"
|
|
33
|
+
- Use "encoded" value for the `api_key` param in Elasticsearch class below
|
|
34
|
+
|
|
35
|
+
Connect to self-managed cluster with HTTP Bearer authentication
|
|
36
|
+
* https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#auth-bearer
|
|
37
|
+
"""
|
|
38
|
+
if self.verbose:
|
|
39
|
+
logger.note(
|
|
40
|
+
f"> Connecting to Elasticsearch: "
|
|
41
|
+
f"{logstr.mesg('['+self.endpoint+']')}"
|
|
42
|
+
)
|
|
43
|
+
try:
|
|
44
|
+
self.client = Elasticsearch(
|
|
45
|
+
hosts=self.endpoint,
|
|
46
|
+
ca_certs=self.ca_certs,
|
|
47
|
+
api_key=self.api_key,
|
|
48
|
+
# basic_auth=(self.username, self.password),
|
|
49
|
+
)
|
|
50
|
+
if self.verbose:
|
|
51
|
+
logger.success(f"+ Connected:")
|
|
52
|
+
logger.mesg(self.client.info())
|
|
53
|
+
except Exception as e:
|
|
54
|
+
raise e
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import pymongo
|
|
2
|
+
import threading
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from tclogger import logger, logstr, FileLogger
|
|
6
|
+
from tclogger import get_now_str, ts_to_str, dict_to_str
|
|
7
|
+
from typing import Literal, Union, TypedDict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MongoConfigsType(TypedDict):
|
|
11
|
+
host: str
|
|
12
|
+
port: int
|
|
13
|
+
dbname: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MongoOperator:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
configs: MongoConfigsType,
|
|
20
|
+
connect_at_init: bool = True,
|
|
21
|
+
connect_msg: str = None,
|
|
22
|
+
lock: threading.Lock = None,
|
|
23
|
+
log_path: Union[str, Path] = None,
|
|
24
|
+
verbose: bool = True,
|
|
25
|
+
):
|
|
26
|
+
self.configs = configs
|
|
27
|
+
self.verbose = verbose
|
|
28
|
+
self.init_configs()
|
|
29
|
+
self.connect_at_init = connect_at_init
|
|
30
|
+
self.connect_msg = connect_msg
|
|
31
|
+
self.lock = lock or threading.Lock()
|
|
32
|
+
if log_path:
|
|
33
|
+
self.file_logger = FileLogger(log_path)
|
|
34
|
+
else:
|
|
35
|
+
self.file_logger = None
|
|
36
|
+
if self.connect_at_init:
|
|
37
|
+
self.connect(connect_msg=connect_msg)
|
|
38
|
+
|
|
39
|
+
def init_configs(self):
|
|
40
|
+
self.host = self.configs["host"]
|
|
41
|
+
self.port = self.configs["port"]
|
|
42
|
+
self.dbname = self.configs["dbname"]
|
|
43
|
+
self.endpoint = f"mongodb://{self.host}:{self.port}"
|
|
44
|
+
|
|
45
|
+
def connect(self, connect_msg: str = None):
|
|
46
|
+
connect_msg = connect_msg or self.connect_msg
|
|
47
|
+
if self.verbose:
|
|
48
|
+
logger.note(f"> Connecting to: {logstr.mesg('['+self.endpoint+']')}")
|
|
49
|
+
logger.file(f" * {get_now_str()}")
|
|
50
|
+
if connect_msg:
|
|
51
|
+
logger.file(f" * {connect_msg}")
|
|
52
|
+
self.client = pymongo.MongoClient(self.endpoint)
|
|
53
|
+
try:
|
|
54
|
+
self.db = self.client[self.dbname]
|
|
55
|
+
if self.verbose:
|
|
56
|
+
logger.file(f" * database: {logstr.success(self.dbname)}")
|
|
57
|
+
except Exception as e:
|
|
58
|
+
raise e
|
|
59
|
+
|
|
60
|
+
def log_error(self, docs: list = None, e: Exception = None):
|
|
61
|
+
error_info = {"datetime": get_now_str(), "doc": docs, "error": repr(e)}
|
|
62
|
+
if self.verbose:
|
|
63
|
+
logger.err(f"× Mongo Error: {logstr.warn(error_info)}")
|
|
64
|
+
if self.file_logger:
|
|
65
|
+
error_str = dict_to_str(error_info, is_colored=False)
|
|
66
|
+
self.file_logger.log(error_str, "error")
|
|
67
|
+
|
|
68
|
+
def get_cursor(
|
|
69
|
+
self,
|
|
70
|
+
collection: str,
|
|
71
|
+
filter_index: str = None,
|
|
72
|
+
filter_op: Literal["gt", "lt", "gte", "lte", "range"] = "gte",
|
|
73
|
+
filter_range: Union[int, str, tuple, list] = None,
|
|
74
|
+
sort_index: str = None,
|
|
75
|
+
sort_order: Literal["asc", "desc"] = "asc",
|
|
76
|
+
verbose: bool = False,
|
|
77
|
+
):
|
|
78
|
+
if verbose:
|
|
79
|
+
args_dict = {
|
|
80
|
+
"collection": collection,
|
|
81
|
+
"filter_index": filter_index,
|
|
82
|
+
"filter_op": filter_op,
|
|
83
|
+
"filter_range": filter_range,
|
|
84
|
+
"sort_index": sort_index,
|
|
85
|
+
"sort_order": sort_order,
|
|
86
|
+
}
|
|
87
|
+
if filter_index and filter_index.lower() in ["pubdate", "insert_at"]:
|
|
88
|
+
if isinstance(filter_range, (tuple, list)):
|
|
89
|
+
filter_range_str = [ts_to_str(i) for i in filter_range]
|
|
90
|
+
elif isinstance(filter_range, int):
|
|
91
|
+
filter_range_str = ts_to_str(filter_range)
|
|
92
|
+
else:
|
|
93
|
+
filter_range_str = filter_range
|
|
94
|
+
args_dict["filter_range_str"] = filter_range_str
|
|
95
|
+
if self.verbose:
|
|
96
|
+
logger.note(f"> Getting cursor with args:")
|
|
97
|
+
logger.mesg(dict_to_str(args_dict), indent=2)
|
|
98
|
+
|
|
99
|
+
filter = {}
|
|
100
|
+
if filter_index:
|
|
101
|
+
if filter_op == "range":
|
|
102
|
+
if filter_range and isinstance(filter_range, (tuple, list)):
|
|
103
|
+
filter[filter_index] = {
|
|
104
|
+
"$gte": min(filter_range),
|
|
105
|
+
"$lte": max(filter_range),
|
|
106
|
+
}
|
|
107
|
+
else:
|
|
108
|
+
raise ValueError(f"× Invalid filter_range: {filter_range}")
|
|
109
|
+
elif filter_op in ["gt", "lt", "gte", "lte"]:
|
|
110
|
+
filter[filter_index] = {f"${filter_op}": filter_range}
|
|
111
|
+
else:
|
|
112
|
+
raise ValueError(f"× Invalid filter_op: {filter_op}")
|
|
113
|
+
|
|
114
|
+
cursor = self.db[collection].find(filter)
|
|
115
|
+
|
|
116
|
+
if sort_index:
|
|
117
|
+
if sort_order and sort_order.lower().startswith("desc"):
|
|
118
|
+
order = pymongo.DESCENDING
|
|
119
|
+
else:
|
|
120
|
+
order = pymongo.ASCENDING
|
|
121
|
+
cursor = cursor.sort(sort_index, order)
|
|
122
|
+
|
|
123
|
+
return cursor
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: sedb
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Search Engine DataBase utils
|
|
5
|
+
Author: Hansimov
|
|
6
|
+
Project-URL: Homepage, https://github.com/Hansimov/tclogger
|
|
7
|
+
Project-URL: Issues, https://github.com/Hansimov/tclogger/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/Hansimov/tclogger/blob/main/CHANGELOG.md
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.6
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: tclogger
|
|
15
|
+
Requires-Dist: pymongo
|
|
16
|
+
Requires-Dist: elasticsearch
|
|
17
|
+
|
|
18
|
+
# sedb
|
|
19
|
+
Search Engine DataBase utils
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
```sh
|
|
25
|
+
pip install sedb --upgrade
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Run example:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
python example.py
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
See: [example.py](./example.py)
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import sys
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
|
43
|
+
|
|
44
|
+
import bldb
|
|
45
|
+
|
|
46
|
+
from bldb import MongoOperator, MongoConfigsType
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
mongo_configs = {
|
|
51
|
+
"host": "localhost",
|
|
52
|
+
"port": 27017,
|
|
53
|
+
"dbname": "test",
|
|
54
|
+
}
|
|
55
|
+
mongo = MongoOperator(configs=mongo_configs)
|
|
56
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/sedb/__init__.py
|
|
4
|
+
src/sedb/elastic.py
|
|
5
|
+
src/sedb/mongo.py
|
|
6
|
+
src/sedb.egg-info/PKG-INFO
|
|
7
|
+
src/sedb.egg-info/SOURCES.txt
|
|
8
|
+
src/sedb.egg-info/dependency_links.txt
|
|
9
|
+
src/sedb.egg-info/requires.txt
|
|
10
|
+
src/sedb.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sedb
|