zrb 1.0.0b2__tar.gz → 1.0.0b4__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 (313) hide show
  1. {zrb-1.0.0b2 → zrb-1.0.0b4}/PKG-INFO +2 -1
  2. {zrb-1.0.0b2 → zrb-1.0.0b4}/pyproject.toml +2 -2
  3. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/__main__.py +3 -0
  4. zrb-1.0.0b4/src/zrb/builtin/llm/llm_chat.py +127 -0
  5. zrb-1.0.0b4/src/zrb/builtin/llm/previous-session.js +13 -0
  6. zrb-1.0.0b4/src/zrb/builtin/llm/tool/api.py +29 -0
  7. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/llm/tool/cli.py +1 -1
  8. zrb-1.0.0b4/src/zrb/builtin/llm/tool/rag.py +152 -0
  9. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/client_method.py +6 -6
  10. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/gateway_subroute.py +3 -1
  11. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +88 -44
  12. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +12 -0
  13. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +28 -22
  14. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +6 -6
  15. zrb-1.0.0b4/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +89 -0
  16. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +8 -0
  17. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +46 -14
  18. zrb-1.0.0b4/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +212 -0
  19. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +29 -0
  20. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +36 -14
  21. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +14 -14
  22. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +1 -1
  23. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +34 -6
  24. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +2 -6
  25. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +41 -2
  26. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/todo.py +1 -0
  27. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/config.py +23 -4
  28. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/any_input.py +5 -0
  29. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/base_input.py +6 -0
  30. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/bool_input.py +2 -0
  31. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/float_input.py +2 -0
  32. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/int_input.py +2 -0
  33. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/option_input.py +2 -0
  34. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/password_input.py +2 -0
  35. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/text_input.py +2 -0
  36. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/common_util.py +1 -1
  37. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/error_page/show_error_page.py +2 -1
  38. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/session/current-session.js +4 -2
  39. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/session/event.js +8 -2
  40. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/task_session_api_route.py +48 -3
  41. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/base_task.py +14 -13
  42. zrb-1.0.0b4/src/zrb/task/llm_task.py +350 -0
  43. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/llm/tool.py +3 -7
  44. zrb-1.0.0b2/src/zrb/builtin/llm/llm_chat.py +0 -47
  45. zrb-1.0.0b2/src/zrb/builtin/llm/tool/rag.py +0 -189
  46. zrb-1.0.0b2/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +0 -75
  47. zrb-1.0.0b2/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +0 -74
  48. zrb-1.0.0b2/src/zrb/task/llm_task.py +0 -220
  49. {zrb-1.0.0b2 → zrb-1.0.0b4}/README.md +0 -0
  50. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/__init__.py +0 -0
  51. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/attr/__init__.py +0 -0
  52. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/attr/type.py +0 -0
  53. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/__init__.py +0 -0
  54. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/base64.py +0 -0
  55. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/git.py +0 -0
  56. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/git_subtree.py +0 -0
  57. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/group.py +0 -0
  58. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/llm/tool/web.py +0 -0
  59. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/md5.py +0 -0
  60. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/__init__.py +0 -0
  61. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_input.py +0 -0
  62. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_task.py +0 -0
  63. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.flake8 +0 -0
  64. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.gitignore +0 -0
  65. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/README.md +0 -0
  66. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/__init__.py +0 -0
  67. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_task.py +0 -0
  68. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py +0 -0
  69. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +0 -0
  70. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +0 -0
  71. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/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 +0 -0
  72. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/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 +0 -0
  73. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/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 -0
  74. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/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 +0 -0
  75. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/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_factory.py +0 -0
  76. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +0 -0
  77. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +0 -0
  78. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/group.py +0 -0
  79. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +0 -0
  80. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +0 -0
  81. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +0 -0
  82. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py +0 -0
  83. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/alembic.ini +0 -0
  84. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_api_client.py +0 -0
  85. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_client.py +0 -0
  86. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_client_factory.py +0 -0
  87. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_direct_client.py +0 -0
  88. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/migration/README +0 -0
  89. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/migration/env.py +0 -0
  90. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/migration/script.py.mako +0 -0
  91. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/migration/versions/.gitkeep +0 -0
  92. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/migration_metadata.py +0 -0
  93. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +0 -0
  94. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/service/__init__.py +0 -0
  95. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py +0 -0
  96. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +0 -0
  97. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +0 -0
  98. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/venv_task.py +0 -0
  99. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/__init__.py +0 -0
  100. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app_factory.py +0 -0
  101. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +0 -0
  102. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/db_engine_factory.py +0 -0
  103. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +0 -0
  104. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/logger_factory.py +0 -0
  105. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/parser_factory.py +0 -0
  106. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/schema.py +0 -0
  107. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/app.py +0 -0
  108. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/parser.py +0 -0
  109. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/user_agent.py +0 -0
  110. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/view.py +0 -0
  111. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +0 -0
  112. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/migrate.py +0 -0
  113. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/__init__.py +0 -0
  114. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/alembic.ini +0 -0
  115. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_api_client.py +0 -0
  116. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client_factory.py +0 -0
  117. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_direct_client.py +0 -0
  118. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/README +0 -0
  119. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/env.py +0 -0
  120. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/script.py.mako +0 -0
  121. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +0 -0
  122. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +0 -0
  123. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py +0 -0
  124. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/__init__.py +0 -0
  125. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +0 -0
  126. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py +0 -0
  127. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py +0 -0
  128. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py +0 -0
  129. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository_factory.py +0 -0
  130. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/__init__.py +0 -0
  131. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py +0 -0
  132. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py +0 -0
  133. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py +0 -0
  134. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +0 -0
  135. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +0 -0
  136. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/alembic.ini +0 -0
  137. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/README +0 -0
  138. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/env.py +0 -0
  139. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/script.py.mako +0 -0
  140. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/versions/.gitkeep +0 -0
  141. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration_metadata.py +0 -0
  142. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +0 -0
  143. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/util/view.py +0 -0
  144. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/error.html +0 -0
  145. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/homepage.html +0 -0
  146. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-192x192.png +0 -0
  147. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-512x512.png +0 -0
  148. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/favicon-32x32.png +0 -0
  149. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.amber.min.css +0 -0
  150. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.blue.min.css +0 -0
  151. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.cyan.min.css +0 -0
  152. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.fuchsia.min.css +0 -0
  153. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.green.min.css +0 -0
  154. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.grey.min.css +0 -0
  155. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.indigo.min.css +0 -0
  156. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.jade.min.css +0 -0
  157. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.lime.min.css +0 -0
  158. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.min.css +0 -0
  159. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.orange.min.css +0 -0
  160. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pink.min.css +0 -0
  161. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pumpkin.min.css +0 -0
  162. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.purple.min.css +0 -0
  163. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.red.min.css +0 -0
  164. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.sand.min.css +0 -0
  165. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.slate.min.css +0 -0
  166. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.violet.min.css +0 -0
  167. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.yellow.min.css +0 -0
  168. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.zinc.min.css +0 -0
  169. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/template/default.html +0 -0
  170. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +0 -0
  171. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py +0 -0
  172. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/template.env +0 -0
  173. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/add/fastapp/fastapp_util.py +0 -0
  174. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/create/__init__.py +0 -0
  175. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/create/project-template/README.md +0 -0
  176. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/create/project-template/zrb_init.py +0 -0
  177. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/project/create/project_task.py +0 -0
  178. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/python.py +0 -0
  179. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/random.py +0 -0
  180. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/asdf/asdf.py +0 -0
  181. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/asdf/asdf_helper.py +0 -0
  182. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/common_input.py +0 -0
  183. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/latex/ubuntu.py +0 -0
  184. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/tmux/tmux.py +0 -0
  185. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/tmux/tmux_config.sh +0 -0
  186. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/tmux/tmux_helper.py +0 -0
  187. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/setup/ubuntu.py +0 -0
  188. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/shell/__init__.py +0 -0
  189. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/shell/autocomplete/__init__.py +0 -0
  190. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/shell/autocomplete/bash.py +0 -0
  191. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/shell/autocomplete/subcmd.py +0 -0
  192. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/builtin/shell/autocomplete/zsh.py +0 -0
  193. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/callback/__init__.py +0 -0
  194. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/callback/any_callback.py +0 -0
  195. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/callback/callback.py +0 -0
  196. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/cmd/__init__.py +0 -0
  197. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/cmd/cmd_result.py +0 -0
  198. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/cmd/cmd_val.py +0 -0
  199. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/content_transformer/__init__.py +0 -0
  200. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/content_transformer/any_content_transformer.py +0 -0
  201. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/content_transformer/content_transformer.py +0 -0
  202. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/context/__init__.py +0 -0
  203. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/context/any_context.py +0 -0
  204. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/context/any_shared_context.py +0 -0
  205. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/context/context.py +0 -0
  206. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/context/shared_context.py +0 -0
  207. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/dot_dict/__init__.py +0 -0
  208. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/dot_dict/dot_dict.py +0 -0
  209. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/env/__init__.py +0 -0
  210. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/env/any_env.py +0 -0
  211. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/env/env.py +0 -0
  212. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/env/env_file.py +0 -0
  213. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/env/env_map.py +0 -0
  214. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/group/__init__.py +0 -0
  215. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/group/any_group.py +0 -0
  216. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/group/group.py +0 -0
  217. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/__init__.py +0 -0
  218. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/input/str_input.py +0 -0
  219. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/__init__.py +0 -0
  220. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/cli.py +0 -0
  221. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_app.py +0 -0
  222. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_config/config.py +0 -0
  223. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_config/config_factory.py +0 -0
  224. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/__init__.py +0 -0
  225. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/docs_route.py +0 -0
  226. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/error_page/serve_default_404.py +0 -0
  227. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/error_page/view.html +0 -0
  228. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/home_page/__init__.py +0 -0
  229. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/home_page/home_page_route.py +0 -0
  230. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/home_page/view.html +0 -0
  231. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/login_api_route.py +0 -0
  232. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/login_page/login_page_route.py +0 -0
  233. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/login_page/view.html +0 -0
  234. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/logout_api_route.py +0 -0
  235. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/logout_page/logout_page_route.py +0 -0
  236. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/logout_page/view.html +0 -0
  237. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/group/show_group_page.py +0 -0
  238. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/group/view.html +0 -0
  239. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/node_page_route.py +0 -0
  240. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/task/partial/input.html +0 -0
  241. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/task/show_task_page.py +0 -0
  242. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/node_page/task/view.html +0 -0
  243. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/refresh_token_api_route.py +0 -0
  244. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/refresh-token.template.js +0 -0
  245. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/common.css +0 -0
  246. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/favicon-32x32.png +0 -0
  247. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/login/event.js +0 -0
  248. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/logout/event.js +0 -0
  249. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/pico.min.css +0 -0
  250. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/session/common-util.js +0 -0
  251. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/resources/session/past-session.js +0 -0
  252. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/static/static_route.py +0 -0
  253. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_route/task_input_api_route.py +0 -0
  254. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_schema/session.py +0 -0
  255. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_schema/token.py +0 -0
  256. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_schema/user.py +0 -0
  257. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_util/cookie.py +0 -0
  258. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_util/html.py +0 -0
  259. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_util/token.py +0 -0
  260. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/runner/web_util/user.py +0 -0
  261. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session/__init__.py +0 -0
  262. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session/any_session.py +0 -0
  263. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session/session.py +0 -0
  264. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_log/__init__.py +0 -0
  265. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_log/session_state_log.py +0 -0
  266. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_logger/__init__.py +0 -0
  267. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_logger/any_session_state_logger.py +0 -0
  268. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_logger/file_session_state_logger.py +0 -0
  269. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/session_state_logger/session_state_logger_factory.py +0 -0
  270. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/__init__.py +0 -0
  271. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/any_task.py +0 -0
  272. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/base_trigger.py +0 -0
  273. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/cmd_task.py +0 -0
  274. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/http_check.py +0 -0
  275. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/make_task.py +0 -0
  276. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/rsync_task.py +0 -0
  277. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/scaffolder.py +0 -0
  278. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/scheduler.py +0 -0
  279. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/task.py +0 -0
  280. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task/tcp_check.py +0 -0
  281. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task_status/__init__.py +0 -0
  282. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/task_status/task_status.py +0 -0
  283. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/__init__.py +0 -0
  284. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/attr.py +0 -0
  285. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cli/__init__.py +0 -0
  286. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cli/style.py +0 -0
  287. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cli/subcommand.py +0 -0
  288. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cmd/__init__.py +0 -0
  289. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cmd/command.py +0 -0
  290. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cmd/remote.py +0 -0
  291. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/__init__.py +0 -0
  292. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/append_code_to_class.py +0 -0
  293. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/append_code_to_function.py +0 -0
  294. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/append_code_to_method.py +0 -0
  295. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/append_key_to_dict.py +0 -0
  296. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/append_param_to_function_call.py +0 -0
  297. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/prepend_code_to_module.py +0 -0
  298. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/prepend_parent_to_class.py +0 -0
  299. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/codemod/prepend_property_to_class.py +0 -0
  300. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/cron.py +0 -0
  301. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/file.py +0 -0
  302. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/git.py +0 -0
  303. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/git_subtree.py +0 -0
  304. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/group.py +0 -0
  305. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/load.py +0 -0
  306. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/run.py +0 -0
  307. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/string/__init__.py +0 -0
  308. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/string/conversion.py +0 -0
  309. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/string/format.py +0 -0
  310. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/string/name.py +0 -0
  311. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/util/todo.py +0 -0
  312. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/xcom/__init__.py +0 -0
  313. {zrb-1.0.0b2 → zrb-1.0.0b4}/src/zrb/xcom/xcom.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 1.0.0b2
3
+ Version: 1.0.0b4
4
4
  Summary: Your Automation Powerhouse
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -26,6 +26,7 @@ Requires-Dist: pdfplumber (>=0.11.4,<0.12.0) ; extra == "rag"
26
26
  Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
27
27
  Requires-Dist: python-jose[cryptography] (>=3.3.0,<4.0.0)
28
28
  Requires-Dist: requests (>=2.32.3,<3.0.0)
29
+ Requires-Dist: ulid-py (>=1.1.0,<2.0.0)
29
30
  Project-URL: Documentation, https://github.com/state-alchemists/zrb
30
31
  Project-URL: Repository, https://github.com/state-alchemists/zrb
31
32
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "zrb"
3
- version = "1.0.0b2"
3
+ version = "1.0.0b4"
4
4
  description = "Your Automation Powerhouse"
5
5
  authors = ["Go Frendi Gunawan <gofrendiasgard@gmail.com>"]
6
6
  license = "AGPL-3.0-or-later"
@@ -50,6 +50,7 @@ pdfplumber = {version = "^0.11.4", optional = true}
50
50
  beautifulsoup4 = "^4.12.3"
51
51
  fastapi = {extras = ["standard"], version = "^0.115.6"}
52
52
  python-jose = {extras = ["cryptography"], version = "^3.3.0"}
53
+ ulid-py = "^1.1.0"
53
54
 
54
55
  [tool.poetry.extras]
55
56
  # poetry install -E rag
@@ -63,7 +64,6 @@ pytest-cov = "~6.0.0"
63
64
  pytest-asyncio = "~0.24.0"
64
65
  sqlmodel = "^0.0.22" # FastApp dependencies
65
66
  tomlkit = "^0.13.2"
66
- ulid = "^1.1" # FastApp dependencies
67
67
 
68
68
  [tool.pytest.ini_options]
69
69
  asyncio_default_fixture_loop_scope = "function"
@@ -16,5 +16,8 @@ def serve_cli():
16
16
  cli.run(sys.argv[1:])
17
17
  except KeyboardInterrupt:
18
18
  print(stylize_warning("\nStopped"), file=sys.stderr)
19
+ except RuntimeError as e:
20
+ if f"{e}".lower() != "event loop is closed":
21
+ raise e
19
22
  except NodeNotFoundError as e:
20
23
  print(stylize_error(f"{e}"), file=sys.stderr)
@@ -0,0 +1,127 @@
1
+ import json
2
+ import os
3
+ from typing import Any
4
+
5
+ from zrb.builtin.group import llm_group
6
+ from zrb.builtin.llm.tool.api import get_current_location, get_current_weather
7
+ from zrb.builtin.llm.tool.cli import run_shell_command
8
+ from zrb.builtin.llm.tool.web import open_web_route, query_internet
9
+ from zrb.config import (
10
+ LLM_ALLOW_ACCESS_INTERNET,
11
+ LLM_ALLOW_ACCESS_SHELL,
12
+ LLM_HISTORY_DIR,
13
+ LLM_MODEL,
14
+ LLM_SYSTEM_PROMPT,
15
+ )
16
+ from zrb.context.any_shared_context import AnySharedContext
17
+ from zrb.input.bool_input import BoolInput
18
+ from zrb.input.str_input import StrInput
19
+ from zrb.input.text_input import TextInput
20
+ from zrb.task.llm_task import LLMTask
21
+ from zrb.util.file import read_file, write_file
22
+ from zrb.util.string.conversion import to_pascal_case
23
+
24
+
25
+ class PreviousSessionInput(StrInput):
26
+
27
+ def to_html(self, ctx: AnySharedContext) -> str:
28
+ name = self.name
29
+ description = self.description
30
+ default = self.get_default_str(ctx)
31
+ script = read_file(
32
+ file_path=os.path.join(os.path.dirname(__file__), "previous-session.js"),
33
+ replace_map={
34
+ "CURRENT_INPUT_NAME": name,
35
+ "CurrentPascalInputName": to_pascal_case(name),
36
+ },
37
+ )
38
+ return "\n".join(
39
+ [
40
+ f'<input name="{name}" placeholder="{description}" value="{default}" />',
41
+ f"<script>{script}</script>",
42
+ ]
43
+ )
44
+
45
+
46
+ def _read_chat_conversation(ctx: AnySharedContext) -> list[dict[str, Any]]:
47
+ if ctx.input.start_new:
48
+ return []
49
+ previous_session_name = ctx.input.previous_session
50
+ if previous_session_name == "" or previous_session_name is None:
51
+ last_session_file_path = os.path.join(LLM_HISTORY_DIR, "last-session")
52
+ if os.path.isfile(last_session_file_path):
53
+ previous_session_name = read_file(last_session_file_path).strip()
54
+ conversation_file_path = os.path.join(
55
+ LLM_HISTORY_DIR, f"{previous_session_name}.json"
56
+ )
57
+ if not os.path.isfile(conversation_file_path):
58
+ return []
59
+ return json.loads(read_file(conversation_file_path))
60
+
61
+
62
+ def _write_chat_conversation(
63
+ ctx: AnySharedContext, conversations: list[dict[str, Any]]
64
+ ):
65
+ os.makedirs(LLM_HISTORY_DIR, exist_ok=True)
66
+ current_session_name = ctx.session.name
67
+ conversation_file_path = os.path.join(
68
+ LLM_HISTORY_DIR, f"{current_session_name}.json"
69
+ )
70
+ write_file(conversation_file_path, json.dumps(conversations, indent=2))
71
+ last_session_file_path = os.path.join(LLM_HISTORY_DIR, "last-session")
72
+ write_file(last_session_file_path, current_session_name)
73
+
74
+
75
+ llm_chat: LLMTask = llm_group.add_task(
76
+ LLMTask(
77
+ name="llm-chat",
78
+ input=[
79
+ StrInput(
80
+ "model",
81
+ description="LLM Model",
82
+ prompt="LLM Model",
83
+ default_str=LLM_MODEL,
84
+ allow_positional_parsing=False,
85
+ ),
86
+ TextInput(
87
+ "system-prompt",
88
+ description="System prompt",
89
+ prompt="System prompt",
90
+ default_str=LLM_SYSTEM_PROMPT,
91
+ allow_positional_parsing=False,
92
+ ),
93
+ BoolInput(
94
+ "start-new",
95
+ description="Start new conversation session",
96
+ prompt="Forget everything and start new conversation session",
97
+ default_str="false",
98
+ allow_positional_parsing=False,
99
+ ),
100
+ TextInput("message", description="User message", prompt="Your message"),
101
+ PreviousSessionInput(
102
+ "previous-session",
103
+ description="Previous conversation session",
104
+ prompt="Previous conversation session (can be empty)",
105
+ allow_positional_parsing=False,
106
+ allow_empty=True,
107
+ ),
108
+ ],
109
+ conversation_history_reader=_read_chat_conversation,
110
+ conversation_history_writer=_write_chat_conversation,
111
+ description="Chat with LLM",
112
+ model="{ctx.input.model}",
113
+ system_prompt="{ctx.input['system-prompt']}",
114
+ message="{ctx.input.message}",
115
+ retries=0,
116
+ ),
117
+ alias="chat",
118
+ )
119
+
120
+ if LLM_ALLOW_ACCESS_SHELL:
121
+ llm_chat.add_tool(run_shell_command)
122
+
123
+ if LLM_ALLOW_ACCESS_INTERNET:
124
+ llm_chat.add_tool(open_web_route)
125
+ llm_chat.add_tool(query_internet)
126
+ llm_chat.add_tool(get_current_location)
127
+ llm_chat.add_tool(get_current_weather)
@@ -0,0 +1,13 @@
1
+ let hasUpdateCurrentPascalInputName = false;
2
+ document.getElementById("submit-task-form").addEventListener("change", async function(event) {
3
+ const currentInput = event.target;
4
+ if (hasUpdateCurrentPascalInputName || currentInput.name === "CURRENT_INPUT_NAME") {
5
+ return
6
+ }
7
+ const previousSessionInput = submitTaskForm.querySelector('[name="CURRENT_INPUT_NAME"]');
8
+ if (previousSessionInput) {
9
+ const currentSessionName = cfg.SESSION_NAME
10
+ previousSessionInput.value = currentSessionName;
11
+ }
12
+ hasUpdateCurrentPascalInputName = true;
13
+ });
@@ -0,0 +1,29 @@
1
+ import json
2
+ from typing import Annotated, Literal
3
+
4
+ import requests
5
+
6
+
7
+ def get_current_location() -> (
8
+ Annotated[str, "JSON string representing latitude and longitude"]
9
+ ): # noqa
10
+ """Get the user's current location."""
11
+ return json.dumps(requests.get("http://ip-api.com/json?fields=lat,lon").json())
12
+
13
+
14
+ def get_current_weather(
15
+ latitude: float,
16
+ longitude: float,
17
+ temperature_unit: Literal["celsius", "fahrenheit"],
18
+ ) -> str:
19
+ """Get the current weather in a given location."""
20
+ resp = requests.get(
21
+ "https://api.open-meteo.com/v1/forecast",
22
+ params={
23
+ "latitude": latitude,
24
+ "longitude": longitude,
25
+ "temperature_unit": temperature_unit,
26
+ "current_weather": True,
27
+ },
28
+ )
29
+ return json.dumps(resp.json())
@@ -2,7 +2,7 @@ import subprocess
2
2
 
3
3
 
4
4
  def run_shell_command(command: str) -> str:
5
- """Running a shell command"""
5
+ """Running an actual shell command on user's computer."""
6
6
  output = subprocess.check_output(
7
7
  command, shell=True, stderr=subprocess.STDOUT, text=True
8
8
  )
@@ -0,0 +1,152 @@
1
+ import hashlib
2
+ import json
3
+ import os
4
+ import sys
5
+
6
+ import litellm
7
+ import ulid
8
+
9
+ from zrb.config import (
10
+ RAG_CHUNK_SIZE,
11
+ RAG_EMBEDDING_MODEL,
12
+ RAG_MAX_RESULT_COUNT,
13
+ RAG_OVERLAP,
14
+ )
15
+ from zrb.util.cli.style import stylize_error, stylize_faint
16
+ from zrb.util.file import read_file
17
+
18
+
19
+ def create_rag_from_directory(
20
+ tool_name: str,
21
+ tool_description: str,
22
+ document_dir_path: str = "./documents",
23
+ model: str = RAG_EMBEDDING_MODEL,
24
+ vector_db_path: str = "./chroma",
25
+ vector_db_collection: str = "documents",
26
+ chunk_size: int = RAG_CHUNK_SIZE,
27
+ overlap: int = RAG_OVERLAP,
28
+ max_result_count: int = RAG_MAX_RESULT_COUNT,
29
+ ):
30
+ async def retrieve(query: str) -> str:
31
+ from chromadb import PersistentClient
32
+ from chromadb.config import Settings
33
+
34
+ client = PersistentClient(
35
+ path=vector_db_path, settings=Settings(allow_reset=True)
36
+ )
37
+ collection = client.get_or_create_collection(vector_db_collection)
38
+
39
+ # Track file changes using a hash-based approach
40
+ hash_file_path = os.path.join(vector_db_path, "file_hashes.json")
41
+ previous_hashes = _load_hashes(hash_file_path)
42
+ current_hashes = {}
43
+
44
+ updated_files = []
45
+
46
+ for root, _, files in os.walk(document_dir_path):
47
+ for file in files:
48
+ file_path = os.path.join(root, file)
49
+ file_hash = _compute_file_hash(file_path)
50
+ relative_path = os.path.relpath(file_path, document_dir_path)
51
+ current_hashes[relative_path] = file_hash
52
+
53
+ if previous_hashes.get(relative_path) != file_hash:
54
+ updated_files.append(file_path)
55
+
56
+ if updated_files:
57
+ print(
58
+ stylize_faint(f"Updating {len(updated_files)} changed files"),
59
+ file=sys.stderr,
60
+ )
61
+
62
+ for file_path in updated_files:
63
+ try:
64
+ relative_path = os.path.relpath(file_path, document_dir_path)
65
+ collection.delete(where={"file_path": relative_path})
66
+ content = _read_file_content(file_path)
67
+ file_id = ulid.new().str
68
+ for i in range(0, len(content), chunk_size - overlap):
69
+ chunk = content[i : i + chunk_size]
70
+ if chunk:
71
+ chunk_id = ulid.new().str
72
+ print(
73
+ stylize_faint(
74
+ f"Vectorizing {relative_path} chunk {chunk_id}"
75
+ ),
76
+ file=sys.stderr,
77
+ )
78
+ response = await litellm.aembedding(
79
+ model=model, input=[chunk]
80
+ )
81
+ vector = response["data"][0]["embedding"]
82
+ collection.upsert(
83
+ ids=[chunk_id],
84
+ embeddings=[vector],
85
+ documents=[chunk],
86
+ metadatas={
87
+ "file_path": relative_path,
88
+ "file_id": file_id,
89
+ },
90
+ )
91
+ except Exception as e:
92
+ print(
93
+ stylize_error(f"Error processing {file_path}: {e}"),
94
+ file=sys.stderr,
95
+ )
96
+
97
+ _save_hashes(hash_file_path, current_hashes)
98
+ else:
99
+ print(
100
+ stylize_faint("No changes detected. Skipping database update."),
101
+ file=sys.stderr,
102
+ )
103
+
104
+ print(stylize_faint("Vectorizing query"), file=sys.stderr)
105
+ query_response = await litellm.aembedding(model=model, input=[query])
106
+ query_vector = query_response["data"][0]["embedding"]
107
+
108
+ print(stylize_faint("Searching documents"), file=sys.stderr)
109
+ results = collection.query(
110
+ query_embeddings=query_vector,
111
+ n_results=max_result_count,
112
+ )
113
+ return json.dumps(results)
114
+
115
+ retrieve.__name__ = tool_name
116
+ retrieve.__doc__ = tool_description
117
+ return retrieve
118
+
119
+
120
+ def _compute_file_hash(file_path: str) -> str:
121
+ hash_md5 = hashlib.md5()
122
+ with open(file_path, "rb") as f:
123
+ for chunk in iter(lambda: f.read(4096), b""):
124
+ hash_md5.update(chunk)
125
+ return hash_md5.hexdigest()
126
+
127
+
128
+ def _read_file_content(file_path: str) -> str:
129
+ if file_path.lower().endswith(".pdf"):
130
+ return _read_pdf(file_path)
131
+ return read_file(file_path)
132
+
133
+
134
+ def _read_pdf(file_path: str) -> str:
135
+ import pdfplumber
136
+
137
+ with pdfplumber.open(file_path) as pdf:
138
+ return "\n".join(
139
+ page.extract_text() for page in pdf.pages if page.extract_text()
140
+ )
141
+
142
+
143
+ def _load_hashes(file_path: str) -> dict:
144
+ if os.path.exists(file_path):
145
+ with open(file_path, "r") as f:
146
+ return json.load(f)
147
+ return {}
148
+
149
+
150
+ def _save_hashes(file_path: str, hashes: dict):
151
+ with open(file_path, "w") as f:
152
+ json.dump(hashes, f)
@@ -18,17 +18,17 @@ async def get_my_entities(
18
18
 
19
19
 
20
20
  @abstractmethod
21
- async def create_my_entity(self, data: MyEntityCreateWithAudit) -> MyEntityResponse:
22
- """Create a new my entities"""
23
-
24
-
25
- @abstractmethod
26
- async def create_my_entity(
21
+ async def create_my_entity_bulk(
27
22
  self, data: list[MyEntityCreateWithAudit]
28
23
  ) -> list[MyEntityResponse]:
29
24
  """Create new my entities"""
30
25
 
31
26
 
27
+ @abstractmethod
28
+ async def create_my_entity(self, data: MyEntityCreateWithAudit) -> MyEntityResponse:
29
+ """Create a new my entities"""
30
+
31
+
32
32
  @abstractmethod
33
33
  async def update_my_entity_bulk(
34
34
  self, my_entity_ids: list[str], data: MyEntityUpdateWithAudit
@@ -51,7 +51,9 @@ async def update_my_entity_bulk(my_entity_ids: list[str], data: MyEntityUpdate):
51
51
  response_model=MyEntityResponse,
52
52
  )
53
53
  async def update_my_entity(my_entity_id: str, data: MyEntityUpdate):
54
- return await my_module_client.update_my_entity(data.with_audit(updated_by="system"))
54
+ return await my_module_client.update_my_entity(
55
+ my_entity_id, data.with_audit(updated_by="system")
56
+ )
55
57
 
56
58
 
57
59
  @app.delete(
@@ -4,10 +4,15 @@ from typing import Any, Callable, Generic, Type, TypeVar
4
4
 
5
5
  import ulid
6
6
  from my_app_name.common.error import InvalidValueError, NotFoundError
7
- from my_app_name.common.parser_factory import parse_filter_param, parse_sort_param
7
+ from my_app_name.common.parser_factory import (
8
+ parse_filter_param as default_parse_filter_param,
9
+ )
10
+ from my_app_name.common.parser_factory import (
11
+ parse_sort_param as default_parse_sort_param,
12
+ )
8
13
  from sqlalchemy import Engine, delete, func, insert, select, update
9
14
  from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
10
- from sqlalchemy.sql import Select
15
+ from sqlalchemy.sql import ClauseElement, ColumnElement, Select
11
16
  from sqlmodel import Session, SQLModel
12
17
 
13
18
  DBModel = TypeVar("DBModel", bound=SQLModel)
@@ -24,16 +29,48 @@ class BaseDBRepository(Generic[DBModel, ResponseModel, CreateModel, UpdateModel]
24
29
  entity_name: str = "entity"
25
30
  column_preprocessors: dict[str, Callable[[Any], Any]] = {}
26
31
 
27
- def __init__(self, engine: Engine | AsyncEngine):
32
+ def __init__(
33
+ self,
34
+ engine: Engine | AsyncEngine,
35
+ filter_param_parser: (
36
+ Callable[[SQLModel, str], list[ClauseElement]] | None
37
+ ) = None,
38
+ sort_param_parser: Callable[[SQLModel, str], list[ColumnElement]] | None = None,
39
+ ):
28
40
  self.engine = engine
29
- self.is_async = isinstance(engine, AsyncEngine)
41
+ self._is_async = isinstance(engine, AsyncEngine)
42
+ self._parse_filter_param = (
43
+ filter_param_parser if filter_param_parser else default_parse_filter_param
44
+ )
45
+ self._parse_sort_param = (
46
+ sort_param_parser if sort_param_parser else default_parse_sort_param
47
+ )
48
+
49
+ @property
50
+ def is_async(self) -> bool:
51
+ return self._is_async
30
52
 
31
53
  def _select(self) -> Select:
54
+ """
55
+ This method is used to contruct select statement for get, get_by_id and get_by_ids.
56
+ To parse the result of the statement, make sure you override _rows_to_response as well.
57
+ """
32
58
  return select(self.db_model)
33
59
 
34
- def _rows_to_responses(self, rows: list[tuple[Any]]) -> list[ResponseModel]:
60
+ def _rows_to_responses(self, rows: list[tuple[Any, ...]]) -> list[ResponseModel]:
61
+ """
62
+ This method is used to parse the result of select statement generated by _select.
63
+ """
35
64
  return [self.response_model.model_validate(row[0]) for row in rows]
36
65
 
66
+ async def _select_to_response(
67
+ self, query_modifier: Callable[[Select], Any]
68
+ ) -> list[ResponseModel]:
69
+ statement = query_modifier(self._select())
70
+ async with self._session_scope() as session:
71
+ result = await self._execute_statement(session, statement)
72
+ return self._rows_to_responses(result.all())
73
+
37
74
  def _ensure_one(self, responses: list[ResponseModel]) -> ResponseModel:
38
75
  if not responses:
39
76
  raise NotFoundError(f"{self.entity_name} not found")
@@ -41,6 +78,22 @@ class BaseDBRepository(Generic[DBModel, ResponseModel, CreateModel, UpdateModel]
41
78
  raise InvalidValueError(f"Duplicate {self.entity_name}")
42
79
  return responses[0]
43
80
 
81
+ def _model_to_data_dict(
82
+ self, data: SQLModel, **additional_data: Any
83
+ ) -> dict[str, Any]:
84
+ """
85
+ This method transform SQLModel into dictionary for insert/update operation.
86
+ """
87
+ data_dict = data.model_dump(exclude_unset=True)
88
+ data_dict.update(additional_data)
89
+ for key, preprocessor in self.column_preprocessors.items():
90
+ if key not in data_dict:
91
+ continue
92
+ if not hasattr(self.db_model, key):
93
+ raise InvalidValueError(f"Invalid {self.entity_name} property: {key}")
94
+ data_dict[key] = preprocessor(data_dict[key])
95
+ return data_dict
96
+
44
97
  @asynccontextmanager
45
98
  async def _session_scope(self):
46
99
  if self.is_async:
@@ -65,25 +118,18 @@ class BaseDBRepository(Generic[DBModel, ResponseModel, CreateModel, UpdateModel]
65
118
  return session.execute(statement)
66
119
 
67
120
  async def get_by_id(self, id: str) -> ResponseModel:
68
- statement = self._select().where(self.db_model.id == id)
69
- async with self._session_scope() as session:
70
- result = await self._execute_statement(session, statement)
71
- responses = self._rows_to_responses(result.all())
72
- return self._ensure_one(responses)
121
+ rows = await self._select_to_response(lambda q: q.where(self.db_model.id == id))
122
+ return self._ensure_one(rows)
73
123
 
74
124
  async def get_by_ids(self, id_list: list[str]) -> list[ResponseModel]:
75
- statement = self._select().where(self.db_model.id.in_(id_list))
76
- async with self._session_scope() as session:
77
- result = await self._execute_statement(session, statement)
78
- return [
79
- self.db_model(**entity.model_dump())
80
- for entity in result.scalars().all()
81
- ]
125
+ return await self._select_to_response(
126
+ lambda q: q.where(self.db_model.id.in_(id_list))
127
+ )
82
128
 
83
129
  async def count(self, filter: str | None = None) -> int:
84
130
  count_statement = select(func.count(1)).select_from(self.db_model)
85
131
  if filter:
86
- filter_param = parse_filter_param(self.db_model, filter)
132
+ filter_param = self._parse_filter_param(self.db_model, filter)
87
133
  count_statement = count_statement.where(*filter_param)
88
134
  async with self._session_scope() as session:
89
135
  result = await self._execute_statement(session, count_statement)
@@ -96,33 +142,31 @@ class BaseDBRepository(Generic[DBModel, ResponseModel, CreateModel, UpdateModel]
96
142
  filter: str | None = None,
97
143
  sort: str | None = None,
98
144
  ) -> list[ResponseModel]:
99
- offset = (page - 1) * page_size
100
- statement = self._select().offset(offset).limit(page_size)
101
- if filter:
102
- filter_param = parse_filter_param(self.db_model, filter)
103
- statement = statement.where(*filter_param)
104
- if sort:
105
- sort_param = parse_sort_param(self.db_model, sort)
106
- statement = statement.order_by(*sort_param)
107
- async with self._session_scope() as session:
108
- result = await self._execute_statement(session, statement)
109
- return [
110
- self.db_model(**entity.model_dump())
111
- for entity in result.scalars().all()
112
- ]
145
+ return await self._select_to_response(
146
+ self._get_pagination_query_modifier(
147
+ page=page, page_size=page_size, filter=filter, sort=sort
148
+ )
149
+ )
113
150
 
114
- def _model_to_data_dict(
115
- self, data: SQLModel, **additional_data: Any
116
- ) -> dict[str, Any]:
117
- data_dict = data.model_dump(exclude_unset=True)
118
- data_dict.update(additional_data)
119
- for key, preprocessor in self.column_preprocessors.items():
120
- if key not in data_dict:
121
- continue
122
- if not hasattr(self.db_model, key):
123
- raise InvalidValueError(f"Invalid {self.entity_name} property: {key}")
124
- data_dict[key] = preprocessor(data_dict[key])
125
- return data_dict
151
+ def _get_pagination_query_modifier(
152
+ self,
153
+ page: int = 1,
154
+ page_size: int = 10,
155
+ filter: str | None = None,
156
+ sort: str | None = None,
157
+ ) -> Callable[[Select], Any]:
158
+ def pagination_query_modifier(statement: Select) -> Any:
159
+ offset = (page - 1) * page_size
160
+ statement = statement.offset(offset).limit(page_size)
161
+ if filter:
162
+ filter_param = self._parse_filter_param(self.db_model, filter)
163
+ statement = statement.where(*filter_param)
164
+ if sort:
165
+ sort_param = self._parse_sort_param(self.db_model, sort)
166
+ statement = statement.order_by(*sort_param)
167
+ return statement
168
+
169
+ return pagination_query_modifier
126
170
 
127
171
  async def create(self, data: CreateModel) -> DBModel:
128
172
  now = datetime.datetime.now(datetime.timezone.utc)
@@ -50,5 +50,17 @@ APP_AUTH_SUPER_USER = os.getenv("MY_APP_NAME_AUTH_SUPER_USER", "admin")
50
50
  APP_AUTH_SUPER_USER_PASSWORD = os.getenv(
51
51
  "MY_APP_NAME_AUTH_SUPER_USER_PASSWORD", "my-secure-password"
52
52
  )
53
+ APP_AUTH_GUEST_USER = os.getenv("MY_APP_NAME_AUTH_GUEST_USER", "user")
54
+ APP_AUTH_GUEST_USER_PERMISSIONS = (
55
+ permission_name.strip()
56
+ for permission_name in os.getenv(
57
+ "MY_APP_NAME_AUTH_GUEST_USER_PERMISSIONS", ""
58
+ ).split(",")
59
+ if permission_name.strip() != ""
60
+ )
61
+ APP_MAX_PARALLEL_SESSION = int(os.getenv("MY_APP_NAME_MAX_PARALLEL_SESSION", "1"))
62
+ APP_SESSION_EXPIRE_MINUTES = int(
63
+ os.getenv("MY_APP_NAME_SESSION_EXPIRE_MINUTES", "1440")
64
+ )
53
65
 
54
66
  APP_AUTH_BASE_URL = os.getenv("MY_APP_NAME_AUTH_BASE_URL", "http://localhost:3001")