openmodule 14.0.1__tar.gz → 14.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 (249) hide show
  1. {openmodule-14.0.1 → openmodule-14.0.3}/ChangeLog +10 -13
  2. {openmodule-14.0.1/openmodule.egg-info → openmodule-14.0.3}/PKG-INFO +1 -1
  3. {openmodule-14.0.1 → openmodule-14.0.3}/docs/sentry.md +6 -0
  4. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/dispatcher.py +6 -4
  5. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/rpc/server.py +14 -11
  6. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/sentry.py +72 -16
  7. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/io.py +17 -16
  8. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/kv_store.py +21 -7
  9. {openmodule-14.0.1 → openmodule-14.0.3/openmodule.egg-info}/PKG-INFO +1 -1
  10. openmodule-14.0.3/openmodule.egg-info/pbr.json +1 -0
  11. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule.egg-info/requires.txt +1 -1
  12. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/sentry.py +12 -10
  13. {openmodule-14.0.1 → openmodule-14.0.3}/requirements.txt +1 -1
  14. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_sentry.py +164 -20
  15. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_kv_store.py +28 -5
  16. openmodule-14.0.1/openmodule.egg-info/pbr.json +0 -1
  17. {openmodule-14.0.1 → openmodule-14.0.3}/.gitlab-ci.yml +0 -0
  18. {openmodule-14.0.1 → openmodule-14.0.3}/AUTHORS +0 -0
  19. {openmodule-14.0.1 → openmodule-14.0.3}/LICENSE +0 -0
  20. {openmodule-14.0.1 → openmodule-14.0.3}/README.md +0 -0
  21. {openmodule-14.0.1 → openmodule-14.0.3}/docs/access_service.md +0 -0
  22. {openmodule-14.0.1 → openmodule-14.0.3}/docs/anonymization.md +0 -0
  23. {openmodule-14.0.1 → openmodule-14.0.3}/docs/cleanup.md +0 -0
  24. {openmodule-14.0.1 → openmodule-14.0.3}/docs/coding_standard.md +0 -0
  25. {openmodule-14.0.1 → openmodule-14.0.3}/docs/commands.md +0 -0
  26. {openmodule-14.0.1 → openmodule-14.0.3}/docs/connection_status_listener.md +0 -0
  27. {openmodule-14.0.1 → openmodule-14.0.3}/docs/csv_export.md +0 -0
  28. {openmodule-14.0.1 → openmodule-14.0.3}/docs/database.md +0 -0
  29. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated.md +0 -0
  30. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/README.md +0 -0
  31. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/access_service/openmodule/models/access_service.py +0 -0
  32. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/access_service/openmodule/utils/access_service.py +0 -0
  33. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/access_service/openmodule_test/access_service.py +0 -0
  34. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/access_service/tests/test_utils_access_service.py +0 -0
  35. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/api/openmodule/utils/api.py +0 -0
  36. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/api/openmodule_test/api.py +0 -0
  37. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/api/tests/test_utils_api.py +0 -0
  38. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/package_reader/openmodule/utils/package_reader.py +0 -0
  39. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/package_reader/openmodule_test/fake_package_creator.py +0 -0
  40. {openmodule-14.0.1 → openmodule-14.0.3}/docs/deprecated_code/package_reader/tests/test_package_reader.py +0 -0
  41. {openmodule-14.0.1 → openmodule-14.0.3}/docs/event_sending.md +0 -0
  42. {openmodule-14.0.1 → openmodule-14.0.3}/docs/getting_started.md +0 -0
  43. {openmodule-14.0.1 → openmodule-14.0.3}/docs/health.md +0 -0
  44. {openmodule-14.0.1 → openmodule-14.0.3}/docs/images/broker.drawio.png +0 -0
  45. {openmodule-14.0.1 → openmodule-14.0.3}/docs/known_issues.md +0 -0
  46. {openmodule-14.0.1 → openmodule-14.0.3}/docs/migrations.md +0 -0
  47. {openmodule-14.0.1 → openmodule-14.0.3}/docs/package_reader.md +0 -0
  48. {openmodule-14.0.1 → openmodule-14.0.3}/docs/rpc.md +0 -0
  49. {openmodule-14.0.1 → openmodule-14.0.3}/docs/settings.md +0 -0
  50. {openmodule-14.0.1 → openmodule-14.0.3}/docs/settings_provider.md +0 -0
  51. {openmodule-14.0.1 → openmodule-14.0.3}/docs/testing.md +0 -0
  52. {openmodule-14.0.1 → openmodule-14.0.3}/docs/translation.md +0 -0
  53. {openmodule-14.0.1 → openmodule-14.0.3}/docs/utils.md +0 -0
  54. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/__init__.py +0 -0
  55. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/alert.py +0 -0
  56. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/config.py +0 -0
  57. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/connection_status.py +0 -0
  58. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/core.py +0 -0
  59. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/database/custom_types.py +0 -0
  60. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/database/database.py +0 -0
  61. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/database/env.py +0 -0
  62. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/database/migration.py +0 -0
  63. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/health.py +0 -0
  64. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/logging.py +0 -0
  65. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/messaging.py +0 -0
  66. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/__init__.py +0 -0
  67. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/access_service.py +0 -0
  68. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/alert.py +0 -0
  69. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/base.py +0 -0
  70. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/io.py +0 -0
  71. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/kv_store.py +0 -0
  72. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/presence.py +0 -0
  73. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/privacy.py +0 -0
  74. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/rpc.py +0 -0
  75. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/settings.py +0 -0
  76. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/validation.py +0 -0
  77. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/models/vehicle.py +0 -0
  78. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/rpc/__init__.py +0 -0
  79. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/rpc/client.py +0 -0
  80. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/rpc/common.py +0 -0
  81. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/threading.py +0 -0
  82. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/__init__.py +0 -0
  83. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/access_service.py +0 -0
  84. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/charset.py +0 -0
  85. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/cleanup.py +0 -0
  86. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/csv_export.py +0 -0
  87. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/databox.py +0 -0
  88. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/db_helper.py +0 -0
  89. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/eventlog.py +0 -0
  90. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/matching.py +0 -0
  91. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/misc_functions.py +0 -0
  92. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/package_reader.py +0 -0
  93. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/presence.py +0 -0
  94. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/schema.py +0 -0
  95. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/settings.py +0 -0
  96. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/translation.py +0 -0
  97. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule/utils/validation.py +0 -0
  98. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule.egg-info/SOURCES.txt +0 -0
  99. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule.egg-info/dependency_links.txt +0 -0
  100. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule.egg-info/not-zip-safe +0 -0
  101. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule.egg-info/top_level.txt +0 -0
  102. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_commands/__init__.py +0 -0
  103. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_commands/setup.cfg +0 -0
  104. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_commands/setup.py +0 -0
  105. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_commands/translate.py +0 -0
  106. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/__init__.py +0 -0
  107. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/alert.py +0 -0
  108. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/connection_status.py +0 -0
  109. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/core.py +0 -0
  110. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/database.py +0 -0
  111. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/eventlistener.py +0 -0
  112. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/files.py +0 -0
  113. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/gate.py +0 -0
  114. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/health.py +0 -0
  115. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/interrupt.py +0 -0
  116. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/io_simulator.py +0 -0
  117. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/package_reader.py +0 -0
  118. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/presence.py +0 -0
  119. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/requirements.txt +0 -0
  120. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/rpc.py +0 -0
  121. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/settings.py +0 -0
  122. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/setup.cfg +0 -0
  123. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/setup.py +0 -0
  124. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/utils.py +0 -0
  125. {openmodule-14.0.1 → openmodule-14.0.3}/openmodule_test/zeromq.py +0 -0
  126. {openmodule-14.0.1 → openmodule-14.0.3}/setup.cfg +0 -0
  127. {openmodule-14.0.1 → openmodule-14.0.3}/setup.py +0 -0
  128. {openmodule-14.0.1 → openmodule-14.0.3}/test-requirements.txt +0 -0
  129. {openmodule-14.0.1 → openmodule-14.0.3}/tests/__init__.py +0 -0
  130. {openmodule-14.0.1 → openmodule-14.0.3}/tests/config.py +0 -0
  131. {openmodule-14.0.1 → openmodule-14.0.3}/tests/database_models_migration.py +0 -0
  132. {openmodule-14.0.1 → openmodule-14.0.3}/tests/database_models_test.py +0 -0
  133. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic/README +0 -0
  134. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic/__init__.py +0 -0
  135. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic/env.py +0 -0
  136. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic/script.py.mako +0 -0
  137. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic/versions/ff26e54332f9_datetime_models.py +0 -0
  138. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/alembic.ini +0 -0
  139. {openmodule-14.0.1 → openmodule-14.0.3}/tests/invalid_database/makemigration.sh +0 -0
  140. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic/__init__.py +0 -0
  141. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic/env.py +0 -0
  142. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic/script.py.mako +0 -0
  143. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic/versions/812a3e5b8517_initial.py +0 -0
  144. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic/versions/a7ea100a784f_key_error.py +0 -0
  145. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/alembic.ini +0 -0
  146. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_double_column_delete_error/makemigration.sh +0 -0
  147. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic/__init__.py +0 -0
  148. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic/env.py +0 -0
  149. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic/script.py.mako +0 -0
  150. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic/versions/812a3e5b8517_initial.py +0 -0
  151. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic/versions/a7ea100a784f_no_such_table_error.py +0 -0
  152. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/alembic.ini +0 -0
  153. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_no_such_table_error/makemigration.sh +0 -0
  154. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/__init__.py +0 -0
  155. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/__init__.py +0 -0
  156. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/env.py +0 -0
  157. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/script.py.mako +0 -0
  158. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/versions/19789aa5361c_initial.py +0 -0
  159. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/versions/19d887929ae7_alter.py +0 -0
  160. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic/versions/__init__.py +0 -0
  161. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic.ini +0 -0
  162. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/alembic_migration_test_database.sqlite3 +0 -0
  163. {openmodule-14.0.1 → openmodule-14.0.3}/tests/migration_test_database/makemigration.sh +0 -0
  164. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/configs/config.py +0 -0
  165. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/configs/test_config.py +0 -0
  166. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/configs/test_config_1.py +0 -0
  167. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/standard_schemes/DEFAULT-10.yml +0 -0
  168. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/standard_schemes/DEFAULT-20.yml +0 -0
  169. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/standard_schemes/LEGACY-0.yml +0 -0
  170. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/locale/de/LC_MESSAGES/translation.mo +0 -0
  171. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/locale/de/LC_MESSAGES/translation.po +0 -0
  172. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/locale/en/LC_MESSAGES/translation.mo +0 -0
  173. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/locale/en/LC_MESSAGES/translation.po +0 -0
  174. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/locale/translation.pot +0 -0
  175. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/translation/translate.sh +0 -0
  176. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/A-10.yml +0 -0
  177. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/A-20.yml +0 -0
  178. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/DEFAULT-10.yml +0 -0
  179. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/DEFAULT-20.yml +0 -0
  180. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/DEFAULT-30.yml +0 -0
  181. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/LEGACY-0.yml +0 -0
  182. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/TEST-10.yml +0 -0
  183. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/TEST-20.yml +0 -0
  184. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/TEST-30.yml +0 -0
  185. {openmodule-14.0.1 → openmodule-14.0.3}/tests/resources/utils_matching/TEST-40.yml +0 -0
  186. {openmodule-14.0.1 → openmodule-14.0.3}/tests/sentry_main.py +0 -0
  187. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/__init__.py +0 -0
  188. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/env.py +0 -0
  189. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/script.py.mako +0 -0
  190. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/versions/7bd4fcd38fde_removed_nfc_and_pin.py +0 -0
  191. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/versions/9ca98a2e5674_added_parksettings_id.py +0 -0
  192. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic/versions/c821971f9230_initial.py +0 -0
  193. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/alembic.ini +0 -0
  194. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_access_service_database/makemigration.sh +0 -0
  195. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_alembic_migrations.py +0 -0
  196. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_alert.py +0 -0
  197. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_checks.py +0 -0
  198. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_config.py +0 -0
  199. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_connection_status.py +0 -0
  200. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_core.py +0 -0
  201. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/alembic/__init__.py +0 -0
  202. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/alembic/env.py +0 -0
  203. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/alembic/script.py.mako +0 -0
  204. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/alembic/versions/32b8c728abbf_initial.py +0 -0
  205. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/alembic.ini +0 -0
  206. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database/makemigration.sh +0 -0
  207. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_database.py +0 -0
  208. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_dispatcher.py +0 -0
  209. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_health.py +0 -0
  210. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_interrupt.py +0 -0
  211. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_io_listen.py +0 -0
  212. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic/__init__.py +0 -0
  213. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic/env.py +0 -0
  214. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic/script.py.mako +0 -0
  215. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic/versions/9c5c944221f4_deprecated_kv_entry_example.py +0 -0
  216. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic/versions/c55a69026a25_initial.py +0 -0
  217. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/alembic.ini +0 -0
  218. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_database/makemigration.sh +0 -0
  219. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic/README +0 -0
  220. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic/__init__.py +0 -0
  221. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic/env.py +0 -0
  222. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic/script.py.mako +0 -0
  223. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic/versions/cdb3214131a9_initial.py +0 -0
  224. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/alembic.ini +0 -0
  225. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_kv_store_multiple_database/makemigration.sh +0 -0
  226. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_logging.py +0 -0
  227. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_messaging.py +0 -0
  228. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_mockrpcclient.py +0 -0
  229. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_model.py +0 -0
  230. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_rpc.py +0 -0
  231. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_schema.py +0 -0
  232. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_test_alert.py +0 -0
  233. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_test_gate.py +0 -0
  234. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_test_zeromq.py +0 -0
  235. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_access_service.py +0 -0
  236. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_charset.py +0 -0
  237. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_cleanup.py +0 -0
  238. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_csv_export.py +0 -0
  239. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_databox.py +0 -0
  240. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_eventlog.py +0 -0
  241. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_kv_store_multiple.py +0 -0
  242. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_matching.py +0 -0
  243. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_misc_functions.py +0 -0
  244. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_package_reader.py +0 -0
  245. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_presence.py +0 -0
  246. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_settings.py +0 -0
  247. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_validation.py +0 -0
  248. {openmodule-14.0.1 → openmodule-14.0.3}/tests/test_utils_vehicle.py +0 -0
  249. {openmodule-14.0.1 → openmodule-14.0.3}/tox.ini +0 -0
@@ -1,6 +1,16 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ v14.0.3
5
+ -------
6
+
7
+ * OM-941 Sentry Bugfix
8
+
9
+ v14.0.2
10
+ -------
11
+
12
+ * Sentry improvements
13
+
4
14
  v14.0.1
5
15
  -------
6
16
 
@@ -161,8 +171,6 @@ v12.0.0.rc0
161
171
  * settings models update
162
172
  * made gate\_control/day\_mode have no scope
163
173
  * schedule exports utility
164
- * SettingsProvider docs
165
- * SettingsProvider docs
166
174
 
167
175
  v11.1.1
168
176
  -------
@@ -197,14 +205,3 @@ v10.0.5
197
205
  -------
198
206
 
199
207
  * fixed problem in presence listener
200
- * README for settings + backend
201
-
202
- v10.0.4
203
- -------
204
-
205
- * Improvements for backend and package reader
206
-
207
- v10.0.3
208
- -------
209
-
210
- * added freezegun and fakeredis to openmodule requirements
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openmodule
3
- Version: 14.0.1
3
+ Version: 14.0.3
4
4
  Summary: Libraries for developing the arivo openmodule
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -24,6 +24,10 @@ for your project that tells the SDK where to send the events. You can find the D
24
24
  * You can provide additional [sentry options](https://docs.sentry.io/platforms/python/configuration/options/) as keyword
25
25
  arguments to the `init_openmodule` function (`server_name` and `environment` cannot be overriden).
26
26
  * the `extras` keyword argument can be used to provide additional data to the Sentry SDK
27
+ * the `topics_to_ignore` keyword argument can be used to provide a list of topics that should not be captured by Sentry.
28
+ You should also check that no trace will be started for every message from that topic. (defaults to `["io"]`)
29
+ * the `functions_to_ignore` keyword argument can be used to provide a list of span names (auto generated for functions)
30
+ that should not be captured by Sentry. (defaults to `[]`)
27
31
 
28
32
  ```python
29
33
  def main():
@@ -75,6 +79,8 @@ with sentry.trace("my_block"):
75
79
 
76
80
  You can add context to the current transaction using one of the following methods:
77
81
 
82
+ * Adding the data as kwargs to the `sentry.trace` function.
83
+ * `sentry.trace("my_block", extras={"key": "value"}, tags={"key": "value"}, context={"key": "value"})`
78
84
  * `sentry_sdk.set_tag(key: str, value: str)`: Adds
79
85
  a [tag](https://docs.sentry.io/platforms/python/enriching-events/tags/) to the current transaction.
80
86
  * `sentry_sdk.set_tags(**key_value_pairs: str)`:
@@ -44,7 +44,7 @@ class Listener:
44
44
  def __init__(self, message_class: Type[ZMQMessage], type: Optional[str], filter: Optional[Callable],
45
45
  handler: Callable):
46
46
  self.filter = filter
47
- self.handler = handler
47
+ self.handler = sentry.trace(f"message_handler.{qualname_from_function(handler)}")(handler)
48
48
  self.type = type
49
49
  self.message_class = message_class
50
50
 
@@ -110,6 +110,7 @@ class MessageDispatcher:
110
110
  self.raise_validation_errors = raise_validation_errors
111
111
  self.raise_handler_errors = raise_handler_errors
112
112
  self.executor = executor or DummyExecutor()
113
+ self._new_transactions = not isinstance(self.executor, DummyExecutor)
113
114
  self._shutdown = False
114
115
  self._shutdown_lock = threading.Lock()
115
116
 
@@ -201,10 +202,12 @@ class MessageDispatcher:
201
202
  listeners = self.listeners.get(topic, [])
202
203
  for listener in listeners:
203
204
  if listener.matches(message):
205
+ message.update(sentry.get_trace_headers())
204
206
  self.executor.submit(self.execute, topic, listener, message)
205
207
 
206
208
  def execute(self, topic: str, listener: Listener, message: Dict):
207
- with sentry.continue_trace_zmq_message_process(topic, message):
209
+ with sentry.continue_trace_zmq_message_process(
210
+ topic, message, force_new_transaction=self._new_transactions):
208
211
  try:
209
212
  parsed_message = parse_obj_as(listener.message_class, message)
210
213
  except ValidationError as e:
@@ -214,8 +217,7 @@ class MessageDispatcher:
214
217
  self.log.exception("Invalid message received")
215
218
  else:
216
219
  try:
217
- with sentry.trace(f"message_handler.{qualname_from_function(listener.handler)}"):
218
- listener.handler(parsed_message)
220
+ listener.handler(parsed_message)
219
221
  except zmq.ContextTerminated:
220
222
  raise
221
223
  except Exception as e:
@@ -77,6 +77,7 @@ class RPCServer(object):
77
77
  self.thread = None
78
78
  self.resource = None
79
79
  self.executor = executor or DummyExecutor()
80
+ self._new_transactions = not isinstance(self.executor, DummyExecutor)
80
81
  # since zmq does prefix matching we keep a list of unique channel names here
81
82
  # so we do not log a warning "unknown handler" if our channel is a prefix of a different channel
82
83
  self.registered_channels = set()
@@ -129,7 +130,8 @@ class RPCServer(object):
129
130
 
130
131
  self.log.debug("register handler {}:{} -> {}".format(channel, type, handler))
131
132
  self.sub.subscribe(channel_to_request_topic(channel).encode("utf8"))
132
- self.handlers[(channel, type)] = HandlerEntry(request_class, response_class, handler)
133
+ traced_handler = sentry.trace(f"rpc_handler.{qualname_from_function(handler)}")(handler)
134
+ self.handlers[(channel, type)] = HandlerEntry(request_class, response_class, traced_handler)
133
135
  self.registered_channels = set(x[0] for x in self.handlers.keys())
134
136
  if register_schema:
135
137
  Schema.save_rpc(channel, type, request_class, response_class, handler)
@@ -194,15 +196,14 @@ class RPCServer(object):
194
196
  if settings.LOG_LEVEL != logging.DEBUG:
195
197
  self.log.info("received RPC channel: %s, type: %s", channel, message.type)
196
198
  try:
197
- with sentry.trace(f"rpc_handler.{qualname_from_function(handler.handler)}"):
198
- response = handler.handler(request, message)
199
- if isinstance(response, handler.response_class):
200
- # shortcut prevent serialization and de-serialization if the correct response
201
- # is already returned
202
- return self._response_to_dict(response)
203
- else:
204
- response = parse_obj_as(handler.response_class, response or {})
205
- return self._response_to_dict(response)
199
+ response = handler.handler(request, message)
200
+ if isinstance(response, handler.response_class):
201
+ # shortcut prevent serialization and de-serialization if the correct response
202
+ # is already returned
203
+ return self._response_to_dict(response)
204
+ else:
205
+ response = parse_obj_as(handler.response_class, response or {})
206
+ return self._response_to_dict(response)
206
207
  except Exception as e:
207
208
  self.log.exception("exception in handler {}:{}".format(channel, message.type))
208
209
  return {"status": RPCServerError.handler_error, "exception": str(e)}
@@ -211,7 +212,8 @@ class RPCServer(object):
211
212
  return None
212
213
 
213
214
  def _process_rpc_message(self, topic: str, message: dict):
214
- with sentry.continue_trace_zmq_message_process(topic, message):
215
+ with sentry.continue_trace_zmq_message_process(
216
+ topic, message, force_new_transaction=self._new_transactions):
215
217
  try:
216
218
  channel = self._channel_from_topic(topic)
217
219
 
@@ -262,6 +264,7 @@ class RPCServer(object):
262
264
  continue
263
265
  if self.running:
264
266
  # someone may have stopped our server while we were receiving a message
267
+ message.update(sentry.get_trace_headers())
265
268
  self.executor.submit(self._process_rpc_message, topic, message)
266
269
  except zmq.ContextTerminated:
267
270
  pass
@@ -5,13 +5,13 @@ import logging
5
5
  import os.path
6
6
  import time
7
7
  from contextlib import contextmanager
8
- from typing import Union, Callable, overload, Generator, Optional, Tuple, Any
8
+ from typing import Union, Callable, overload, Generator, Optional, Tuple, Any, List
9
9
 
10
10
  import orjson
11
11
  import requests
12
+ import sentry_sdk.integrations.logging
12
13
  import sentry_sdk.tracing
13
14
  import sentry_sdk.tracing_utils
14
- import sentry_sdk.integrations.logging
15
15
  import urllib3.exceptions
16
16
  from sentry_sdk.consts import EndpointType
17
17
  from sentry_sdk.envelope import Envelope
@@ -20,26 +20,35 @@ from sentry_sdk.utils import qualname_from_function
20
20
  from openmodule.config import settings
21
21
 
22
22
  _log = logging.getLogger("OmSentry")
23
+ _topics_to_ignore: List[str] = ["io"]
24
+ _functions_to_ignore: List[str] = ["message_handler.openmodule.utils.io.IoListener._on_io_message"]
25
+
26
+
27
+ @contextmanager
28
+ def noop_context():
29
+ yield
23
30
 
24
31
 
25
- def continue_trace_zmq_message_receive(topic: str, message: dict):
32
+ def continue_trace_zmq_message_receive(topic: str, message: dict, **kwargs):
26
33
  """
27
34
  Continues a sentry trace for a received zmq message. (If already in a transaction, it will create a scope instead)
28
35
  Our ZMQMessage class contains the baggage and sentry-trace fields required for this, so the dict must contain these.
29
36
  :param topic: The topic of the message (as received from the ZMQ socket and decoded)
30
37
  :param message: The ZMQMessage as a dict (as received from the ZMQ socket and json loaded)
31
38
  """
32
- return _continue_trace_zmq_message(topic, message, "topic.receive")
39
+ return _continue_trace_zmq_message(topic, message, "topic.receive", **kwargs)
33
40
 
34
41
 
35
- def continue_trace_zmq_message_process(topic: str, message: dict):
42
+ def continue_trace_zmq_message_process(topic: str, message: dict, **kwargs):
36
43
  """
37
44
  Continues a sentry trace for a zmq message executor. (If already in a transaction, it will create a scope instead)
38
45
  Our ZMQMessage class contains the baggage and sentry-trace fields required for this, so the dict must contain these.
39
46
  :param topic: The topic of the message (as received from the ZMQ socket and decoded)
40
47
  :param message: The ZMQMessage as a dict (as received from the ZMQ socket and json loaded)
41
48
  """
42
- return _continue_trace_zmq_message(topic, message, "topic.process")
49
+ if topic in _topics_to_ignore:
50
+ return noop_context()
51
+ return _continue_trace_zmq_message(topic, message, "topic.process", **kwargs)
43
52
 
44
53
 
45
54
  @overload # pragma: no cover
@@ -48,6 +57,7 @@ def trace(
48
57
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
49
58
  trace_headers: Optional[dict] = None,
50
59
  force_new_transaction: bool = False,
60
+ force_no_trace: bool = False,
51
61
  **span_kwargs) -> Callable[[Callable], Callable]:
52
62
  ...
53
63
 
@@ -58,6 +68,7 @@ def trace(
58
68
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
59
69
  trace_headers: Optional[dict] = None,
60
70
  force_new_transaction: bool = False,
71
+ force_no_trace: bool = False,
61
72
  **span_kwargs) -> Union[Callable, Generator[sentry_sdk.tracing.Span, None, None]]:
62
73
  ...
63
74
 
@@ -68,6 +79,7 @@ def trace(
68
79
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
69
80
  trace_headers: Optional[dict] = None,
70
81
  force_new_transaction: bool = False,
82
+ force_no_trace: bool = False,
71
83
  **span_kwargs) -> Callable:
72
84
  ...
73
85
 
@@ -77,6 +89,7 @@ def trace(
77
89
  op: Union[sentry_sdk.consts.OP, str] = sentry_sdk.consts.OP.FUNCTION,
78
90
  trace_headers: Optional[dict] = None,
79
91
  force_new_transaction: bool = False,
92
+ force_no_trace: bool = False,
80
93
  **span_kwargs):
81
94
  """
82
95
  Trace a function or a block of code.
@@ -86,6 +99,7 @@ def trace(
86
99
  span_kwargs["op"] = op
87
100
  span_kwargs["trace_headers"] = trace_headers
88
101
  span_kwargs["force_new_transaction"] = force_new_transaction
102
+ span_kwargs["force_no_trace"] = force_no_trace
89
103
  if name is None:
90
104
  return _Trace(**span_kwargs)
91
105
  elif callable(name):
@@ -109,6 +123,14 @@ def get_baggage() -> Optional[str]:
109
123
  get_traceparent = sentry_sdk.get_traceparent
110
124
 
111
125
 
126
+ def get_trace_headers(empty_if_not_sampled: bool = False) -> dict:
127
+ if empty_if_not_sampled:
128
+ span = sentry_sdk.get_current_span()
129
+ if span and not span.sampled:
130
+ return {}
131
+ return {"sentry-trace": get_traceparent(), "baggage": get_baggage()}
132
+
133
+
112
134
  class _Trace:
113
135
  """
114
136
  Context manager for sentry tracing.
@@ -118,9 +140,11 @@ class _Trace:
118
140
  force_new_transaction: bool
119
141
  ctx: Any
120
142
 
121
- def __init__(self, *, trace_headers: Optional[dict] = None, force_new_transaction: bool = False, **span_kwargs):
143
+ def __init__(self, *, trace_headers: Optional[dict] = None, force_new_transaction: bool = False,
144
+ force_no_trace: bool = False, **span_kwargs):
122
145
  self.trace_headers = trace_headers
123
146
  self.force_new_transaction = force_new_transaction
147
+ self.force_no_trace = force_no_trace
124
148
  self.span_kwargs = span_kwargs
125
149
 
126
150
  @contextmanager
@@ -130,21 +154,40 @@ class _Trace:
130
154
  Otherwise, start a new span.
131
155
  If given a trace_headers dict, it will continue the trace with the given headers.
132
156
  """
157
+ force_no_trace = self.force_no_trace or self.span_kwargs.get("name") in _functions_to_ignore
158
+
159
+ def set_context():
160
+ for key, value in extras.items():
161
+ sentry_sdk.set_extra(key, value)
162
+ sentry_sdk.set_tags(tags)
163
+ for key, value in contexts.items():
164
+ sentry_sdk.set_context(key, value)
165
+
166
+ extras = self.span_kwargs.pop("extras", {})
167
+ tags = self.span_kwargs.pop("tags", {})
168
+ contexts = self.span_kwargs.pop("contexts", {})
133
169
  span = sentry_sdk.get_current_span()
134
170
  if span is None or self.force_new_transaction:
135
171
  with sentry_sdk.isolation_scope():
136
- transaction: Optional[sentry_sdk.tracing.Transaction] = None
137
- if self.trace_headers and "sentry-trace" in self.trace_headers:
138
- transaction = sentry_sdk.continue_trace(self.trace_headers, **self.span_kwargs)
139
- with sentry_sdk.start_transaction(transaction=transaction, **self.span_kwargs) as transaction:
140
- if transaction:
141
- transaction.description = transaction.name
172
+ if force_no_trace:
173
+ set_context()
142
174
  yield
143
- elif span.sampled:
175
+ else:
176
+ transaction: Optional[sentry_sdk.tracing.Transaction] = None
177
+ if self.trace_headers and "sentry-trace" in self.trace_headers:
178
+ transaction = sentry_sdk.continue_trace(self.trace_headers, **self.span_kwargs)
179
+ with sentry_sdk.start_transaction(transaction=transaction, **self.span_kwargs) as transaction:
180
+ if transaction:
181
+ transaction.description = transaction.name
182
+ set_context()
183
+ yield
184
+ elif not force_no_trace and span.sampled:
144
185
  self.span_kwargs.pop("source", None)
145
186
  with sentry_sdk.start_span(**self.span_kwargs):
187
+ set_context()
146
188
  yield
147
189
  else: # No need to start a span if the parent is not sampled
190
+ set_context()
148
191
  yield
149
192
 
150
193
  def __enter__(self) -> None:
@@ -179,9 +222,10 @@ class _Trace:
179
222
  return func_with_tracing
180
223
 
181
224
 
182
- def _continue_trace_zmq_message(topic: str, message: dict, op: str):
225
+ def _continue_trace_zmq_message(topic: str, message: dict, op: str, **kwargs):
183
226
  name = f"{topic}/{message.get('type', '')}"
184
- return _Trace(trace_headers=message, op=op, name=name, source="zmq", origin="auto.zmq")
227
+ return _Trace(trace_headers=message, op=op, name=name, source="zmq", origin="auto.zmq",
228
+ force_no_trace=topic in _topics_to_ignore, **kwargs)
185
229
 
186
230
 
187
231
  class StoringTransport(sentry_sdk.transport.HttpTransport):
@@ -349,6 +393,11 @@ def _patch_sentry_method():
349
393
 
350
394
  def _update_sentry_config(kwargs: dict):
351
395
  # Set default values
396
+ global _topics_to_ignore, _functions_to_ignore
397
+ _topics_to_ignore = kwargs.pop("topics_to_ignore", ["io"])
398
+ _functions_to_ignore = kwargs.pop(
399
+ "functions_to_ignore", ["message_handler.openmodule.utils.io.IoListener._on_io_message"])
400
+
352
401
  if "traces_sampler" not in kwargs:
353
402
  kwargs.setdefault("traces_sample_rate", 0.0001)
354
403
  if "profiles_sampler" not in kwargs:
@@ -371,6 +420,8 @@ def _update_sentry_config(kwargs: dict):
371
420
  kwargs["extras"]["name"] = settings.NAME
372
421
  if hasattr(settings, "GATE"):
373
422
  kwargs["extras"]["gate"] = settings.GATE
423
+ kwargs.setdefault("contexts", {})
424
+ kwargs["contexts"]["device"] = {"name": settings.RESOURCE, "model": settings.RESOURCE}
374
425
 
375
426
 
376
427
  def init_sentry(dsn: str, **kwargs):
@@ -388,12 +439,17 @@ def init_sentry(dsn: str, **kwargs):
388
439
 
389
440
  _update_sentry_config(kwargs)
390
441
  extras = kwargs.pop("extras", {})
442
+ contexts = kwargs.pop("contexts", {})
443
+ tags = kwargs.pop("tags", {})
391
444
  sentry_sdk.init(dsn=dsn, **kwargs)
392
445
 
393
446
  _patch_requests_library()
394
447
  _patch_sentry_method()
395
448
  for key, value in extras.items():
396
449
  sentry_sdk.get_global_scope().set_extra(key, value)
450
+ sentry_sdk.get_global_scope().set_tags(tags)
451
+ for key, value in contexts.items():
452
+ sentry_sdk.get_global_scope().set_context(key, value)
397
453
 
398
454
 
399
455
  def deinit_sentry():
@@ -137,7 +137,6 @@ class IoListener:
137
137
  return x if x else [IoState(pin="", gateway=Gateway(gate="", direction=""), type="", value=0, physical=0,
138
138
  inverted=False, last_timestamp=datetime.fromtimestamp(0))]
139
139
 
140
- @sentry.trace
141
140
  def _on_io_message(self, message: IoMessage):
142
141
  """
143
142
  This handler receives all IO Messages, saves any changes and calls any listeners registered in the IoListener
@@ -170,18 +169,20 @@ class IoListener:
170
169
  self.current_states[message.pin].last_timestamp = message.timestamp
171
170
 
172
171
  message = message.dict()
173
- for listener in self.listeners:
174
- """
175
- Handles the registered listeners the same as the dispatcher.
176
- Is copied here because all messages are needed to keep current_states up to date.
177
- """
178
- if listener.matches(message):
179
- try:
180
- listener.handler(self.current_states[message["pin"]])
181
- except zmq.ContextTerminated:
182
- raise
183
- except Exception as e:
184
- if self.raise_handler_errors:
185
- raise e from None
186
- else:
187
- self.log.exception("Error in message handler")
172
+ matched_listeners = [listener for listener in self.listeners if listener.matches(message)]
173
+ if matched_listeners:
174
+ with sentry.continue_trace_zmq_message_process("io", message):
175
+ for listener in matched_listeners:
176
+ """
177
+ Handles the registered listeners the same as the dispatcher.
178
+ Is copied here because all messages are needed to keep current_states up to date.
179
+ """
180
+ try:
181
+ listener.handler(self.current_states[message["pin"]])
182
+ except zmq.ContextTerminated:
183
+ raise
184
+ except Exception as e:
185
+ if self.raise_handler_errors:
186
+ raise e from None
187
+ else:
188
+ self.log.exception("Error in message handler")
@@ -3,6 +3,7 @@ import logging
3
3
  import random
4
4
  import threading
5
5
  import time
6
+ import uuid
6
7
  import warnings
7
8
  from typing import Type, Optional, List, Union, Dict
8
9
 
@@ -193,7 +194,7 @@ class KVStore:
193
194
  additional_kvs = current_kvs
194
195
  return KVSyncResponse(additions=additional_kvs, changes=changed_kvs, missing=missing_kvs)
195
196
 
196
- def _log_sync_rpc_response(self, rpc_entry: RPCClient.RPCEntry) -> bool:
197
+ def _log_sync_rpc_response(self, rpc_entry: RPCClient.RPCEntry, conn_id: str) -> bool:
197
198
  """
198
199
  Waits for the RPC to finish and logs the response
199
200
  :return: if successful
@@ -203,11 +204,22 @@ class KVStore:
203
204
  rpc_entry.result(ServerSyncResponse)
204
205
  return True
205
206
  except RPCClient.TimeoutError:
206
- self.log.error("Timeout syncing kvs")
207
+ if core().connection_listener.changed(conn_id):
208
+ self.log.warning("Connection loss during sync")
209
+ else:
210
+ self.log.error("Timeout syncing kvs")
207
211
  except RPCClient.CancelError:
208
- self.log.error("Cancelled waiting for result of syncing kvs")
212
+ if core().connection_listener.changed(conn_id):
213
+ self.log.warning("Connection loss during sync")
214
+ else:
215
+ self.log.error("Cancelled waiting for result of syncing kvs")
209
216
  except RPCClient.ValidationError:
210
217
  self.log.exception("Error parsing sync response")
218
+ except RPCClient.RPCServerError as e:
219
+ if len(e.args) > 0 and e.args[0] == "request_timeout" and core().connection_listener.changed(conn_id):
220
+ self.log.warning("Connection loss during sync")
221
+ else:
222
+ self.log.exception("Error on server side in sync")
211
223
  except (RPCClient.ServerHandlerError, RPCClient.ServerValidationError, RPCClient.ServerFilterError):
212
224
  self.log.exception("Error on server side in sync")
213
225
  except Exception:
@@ -215,9 +227,9 @@ class KVStore:
215
227
  return False
216
228
 
217
229
  @sentry.trace
218
- def sync(self) -> bool:
230
+ def sync(self, conn_id: str) -> bool:
219
231
  self.sync_rpc_entry = self.sync_with_server()
220
- success = self._log_sync_rpc_response(self.sync_rpc_entry)
232
+ success = self._log_sync_rpc_response(self.sync_rpc_entry, conn_id)
221
233
  self.sync_rpc_entry = None
222
234
  if success: # if sync was successful cancel retries
223
235
  return True
@@ -291,6 +303,7 @@ class KVStoreHandler:
291
303
 
292
304
  def run(self):
293
305
  """We only sync on startup and on reconnect"""
306
+ conn_id = uuid.uuid4().hex
294
307
  try:
295
308
  while self.running:
296
309
  if self._wait_for_change_to_online():
@@ -305,7 +318,8 @@ class KVStoreHandler:
305
318
  ConnectionStatus.online):
306
319
  # cancel trying to sync if offline
307
320
  break
308
- if store.sync():
321
+ core().connection_listener.changed(conn_id)
322
+ if store.sync(conn_id):
309
323
  # if sync was successful cancel retries
310
324
  break
311
325
  # we try again as long we are still alive
@@ -347,7 +361,7 @@ class KVStoreWithChangedNotification(KVStore):
347
361
  changed += list(old_values.keys())
348
362
  return changed
349
363
 
350
- def _send_changed_notification(self, new_values: Dict[str, str], old_values: Dict[str, str]): # pragma: no cover
364
+ def _send_changed_notification(self, new_values: Dict[str, str], old_values: Dict[str, str]): # pragma: no cover
351
365
  """
352
366
  consider using self._find_changed_kvs when implementing this
353
367
  also make sure your db model has a meaningful `comparison_value` method
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openmodule
3
- Version: 14.0.1
3
+ Version: 14.0.3
4
4
  Summary: Libraries for developing the arivo openmodule
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -0,0 +1 @@
1
+ {"git_version": "03b80ec", "is_release": true}
@@ -1,5 +1,5 @@
1
1
  pydantic<2,>=1.7
2
- sentry-sdk==2.19.0
2
+ sentry-sdk~=2.19.0
3
3
  orjson<4,>=3.4.7
4
4
  pyzmq<23,>=22
5
5
  pyyaml<6,>5
@@ -1,3 +1,4 @@
1
+ import threading
1
2
  from typing import List
2
3
  from unittest import TestCase, mock
3
4
 
@@ -16,15 +17,18 @@ class SentryTestTransport(sentry_sdk.transport.Transport):
16
17
  def __init__(self, options=None):
17
18
  super().__init__(options)
18
19
  self.envelopes: List[Envelope] = []
20
+ self.envelopes_lock = threading.Lock()
19
21
 
20
22
  def capture_envelope(self, envelope: Envelope):
21
- self.envelopes.append(envelope)
23
+ with self.envelopes_lock:
24
+ self.envelopes.append(envelope)
22
25
 
23
26
  def get_envelopes(self, clear: bool = True) -> List[Envelope]:
24
- envelopes = self.envelopes
25
- if clear:
26
- self.envelopes = []
27
- return envelopes
27
+ with self.envelopes_lock:
28
+ envelopes = self.envelopes
29
+ if clear:
30
+ self.envelopes = []
31
+ return envelopes
28
32
 
29
33
 
30
34
  class SentryTestMixin(TestCase):
@@ -56,10 +60,8 @@ class SentryTestMixin(TestCase):
56
60
  return transport
57
61
 
58
62
  def _get_envelopes(self) -> List[Envelope]:
59
- return self.sentry_transport.envelopes
63
+ return self.sentry_transport.get_envelopes(clear=False)
60
64
 
61
65
  def get_sent_envelopes(self, timeout: float = 0, clear: bool = True) -> List[Envelope]:
62
- envelopes = wait_for_value(self._get_envelopes, target=[], invert_target=True, timeout=timeout)
63
- if clear:
64
- self.sentry_transport.envelopes = []
65
- return envelopes
66
+ wait_for_value(self._get_envelopes, target=[], invert_target=True, timeout=timeout)
67
+ return self.sentry_transport.get_envelopes(clear=clear)
@@ -1,5 +1,5 @@
1
1
  pydantic>=1.7,<2
2
- sentry-sdk==2.19.0
2
+ sentry-sdk~=2.19.0
3
3
  orjson>=3.4.7,<4
4
4
  pyzmq>=22,<23
5
5
  pyyaml>5,<6