rococo 1.0.0__tar.gz → 1.0.3__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.
- {rococo-1.0.0 → rococo-1.0.3}/PKG-INFO +1 -1
- {rococo-1.0.0 → rococo-1.0.3}/rococo/data/mysql.py +8 -2
- {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/rabbitmq.py +20 -10
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/versioned_model.py +3 -3
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/mysql_repository.py +4 -3
- {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/PKG-INFO +1 -1
- {rococo-1.0.0 → rococo-1.0.3}/setup.py +1 -1
- {rococo-1.0.0 → rococo-1.0.3}/LICENSE +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/README.md +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/config/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/config/config.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/data/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/data/base.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/data/surrealdb.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/base.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/config.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/enums.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/factory.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/mailjet.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/ses.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/base.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/sqs.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/email.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/login_method.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/organization.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/otp_method.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/person.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/person_organization_role.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/recovery_code.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/email.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/login_method.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/organization.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/otp_method.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/person.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/person_organization_role.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/surreal_versioned_model.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/base_repository.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/organization_repository.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/organization_repository.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/person_organization_role_repository.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/surreal_db_repository.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/SOURCES.txt +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/dependency_links.txt +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/requires.txt +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/top_level.txt +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/setup.cfg +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/tests/__init__.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/tests/base_repository_test.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/tests/config_test.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/tests/model_test.py +0 -0
- {rococo-1.0.0 → rococo-1.0.3}/tests/surreal_db_repository_test.py +0 -0
|
@@ -148,7 +148,8 @@ class MySqlAdapter(DbAdapter):
|
|
|
148
148
|
table: str,
|
|
149
149
|
conditions: Dict[str, Any] = None,
|
|
150
150
|
sort: List[Tuple[str, str]] = None,
|
|
151
|
-
limit: int =
|
|
151
|
+
limit: int = None,
|
|
152
|
+
offset: int = None,
|
|
152
153
|
active: bool = True,
|
|
153
154
|
join_statements: list = None,
|
|
154
155
|
additional_fields: list = None
|
|
@@ -172,7 +173,12 @@ class MySqlAdapter(DbAdapter):
|
|
|
172
173
|
if sort:
|
|
173
174
|
sort_strs = [f"{column} {direction}" for column, direction in sort]
|
|
174
175
|
query += f" ORDER BY {', '.join(sort_strs)}"
|
|
175
|
-
|
|
176
|
+
if limit is not None:
|
|
177
|
+
query += f" LIMIT {limit}"
|
|
178
|
+
if offset is not None:
|
|
179
|
+
query += f" OFFSET {offset}"
|
|
180
|
+
|
|
181
|
+
print(query)
|
|
176
182
|
|
|
177
183
|
db_response = self.parse_db_response(self.execute_query(query))
|
|
178
184
|
if not db_response:
|
|
@@ -7,6 +7,7 @@ import threading
|
|
|
7
7
|
import logging
|
|
8
8
|
from typing import Callable
|
|
9
9
|
import pika
|
|
10
|
+
from dotenv import dotenv_values
|
|
10
11
|
|
|
11
12
|
from . import MessageAdapter
|
|
12
13
|
|
|
@@ -16,7 +17,7 @@ logger = logging.getLogger(__name__)
|
|
|
16
17
|
class RabbitMqConnection(MessageAdapter):
|
|
17
18
|
"""A connection to a RabbitMQ message queue that allows to send and receive messages."""
|
|
18
19
|
|
|
19
|
-
def __init__(self, host: str, port: int, username: str, password: str, virtual_host: str = ''):
|
|
20
|
+
def __init__(self, host: str, port: int, username: str, password: str, virtual_host: str = '', consume_config_file_path: str = None):
|
|
20
21
|
"""
|
|
21
22
|
Initializes a new RabbitMQ connection.
|
|
22
23
|
|
|
@@ -32,10 +33,11 @@ class RabbitMqConnection(MessageAdapter):
|
|
|
32
33
|
self._username = username
|
|
33
34
|
self._password = password
|
|
34
35
|
self._virtual_host = virtual_host
|
|
36
|
+
self._consume_config_file_path = consume_config_file_path
|
|
35
37
|
|
|
36
38
|
self._connection = None
|
|
37
39
|
self._channel = None
|
|
38
|
-
self._threads =
|
|
40
|
+
self._threads = {}
|
|
39
41
|
|
|
40
42
|
def __enter__(self):
|
|
41
43
|
"""
|
|
@@ -63,6 +65,11 @@ class RabbitMqConnection(MessageAdapter):
|
|
|
63
65
|
self._connection = None
|
|
64
66
|
self._channel = None
|
|
65
67
|
|
|
68
|
+
def _read_consume_config(self):
|
|
69
|
+
if self._consume_config_file_path is None:
|
|
70
|
+
return {}
|
|
71
|
+
return dotenv_values(self._consume_config_file_path)
|
|
72
|
+
|
|
66
73
|
def send_message(self, queue_name: str, message: dict):
|
|
67
74
|
"""
|
|
68
75
|
Sends a message to the specified queue.
|
|
@@ -114,6 +121,7 @@ class RabbitMqConnection(MessageAdapter):
|
|
|
114
121
|
cb = functools.partial(_ack_message, ch, delivery_tag)
|
|
115
122
|
logger.info("Sent ack for Delivery tag %s...", delivery_tag)
|
|
116
123
|
self._connection.add_callback_threadsafe(cb)
|
|
124
|
+
self._threads.pop(delivery_tag, None)
|
|
117
125
|
|
|
118
126
|
def _on_message(ch, method_frame, _header_frame, body, args):
|
|
119
127
|
"""Called when a message is received."""
|
|
@@ -125,27 +133,29 @@ class RabbitMqConnection(MessageAdapter):
|
|
|
125
133
|
target=_do_work, args=(ch, delivery_tag, body, callback)
|
|
126
134
|
)
|
|
127
135
|
t.start()
|
|
128
|
-
self._threads
|
|
136
|
+
self._threads[delivery_tag] = t
|
|
129
137
|
|
|
130
138
|
self._channel.queue_declare(queue=queue_name, durable=True)
|
|
131
139
|
|
|
132
|
-
self._threads =
|
|
140
|
+
self._threads = {}
|
|
133
141
|
self._channel.basic_qos(prefetch_count=num_threads)
|
|
134
142
|
|
|
135
143
|
on_message_callback = functools.partial(_on_message, args=(callback_function,))
|
|
136
|
-
self._channel.basic_consume(
|
|
137
|
-
queue=queue_name, on_message_callback=on_message_callback
|
|
138
|
-
)
|
|
139
144
|
|
|
140
145
|
try:
|
|
141
146
|
logger.info('Listening to RabbitMQ queue %s on %s:%s with %s threads...', queue_name,
|
|
142
147
|
self._host, self._port, num_threads)
|
|
143
|
-
self._channel.
|
|
148
|
+
for method, properties, body in self._channel.consume(queue=queue_name, inactivity_timeout=5):
|
|
149
|
+
if (method, properties, body) == (None, None, None):
|
|
150
|
+
if len(self._threads) == 0 and self._read_consume_config().get('EXIT_WHEN_FINISHED') == '1':
|
|
151
|
+
logger.info("Reached inactivity timeout. No threads are running and EXIT_WHEN_FINISHED=1, exiting!")
|
|
152
|
+
break
|
|
153
|
+
else:
|
|
154
|
+
on_message_callback(self._channel, method, properties, body)
|
|
144
155
|
except KeyboardInterrupt:
|
|
145
156
|
logger.info("Exiting gracefully...")
|
|
146
|
-
self._channel.stop_consuming()
|
|
147
157
|
finally:
|
|
148
158
|
# Wait for all to complete
|
|
149
|
-
for thread in self._threads:
|
|
159
|
+
for thread in self._threads.values():
|
|
150
160
|
thread.join()
|
|
151
161
|
self._connection.close()
|
|
@@ -36,10 +36,10 @@ class VersionedModel:
|
|
|
36
36
|
"""A base class for versioned models with common (Big 6) attributes."""
|
|
37
37
|
|
|
38
38
|
entity_id: UUID = field(default_factory=uuid4, metadata={'field_type': 'entity_id'})
|
|
39
|
-
version: UUID = UUID('00000000-0000-4000-8000-000000000000')
|
|
40
|
-
previous_version: UUID = None
|
|
39
|
+
version: UUID = field(default_factory=lambda: UUID('00000000-0000-4000-8000-000000000000'), metadata={'field_type': 'uuid'})
|
|
40
|
+
previous_version: UUID = field(default_factory=lambda: None, metadata={'field_type': 'uuid'})
|
|
41
41
|
active: bool = True
|
|
42
|
-
changed_by_id: UUID = UUID('00000000-0000-4000-8000-000000000000')
|
|
42
|
+
changed_by_id: UUID = field(default_factory=lambda: UUID('00000000-0000-4000-8000-000000000000'), metadata={'field_type': 'uuid'})
|
|
43
43
|
changed_on: datetime = field(default_factory=default_datetime)
|
|
44
44
|
|
|
45
45
|
_is_partial: InitVar[bool] = False
|
|
@@ -37,7 +37,7 @@ class MySqlRepository(BaseRepository):
|
|
|
37
37
|
|
|
38
38
|
field_value = data[field.name]
|
|
39
39
|
|
|
40
|
-
if field.metadata.get('field_type')
|
|
40
|
+
if field.metadata.get('field_type') in ['entity_id', 'uuid']:
|
|
41
41
|
if isinstance(field_value, VersionedModel):
|
|
42
42
|
field_value = str(field_value.entity_id).replace('-', '')
|
|
43
43
|
elif isinstance(field_value, dict):
|
|
@@ -174,7 +174,8 @@ class MySqlRepository(BaseRepository):
|
|
|
174
174
|
join_fields: List[str] = None,
|
|
175
175
|
additional_fields: List[str] = None,
|
|
176
176
|
sort: List[tuple] = None,
|
|
177
|
-
limit: int =
|
|
177
|
+
limit: int = None,
|
|
178
|
+
offset: int = None
|
|
178
179
|
) -> List[VersionedModel]:
|
|
179
180
|
"""get many"""
|
|
180
181
|
if additional_fields is None:
|
|
@@ -230,7 +231,7 @@ class MySqlRepository(BaseRepository):
|
|
|
230
231
|
raise NotImplementedError
|
|
231
232
|
|
|
232
233
|
records = self._execute_within_context(
|
|
233
|
-
self.adapter.get_many, self.table_name, conditions, sort, limit, join_statements=join_stmt_list, additional_fields=additional_fields
|
|
234
|
+
self.adapter.get_many, self.table_name, conditions, sort, limit, offset, join_statements=join_stmt_list, additional_fields=additional_fields
|
|
234
235
|
)
|
|
235
236
|
|
|
236
237
|
# If the adapter returned a single dictionary, wrap it in a list
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/person_organization_role_repository.py
RENAMED
|
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
|