rococo 1.3.0__tar.gz → 1.3.2__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 (120) hide show
  1. {rococo-1.3.0 → rococo-1.3.2}/PKG-INFO +1 -1
  2. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/postgresql.py +19 -5
  3. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/mailjet.py +10 -4
  4. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/PKG-INFO +1 -1
  5. {rococo-1.3.0 → rococo-1.3.2}/setup.py +1 -1
  6. {rococo-1.3.0 → rococo-1.3.2}/LICENSE +0 -0
  7. {rococo-1.3.0 → rococo-1.3.2}/README.md +0 -0
  8. {rococo-1.3.0 → rococo-1.3.2}/rococo/__init__.py +0 -0
  9. {rococo-1.3.0 → rococo-1.3.2}/rococo/auth/__init__.py +0 -0
  10. {rococo-1.3.0 → rococo-1.3.2}/rococo/auth/tokens.py +0 -0
  11. {rococo-1.3.0 → rococo-1.3.2}/rococo/config/__init__.py +0 -0
  12. {rococo-1.3.0 → rococo-1.3.2}/rococo/config/config.py +0 -0
  13. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/__init__.py +0 -0
  14. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/base.py +0 -0
  15. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/dynamodb.py +0 -0
  16. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/mongodb.py +0 -0
  17. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/mysql.py +0 -0
  18. {rococo-1.3.0 → rococo-1.3.2}/rococo/data/surrealdb.py +0 -0
  19. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/__init__.py +0 -0
  20. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/base.py +0 -0
  21. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/config.py +0 -0
  22. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/enums.py +0 -0
  23. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/factory.py +0 -0
  24. {rococo-1.3.0 → rococo-1.3.2}/rococo/emailing/ses.py +0 -0
  25. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/__init__.py +0 -0
  26. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/base.py +0 -0
  27. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/config.py +0 -0
  28. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/enums.py +0 -0
  29. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/factory.py +0 -0
  30. {rococo-1.3.0 → rococo-1.3.2}/rococo/faxing/ifax.py +0 -0
  31. {rococo-1.3.0 → rococo-1.3.2}/rococo/messaging/__init__.py +0 -0
  32. {rococo-1.3.0 → rococo-1.3.2}/rococo/messaging/base.py +0 -0
  33. {rococo-1.3.0 → rococo-1.3.2}/rococo/messaging/rabbitmq.py +0 -0
  34. {rococo-1.3.0 → rococo-1.3.2}/rococo/messaging/sqs.py +0 -0
  35. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/__init__.py +0 -0
  36. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/__init__.py +0 -0
  37. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/cli_base.py +0 -0
  38. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/migration_base.py +0 -0
  39. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/migration_runner.py +0 -0
  40. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/migration_template.py +0 -0
  41. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/common/sql_migration_base.py +0 -0
  42. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mongo/__init__.py +0 -0
  43. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mongo/cli.py +0 -0
  44. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mongo/migration.py +0 -0
  45. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mysql/__init__.py +0 -0
  46. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mysql/cli.py +0 -0
  47. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/mysql/migration.py +0 -0
  48. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/postgres/__init__.py +0 -0
  49. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/postgres/cli.py +0 -0
  50. {rococo-1.3.0 → rococo-1.3.2}/rococo/migrations/postgres/migration.py +0 -0
  51. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/__init__.py +0 -0
  52. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/email.py +0 -0
  53. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/login_method.py +0 -0
  54. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/organization.py +0 -0
  55. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/otp_method.py +0 -0
  56. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/person.py +0 -0
  57. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/person_organization_role.py +0 -0
  58. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/recovery_code.py +0 -0
  59. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/__init__.py +0 -0
  60. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/email.py +0 -0
  61. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/login_method.py +0 -0
  62. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/organization.py +0 -0
  63. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/otp_method.py +0 -0
  64. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/person.py +0 -0
  65. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/person_organization_role.py +0 -0
  66. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/surrealdb/surreal_versioned_model.py +0 -0
  67. {rococo-1.3.0 → rococo-1.3.2}/rococo/models/versioned_model.py +0 -0
  68. {rococo-1.3.0 → rococo-1.3.2}/rococo/plugins/__init__.py +0 -0
  69. {rococo-1.3.0 → rococo-1.3.2}/rococo/plugins/pooled_connection.py +0 -0
  70. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/__init__.py +0 -0
  71. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/base_repository.py +0 -0
  72. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/dynamodb/__init__.py +0 -0
  73. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/dynamodb/dynamodb_repository.py +0 -0
  74. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/mongodb/__init__.py +0 -0
  75. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/mongodb/mongodb_repository.py +0 -0
  76. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/mysql/__init__.py +0 -0
  77. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/mysql/mysql_repository.py +0 -0
  78. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/mysql/organization_repository.py +0 -0
  79. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/postgresql/__init__.py +0 -0
  80. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/postgresql/postgresql_repository.py +0 -0
  81. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/surrealdb/__init__.py +0 -0
  82. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/surrealdb/organization_repository.py +0 -0
  83. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/surrealdb/person_organization_role_repository.py +0 -0
  84. {rococo-1.3.0 → rococo-1.3.2}/rococo/repositories/surrealdb/surreal_db_repository.py +0 -0
  85. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/__init__.py +0 -0
  86. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/base.py +0 -0
  87. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/config.py +0 -0
  88. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/enums.py +0 -0
  89. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/factory.py +0 -0
  90. {rococo-1.3.0 → rococo-1.3.2}/rococo/sms/twilio.py +0 -0
  91. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/SOURCES.txt +0 -0
  92. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/dependency_links.txt +0 -0
  93. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/entry_points.txt +0 -0
  94. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/requires.txt +0 -0
  95. {rococo-1.3.0 → rococo-1.3.2}/rococo.egg-info/top_level.txt +0 -0
  96. {rococo-1.3.0 → rococo-1.3.2}/setup.cfg +0 -0
  97. {rococo-1.3.0 → rococo-1.3.2}/tests/__init__.py +0 -0
  98. {rococo-1.3.0 → rococo-1.3.2}/tests/base_repository_test.py +0 -0
  99. {rococo-1.3.0 → rococo-1.3.2}/tests/config_test.py +0 -0
  100. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/__init__.py +0 -0
  101. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/conftest.py +0 -0
  102. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_dynamodb_integration.py +0 -0
  103. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_models.py +0 -0
  104. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_mongodb_integration.py +0 -0
  105. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_mysql_integration.py +0 -0
  106. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_postgres_integration.py +0 -0
  107. {rococo-1.3.0 → rococo-1.3.2}/tests/database-integration/test_surrealdb_integration.py +0 -0
  108. {rococo-1.3.0 → rococo-1.3.2}/tests/dynamodb_repository_test.py +0 -0
  109. {rococo-1.3.0 → rococo-1.3.2}/tests/migration_cli_base_test.py +0 -0
  110. {rococo-1.3.0 → rococo-1.3.2}/tests/migration_runner_test.py +0 -0
  111. {rococo-1.3.0 → rococo-1.3.2}/tests/model_test.py +0 -0
  112. {rococo-1.3.0 → rococo-1.3.2}/tests/mongodb_repository_test.py +0 -0
  113. {rococo-1.3.0 → rococo-1.3.2}/tests/mysql_repository_test.py +0 -0
  114. {rococo-1.3.0 → rococo-1.3.2}/tests/postgre_repository_test.py +0 -0
  115. {rococo-1.3.0 → rococo-1.3.2}/tests/sql_migration_base_test.py +0 -0
  116. {rococo-1.3.0 → rococo-1.3.2}/tests/surrealdb_repository_test.py +0 -0
  117. {rococo-1.3.0 → rococo-1.3.2}/tests/test_calculated_properties_fix.py +0 -0
  118. {rococo-1.3.0 → rococo-1.3.2}/tests/test_faxing.py +0 -0
  119. {rococo-1.3.0 → rococo-1.3.2}/tests/test_mailjet_addresses.py +0 -0
  120. {rococo-1.3.0 → rococo-1.3.2}/tests/test_non_versioned_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rococo
3
- Version: 1.3.0
3
+ Version: 1.3.2
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
@@ -11,7 +11,18 @@ from rococo.data.base import DbAdapter
11
11
  class PostgreSQLAdapter(DbAdapter):
12
12
  """PostgreSQL adapter for interacting with PostgreSQL."""
13
13
 
14
- def __init__(self, host: str, port: int, user: str, password: str, database: str, connection_resolver: Optional[Callable] = None, connection_closer: Optional[Callable] = None):
14
+
15
+ def __init__(
16
+ self,
17
+ host: str,
18
+ port: int,
19
+ user: str,
20
+ password: str,
21
+ database: str,
22
+ connection_resolver: Optional[Callable] = None,
23
+ connection_closer: Optional[Callable] = None,
24
+ connect_kwargs: Optional[dict] = None,
25
+ ):
15
26
  self._host = host
16
27
  self._port = port
17
28
  self._user = user
@@ -19,7 +30,8 @@ class PostgreSQLAdapter(DbAdapter):
19
30
  self._database = database
20
31
  self._connection = None
21
32
  self._cursor = None
22
- self._table_columns_cache = {} # Cache for table column names
33
+ self._table_columns_cache = {}
34
+ self._connect_kwargs = connect_kwargs or {}
23
35
 
24
36
  if connection_resolver is None:
25
37
  self._connection_resolver = psycopg2.connect
@@ -28,6 +40,7 @@ class PostgreSQLAdapter(DbAdapter):
28
40
 
29
41
  self._connection_closer = connection_closer
30
42
 
43
+
31
44
  def __enter__(self):
32
45
  """Context manager entry point for creating DB connection."""
33
46
  self._connection = self.connect
@@ -60,7 +73,8 @@ class PostgreSQLAdapter(DbAdapter):
60
73
  port=self._port,
61
74
  user=self._user,
62
75
  password=self._password,
63
- database=self._database
76
+ database=self._database,
77
+ **self._connect_kwargs
64
78
  )
65
79
 
66
80
  def _call_cursor(self, function_name, *args, **kwargs):
@@ -405,8 +419,8 @@ class PostgreSQLAdapter(DbAdapter):
405
419
  return True
406
420
  except psycopg2.Error as ex:
407
421
  self._connection.rollback()
408
- if retry_count < 3 and ex.args[0] == 1213:
409
- # Deadlock detected
422
+ if retry_count < 3 and getattr(ex, 'pgcode', None) == '40P01':
423
+ # Deadlock detected (PostgreSQL SQLSTATE 40P01)
410
424
  logging.warning("Deadlock detected on table %s. Retrying in %d seconds. Attempt %d",
411
425
  table_name, 2**retry_count, retry_count+1)
412
426
  time.sleep(2**retry_count)
@@ -71,8 +71,14 @@ class MailjetService(EmailService):
71
71
  def __call__(self, config: MailjetConfig, *args, **kwargs):
72
72
  super().__call__(config)
73
73
 
74
- match = re.match(r'^(.*)\s*<(.*)>$', self.config.SOURCE_EMAIL)
75
- name, email = match.groups()
74
+ # Parse SOURCE_EMAIL which accepts two formats:
75
+ # "Name <email@example.com>" → {"Name": "Name", "Email": "email@example.com"}
76
+ # "user@example.com" → {"Name": "", "Email": "user@example.com"}
77
+ match = re.match(r'^\s*(.*?)\s*<(.+)>\s*$', self.config.SOURCE_EMAIL)
78
+ if match:
79
+ name, email = match.groups()
80
+ else:
81
+ name, email = '', self.config.SOURCE_EMAIL.strip()
76
82
  self.from_address = {"Name": name, "Email": email}
77
83
 
78
84
  self.client = Client(
@@ -152,7 +158,7 @@ class MailjetService(EmailService):
152
158
  response_data = result.json()["Data"]
153
159
  except Exception as e:
154
160
  message = f"Couldn't find Mailjet contact for {email}: {e}"
155
- logger.exception(message, "warning")
161
+ logger.exception(message)
156
162
  return
157
163
 
158
164
  for contact in response_data:
@@ -163,4 +169,4 @@ class MailjetService(EmailService):
163
169
  self.config.MAILJET_API_KEY, self.config.MAILJET_API_SECRET), timeout=15)
164
170
  except Exception as e:
165
171
  message = f"Couldn't remove Mailjet contact for {email} : {e}"
166
- logger.exception(message, "warning")
172
+ logger.exception(message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rococo
3
- Version: 1.3.0
3
+ Version: 1.3.2
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
@@ -64,7 +64,7 @@ extras_require["all"] = [
64
64
 
65
65
  setup(
66
66
  name='rococo',
67
- version='1.3.0',
67
+ version='1.3.2',
68
68
  packages=find_packages(),
69
69
  url='https://github.com/EcorRouge/rococo',
70
70
  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
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