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.
Files changed (59) hide show
  1. {rococo-1.0.0 → rococo-1.0.3}/PKG-INFO +1 -1
  2. {rococo-1.0.0 → rococo-1.0.3}/rococo/data/mysql.py +8 -2
  3. {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/rabbitmq.py +20 -10
  4. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/versioned_model.py +3 -3
  5. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/mysql_repository.py +4 -3
  6. {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/PKG-INFO +1 -1
  7. {rococo-1.0.0 → rococo-1.0.3}/setup.py +1 -1
  8. {rococo-1.0.0 → rococo-1.0.3}/LICENSE +0 -0
  9. {rococo-1.0.0 → rococo-1.0.3}/README.md +0 -0
  10. {rococo-1.0.0 → rococo-1.0.3}/rococo/__init__.py +0 -0
  11. {rococo-1.0.0 → rococo-1.0.3}/rococo/config/__init__.py +0 -0
  12. {rococo-1.0.0 → rococo-1.0.3}/rococo/config/config.py +0 -0
  13. {rococo-1.0.0 → rococo-1.0.3}/rococo/data/__init__.py +0 -0
  14. {rococo-1.0.0 → rococo-1.0.3}/rococo/data/base.py +0 -0
  15. {rococo-1.0.0 → rococo-1.0.3}/rococo/data/surrealdb.py +0 -0
  16. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/__init__.py +0 -0
  17. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/base.py +0 -0
  18. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/config.py +0 -0
  19. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/enums.py +0 -0
  20. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/factory.py +0 -0
  21. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/mailjet.py +0 -0
  22. {rococo-1.0.0 → rococo-1.0.3}/rococo/emailing/ses.py +0 -0
  23. {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/__init__.py +0 -0
  24. {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/base.py +0 -0
  25. {rococo-1.0.0 → rococo-1.0.3}/rococo/messaging/sqs.py +0 -0
  26. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/__init__.py +0 -0
  27. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/email.py +0 -0
  28. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/login_method.py +0 -0
  29. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/organization.py +0 -0
  30. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/otp_method.py +0 -0
  31. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/person.py +0 -0
  32. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/person_organization_role.py +0 -0
  33. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/recovery_code.py +0 -0
  34. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/__init__.py +0 -0
  35. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/email.py +0 -0
  36. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/login_method.py +0 -0
  37. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/organization.py +0 -0
  38. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/otp_method.py +0 -0
  39. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/person.py +0 -0
  40. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/person_organization_role.py +0 -0
  41. {rococo-1.0.0 → rococo-1.0.3}/rococo/models/surrealdb/surreal_versioned_model.py +0 -0
  42. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/__init__.py +0 -0
  43. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/base_repository.py +0 -0
  44. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/__init__.py +0 -0
  45. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/mysql/organization_repository.py +0 -0
  46. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/__init__.py +0 -0
  47. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/organization_repository.py +0 -0
  48. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/person_organization_role_repository.py +0 -0
  49. {rococo-1.0.0 → rococo-1.0.3}/rococo/repositories/surrealdb/surreal_db_repository.py +0 -0
  50. {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/SOURCES.txt +0 -0
  51. {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/dependency_links.txt +0 -0
  52. {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/requires.txt +0 -0
  53. {rococo-1.0.0 → rococo-1.0.3}/rococo.egg-info/top_level.txt +0 -0
  54. {rococo-1.0.0 → rococo-1.0.3}/setup.cfg +0 -0
  55. {rococo-1.0.0 → rococo-1.0.3}/tests/__init__.py +0 -0
  56. {rococo-1.0.0 → rococo-1.0.3}/tests/base_repository_test.py +0 -0
  57. {rococo-1.0.0 → rococo-1.0.3}/tests/config_test.py +0 -0
  58. {rococo-1.0.0 → rococo-1.0.3}/tests/model_test.py +0 -0
  59. {rococo-1.0.0 → rococo-1.0.3}/tests/surreal_db_repository_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rococo
3
- Version: 1.0.0
3
+ Version: 1.0.3
4
4
  Summary: A Python library to help build things the way we want them built
5
5
  Home-page: https://github.com/EcorRouge/rococo
6
6
  Author: Jay Grieves
@@ -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 = 100,
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
- query += f" LIMIT {limit}"
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.append(t)
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.start_consuming()
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') == 'entity_id':
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 = 100
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rococo
3
- Version: 1.0.0
3
+ Version: 1.0.3
4
4
  Summary: A Python library to help build things the way we want them built
5
5
  Home-page: https://github.com/EcorRouge/rococo
6
6
  Author: Jay Grieves
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
2
2
 
3
3
  setup(
4
4
  name='rococo',
5
- version='1.0.0',
5
+ version='1.0.3',
6
6
  packages=find_packages(),
7
7
  url='https://github.com/EcorRouge/rococo',
8
8
  license='MIT',
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