workercommon 0.4.2__tar.gz → 0.5.0__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.
- {workercommon-0.4.2 → workercommon-0.5.0}/PKG-INFO +4 -2
- {workercommon-0.4.2 → workercommon-0.5.0}/pyproject.toml +4 -2
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/worker.py +16 -8
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon.egg-info/PKG-INFO +4 -2
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon.egg-info/SOURCES.txt +0 -1
- workercommon-0.5.0/workercommon.egg-info/requires.txt +4 -0
- workercommon-0.4.2/workercommon/config.py +0 -81
- workercommon-0.4.2/workercommon.egg-info/requires.txt +0 -2
- {workercommon-0.4.2 → workercommon-0.5.0}/LICENSE.TXT +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/README.md +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/setup.cfg +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/__init__.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/background.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/commands.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/connectionpool.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/database/__init__.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/database/base.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/database/pg.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/database/py.typed +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/locking.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/py.typed +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/rabbitmqueue.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon/test.py +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon.egg-info/dependency_links.txt +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon.egg-info/not-zip-safe +0 -0
- {workercommon-0.4.2 → workercommon-0.5.0}/workercommon.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: workercommon
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Support code for various projects
|
|
5
5
|
Author-email: "Neil E. Hodges" <47hasbegun@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -13,8 +13,10 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
13
13
|
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE.TXT
|
|
16
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: immutables
|
|
17
17
|
Requires-Dist: pika
|
|
18
|
+
Requires-Dist: psycopg2
|
|
19
|
+
Requires-Dist: pyyaml
|
|
18
20
|
Dynamic: license-file
|
|
19
21
|
|
|
20
22
|
# Requirements
|
|
@@ -13,10 +13,12 @@ readme = "README.md"
|
|
|
13
13
|
requires-python = ">= 3.8"
|
|
14
14
|
license = "BSD-3-Clause"
|
|
15
15
|
dependencies = [
|
|
16
|
-
"
|
|
16
|
+
"immutables",
|
|
17
17
|
"pika",
|
|
18
|
+
"psycopg2",
|
|
19
|
+
"pyyaml",
|
|
18
20
|
]
|
|
19
|
-
version = "0.
|
|
21
|
+
version = "0.5.0"
|
|
20
22
|
license-files = ["LICENSE.TXT"]
|
|
21
23
|
classifiers = [
|
|
22
24
|
"Programming Language :: Python :: 3",
|
|
@@ -4,19 +4,21 @@ import sys
|
|
|
4
4
|
if sys.version_info < (3, 8):
|
|
5
5
|
raise RuntimeError("At least Python 3.8 is required")
|
|
6
6
|
|
|
7
|
-
from pathlib import Path
|
|
8
7
|
from .database import Connection, Cursor
|
|
9
8
|
from . import rabbitmqueue
|
|
10
|
-
import json,
|
|
9
|
+
import json, pika.connection, pika.channel, pika.spec, logging
|
|
11
10
|
from collections.abc import Mapping
|
|
12
|
-
from time import sleep
|
|
13
11
|
from threading import Thread, Lock
|
|
14
12
|
from typing import Iterable, Optional, Any, Callable, List
|
|
15
|
-
from multiprocessing import Process
|
|
13
|
+
from multiprocessing import Process
|
|
16
14
|
from multiprocessing.managers import SyncManager
|
|
17
15
|
from concurrent.futures import ThreadPoolExecutor
|
|
18
16
|
|
|
19
17
|
|
|
18
|
+
class NoDatabase(RuntimeError):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
20
22
|
class BaseWorker(object):
|
|
21
23
|
def start(self) -> None:
|
|
22
24
|
raise NotImplementedError
|
|
@@ -43,7 +45,7 @@ class ThreadWorker(BaseWorker, Thread):
|
|
|
43
45
|
class ReaderWorker(ThreadWorker):
|
|
44
46
|
def __init__(
|
|
45
47
|
self,
|
|
46
|
-
database_source: Callable[[], Connection],
|
|
48
|
+
database_source: Optional[Callable[[], Connection]],
|
|
47
49
|
readq_parameters: rabbitmqueue.Parameters,
|
|
48
50
|
any_exchange: bool = False,
|
|
49
51
|
**readq_arguments: Any,
|
|
@@ -152,7 +154,7 @@ class ReaderWorker(ThreadWorker):
|
|
|
152
154
|
def get_cursor(self) -> Cursor:
|
|
153
155
|
if self.database is None:
|
|
154
156
|
if self.database_source is None:
|
|
155
|
-
raise
|
|
157
|
+
raise NoDatabase("Database source is unavailable")
|
|
156
158
|
self.database = self.database_source()
|
|
157
159
|
|
|
158
160
|
return self.database.cursor()
|
|
@@ -192,8 +194,11 @@ class ReaderWorker(ThreadWorker):
|
|
|
192
194
|
filtered = self.filter_message(root)
|
|
193
195
|
|
|
194
196
|
if filtered is not None:
|
|
195
|
-
|
|
196
|
-
self.
|
|
197
|
+
try:
|
|
198
|
+
with self.get_cursor() as cursor:
|
|
199
|
+
self.handle_message(cursor, filtered)
|
|
200
|
+
except NoDatabase:
|
|
201
|
+
self.handle_message_nodb(filtered)
|
|
197
202
|
|
|
198
203
|
logging.debug(f"Successfully handled {method.delivery_tag}")
|
|
199
204
|
self.get_readq().add_callback_threadsafe(
|
|
@@ -242,6 +247,9 @@ class ReaderWorker(ThreadWorker):
|
|
|
242
247
|
def handle_message(self, cursor: Cursor, message: Any) -> None:
|
|
243
248
|
raise NotImplementedError
|
|
244
249
|
|
|
250
|
+
def handle_message_nodb(self, message: Any) -> None:
|
|
251
|
+
raise NotImplementedError
|
|
252
|
+
|
|
245
253
|
def stop(self) -> None:
|
|
246
254
|
with self.lock:
|
|
247
255
|
if self.readq is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: workercommon
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Support code for various projects
|
|
5
5
|
Author-email: "Neil E. Hodges" <47hasbegun@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -13,8 +13,10 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
13
13
|
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE.TXT
|
|
16
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: immutables
|
|
17
17
|
Requires-Dist: pika
|
|
18
|
+
Requires-Dist: psycopg2
|
|
19
|
+
Requires-Dist: pyyaml
|
|
18
20
|
Dynamic: license-file
|
|
19
21
|
|
|
20
22
|
# Requirements
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import sys
|
|
3
|
-
|
|
4
|
-
if sys.version_info < (3, 8):
|
|
5
|
-
raise RuntimeError("At least Python 3.8 is required")
|
|
6
|
-
|
|
7
|
-
from configparser import ConfigParser
|
|
8
|
-
import logging
|
|
9
|
-
from logging.handlers import WatchedFileHandler
|
|
10
|
-
from typing import Tuple, Optional, Callable
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Configuration(object):
|
|
15
|
-
def __init__(self, filename: str):
|
|
16
|
-
self.parser = self.create_parser()
|
|
17
|
-
self.set_base_config(self.parser)
|
|
18
|
-
self.parser.read(filename)
|
|
19
|
-
self.check_all_values(self.parser)
|
|
20
|
-
|
|
21
|
-
def create_parser(self) -> ConfigParser:
|
|
22
|
-
return ConfigParser()
|
|
23
|
-
|
|
24
|
-
def set_base_config(self, parser: ConfigParser) -> None:
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
def check_all_values(self, parser: ConfigParser) -> None:
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
@staticmethod
|
|
31
|
-
def dir_exists(s: str) -> bool:
|
|
32
|
-
return bool(s and Path(s).is_dir())
|
|
33
|
-
|
|
34
|
-
def check_value(
|
|
35
|
-
self, section: str, key: str, validator: Callable[[str], bool]
|
|
36
|
-
) -> None:
|
|
37
|
-
value: Optional[str] = self[section, key]
|
|
38
|
-
try:
|
|
39
|
-
if value is None or not validator(value):
|
|
40
|
-
raise ValueError
|
|
41
|
-
except:
|
|
42
|
-
raise ValueError(f"Invalid {section}/{key} value: {value}")
|
|
43
|
-
|
|
44
|
-
def __getitem__(self, parts: Tuple[str, str]) -> Optional[str]:
|
|
45
|
-
section, key = parts
|
|
46
|
-
|
|
47
|
-
try:
|
|
48
|
-
value = self.parser[section][key]
|
|
49
|
-
return value if value else None
|
|
50
|
-
except KeyError:
|
|
51
|
-
return None
|
|
52
|
-
|
|
53
|
-
def get_strict(self, section: str, key: str) -> str:
|
|
54
|
-
value = self[section, key]
|
|
55
|
-
if value is None:
|
|
56
|
-
raise ValueError(f"Missing {section}/{key} value")
|
|
57
|
-
|
|
58
|
-
return value
|
|
59
|
-
|
|
60
|
-
def get(self, section: str, key: str, default: str) -> str:
|
|
61
|
-
value = self[section, key]
|
|
62
|
-
return value if value is not None else default
|
|
63
|
-
|
|
64
|
-
def configure_logging(self, *handlers) -> None:
|
|
65
|
-
level = self["Logging", "level"]
|
|
66
|
-
if not level:
|
|
67
|
-
raise RuntimeError("Logging level should have already been validated")
|
|
68
|
-
|
|
69
|
-
log_format = self["Logging", "format"]
|
|
70
|
-
if not log_format:
|
|
71
|
-
log_format = "[%(asctime)s] [%(levelname)s] [%(module)s] [%(filename)s:%(lineno)d %(funcName)s] %(message)s"
|
|
72
|
-
|
|
73
|
-
if handlers:
|
|
74
|
-
logging.basicConfig(level=level, format=log_format, handlers=handlers)
|
|
75
|
-
else:
|
|
76
|
-
fname = self["Logging", "file"]
|
|
77
|
-
if fname:
|
|
78
|
-
handler = WatchedFileHandler(fname)
|
|
79
|
-
logging.basicConfig(level=level, format=log_format, handlers=[handler])
|
|
80
|
-
else:
|
|
81
|
-
logging.basicConfig(level=level, format=log_format, stream=sys.stderr)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|