labtasker 0.2.7__tar.gz → 0.2.8__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 (215) hide show
  1. {labtasker-0.2.7 → labtasker-0.2.8}/PKG-INFO +1 -1
  2. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/__init__.py +1 -1
  3. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/api_models.py +2 -1
  4. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/client_api.py +9 -1
  5. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/api.py +2 -0
  6. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/context.py +5 -0
  7. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/job_runner.py +2 -5
  8. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/logging.py +2 -0
  9. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/query_transpiler.py +2 -2
  10. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/database.py +5 -2
  11. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/endpoints.py +1 -0
  12. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker.egg-info/SOURCES.txt +1 -1
  13. {labtasker-0.2.7 → labtasker-0.2.8}/pyproject.toml +1 -1
  14. labtasker-0.2.8/tests/test_client/test_core/test_event/test_event_listener_entity_data.py +108 -0
  15. labtasker-0.2.7/tests/test_client/test_core/test_event/test_event_integration.py +0 -0
  16. {labtasker-0.2.7 → labtasker-0.2.8}/LICENSE +0 -0
  17. {labtasker-0.2.7 → labtasker-0.2.8}/MANIFEST.in +0 -0
  18. {labtasker-0.2.7 → labtasker-0.2.8}/README.md +0 -0
  19. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/__main__.py +0 -0
  20. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/__init__.py +0 -0
  21. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/__init__.py +0 -0
  22. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/cli.py +0 -0
  23. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/config.py +0 -0
  24. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/event.py +0 -0
  25. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/init.py +0 -0
  26. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/loop.py +0 -0
  27. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/queue.py +0 -0
  28. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/task.py +0 -0
  29. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/cli/worker.py +0 -0
  30. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/__init__.py +0 -0
  31. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cli_utils.py +0 -0
  32. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/LabCmd.g4 +0 -0
  33. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/LabCmdLexer.g4 +0 -0
  34. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/__init__.py +0 -0
  35. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/generated/LabCmd.py +0 -0
  36. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/generated/LabCmdLexer.py +0 -0
  37. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/generated/LabCmdListener.py +0 -0
  38. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/generated/__init__.py +0 -0
  39. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/cmd_parser/parser.py +0 -0
  40. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/config.py +0 -0
  41. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/events.py +0 -0
  42. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/exceptions.py +0 -0
  43. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/heartbeat.py +0 -0
  44. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/paths.py +0 -0
  45. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/plugin_utils.py +0 -0
  46. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/resolver/__init__.py +0 -0
  47. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/resolver/models.py +0 -0
  48. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/resolver/utils.py +0 -0
  49. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/utils.py +0 -0
  50. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/core/version_checker.py +0 -0
  51. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/templates/labtasker_root/.gitignore +0 -0
  52. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/templates/labtasker_root/client.toml +0 -0
  53. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/client/templates/labtasker_root/logs/.gitkeep +0 -0
  54. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/constants.py +0 -0
  55. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/filtering.py +0 -0
  56. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/security.py +0 -0
  57. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/__init__.py +0 -0
  58. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/cli.py +0 -0
  59. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/config.py +0 -0
  60. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/db_utils.py +0 -0
  61. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/dependencies.py +0 -0
  62. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/embedded_db.py +0 -0
  63. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/event_manager.py +0 -0
  64. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/fsm.py +0 -0
  65. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/server/logging.py +0 -0
  66. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/utils.py +0 -0
  67. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/README.txt +0 -0
  68. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/__init__.py +0 -0
  69. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/BufferedTokenStream.py +0 -0
  70. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/CommonTokenFactory.py +0 -0
  71. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/CommonTokenStream.py +0 -0
  72. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/FileStream.py +0 -0
  73. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/InputStream.py +0 -0
  74. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/IntervalSet.py +0 -0
  75. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/LL1Analyzer.py +0 -0
  76. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/Lexer.py +0 -0
  77. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/ListTokenSource.py +0 -0
  78. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/Parser.py +0 -0
  79. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/ParserInterpreter.py +0 -0
  80. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/ParserRuleContext.py +0 -0
  81. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/PredictionContext.py +0 -0
  82. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/Recognizer.py +0 -0
  83. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/RuleContext.py +0 -0
  84. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/StdinStream.py +0 -0
  85. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/Token.py +0 -0
  86. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/TokenStreamRewriter.py +0 -0
  87. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/Utils.py +0 -0
  88. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/__init__.py +0 -0
  89. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/_pygrun.py +0 -0
  90. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATN.py +0 -0
  91. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNConfig.py +0 -0
  92. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNConfigSet.py +0 -0
  93. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNDeserializationOptions.py +0 -0
  94. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNDeserializer.py +0 -0
  95. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNSimulator.py +0 -0
  96. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNState.py +0 -0
  97. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ATNType.py +0 -0
  98. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/LexerATNSimulator.py +0 -0
  99. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/LexerAction.py +0 -0
  100. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/LexerActionExecutor.py +0 -0
  101. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/ParserATNSimulator.py +0 -0
  102. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/PredictionMode.py +0 -0
  103. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/SemanticContext.py +0 -0
  104. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/Transition.py +0 -0
  105. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/atn/__init__.py +0 -0
  106. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/dfa/DFA.py +0 -0
  107. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/dfa/DFASerializer.py +0 -0
  108. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/dfa/DFAState.py +0 -0
  109. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/dfa/__init__.py +0 -0
  110. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/error/DiagnosticErrorListener.py +0 -0
  111. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/error/ErrorListener.py +0 -0
  112. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/error/ErrorStrategy.py +0 -0
  113. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/error/Errors.py +0 -0
  114. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/error/__init__.py +0 -0
  115. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/Chunk.py +0 -0
  116. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/ParseTreeMatch.py +0 -0
  117. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/ParseTreePattern.py +0 -0
  118. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/ParseTreePatternMatcher.py +0 -0
  119. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/RuleTagToken.py +0 -0
  120. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/TokenTagToken.py +0 -0
  121. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/Tree.py +0 -0
  122. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/Trees.py +0 -0
  123. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/tree/__init__.py +0 -0
  124. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/xpath/XPath.py +0 -0
  125. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/xpath/XPathLexer.py +0 -0
  126. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/antlr4/xpath/__init__.py +0 -0
  127. {labtasker-0.2.7 → labtasker-0.2.8}/labtasker/vendor/vendor.txt +0 -0
  128. {labtasker-0.2.7 → labtasker-0.2.8}/setup.cfg +0 -0
  129. {labtasker-0.2.7 → labtasker-0.2.8}/tests/__init__.py +0 -0
  130. {labtasker-0.2.7 → labtasker-0.2.8}/tests/conftest.py +0 -0
  131. {labtasker-0.2.7 → labtasker-0.2.8}/tests/demo_pager_iterator.py +0 -0
  132. {labtasker-0.2.7 → labtasker-0.2.8}/tests/dummy_jobs/job_1.py +0 -0
  133. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/__init__.py +0 -0
  134. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/database/__init__.py +0 -0
  135. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/database/mock.py +0 -0
  136. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/database/real.py +0 -0
  137. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/logging.py +0 -0
  138. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/mock_datetime_now.py +0 -0
  139. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/server/__init__.py +0 -0
  140. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/server/async_app.py +0 -0
  141. {labtasker-0.2.7 → labtasker-0.2.8}/tests/fixtures/server/sync_app.py +0 -0
  142. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_api_models.py +0 -0
  143. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/__init__.py +0 -0
  144. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/conftest.py +0 -0
  145. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/__init__.py +0 -0
  146. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/conftest.py +0 -0
  147. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_basic.py +0 -0
  148. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_config.py +0 -0
  149. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_event.py +0 -0
  150. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_init.py +0 -0
  151. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_loop.py +0 -0
  152. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_queue.py +0 -0
  153. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_task.py +0 -0
  154. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_cli/test_worker.py +0 -0
  155. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/__init__.py +0 -0
  156. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_cli_utils.py +0 -0
  157. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_event/__init__.py +0 -0
  158. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_event/test_concurrency_job_flow_event.py +0 -0
  159. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_event/test_event_listener_basic.py +0 -0
  160. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_event/test_various_actions.py +0 -0
  161. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_event/utils.py +0 -0
  162. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_heartbeat.py +0 -0
  163. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_job_runner.py +0 -0
  164. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_logging.py +0 -0
  165. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_loop_internal_error_handler.py +0 -0
  166. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_pager_iterator.py +0 -0
  167. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_parser.py +0 -0
  168. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/__init__.py +0 -0
  169. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/conftest.py +0 -0
  170. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/test_behavior.py +0 -0
  171. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/test_matching.py +0 -0
  172. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/test_utils.py +0 -0
  173. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_query_transpiler/utils.py +0 -0
  174. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_resolver.py +0 -0
  175. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_concurrency/__init__.py +0 -0
  176. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_concurrency/run_concurrent.py +0 -0
  177. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_concurrency/test_runner_concurrency_success_failure.py +0 -0
  178. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_concurrency/test_runner_high_concurrency.py +0 -0
  179. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_timeout/__init__.py +0 -0
  180. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_timeout/conftest.py +0 -0
  181. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_timeout/test_job_runner_timeout.py +0 -0
  182. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_timeout/test_job_runner_with_resolver_timeout.py +0 -0
  183. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_runner_with_resolver.py +0 -0
  184. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_server_notification_and_client_version.py +0 -0
  185. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_client/test_core/test_version_checker.py +0 -0
  186. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_filtering/__init__.py +0 -0
  187. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_filtering/exception_utils.py +0 -0
  188. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_filtering/test_exception_filtering.py +0 -0
  189. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_mock_time.py +0 -0
  190. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_security.py +0 -0
  191. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/__init__.py +0 -0
  192. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/conftest.py +0 -0
  193. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/__init__.py +0 -0
  194. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/conftest.py +0 -0
  195. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/test_database_basic.py +0 -0
  196. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/test_fetch_extra_filter.py +0 -0
  197. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/test_query_dict_to_mongo_filter.py +0 -0
  198. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_database/test_required_field_fetching.py +0 -0
  199. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_db_utils/__init__.py +0 -0
  200. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_db_utils/test_arg_match.py +0 -0
  201. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_db_utils/test_keys_to_query_dict.py +0 -0
  202. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_db_utils/test_keys_to_query_dict_deepest.py +0 -0
  203. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_db_utils/test_keys_to_query_dict_topmost.py +0 -0
  204. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_embedded_db.py +0 -0
  205. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_endpoint/__init__.py +0 -0
  206. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_endpoint/test_event_basic.py +0 -0
  207. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_endpoint/test_server.py +0 -0
  208. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_endpoint/test_server_async.py +0 -0
  209. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_endpoint/test_server_async_ping.py +0 -0
  210. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_fsm.py +0 -0
  211. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_server/test_get_verified_queue_dependency.py +0 -0
  212. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_utils/__init__.py +0 -0
  213. {labtasker-0.2.7 → labtasker-0.2.8}/tests/test_utils/test_utils.py +0 -0
  214. {labtasker-0.2.7 → labtasker-0.2.8}/tests/utils.py +0 -0
  215. {labtasker-0.2.7 → labtasker-0.2.8}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labtasker
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: A task queue system for lab experiments
5
5
  Author-email: Your Name <your.email@example.com>
6
6
  License: Apache License 2.0
@@ -1,4 +1,4 @@
1
- __version__ = "0.2.7"
1
+ __version__ = "0.2.8"
2
2
 
3
3
  from labtasker.client.client_api import *
4
4
  from labtasker.client.core.config import get_client_config
@@ -126,6 +126,7 @@ class TaskFetchRequest(BaseRequestModel):
126
126
  start_heartbeat: bool = True
127
127
  required_fields: Optional[List[str]] = None
128
128
  extra_filter: Optional[Dict[str, Any]] = None
129
+ cmd: Optional[Union[str, List[str]]] = None
129
130
 
130
131
 
131
132
  class Task(
@@ -149,7 +150,7 @@ class Task(
149
150
  priority: int
150
151
  metadata: Dict
151
152
  args: Dict
152
- cmd: Union[str, List[str]]
153
+ cmd: Optional[Union[str, List[str]]]
153
154
  summary: Dict
154
155
  worker_id: Optional[str]
155
156
 
@@ -1,7 +1,12 @@
1
1
  from typing import Any, Dict, List, Optional, Union
2
2
 
3
3
  from labtasker.client.core.api import * # noqa: F403
4
- from labtasker.client.core.context import current_task_id, current_worker_id, task_info
4
+ from labtasker.client.core.context import (
5
+ current_task_id,
6
+ current_worker_id,
7
+ is_enabled,
8
+ task_info,
9
+ )
5
10
  from labtasker.client.core.events import EventListener, connect_events
6
11
  from labtasker.client.core.exceptions import LabtaskerTypeError, LabtaskerValueError
7
12
  from labtasker.client.core.job_runner import (
@@ -10,6 +15,7 @@ from labtasker.client.core.job_runner import (
10
15
  set_loop_internal_error_handler,
11
16
  set_prompt_on_task_failure,
12
17
  )
18
+ from labtasker.client.core.paths import get_labtasker_log_dir
13
19
  from labtasker.client.core.resolver import (
14
20
  Required,
15
21
  get_params_from_function,
@@ -29,6 +35,8 @@ __all__ = [
29
35
  "task_info",
30
36
  "current_task_id",
31
37
  "current_worker_id",
38
+ "is_enabled",
39
+ "get_labtasker_log_dir",
32
40
  # event api
33
41
  "connect_events",
34
42
  "EventListener",
@@ -195,6 +195,7 @@ def fetch_task(
195
195
  required_fields: Optional[List[str]] = None,
196
196
  extra_filter: Optional[Dict[str, Any]] = None,
197
197
  client: Optional[httpx.Client] = None,
198
+ cmd: Optional[Union[str, List[str]]] = None,
198
199
  ) -> TaskFetchResponse:
199
200
  """Fetch the next available task from the queue."""
200
201
  if client is None:
@@ -212,6 +213,7 @@ def fetch_task(
212
213
  start_heartbeat=start_heartbeat,
213
214
  required_fields=required_fields,
214
215
  extra_filter=extra_filter,
216
+ cmd=cmd,
215
217
  ).model_dump()
216
218
  response = client.post("/api/v1/queues/me/tasks/next", json=payload)
217
219
  if response.status_code == HTTP_403_FORBIDDEN:
@@ -52,3 +52,8 @@ def set_current_task_id(task_id: str):
52
52
  def set_current_worker_id(worker_id: Optional[str]):
53
53
  os.environ["LABTASKER_WORKER_ID"] = worker_id if worker_id else ""
54
54
  _current_worker_id.set(worker_id)
55
+
56
+
57
+ def is_enabled() -> bool:
58
+ """Whether current script is executed under Labtasker context."""
59
+ return current_worker_id() is not None
@@ -183,6 +183,7 @@ def loop_run(
183
183
  start_heartbeat=True,
184
184
  required_fields=required_fields,
185
185
  extra_filter=extra_filter,
186
+ cmd=cmd,
186
187
  )
187
188
  if not resp.found: # task run complete
188
189
  logger.info(
@@ -190,11 +191,7 @@ def loop_run(
190
191
  )
191
192
  break
192
193
 
193
- # update the "cmd" field of the current task, and get the updated task info
194
- task = update_tasks(
195
- [TaskUpdateRequest(task_id=resp.task.task_id, cmd=cmd)], # noqa
196
- reset_pending=False,
197
- ).content[0]
194
+ task = resp.task
198
195
 
199
196
  logger.info(
200
197
  f"Prepared to run task {task.task_id} with args {task.args}."
@@ -18,12 +18,14 @@ stderr_console = Console(markup=True, stderr=True)
18
18
  LOGGER_FORMAT = (
19
19
  "<green>[{time:YYYY-MM-DD HH:mm:ss.SSS}]</green>"
20
20
  "[<level>{level: <8}</level>]"
21
+ "[<cyan>{name}</cyan>]"
21
22
  " - <level>{message}</level>"
22
23
  )
23
24
 
24
25
  DEBUG_LOGGER_FORMAT = (
25
26
  "<green>[{time:YYYY-MM-DD HH:mm:ss.SSS}]</green>"
26
27
  "[<level>{level: <8}</level>]"
28
+ "[<cyan>{name}</cyan>]"
27
29
  "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>"
28
30
  )
29
31
 
@@ -726,7 +726,7 @@ class QueryTranspiler(ast.NodeVisitor):
726
726
  operand_info = ""
727
727
  try:
728
728
  if isinstance(node.slice.value.operand, ast.Constant): # type: ignore[attr-defined]
729
- operand_info = f" (value: -{node.slice.value.operand.value})" # type: ignore[attr-defined]
729
+ operand_info = f" (value: -{node.slice.value.operand.value!s})" # type: ignore[attr-defined]
730
730
  elif isinstance(node.slice.value.operand, ast.Name): # type: ignore[attr-defined]
731
731
  operand_info = f" (variable: -{node.slice.value.operand.id})" # type: ignore[attr-defined]
732
732
  except AttributeError:
@@ -769,7 +769,7 @@ class QueryTranspiler(ast.NodeVisitor):
769
769
  operand_info = ""
770
770
  try:
771
771
  if isinstance(node.slice.operand, ast.Constant):
772
- operand_info = f" (value: -{node.slice.operand.value})"
772
+ operand_info = f" (value: -{node.slice.operand.value})" # type: ignore[str-bytes-safe]
773
773
  elif isinstance(node.slice.operand, ast.Name):
774
774
  operand_info = f" (variable: -{node.slice.operand.id})"
775
775
  except AttributeError:
@@ -521,6 +521,7 @@ class DBService:
521
521
  start_heartbeat: bool = True,
522
522
  required_fields: Optional[List[str]] = None,
523
523
  extra_filter: Optional[Dict[str, Any]] = None,
524
+ cmd: Optional[Union[str, List[str]]] = None,
524
525
  ) -> Optional[Mapping[str, Any]]:
525
526
  """
526
527
  Fetch next available task from queue.
@@ -538,6 +539,7 @@ class DBService:
538
539
  start_heartbeat (bool): Whether to start heartbeat.
539
540
  required_fields (list, optional): Which fields are required. If None, no constraint is put on which fields should exist in args dict.
540
541
  extra_filter (Dict[str, Any], optional): Additional filter criteria for the task.
542
+ cmd (Optional[Union[str, List[str]]]): The command that runs the job.
541
543
  """
542
544
  task_timeout = parse_timeout(eta_max) if eta_max else None
543
545
 
@@ -611,6 +613,7 @@ class DBService:
611
613
  "last_heartbeat": now if start_heartbeat else None,
612
614
  "last_modified": now,
613
615
  "worker_id": worker_id,
616
+ "cmd": cmd,
614
617
  }
615
618
  }
616
619
 
@@ -741,7 +744,7 @@ class DBService:
741
744
  )
742
745
 
743
746
  for event_handle in event_handles:
744
- event_handle.update_fsm_event(task, commit=True)
747
+ event_handle.commit()
745
748
 
746
749
  return True
747
750
 
@@ -774,7 +777,7 @@ class DBService:
774
777
  )
775
778
 
776
779
  for event_handle in event_handles:
777
- event_handle.update_fsm_event(task, commit=True)
780
+ event_handle.commit()
778
781
  return True
779
782
 
780
783
  def _report_task_status(
@@ -263,6 +263,7 @@ def fetch_task(
263
263
  start_heartbeat=task_request.start_heartbeat,
264
264
  required_fields=task_request.required_fields,
265
265
  extra_filter=task_request.extra_filter,
266
+ cmd=task_request.cmd,
266
267
  )
267
268
 
268
269
  if not task:
@@ -165,8 +165,8 @@ tests/test_client/test_core/test_server_notification_and_client_version.py
165
165
  tests/test_client/test_core/test_version_checker.py
166
166
  tests/test_client/test_core/test_event/__init__.py
167
167
  tests/test_client/test_core/test_event/test_concurrency_job_flow_event.py
168
- tests/test_client/test_core/test_event/test_event_integration.py
169
168
  tests/test_client/test_core/test_event/test_event_listener_basic.py
169
+ tests/test_client/test_core/test_event/test_event_listener_entity_data.py
170
170
  tests/test_client/test_core/test_event/test_various_actions.py
171
171
  tests/test_client/test_core/test_event/utils.py
172
172
  tests/test_client/test_core/test_query_transpiler/__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "labtasker"
7
- version = "0.2.7"
7
+ version = "0.2.8"
8
8
  description = "A task queue system for lab experiments"
9
9
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
10
10
  license = { text = "Apache License 2.0" }
@@ -0,0 +1,108 @@
1
+ """
2
+ End-to-end tests for the EventListener class that checks entity data.
3
+ """
4
+
5
+ import threading
6
+ import time
7
+
8
+ import pytest
9
+
10
+ from labtasker import Required, create_queue, loop, submit_task
11
+ from labtasker.api_models import EventResponse
12
+ from labtasker.client.core.events import connect_events
13
+ from tests.fixtures.logging import silence_logger
14
+ from tests.test_client.test_core.test_event.utils import dump_events
15
+
16
+ pytestmark = [
17
+ pytest.mark.e2e,
18
+ pytest.mark.usefixtures("silence_logger"),
19
+ ]
20
+
21
+
22
+ @pytest.fixture(autouse=True)
23
+ def setup_queue(client_config, db_fixture):
24
+ # relies on db_fixture so that DB is cleaned up after each test
25
+ return create_queue(
26
+ queue_name=client_config.queue.queue_name,
27
+ password=client_config.queue.password.get_secret_value(),
28
+ metadata={"tag": "test"},
29
+ )
30
+
31
+
32
+ def test_event_listener_entity_data():
33
+ """Test the basic flow of events when tasks are submitted and processed."""
34
+ job_finish_event = threading.Event()
35
+ listener = connect_events(timeout=5)
36
+
37
+ def jobflow_thread():
38
+ try:
39
+ # Submit tasks to generate events
40
+ task_id = submit_task(
41
+ task_name="test_task",
42
+ args={"foo": "bar"},
43
+ max_retries=1, # only 1 attempt
44
+ ).task_id
45
+
46
+ @loop()
47
+ def dummy(foo=Required()):
48
+ time.sleep(0.5)
49
+ raise RuntimeError # crash task
50
+
51
+ dummy() # fetch and run tasks
52
+ except Exception as e:
53
+ pytest.fail(f"Error in jobflow thread: {e}")
54
+ finally:
55
+ job_finish_event.set()
56
+
57
+ jobflow_thread = threading.Thread(target=jobflow_thread, daemon=True)
58
+
59
+ time.sleep(1) # wait for the listener to start
60
+ jobflow_thread.start()
61
+
62
+ # Wait for job to finish with timeout
63
+ job_finish_event.wait(timeout=10)
64
+ # Give some time for all events to be processed
65
+ time.sleep(2)
66
+ listener.stop()
67
+
68
+ # Check that we received the expected events
69
+ received_events = dump_events(listener)
70
+
71
+ expected_transition_sequence = [
72
+ # 1 job creation events
73
+ ("created", "pending"),
74
+ # worker creation event
75
+ ("created", "active"),
76
+ # 1 running and failure events
77
+ ("pending", "running"),
78
+ # worker fail() event result in either active -> active or active -> crashed
79
+ ("active", "active"),
80
+ # task fail() event
81
+ ("running", "failed"),
82
+ ]
83
+
84
+ assert len(received_events) == len(
85
+ expected_transition_sequence
86
+ ), f"Not enough events, got {len(received_events)} / {len(expected_transition_sequence)}"
87
+
88
+ # Verify event transitions match expected sequence
89
+ for i, event_resp in enumerate(received_events):
90
+ event_resp: EventResponse
91
+ from_state, to_state = expected_transition_sequence[i]
92
+ assert (
93
+ event_resp.event.old_state == from_state
94
+ ), f"Event {i} has wrong from_state: {event_resp.event.old_state}, expected {from_state}"
95
+ assert (
96
+ event_resp.event.new_state == to_state
97
+ ), f"Event {i} has wrong to_state: {event_resp.event.new_state}, expected {to_state}"
98
+
99
+ print(f"Event data: {event_resp.event.entity_data}")
100
+
101
+ # assert cmd in pending -> running event
102
+ assert received_events[2].event.entity_data["cmd"], "Cmd is missing"
103
+
104
+ # assert summary in running -> failed event
105
+ assert received_events[-1].event.entity_data["summary"], "Summary is missing"
106
+
107
+ # Join threads to clean up
108
+ jobflow_thread.join(timeout=3)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes