zrb 1.0.0a20__py3-none-any.whl → 1.0.0b3__py3-none-any.whl

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 (195) hide show
  1. zrb/__init__.py +2 -1
  2. zrb/__main__.py +3 -3
  3. zrb/builtin/__init__.py +3 -0
  4. zrb/builtin/group.py +1 -0
  5. zrb/builtin/llm/llm_chat.py +5 -3
  6. zrb/builtin/llm/tool/cli.py +1 -1
  7. zrb/builtin/llm/tool/rag.py +108 -145
  8. zrb/builtin/llm/tool/web.py +1 -1
  9. zrb/builtin/project/add/fastapp/fastapp_task.py +2 -0
  10. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py +5 -2
  11. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +80 -20
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +150 -42
  13. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service.py +113 -0
  14. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service_factory.py +9 -0
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_db_repository.py +0 -10
  16. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_repository.py +37 -16
  17. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/{factory.py → my_entity_repository_factory.py} +2 -2
  18. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +16 -6
  19. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/client_method.py +57 -0
  20. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/gateway_subroute.py +74 -0
  21. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +1 -1
  22. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +13 -0
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +23 -0
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +42 -0
  25. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py +7 -0
  26. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_api_client.py +6 -0
  27. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/{any_client.py → my_module_client.py} +1 -1
  28. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_client_factory.py +11 -0
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_direct_client.py +5 -0
  30. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +11 -11
  31. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py +2 -2
  32. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +8 -8
  33. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +47 -20
  34. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app_factory.py +29 -0
  35. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +230 -102
  36. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +236 -0
  37. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/{db_engine.py → db_engine_factory.py} +1 -1
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +12 -0
  39. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/logger_factory.py +10 -0
  40. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/parser_factory.py +7 -0
  41. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/app.py +47 -0
  42. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/parser.py +105 -0
  43. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/user_agent.py +58 -0
  44. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/view.py +37 -0
  45. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +37 -1
  46. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +1 -1
  47. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_api_client.py +16 -0
  48. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +169 -0
  49. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client_factory.py +9 -0
  50. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_direct_client.py +15 -0
  51. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +160 -0
  52. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +18 -1
  53. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +7 -3
  54. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +117 -0
  55. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py +11 -0
  56. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py +26 -0
  57. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py +61 -0
  58. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository_factory.py +13 -0
  59. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +89 -0
  60. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +67 -0
  61. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py +13 -0
  62. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +137 -0
  63. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py +7 -0
  64. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +179 -12
  65. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +67 -17
  66. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +2 -2
  67. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +127 -0
  68. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +7 -0
  69. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +43 -14
  70. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +200 -30
  71. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/util/view.py +74 -0
  72. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/error.html +6 -0
  73. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/homepage.html +6 -0
  74. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-192x192.png +0 -0
  75. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-512x512.png +0 -0
  76. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/favicon-32x32.png +0 -0
  77. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.amber.min.css +4 -0
  78. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.blue.min.css +4 -0
  79. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.cyan.min.css +4 -0
  80. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.fuchsia.min.css +4 -0
  81. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.green.min.css +4 -0
  82. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.grey.min.css +4 -0
  83. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.indigo.min.css +4 -0
  84. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.jade.min.css +4 -0
  85. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.lime.min.css +4 -0
  86. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.min.css +4 -0
  87. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.orange.min.css +4 -0
  88. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pink.min.css +4 -0
  89. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pumpkin.min.css +4 -0
  90. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.purple.min.css +4 -0
  91. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.red.min.css +4 -0
  92. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.sand.min.css +4 -0
  93. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.slate.min.css +4 -0
  94. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.violet.min.css +4 -0
  95. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.yellow.min.css +4 -0
  96. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.zinc.min.css +4 -0
  97. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/template/default.html +34 -0
  98. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +1 -0
  99. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +17 -5
  100. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +78 -4
  101. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +48 -0
  102. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +69 -5
  103. zrb/builtin/python.py +1 -1
  104. zrb/builtin/random.py +61 -0
  105. zrb/cmd/cmd_val.py +6 -5
  106. zrb/config.py +16 -3
  107. zrb/content_transformer/any_content_transformer.py +7 -0
  108. zrb/content_transformer/content_transformer.py +6 -0
  109. zrb/runner/cli.py +14 -7
  110. zrb/runner/web_app.py +28 -238
  111. zrb/runner/web_config/config.py +91 -0
  112. zrb/runner/web_config/config_factory.py +26 -0
  113. zrb/runner/web_route/docs_route.py +17 -0
  114. zrb/runner/web_route/error_page/serve_default_404.py +28 -0
  115. zrb/runner/{web_controller/error_page/controller.py → web_route/error_page/show_error_page.py} +4 -3
  116. zrb/runner/{web_controller → web_route}/error_page/view.html +6 -0
  117. zrb/runner/web_route/home_page/home_page_route.py +51 -0
  118. zrb/runner/{web_controller → web_route}/home_page/view.html +1 -0
  119. zrb/runner/web_route/login_api_route.py +31 -0
  120. zrb/runner/web_route/login_page/login_page_route.py +39 -0
  121. zrb/runner/{web_controller → web_route}/login_page/view.html +1 -0
  122. zrb/runner/web_route/logout_api_route.py +18 -0
  123. zrb/runner/web_route/logout_page/logout_page_route.py +40 -0
  124. zrb/runner/{web_controller → web_route}/logout_page/view.html +1 -0
  125. zrb/runner/{web_controller/group_info_page/controller.py → web_route/node_page/group/show_group_page.py} +3 -3
  126. zrb/runner/{web_controller/group_info_page → web_route/node_page/group}/view.html +1 -0
  127. zrb/runner/web_route/node_page/node_page_route.py +50 -0
  128. zrb/runner/{web_controller/session_page/controller.py → web_route/node_page/task/show_task_page.py} +5 -5
  129. zrb/runner/{web_controller/session_page → web_route/node_page/task}/view.html +1 -0
  130. zrb/runner/web_route/refresh_token_api_route.py +38 -0
  131. zrb/runner/web_route/static/refresh-token.template.js +22 -0
  132. zrb/runner/{web_controller/static → web_route/static/resources}/session/current-session.js +6 -3
  133. zrb/runner/{web_controller/static → web_route/static/resources}/session/event.js +10 -8
  134. zrb/runner/{web_controller/static → web_route/static/resources}/session/past-session.js +9 -3
  135. zrb/runner/web_route/static/static_route.py +44 -0
  136. zrb/runner/web_route/task_input_api_route.py +47 -0
  137. zrb/runner/web_route/task_session_api_route.py +147 -0
  138. zrb/runner/web_schema/session.py +5 -0
  139. zrb/runner/web_schema/token.py +11 -0
  140. zrb/runner/web_schema/user.py +32 -0
  141. zrb/runner/web_util/cookie.py +29 -0
  142. zrb/runner/{web_util.py → web_util/html.py} +1 -18
  143. zrb/runner/web_util/token.py +72 -0
  144. zrb/runner/web_util/user.py +63 -0
  145. zrb/session/session.py +6 -4
  146. zrb/session_state_logger/{default_session_state_logger.py → session_state_logger_factory.py} +1 -1
  147. zrb/task/base_task.py +56 -8
  148. zrb/task/base_trigger.py +2 -0
  149. zrb/task/cmd_task.py +9 -5
  150. zrb/task/http_check.py +2 -0
  151. zrb/task/llm_task.py +184 -71
  152. zrb/task/make_task.py +2 -0
  153. zrb/task/rsync_task.py +2 -0
  154. zrb/task/scaffolder.py +8 -5
  155. zrb/task/scheduler.py +2 -0
  156. zrb/task/tcp_check.py +2 -0
  157. zrb/task_status/task_status.py +4 -3
  158. zrb/util/cmd/command.py +1 -0
  159. zrb/util/file.py +7 -1
  160. zrb/util/llm/tool.py +3 -7
  161. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/METADATA +9 -52
  162. zrb-1.0.0b3.dist-info/RECORD +307 -0
  163. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +0 -27
  164. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_usecase.py +0 -65
  165. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +0 -6
  166. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +0 -6
  167. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +0 -9
  168. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app.py +0 -20
  169. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_usecase.py +0 -245
  170. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py +0 -33
  171. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +0 -7
  172. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +0 -6
  173. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +0 -9
  174. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
  175. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +0 -53
  176. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +0 -6
  177. zrb/runner/web_config.py +0 -288
  178. zrb/runner/web_controller/home_page/controller.py +0 -33
  179. zrb/runner/web_controller/login_page/controller.py +0 -25
  180. zrb/runner/web_controller/logout_page/controller.py +0 -26
  181. zrb-1.0.0a20.dist-info/RECORD +0 -243
  182. /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/{create_column_task.py → add_column_task.py} +0 -0
  183. /zrb/{runner/web_controller → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission}/__init__.py +0 -0
  184. /zrb/{runner/web_controller/group_info_page → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role}/__init__.py +0 -0
  185. /zrb/runner/{web_controller/home_page → web_route}/__init__.py +0 -0
  186. /zrb/runner/{web_controller/session_page → web_route/home_page}/__init__.py +0 -0
  187. /zrb/runner/{web_controller/session_page → web_route/node_page/task}/partial/input.html +0 -0
  188. /zrb/runner/{web_controller/static → web_route/static/resources}/common.css +0 -0
  189. /zrb/runner/{web_controller/static → web_route/static/resources}/favicon-32x32.png +0 -0
  190. /zrb/runner/{web_controller/static → web_route/static/resources}/login/event.js +0 -0
  191. /zrb/runner/{web_controller/static → web_route/static/resources}/logout/event.js +0 -0
  192. /zrb/runner/{web_controller/static → web_route/static/resources}/pico.min.css +0 -0
  193. /zrb/runner/{web_controller/static → web_route/static/resources}/session/common-util.js +0 -0
  194. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/WHEEL +0 -0
  195. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,11 @@
1
1
  from fastapi import FastAPI
2
- from my_app_name.common.app import app
2
+ from my_app_name.common.app_factory import app
3
3
  from my_app_name.common.schema import BasicResponse
4
4
  from my_app_name.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
5
- from my_app_name.module.auth.service.user.user_usecase_factory import user_usecase
5
+ from my_app_name.module.auth.service.permission.permission_service_factory import (
6
+ permission_service,
7
+ )
8
+ from my_app_name.module.auth.service.user.user_service_factory import user_service
6
9
 
7
10
 
8
11
  def serve_health_check(app: FastAPI):
@@ -31,7 +34,8 @@ def serve_route(app: FastAPI):
31
34
  serve_readiness_check(app)
32
35
 
33
36
  # Serve user endpoints for APIClient
34
- user_usecase.serve_route(app)
37
+ user_service.serve_route(app)
38
+ permission_service.serve_route(app)
35
39
 
36
40
 
37
41
  serve_route(app)
@@ -0,0 +1,117 @@
1
+ from logging import Logger
2
+
3
+ from my_app_name.common.base_service import BaseService
4
+ from my_app_name.module.auth.service.permission.repository.permission_repository import (
5
+ PermissionRepository,
6
+ )
7
+ from my_app_name.schema.permission import (
8
+ MultiplePermissionResponse,
9
+ PermissionCreateWithAudit,
10
+ PermissionResponse,
11
+ PermissionUpdateWithAudit,
12
+ )
13
+
14
+
15
+ class PermissionService(BaseService):
16
+
17
+ def __init__(self, logger: Logger, permission_repository: PermissionRepository):
18
+ super().__init__(logger)
19
+ self.permission_repository = permission_repository
20
+
21
+ @BaseService.route(
22
+ "/api/v1/permissions/{permission_id}",
23
+ methods=["get"],
24
+ response_model=PermissionResponse,
25
+ )
26
+ async def get_permission_by_id(self, permission_id: str) -> PermissionResponse:
27
+ return await self.permission_repository.get_by_id(permission_id)
28
+
29
+ @BaseService.route(
30
+ "/api/v1/permissions",
31
+ methods=["get"],
32
+ response_model=MultiplePermissionResponse,
33
+ )
34
+ async def get_permissions(
35
+ self,
36
+ page: int = 1,
37
+ page_size: int = 10,
38
+ sort: str | None = None,
39
+ filter: str | None = None,
40
+ ) -> MultiplePermissionResponse:
41
+ permissions = await self.permission_repository.get(
42
+ page, page_size, filter, sort
43
+ )
44
+ count = await self.permission_repository.count(filter)
45
+ return MultiplePermissionResponse(data=permissions, count=count)
46
+
47
+ @BaseService.route(
48
+ "/api/v1/permissions/bulk",
49
+ methods=["post"],
50
+ response_model=list[PermissionResponse],
51
+ )
52
+ async def create_permission_bulk(
53
+ self, data: list[PermissionCreateWithAudit]
54
+ ) -> list[PermissionResponse]:
55
+ permissions = await self.permission_repository.create_bulk(data)
56
+ return await self.permission_repository.get_by_ids(
57
+ [permission.id for permission in permissions]
58
+ )
59
+
60
+ @BaseService.route(
61
+ "/api/v1/permissions",
62
+ methods=["post"],
63
+ response_model=PermissionResponse,
64
+ )
65
+ async def create_permission(
66
+ self, data: PermissionCreateWithAudit
67
+ ) -> PermissionResponse:
68
+ permission = await self.permission_repository.create(data)
69
+ return await self.permission_repository.get_by_id(permission.id)
70
+
71
+ @BaseService.route(
72
+ "/api/v1/permissions/bulk",
73
+ methods=["put"],
74
+ response_model=PermissionResponse,
75
+ )
76
+ async def update_permission_bulk(
77
+ self, permission_ids: list[str], data: PermissionUpdateWithAudit
78
+ ) -> PermissionResponse:
79
+ permissions = await self.permission_repository.update_bulk(permission_ids, data)
80
+ return await self.permission_repository.get_by_ids(
81
+ [permission.id for permission in permissions]
82
+ )
83
+
84
+ @BaseService.route(
85
+ "/api/v1/permissions/{permission_id}",
86
+ methods=["put"],
87
+ response_model=PermissionResponse,
88
+ )
89
+ async def update_permission(
90
+ self, permission_id: str, data: PermissionUpdateWithAudit
91
+ ) -> PermissionResponse:
92
+ permission = await self.permission_repository.update(permission_id, data)
93
+ return await self.permission_repository.get_by_id(permission.id)
94
+
95
+ @BaseService.route(
96
+ "/api/v1/permissions/{permission_id}",
97
+ methods=["delete"],
98
+ response_model=PermissionResponse,
99
+ )
100
+ async def delete_permission_bulk(
101
+ self, permission_ids: list[str], deleted_by: str
102
+ ) -> PermissionResponse:
103
+ permissions = await self.permission_repository.delete_bulk(permission_ids)
104
+ return await self.permission_repository.get_by_ids(
105
+ [permission.id for permission in permissions]
106
+ )
107
+
108
+ @BaseService.route(
109
+ "/api/v1/permissions/{permission_id}",
110
+ methods=["delete"],
111
+ response_model=PermissionResponse,
112
+ )
113
+ async def delete_permission(
114
+ self, permission_id: str, deleted_by: str
115
+ ) -> PermissionResponse:
116
+ permission = await self.permission_repository.delete(permission_id)
117
+ return await self.permission_repository.get_by_id(permission.id)
@@ -0,0 +1,11 @@
1
+ from my_app_name.common.logger_factory import logger
2
+ from my_app_name.module.auth.service.permission.permission_service import (
3
+ PermissionService,
4
+ )
5
+ from my_app_name.module.auth.service.permission.repository.permission_repository_factory import (
6
+ permission_repository,
7
+ )
8
+
9
+ permission_service = PermissionService(
10
+ logger, permission_repository=permission_repository
11
+ )
@@ -0,0 +1,26 @@
1
+ from my_app_name.common.base_db_repository import BaseDBRepository
2
+ from my_app_name.module.auth.service.permission.repository.permission_repository import (
3
+ PermissionRepository,
4
+ )
5
+ from my_app_name.schema.permission import (
6
+ Permission,
7
+ PermissionCreateWithAudit,
8
+ PermissionResponse,
9
+ PermissionUpdateWithAudit,
10
+ )
11
+
12
+
13
+ class PermissionDBRepository(
14
+ BaseDBRepository[
15
+ Permission,
16
+ PermissionResponse,
17
+ PermissionCreateWithAudit,
18
+ PermissionUpdateWithAudit,
19
+ ],
20
+ PermissionRepository,
21
+ ):
22
+ db_model = Permission
23
+ response_model = PermissionResponse
24
+ create_model = PermissionCreateWithAudit
25
+ update_model = PermissionUpdateWithAudit
26
+ entity_name = "permission"
@@ -0,0 +1,61 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from my_app_name.schema.permission import (
4
+ Permission,
5
+ PermissionCreateWithAudit,
6
+ PermissionResponse,
7
+ PermissionUpdateWithAudit,
8
+ )
9
+
10
+
11
+ class PermissionRepository(ABC):
12
+
13
+ @abstractmethod
14
+ async def get_by_id(self, id: str) -> PermissionResponse:
15
+ """Get permission by id"""
16
+
17
+ @abstractmethod
18
+ async def get_by_ids(self, id_list: list[str]) -> PermissionResponse:
19
+ """Get permissions by ids"""
20
+
21
+ @abstractmethod
22
+ async def get(
23
+ self,
24
+ page: int = 1,
25
+ page_size: int = 10,
26
+ filter: str | None = None,
27
+ sort: str | None = None,
28
+ ) -> list[Permission]:
29
+ """Get permissions by filter and sort"""
30
+
31
+ @abstractmethod
32
+ async def count(self, filter: str | None = None) -> int:
33
+ """Count permissions by filter"""
34
+
35
+ @abstractmethod
36
+ async def create(self, data: PermissionCreateWithAudit) -> Permission:
37
+ """Create a new permission"""
38
+
39
+ @abstractmethod
40
+ async def create_bulk(
41
+ self, data: list[PermissionCreateWithAudit]
42
+ ) -> list[Permission]:
43
+ """Create some permissions"""
44
+
45
+ @abstractmethod
46
+ async def delete(self, id: str) -> Permission:
47
+ """Delete a permission"""
48
+
49
+ @abstractmethod
50
+ async def delete_bulk(self, id_list: list[str]) -> list[Permission]:
51
+ """Delete some permissions"""
52
+
53
+ @abstractmethod
54
+ async def update(self, id: str, data: PermissionUpdateWithAudit) -> Permission:
55
+ """Update a permission"""
56
+
57
+ @abstractmethod
58
+ async def update_bulk(
59
+ self, id_list: list[str], data: PermissionUpdateWithAudit
60
+ ) -> list[Permission]:
61
+ """Update some permissions"""
@@ -0,0 +1,13 @@
1
+ from my_app_name.common.db_engine_factory import db_engine
2
+ from my_app_name.config import APP_REPOSITORY_TYPE
3
+ from my_app_name.module.auth.service.permission.repository.permission_db_repository import (
4
+ PermissionDBRepository,
5
+ )
6
+ from my_app_name.module.auth.service.permission.repository.permission_repository import (
7
+ PermissionRepository,
8
+ )
9
+
10
+ if APP_REPOSITORY_TYPE == "db":
11
+ permission_repository: PermissionRepository = PermissionDBRepository(db_engine)
12
+ else:
13
+ permission_repository: PermissionRepository = None
@@ -0,0 +1,89 @@
1
+ import datetime
2
+ from typing import Any
3
+
4
+ import ulid
5
+ from my_app_name.common.base_db_repository import BaseDBRepository
6
+ from my_app_name.module.auth.service.role.repository.role_repository import (
7
+ RoleRepository,
8
+ )
9
+ from my_app_name.schema.permission import Permission
10
+ from my_app_name.schema.role import (
11
+ Role,
12
+ RoleCreateWithAudit,
13
+ RolePermission,
14
+ RoleResponse,
15
+ RoleUpdateWithAudit,
16
+ )
17
+ from sqlalchemy.sql import Select
18
+ from sqlmodel import delete, insert, select
19
+
20
+
21
+ class RoleDBRepository(
22
+ BaseDBRepository[
23
+ Role,
24
+ RoleResponse,
25
+ RoleCreateWithAudit,
26
+ RoleUpdateWithAudit,
27
+ ],
28
+ RoleRepository,
29
+ ):
30
+ db_model = Role
31
+ response_model = RoleResponse
32
+ create_model = RoleCreateWithAudit
33
+ update_model = RoleUpdateWithAudit
34
+ entity_name = "role"
35
+
36
+ def _select(self) -> Select:
37
+ return (
38
+ select(Role, Permission)
39
+ .join(RolePermission, RolePermission.role_id == Role.id, isouter=True)
40
+ .join(
41
+ Permission, Permission.id == RolePermission.permission_id, isouter=True
42
+ )
43
+ )
44
+
45
+ def _rows_to_responses(self, rows: list[tuple[Any, ...]]) -> list[RoleResponse]:
46
+ role_map: dict[str, dict[str, Any]] = {}
47
+ role_permission_map: dict[str, list[str]] = {}
48
+ for role, permission in rows:
49
+ if role.id not in role_map:
50
+ role_map[role.id] = {"role": role, "permissions": []}
51
+ role_permission_map[role.id] = []
52
+ if (
53
+ permission is not None
54
+ and permission.id not in role_permission_map[role.id]
55
+ ):
56
+ role_permission_map[role.id].append(permission.id)
57
+ role_map[role.id]["permissions"].append(permission.model_dump())
58
+ return [
59
+ RoleResponse(**data["role"].model_dump(), permissions=data["permissions"])
60
+ for data in role_map.values()
61
+ ]
62
+
63
+ async def add_permissions(self, data: dict[str, list[str]], created_by: str):
64
+ now = datetime.datetime.now(datetime.timezone.utc)
65
+ data_dict_list: list[dict[str, Any]] = []
66
+ for role_id, permission_ids in data.items():
67
+ for permission_id in permission_ids:
68
+ data_dict_list.append(
69
+ self._model_to_data_dict(
70
+ RolePermission(
71
+ id=ulid.new().str,
72
+ role_id=role_id,
73
+ permission_id=permission_id,
74
+ created_at=now,
75
+ created_by=created_by,
76
+ )
77
+ )
78
+ )
79
+ async with self._session_scope() as session:
80
+ await self._execute_statement(
81
+ session, insert(RolePermission).values(data_dict_list)
82
+ )
83
+
84
+ async def remove_all_permissions(self, role_ids: list[str] = []):
85
+ async with self._session_scope() as session:
86
+ await self._execute_statement(
87
+ session,
88
+ delete(RolePermission).where(RolePermission.role_id._in(role_ids)),
89
+ )
@@ -0,0 +1,67 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from my_app_name.schema.role import (
4
+ Role,
5
+ RoleCreateWithAudit,
6
+ RoleResponse,
7
+ RoleUpdateWithAudit,
8
+ )
9
+
10
+
11
+ class RoleRepository(ABC):
12
+
13
+ @abstractmethod
14
+ async def get_by_id(self, id: str) -> RoleResponse:
15
+ """Get role by id"""
16
+
17
+ @abstractmethod
18
+ async def get_by_ids(self, id_list: list[str]) -> RoleResponse:
19
+ """Get roles by ids"""
20
+
21
+ @abstractmethod
22
+ async def add_permissions(self, data: dict[str, list[str]], created_by: str):
23
+ """Adding permissions to roles"""
24
+
25
+ @abstractmethod
26
+ async def remove_all_permissions(self, role_ids: list[str] = []):
27
+ """Remove permissions from roles"""
28
+
29
+ @abstractmethod
30
+ async def get(
31
+ self,
32
+ page: int = 1,
33
+ page_size: int = 10,
34
+ filter: str | None = None,
35
+ sort: str | None = None,
36
+ ) -> list[Role]:
37
+ """Get roles by filter and sort"""
38
+
39
+ @abstractmethod
40
+ async def count(self, filter: str | None = None) -> int:
41
+ """Count roles by filter"""
42
+
43
+ @abstractmethod
44
+ async def create(self, data: RoleCreateWithAudit) -> Role:
45
+ """Create a new role"""
46
+
47
+ @abstractmethod
48
+ async def create_bulk(self, data: list[RoleCreateWithAudit]) -> list[Role]:
49
+ """Create some roles"""
50
+
51
+ @abstractmethod
52
+ async def delete(self, id: str) -> Role:
53
+ """Delete a role"""
54
+
55
+ @abstractmethod
56
+ async def delete_bulk(self, id_list: list[str]) -> list[Role]:
57
+ """Delete some roles"""
58
+
59
+ @abstractmethod
60
+ async def update(self, id: str, data: RoleUpdateWithAudit) -> Role:
61
+ """Update a role"""
62
+
63
+ @abstractmethod
64
+ async def update_bulk(
65
+ self, id_list: list[str], data: RoleUpdateWithAudit
66
+ ) -> list[Role]:
67
+ """Update some roles"""
@@ -0,0 +1,13 @@
1
+ from my_app_name.common.db_engine_factory import db_engine
2
+ from my_app_name.config import APP_REPOSITORY_TYPE
3
+ from my_app_name.module.auth.service.role.repository.role_db_repository import (
4
+ RoleDBRepository,
5
+ )
6
+ from my_app_name.module.auth.service.role.repository.role_repository import (
7
+ RoleRepository,
8
+ )
9
+
10
+ if APP_REPOSITORY_TYPE == "db":
11
+ role_repository: RoleRepository = RoleDBRepository(db_engine)
12
+ else:
13
+ role_repository: RoleRepository = None
@@ -0,0 +1,137 @@
1
+ from logging import Logger
2
+
3
+ from my_app_name.common.base_service import BaseService
4
+ from my_app_name.module.auth.service.role.repository.role_repository import (
5
+ RoleRepository,
6
+ )
7
+ from my_app_name.schema.role import (
8
+ MultipleRoleResponse,
9
+ RoleCreateWithPermissionsAndAudit,
10
+ RoleResponse,
11
+ RoleUpdateWithPermissionsAndAudit,
12
+ )
13
+
14
+
15
+ class RoleService(BaseService):
16
+
17
+ def __init__(self, logger: Logger, role_repository: RoleRepository):
18
+ super().__init__(logger)
19
+ self.role_repository = role_repository
20
+
21
+ @BaseService.route(
22
+ "/api/v1/roles/{role_id}",
23
+ methods=["get"],
24
+ response_model=RoleResponse,
25
+ )
26
+ async def get_role_by_id(self, role_id: str) -> RoleResponse:
27
+ return await self.role_repository.get_by_id(role_id)
28
+
29
+ @BaseService.route(
30
+ "/api/v1/roles",
31
+ methods=["get"],
32
+ response_model=MultipleRoleResponse,
33
+ )
34
+ async def get_roles(
35
+ self,
36
+ page: int = 1,
37
+ page_size: int = 10,
38
+ sort: str | None = None,
39
+ filter: str | None = None,
40
+ ) -> MultipleRoleResponse:
41
+ roles = await self.role_repository.get(page, page_size, filter, sort)
42
+ count = await self.role_repository.count(filter)
43
+ return MultipleRoleResponse(data=roles, count=count)
44
+
45
+ @BaseService.route(
46
+ "/api/v1/roles/bulk",
47
+ methods=["post"],
48
+ response_model=list[RoleResponse],
49
+ )
50
+ async def create_role_bulk(
51
+ self, data: list[RoleCreateWithPermissionsAndAudit]
52
+ ) -> list[RoleResponse]:
53
+ permission_ids = [row.get_permission_ids() for row in data]
54
+ data = [row.get_role_create_with_audit() for row in data]
55
+ roles = await self.role_repository.create_bulk(data)
56
+ if len(roles) > 0:
57
+ created_by = roles[0].created_by
58
+ await self.role_repository.add_permissions(
59
+ data={role.id: permission_ids[i] for i, role in enumerate(roles)},
60
+ created_by=created_by,
61
+ )
62
+ return await self.role_repository.get_by_ids([role.id for role in roles])
63
+
64
+ @BaseService.route(
65
+ "/api/v1/roles",
66
+ methods=["post"],
67
+ response_model=RoleResponse,
68
+ )
69
+ async def create_role(
70
+ self, data: RoleCreateWithPermissionsAndAudit
71
+ ) -> RoleResponse:
72
+ permission_ids = data.get_permission_ids()
73
+ data = data.get_role_create_with_audit()
74
+ role = await self.role_repository.create(data)
75
+ await self.role_repository.add_permissions(
76
+ data={role.id: permission_ids}, created_by=role.created_by
77
+ )
78
+ return await self.role_repository.get_by_id(role.id)
79
+
80
+ @BaseService.route(
81
+ "/api/v1/roles/bulk",
82
+ methods=["put"],
83
+ response_model=RoleResponse,
84
+ )
85
+ async def update_role_bulk(
86
+ self, role_ids: list[str], data: RoleUpdateWithPermissionsAndAudit
87
+ ) -> RoleResponse:
88
+ permission_ids = [row.get_permission_ids() for row in data]
89
+ data = [row.get_role_update_with_audit() for row in data]
90
+ roles = await self.role_repository.update_bulk(role_ids, data)
91
+ if len(roles) > 0:
92
+ updated_by = roles[0].updated_by
93
+ await self.role_repository.remove_all_permissions(
94
+ [role.id for role in roles]
95
+ )
96
+ await self.role_repository.add_permissions(
97
+ data={role.id: permission_ids[i] for i, role in enumerate(roles)},
98
+ created_by=updated_by,
99
+ )
100
+ return await self.role_repository.get_by_ids([role.id for role in roles])
101
+
102
+ @BaseService.route(
103
+ "/api/v1/roles/{role_id}",
104
+ methods=["put"],
105
+ response_model=RoleResponse,
106
+ )
107
+ async def update_role(
108
+ self, role_id: str, data: RoleUpdateWithPermissionsAndAudit
109
+ ) -> RoleResponse:
110
+ permission_ids = data.get_permission_ids()
111
+ data = data.get_role_update_with_audit()
112
+ role = await self.role_repository.update(role_id, data)
113
+ await self.role_repository.remove_all_permissions([role.id])
114
+ await self.role_repository.add_permissions(
115
+ data={role.id: permission_ids}, created_by=role.updated_by
116
+ )
117
+ return await self.role_repository.get_by_id(role.id)
118
+
119
+ @BaseService.route(
120
+ "/api/v1/roles/{role_id}",
121
+ methods=["delete"],
122
+ response_model=RoleResponse,
123
+ )
124
+ async def delete_role_bulk(
125
+ self, role_ids: list[str], deleted_by: str
126
+ ) -> RoleResponse:
127
+ roles = await self.role_repository.delete_bulk(role_ids)
128
+ return await self.role_repository.get_by_ids([role.id for role in roles])
129
+
130
+ @BaseService.route(
131
+ "/api/v1/roles/{role_id}",
132
+ methods=["delete"],
133
+ response_model=RoleResponse,
134
+ )
135
+ async def delete_role(self, role_id: str, deleted_by: str) -> RoleResponse:
136
+ role = await self.role_repository.delete(role_id)
137
+ return await self.role_repository.get_by_id(role.id)
@@ -0,0 +1,7 @@
1
+ from my_app_name.common.logger_factory import logger
2
+ from my_app_name.module.auth.service.role.repository.role_repository_factory import (
3
+ role_repository,
4
+ )
5
+ from my_app_name.module.auth.service.role.role_service import RoleService
6
+
7
+ role_service = RoleService(logger, role_repository=role_repository)