wiederverwendbar 0.8.3__tar.gz → 0.8.5__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 (178) hide show
  1. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/PKG-INFO +14 -14
  2. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/pyproject.toml +14 -14
  3. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/__init__.py +1 -1
  4. wiederverwendbar-0.8.5/src/wiederverwendbar/examples/sqlalchemy/db.py +89 -0
  5. wiederverwendbar-0.8.5/src/wiederverwendbar/functions/get_pretty_str.py +9 -0
  6. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/base.py +31 -2
  7. wiederverwendbar-0.8.5/src/wiederverwendbar/sqlalchemy/db.py +278 -0
  8. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/settings.py +9 -0
  9. wiederverwendbar-0.8.3/src/wiederverwendbar/examples/sqlalchemy/db.py +0 -31
  10. wiederverwendbar-0.8.3/src/wiederverwendbar/sqlalchemy/db.py +0 -152
  11. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/README.md +0 -0
  12. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/before_after_wrap.py +0 -0
  13. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/default.py +0 -0
  14. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/__init__.py +0 -0
  15. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/before_after_wrap.py +0 -0
  16. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/colors.py +0 -0
  17. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/extended_thread.py +0 -0
  18. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/file_config.py +0 -0
  19. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/indexable_model.py +0 -0
  20. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger.py +0 -0
  21. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/__init__.py +0 -0
  22. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/example.py +0 -0
  23. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/example_module.py +0 -0
  24. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/__init__.py +0 -0
  25. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/automatic_reference.py +0 -0
  26. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/db.py +0 -0
  27. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/log_streamer.py +0 -0
  28. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/logger.py +0 -0
  29. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/post_init.py +0 -0
  30. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/route.py +0 -0
  31. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/singletons.py +0 -0
  32. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/sqlalchemy/__init__.py +0 -0
  33. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/__init__.py +0 -0
  34. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log.py +0 -0
  35. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_file_download.py +0 -0
  36. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_form.py +0 -0
  37. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_thread.py +0 -0
  38. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/automatic_reference_admin.py +0 -0
  39. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/generic_embedded_document_field.py +0 -0
  40. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/multi_path_admin.py +0 -0
  41. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/task_manager.py +0 -0
  42. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/test_file.py +0 -0
  43. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/typer_resolve_defaults.py +0 -0
  44. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/uvicorn_server.py +0 -0
  45. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/__init__.py +0 -0
  46. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/admin.py +0 -0
  47. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/animal_name_generator.py +0 -0
  48. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/case_converter.py +0 -0
  49. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/check_hash_file.py +0 -0
  50. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/colors.py +0 -0
  51. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/datetime.py +0 -0
  52. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/download_file.py +0 -0
  53. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/eval.py +0 -0
  54. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/find_class_method.py +0 -0
  55. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/run_command.py +0 -0
  56. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/security/__init__.py +0 -0
  57. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/security/hashed_password.py +0 -0
  58. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/test_file.py +0 -0
  59. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/wait_ping.py +0 -0
  60. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/__init__.py +0 -0
  61. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/context.py +0 -0
  62. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/file_modes.py +0 -0
  63. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/__init__.py +0 -0
  64. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/rich_console_handler.py +0 -0
  65. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/stream_console_handler.py +0 -0
  66. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/tar_rotating_file_handler.py +0 -0
  67. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/helper.py +0 -0
  68. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/log_levels.py +0 -0
  69. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/logger.py +0 -0
  70. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/settings.py +0 -0
  71. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/singleton.py +0 -0
  72. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/terminal_out_files.py +0 -0
  73. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/__init__.py +0 -0
  74. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/automatic_reference.py +0 -0
  75. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/backup.py +0 -0
  76. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/db.py +0 -0
  77. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/__init__.py +0 -0
  78. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/boolean_also_field.py +0 -0
  79. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/domain_field.py +0 -0
  80. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/ipv4_address_field.py +0 -0
  81. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/ipv4_network_field.py +0 -0
  82. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/port_field.py +0 -0
  83. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/with_instance_field.py +0 -0
  84. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/__init__.py +0 -0
  85. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/documets.py +0 -0
  86. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/formatters.py +0 -0
  87. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/handlers.py +0 -0
  88. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/streamer.py +0 -0
  89. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/property_document.py +0 -0
  90. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/security/__init__.py +0 -0
  91. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/security/hashed_password.py +0 -0
  92. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/settings.py +0 -0
  93. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/singleton.py +0 -0
  94. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/post_init.py +0 -0
  95. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/__init__.py +0 -0
  96. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/file_config.py +0 -0
  97. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/indexable_model.py +0 -0
  98. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/printable_settings.py +0 -0
  99. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/security/__init__.py +0 -0
  100. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/security/hashed_password.py +0 -0
  101. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/singleton.py +0 -0
  102. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/route.py +0 -0
  103. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/singleton.py +0 -0
  104. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/__init__.py +0 -0
  105. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/raise_has_not_attr.py +0 -0
  106. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/singleton.py +0 -0
  107. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/types.py +0 -0
  108. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/__init__.py +0 -0
  109. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/__init__.py +0 -0
  110. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/admin.py +0 -0
  111. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/logger.py +0 -0
  112. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/settings.py +0 -0
  113. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/statics/js/actions.js +0 -0
  114. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/templates/modals/loading.html +0 -0
  115. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/thread.py +0 -0
  116. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/admin.py +0 -0
  117. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/__init__.py +0 -0
  118. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/admin.py +0 -0
  119. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/templates/macros/views.html +0 -0
  120. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/views.py +0 -0
  121. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/__init__.py +0 -0
  122. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/admin.py +0 -0
  123. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/settings.py +0 -0
  124. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/__init__.py +0 -0
  125. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/__init__.py +0 -0
  126. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/admin.py +0 -0
  127. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/__init__.py +0 -0
  128. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/session.py +0 -0
  129. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/user.py +0 -0
  130. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/provider.py +0 -0
  131. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/settings.py +0 -0
  132. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/__init__.py +0 -0
  133. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/auth.py +0 -0
  134. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/session.py +0 -0
  135. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/user.py +0 -0
  136. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/__init__.py +0 -0
  137. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/admin.py +0 -0
  138. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/converter.py +0 -0
  139. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/field.py +0 -0
  140. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/statics/js/boolean_also_field.js +0 -0
  141. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/templates/forms/boolean.html +0 -0
  142. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/converter.py +0 -0
  143. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/__init__.py +0 -0
  144. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/admin.py +0 -0
  145. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/converter.py +0 -0
  146. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/field.py +0 -0
  147. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/statics/js/form.js +0 -0
  148. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/statics/js/generic_embedded.js +0 -0
  149. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/templates/displays/generic_embedded.html +0 -0
  150. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/templates/forms/generic_embedded.html +0 -0
  151. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/view.py +0 -0
  152. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/helper.py +0 -0
  153. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/ipv4_field/__init__.py +0 -0
  154. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/ipv4_field/converter.py +0 -0
  155. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/view.py +0 -0
  156. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/multi_path/__init__.py +0 -0
  157. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/multi_path/admin.py +0 -0
  158. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/__init__.py +0 -0
  159. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/admin.py +0 -0
  160. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/settings.py +0 -0
  161. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/__init__.py +0 -0
  162. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/singleton.py +0 -0
  163. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/task.py +0 -0
  164. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/task_manager.py +0 -0
  165. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/trigger.py +0 -0
  166. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/threading/__init__.py +0 -0
  167. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/threading/extended_thread.py +0 -0
  168. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/typer/__init__.py +0 -0
  169. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/typer/typer_resolve_defaults.py +0 -0
  170. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/__init__.py +0 -0
  171. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/server.py +0 -0
  172. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/settings.py +0 -0
  173. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/__init__.py +0 -0
  174. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/frontend.py +0 -0
  175. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/meta.py +0 -0
  176. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/shared.py +0 -0
  177. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/task_manager.py +0 -0
  178. {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/worker.py +0 -0
@@ -1,49 +1,49 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wiederverwendbar
3
- Version: 0.8.3
3
+ Version: 0.8.5
4
4
  Summary: A collection of scripts, classes and tools they are \"wiederverwendbar\".
5
5
  Author-Email: Julius Koenig <info@bastelquartier.de>
6
6
  License: GPL-3.0
7
7
  Requires-Python: >=3.9
8
- Requires-Dist: pydantic>=2.11.4
8
+ Requires-Dist: pydantic>=2.11.5
9
9
  Requires-Dist: pydantic-settings>=2.9.1
10
10
  Requires-Dist: devtools>=0.12.2
11
11
  Provides-Extra: full
12
12
  Requires-Dist: rich>=14.0.0; extra == "full"
13
- Requires-Dist: typer>=0.15.3; extra == "full"
13
+ Requires-Dist: typer>=0.16.0; extra == "full"
14
14
  Requires-Dist: pythonping>=1.1.4; extra == "full"
15
15
  Requires-Dist: mongoengine>=0.29.1; extra == "full"
16
- Requires-Dist: nicegui>=2.17.0; extra == "full"
17
- Requires-Dist: uvicorn>=0.34.2; extra == "full"
16
+ Requires-Dist: nicegui>=2.19.0; extra == "full"
17
+ Requires-Dist: uvicorn>=0.34.3; extra == "full"
18
18
  Requires-Dist: fastapi>=0.115.12; extra == "full"
19
- Requires-Dist: starlette-admin[i18n]>=0.14.1; extra == "full"
19
+ Requires-Dist: starlette-admin[i18n]>=0.15.1; extra == "full"
20
20
  Requires-Dist: pillow>=11.2.1; extra == "full"
21
21
  Requires-Dist: blinker>=1.9.0; extra == "full"
22
- Requires-Dist: kombu>=5.5.3; extra == "full"
22
+ Requires-Dist: kombu>=5.5.4; extra == "full"
23
23
  Requires-Dist: nest-asyncio>=1.6.0; extra == "full"
24
- Requires-Dist: sqlalchemy>=2.0.40; extra == "full"
24
+ Requires-Dist: sqlalchemy>=2.0.41; extra == "full"
25
25
  Provides-Extra: rich
26
26
  Requires-Dist: rich>=14.0.0; extra == "rich"
27
27
  Provides-Extra: typer
28
- Requires-Dist: typer>=0.15.3; extra == "typer"
28
+ Requires-Dist: typer>=0.16.0; extra == "typer"
29
29
  Provides-Extra: mongoengine
30
30
  Requires-Dist: mongoengine>=0.29.1; extra == "mongoengine"
31
31
  Requires-Dist: blinker>=1.9.0; extra == "mongoengine"
32
32
  Provides-Extra: uvicorn
33
- Requires-Dist: uvicorn>=0.34.2; extra == "uvicorn"
33
+ Requires-Dist: uvicorn>=0.34.3; extra == "uvicorn"
34
34
  Provides-Extra: fastapi
35
35
  Requires-Dist: fastapi>=0.115.12; extra == "fastapi"
36
36
  Provides-Extra: nicegui
37
- Requires-Dist: nicegui>=2.17.0; extra == "nicegui"
37
+ Requires-Dist: nicegui>=2.19.0; extra == "nicegui"
38
38
  Provides-Extra: starlette-admin
39
- Requires-Dist: starlette-admin[i18n]>=0.14.1; extra == "starlette-admin"
39
+ Requires-Dist: starlette-admin[i18n]>=0.15.1; extra == "starlette-admin"
40
40
  Requires-Dist: pillow>=11.2.1; extra == "starlette-admin"
41
- Requires-Dist: kombu>=5.5.3; extra == "starlette-admin"
41
+ Requires-Dist: kombu>=5.5.4; extra == "starlette-admin"
42
42
  Requires-Dist: nest-asyncio>=1.6.0; extra == "starlette-admin"
43
43
  Provides-Extra: fuctions
44
44
  Requires-Dist: pythonping>=1.1.4; extra == "fuctions"
45
45
  Provides-Extra: sqlalchemy
46
- Requires-Dist: sqlalchemy>=2.0.40; extra == "sqlalchemy"
46
+ Requires-Dist: sqlalchemy>=2.0.41; extra == "sqlalchemy"
47
47
  Description-Content-Type: text/markdown
48
48
 
49
49
  # wiederverwendbar
@@ -6,13 +6,13 @@ authors = [
6
6
  { name = "Julius Koenig", email = "info@bastelquartier.de" },
7
7
  ]
8
8
  dependencies = [
9
- "pydantic>=2.11.4",
9
+ "pydantic>=2.11.5",
10
10
  "pydantic-settings>=2.9.1",
11
11
  "devtools>=0.12.2",
12
12
  ]
13
13
  requires-python = ">=3.9"
14
14
  readme = "README.md"
15
- version = "0.8.3"
15
+ version = "0.8.5"
16
16
 
17
17
  [project.license]
18
18
  text = "GPL-3.0"
@@ -20,49 +20,49 @@ text = "GPL-3.0"
20
20
  [project.optional-dependencies]
21
21
  full = [
22
22
  "rich>=14.0.0",
23
- "typer>=0.15.3",
23
+ "typer>=0.16.0",
24
24
  "pythonping>=1.1.4",
25
25
  "mongoengine>=0.29.1",
26
- "nicegui>=2.17.0",
27
- "uvicorn>=0.34.2",
26
+ "nicegui>=2.19.0",
27
+ "uvicorn>=0.34.3",
28
28
  "fastapi>=0.115.12",
29
- "starlette-admin[i18n]>=0.14.1",
29
+ "starlette-admin[i18n]>=0.15.1",
30
30
  "pillow>=11.2.1",
31
31
  "blinker>=1.9.0",
32
- "kombu>=5.5.3",
32
+ "kombu>=5.5.4",
33
33
  "nest-asyncio>=1.6.0",
34
- "sqlalchemy>=2.0.40",
34
+ "sqlalchemy>=2.0.41",
35
35
  ]
36
36
  rich = [
37
37
  "rich>=14.0.0",
38
38
  ]
39
39
  typer = [
40
- "typer>=0.15.3",
40
+ "typer>=0.16.0",
41
41
  ]
42
42
  mongoengine = [
43
43
  "mongoengine>=0.29.1",
44
44
  "blinker>=1.9.0",
45
45
  ]
46
46
  uvicorn = [
47
- "uvicorn>=0.34.2",
47
+ "uvicorn>=0.34.3",
48
48
  ]
49
49
  fastapi = [
50
50
  "fastapi>=0.115.12",
51
51
  ]
52
52
  nicegui = [
53
- "nicegui>=2.17.0",
53
+ "nicegui>=2.19.0",
54
54
  ]
55
55
  starlette-admin = [
56
- "starlette-admin[i18n]>=0.14.1",
56
+ "starlette-admin[i18n]>=0.15.1",
57
57
  "pillow>=11.2.1",
58
- "kombu>=5.5.3",
58
+ "kombu>=5.5.4",
59
59
  "nest-asyncio>=1.6.0",
60
60
  ]
61
61
  fuctions = [
62
62
  "pythonping>=1.1.4",
63
63
  ]
64
64
  sqlalchemy = [
65
- "sqlalchemy>=2.0.40",
65
+ "sqlalchemy>=2.0.41",
66
66
  ]
67
67
 
68
68
  [build-system]
@@ -1,4 +1,4 @@
1
- __version__ = "0.8.3"
1
+ __version__ = "0.8.5"
2
2
  TITLE = "wiederverwendbar"
3
3
  VERSION = __version__
4
4
  AUTHOR = "Julius Koenig"
@@ -0,0 +1,89 @@
1
+ from pathlib import Path
2
+ from typing import Optional
3
+
4
+ from sqlalchemy import Column, ForeignKey, Integer, Text
5
+
6
+ from sqlalchemy.orm import relationship
7
+
8
+ from wiederverwendbar.logger import LoggerSingleton, LoggerSettings, LogLevels
9
+ from wiederverwendbar.sqlalchemy import Base, SqlalchemySettings, SqlalchemyDbSingleton
10
+
11
+ LoggerSingleton(name="test", settings=LoggerSettings(log_level=LogLevels.DEBUG), init=True)
12
+ SqlalchemyDbSingleton(settings=SqlalchemySettings(db_file=Path("test.db")), init=True)
13
+
14
+
15
+ class MyBase(Base, SqlalchemyDbSingleton().Base):
16
+ __abstract__ = True
17
+
18
+
19
+ class Parent(MyBase):
20
+ __tablename__ = "parent"
21
+ __str_columns__: list[str] = ["id", "name"]
22
+
23
+ id: int = Column(Integer(), primary_key=True, autoincrement=True, name="parent_id")
24
+ name: str = Column(Text(50), nullable=False, unique=True)
25
+ children: list["Child"] = relationship("Child",
26
+ foreign_keys="Child.parent_id",
27
+ primaryjoin="Parent.id == Child.parent_id",
28
+ viewonly=True)
29
+
30
+
31
+ class Child(MyBase):
32
+ __tablename__ = "child"
33
+ __str_columns__: list[str] = ["id", "name"]
34
+
35
+ id: int = Column(Integer(), primary_key=True, autoincrement=True, name="parent_id")
36
+ name: str = Column(Text(50), nullable=False, unique=True)
37
+ parent_id: int = Column(Integer(), ForeignKey("parent.parent_id"), nullable=False, name="child_parent_id")
38
+ parent: Optional[Parent] = relationship("Parent",
39
+ foreign_keys="Parent.id",
40
+ primaryjoin="Child.parent_id == Parent.id")
41
+
42
+
43
+ if __name__ == '__main__':
44
+ SqlalchemyDbSingleton().create_all()
45
+
46
+ parent1 = Parent.get(name="parent1")
47
+ if parent1 is None:
48
+ parent1 = Parent(name="parent1")
49
+ parent1.save()
50
+
51
+ child1 = Child.get(name="child1")
52
+ if child1 is None:
53
+ child1 = Child(name="child1", parent_id=parent1.id)
54
+ child1.save()
55
+
56
+ child2 = Child.get(name="child2")
57
+ if child2 is None:
58
+ child2 = Child(name="child2", parent_id=parent1.id)
59
+ child2.save()
60
+
61
+ child3 = Child.get(name="child3")
62
+ if child3 is None:
63
+ child3 = Child(name="child3", parent_id=parent1.id)
64
+ child3.save()
65
+
66
+ parent2 = Parent.get(name="parent2")
67
+ if parent2 is None:
68
+ parent2 = Parent(name="parent2")
69
+ parent2.save()
70
+
71
+ child4 = Child.get(name="child4")
72
+ if child4 is None:
73
+ child4 = Child(name="child4", parent_id=parent2.id)
74
+ child4.save()
75
+
76
+ child5 = Child.get(name="child5")
77
+ if child5 is None:
78
+ child5 = Child(name="child5", parent_id=parent2.id)
79
+ child5.save()
80
+
81
+ child6 = Child.get(name="child6")
82
+ if child6 is None:
83
+ child6 = Child(name="child6", parent_id=parent2.id)
84
+ child6.save()
85
+
86
+ Parent.delete_all() # Should raise an IntegrityError --> FOREIGN KEY constraint failed
87
+ parent2.delete() # Should raise an IntegrityError --> FOREIGN KEY constraint failed
88
+
89
+ print()
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ def get_pretty_str(value):
5
+ if type(value) is str:
6
+ return f"'{value}'"
7
+ elif isinstance(value, Enum):
8
+ return get_pretty_str(value.value)
9
+ return f"{value}"
@@ -1,11 +1,13 @@
1
+ import warnings
1
2
  from typing import Any, Optional, Callable, Union, TYPE_CHECKING
2
3
 
3
4
  from sqlalchemy import inspect
4
5
  from sqlalchemy.sql import ColumnExpressionArgument
5
- from sqlalchemy.orm import Session, QueryableAttribute, InstrumentedAttribute
6
+ from sqlalchemy.orm import Session, QueryableAttribute
6
7
  from sqlalchemy.orm.exc import DetachedInstanceError
7
8
 
8
9
  from wiederverwendbar.default import Default
10
+ from wiederverwendbar.functions.get_pretty_str import get_pretty_str
9
11
  from wiederverwendbar.sqlalchemy.raise_has_not_attr import raise_has_not_attr
10
12
 
11
13
  if TYPE_CHECKING:
@@ -141,7 +143,18 @@ class Base:
141
143
  super().__init__(*args, **kwargs)
142
144
 
143
145
  def __str__(self):
144
- return f"{self.__class__.__name__}({', '.join([f'{column_name}={getattr(self, column_name)}' for column_name in self.__str_columns__])})"
146
+ out = f"{self.__class__.__name__}("
147
+ for attr_name in self.__str_columns__:
148
+ if type(attr_name) is tuple:
149
+ attr_view_name = attr_name[0]
150
+ attr_name = attr_name[1]
151
+ else:
152
+ attr_view_name = attr_name
153
+ if not hasattr(self, attr_name):
154
+ warnings.warn(f"Attribute '{attr_name}' is not set for {self}.")
155
+ out += f"{attr_view_name}={get_pretty_str(getattr(self, attr_name))}, "
156
+ out = out[:-2] + ")"
157
+ return out
145
158
 
146
159
  def __repr__(self):
147
160
  return self.__str__()
@@ -399,3 +412,19 @@ class Base:
399
412
  session.commit()
400
413
 
401
414
  self.session_close(session_created=session_created, session=session)
415
+
416
+ @classmethod
417
+ def delete_all(cls,
418
+ *criterion: Union[ColumnExpressionArgument[bool], bool],
419
+ session: Optional[Session] = None,
420
+ **kwargs: Any) -> None:
421
+ session_created, session = cls.session(session=session)
422
+
423
+ # delete rows
424
+ if criterion:
425
+ session.query(cls).filter(*criterion, **kwargs).delete()
426
+ else:
427
+ session.query(cls).filter_by(**kwargs).delete()
428
+ session.commit()
429
+
430
+ cls.session_close(session_created=session_created, session=session)
@@ -0,0 +1,278 @@
1
+ import inspect
2
+ import logging
3
+ import sqlite3
4
+ from ipaddress import IPv4Address
5
+ from pathlib import Path
6
+ from typing import Any, Optional, Union, Sequence, Callable
7
+
8
+ from sqlalchemy import create_engine, Table, event
9
+ from sqlalchemy.orm import sessionmaker, declarative_base, DeclarativeMeta as _DeclarativeMeta, Session
10
+ from sqlalchemy.ext.declarative import declarative_base
11
+
12
+ from wiederverwendbar.sqlalchemy.settings import SqlalchemySettings
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class DeclarativeMeta(_DeclarativeMeta):
18
+ def __init__(cls, classname: Any, bases: Any, dict_: Any, **kw: Any) -> None:
19
+ db = None
20
+ for base in bases:
21
+ if hasattr(base, "db"):
22
+ db = base.db
23
+ if db is None:
24
+ stack = inspect.stack()
25
+ for frame in stack:
26
+ if frame.function == "__init__":
27
+ db = frame.frame.f_locals.get("self", None)
28
+ if isinstance(db, SqlalchemyDb):
29
+ break
30
+ super().__init__(classname=classname, bases=bases, dict_=dict_, **kw)
31
+
32
+ cls.db: SqlalchemyDb = db
33
+
34
+
35
+ class SqlalchemyDb:
36
+ def __init__(self,
37
+ file: Optional[Path] = None,
38
+ host: Union[None, IPv4Address, str] = None,
39
+ port: Optional[int] = None,
40
+ protocol: Optional[str] = None,
41
+ name: Optional[str] = None,
42
+ username: Optional[str] = None,
43
+ password: Optional[str] = None,
44
+ echo: Optional[bool] = None,
45
+ test_on_startup: Optional[bool] = None,
46
+ sqlite_check_if_file_exist: Optional[bool] = None,
47
+ sqlite_handle_foreign_keys: Optional[bool] = None,
48
+ settings: Optional[SqlalchemySettings] = None):
49
+ """
50
+ Create a new Sqlalchemy Database
51
+
52
+ :param host: Host to connect to database
53
+ :param port: Port to connect to database
54
+ :param protocol: Protocol to connect to database
55
+ :param name: Name of the database
56
+ :param username: User to connect to database
57
+ :param password: Password to connect to database
58
+ :param echo: Echo SQL queries to console
59
+ :param test_on_startup: Test the database connection on startup.
60
+ :param sqlite_check_if_file_exist: Check if SQLite file exists before connecting to it.
61
+ :param sqlite_handle_foreign_keys: Enable SQLite Foreign Keys
62
+ :param settings: Sqlalchemy Settings
63
+ """
64
+
65
+ self._settings: SqlalchemySettings = settings or SqlalchemySettings()
66
+ self._file: Optional[Path] = file or self.settings.db_file
67
+ self._host: Union[IPv4Address, str, None] = host or self.settings.db_host
68
+ self._port: Optional[int] = port or self.settings.db_port
69
+ self._protocol: Optional[str] = protocol or self.settings.db_protocol
70
+ self._name: Optional[str] = name or self.settings.db_name
71
+ self._username: Optional[str] = username or self.settings.db_username
72
+ self._password: Optional[str] = password or self.settings.db_password
73
+ self._echo: bool = echo or self.settings.db_echo
74
+ self._test_on_startup: bool = test_on_startup or self.settings.db_test_on_startup
75
+ self._sqlite_check_if_file_exist: bool = sqlite_check_if_file_exist or self.settings.db_sqlite_check_if_file_exist
76
+ self._sqlite_handle_foreign_keys: bool = sqlite_handle_foreign_keys or self.settings.db_sqlite_handle_foreign_keys
77
+
78
+ logger.debug(f"Create {self}")
79
+
80
+ self.engine = create_engine(self.connection_string, echo=self.echo)
81
+ if self.protocol == "sqlite":
82
+ if self.sqlite_check_if_file_exist:
83
+ self.listen("connect", self._sqlite_check_if_file_exist_func)
84
+ if self.sqlite_handle_foreign_keys:
85
+ self.listen("connect", self._sqlite_handle_foreign_keys_func)
86
+ self._session_maker = sessionmaker(bind=self.engine)
87
+ self._Base: DeclarativeMeta = declarative_base(metaclass=DeclarativeMeta)
88
+ self.session_maker.configure(binds={self._Base: self.engine})
89
+
90
+ if self.test_on_startup:
91
+ self.test()
92
+
93
+ def __str__(self):
94
+ return f"{self.__class__.__name__}({self.connection_string_printable})"
95
+
96
+ @property
97
+ def settings(self) -> SqlalchemySettings:
98
+ return self._settings
99
+
100
+ @property
101
+ def file(self) -> Optional[Path]:
102
+ return self._file
103
+
104
+ @property
105
+ def host(self) -> Union[IPv4Address, str, None]:
106
+ return self._host
107
+
108
+ @property
109
+ def port(self) -> Optional[int]:
110
+ return self._port
111
+
112
+ @property
113
+ def protocol(self) -> Optional[str]:
114
+ return self._protocol
115
+
116
+ @property
117
+ def name(self) -> Optional[str]:
118
+ return self._name
119
+
120
+ @property
121
+ def username(self) -> Optional[str]:
122
+ return self._username
123
+
124
+ @property
125
+ def password(self) -> Optional[str]:
126
+ return self._password
127
+
128
+ @property
129
+ def echo(self) -> bool:
130
+ return self._echo
131
+
132
+ @property
133
+ def test_on_startup(self) -> bool:
134
+ return self._test_on_startup
135
+
136
+ @property
137
+ def sqlite_check_if_file_exist(self) -> bool:
138
+ return self._sqlite_check_if_file_exist
139
+
140
+ @property
141
+ def sqlite_handle_foreign_keys(self) -> bool:
142
+ return self._sqlite_handle_foreign_keys
143
+
144
+ @property
145
+ def session_maker(self) -> sessionmaker:
146
+ return self._session_maker
147
+
148
+ # noinspection PyPep8Naming
149
+ @property
150
+ def Base(self) -> Any:
151
+ return self._Base
152
+
153
+ def get_connection_string(self, printable: bool = False) -> str:
154
+ """
155
+ Get the Connection String
156
+
157
+ :param printable: If True, the password will be hidden
158
+ :return: str
159
+ """
160
+
161
+ connection_string = f"{self.protocol}://"
162
+ if self.protocol == "sqlite":
163
+ if self.file is not None:
164
+ connection_string += f"/{self.file}"
165
+ else:
166
+ if self.username is not None:
167
+ connection_string += f"{self.username}"
168
+ if self.password is not None:
169
+ connection_string += ":"
170
+ if printable:
171
+ connection_string += "***"
172
+ else:
173
+ connection_string += self.password
174
+ if self.host is None:
175
+ raise RuntimeError(f"No host specified for {self}")
176
+ connection_string += f"@{self.host}"
177
+ if self.port is None:
178
+ raise RuntimeError(f"No port specified for {self}")
179
+ connection_string += f":{self.port}"
180
+ if self.name is None:
181
+ raise RuntimeError(f"No name specified for {self}")
182
+ connection_string += f"/{self.name}"
183
+ return connection_string
184
+
185
+ @property
186
+ def connection_string(self) -> str:
187
+ """
188
+ Get the Connection String
189
+
190
+ :return: str
191
+ """
192
+
193
+ return self.get_connection_string()
194
+
195
+ @property
196
+ def connection_string_printable(self) -> str:
197
+ """
198
+ Get the Connection String with Password hidden
199
+
200
+ :return: str
201
+ """
202
+
203
+ return self.get_connection_string(printable=True)
204
+
205
+ def test(self):
206
+ self.engine.connect()
207
+ print()
208
+
209
+ def create_all(self,
210
+ tables: Optional[Sequence[Table]] = None,
211
+ check_first: bool = True) -> None:
212
+ """
213
+ Create all Tables
214
+
215
+ :param tables: List of Tables to create. If None, all Tables will be created.
216
+ :param check_first: Check if Tables exist before creating them.
217
+ :return: None
218
+ """
219
+
220
+ logger.debug(f"Create all for {self}")
221
+ self.Base.metadata.create_all(bind=self.engine, tables=tables, checkfirst=check_first)
222
+
223
+ def session(self) -> Session:
224
+ """
225
+ Create a new Session
226
+
227
+ :return: Session
228
+ """
229
+
230
+ logger.debug(f"Create Session for {self}")
231
+ return self.session_maker()
232
+
233
+ def listen(self,
234
+ identifier: str,
235
+ func: Callable[..., Any],
236
+ *args: Any,
237
+ **kwargs: Any) -> None:
238
+ """
239
+ Register a listener function for the engine.
240
+
241
+ :param identifier: String name of the event.
242
+ :param func: Callable function.
243
+ :return: None
244
+
245
+ .. Seealso::
246
+ sqlalchemy.event.api.listen for more.
247
+ """
248
+
249
+ event.listen(self.engine, identifier, func, *args, **kwargs)
250
+
251
+ def listens_for(self,
252
+ identifier: str,
253
+ *args: Any,
254
+ **kw: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
255
+ """
256
+ Decorate a function as a listener for the engine.
257
+
258
+ :param identifier: String name of the event.
259
+ :return: Callable[[Callable[..., Any]], Callable[..., Any]]
260
+
261
+ .. Seealso::
262
+ sqlalchemy.event.api.listens_for for more.
263
+ """
264
+
265
+ return event.listens_for(self.engine, identifier, *args, **kw)
266
+
267
+ def _sqlite_check_if_file_exist_func(self, connection, _connection_record):
268
+ if self.file is not None:
269
+ if not self.file.is_file():
270
+ raise FileNotFoundError(f"Database file does not exist: {self.file}")
271
+
272
+ # noinspection PyMethodMayBeStatic
273
+ def _sqlite_handle_foreign_keys_func(self, connection, _connection_record):
274
+ if not isinstance(connection, sqlite3.Connection):
275
+ raise RuntimeError(f"Connection is not a sqlite3.Connection: {connection}")
276
+ cursor = connection.cursor()
277
+ cursor.execute("PRAGMA foreign_keys=ON")
278
+ cursor.close()
@@ -34,3 +34,12 @@ class SqlalchemySettings(PrintableSettings):
34
34
  db_echo: bool = Field(default=False,
35
35
  title="Database echo.",
36
36
  description="Echo SQL queries to console")
37
+ db_test_on_startup: bool = Field(default=True,
38
+ title="Test Database on Startup",
39
+ description="Test database connection on startup")
40
+ db_sqlite_check_if_file_exist: bool = Field(default=True,
41
+ title="Database SQLite Check If File Exist",
42
+ description="Check if file exists in SQLite")
43
+ db_sqlite_handle_foreign_keys: bool = Field(default=True,
44
+ title="Database SQLite Handle Foreign Keys",
45
+ description="Handle foreign keys in SQLite")
@@ -1,31 +0,0 @@
1
- from pathlib import Path
2
-
3
- from sqlalchemy import Column, Text, Integer
4
-
5
- from wiederverwendbar.logger import LoggerSingleton, LoggerSettings
6
- from wiederverwendbar.sqlalchemy import Base, SqlalchemySettings, SqlalchemyDbSingleton
7
-
8
- LoggerSingleton(name="test", settings=LoggerSettings(log_level=LoggerSettings.LogLevels.DEBUG), init=True)
9
-
10
-
11
- class MyBase(Base, SqlalchemyDbSingleton(settings=SqlalchemySettings(db_file=Path("test.db")), init=True).Base):
12
- __abstract__ = True
13
-
14
-
15
- class MyTable(MyBase):
16
- __tablename__ = "my_table"
17
- __str_columns__: list[str] = ["name"]
18
-
19
- name = Column(Text(50), primary_key=True)
20
- value = Column(Integer)
21
-
22
-
23
- if __name__ == '__main__':
24
- SqlalchemyDbSingleton().create_all()
25
-
26
- my_table = MyTable(name="test", value=1)
27
-
28
- d = my_table.as_dict()
29
- my_table.save()
30
-
31
- print()