haiway 0.18.1__tar.gz → 0.19.0__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 (106) hide show
  1. {haiway-0.18.1 → haiway-0.19.0}/PKG-INFO +1 -1
  2. {haiway-0.18.1 → haiway-0.19.0}/junit/test-results.xml +1 -1
  3. {haiway-0.18.1 → haiway-0.19.0}/pyproject.toml +1 -1
  4. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/__init__.py +0 -2
  5. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/access.py +53 -64
  6. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/observability.py +57 -35
  7. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/__init__.py +1 -2
  8. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/observability.py +54 -35
  9. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/tracing.py +36 -45
  10. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/opentelemetry/observability.py +60 -38
  11. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/structure.py +3 -151
  12. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/__init__.py +2 -0
  13. haiway-0.19.0/src/haiway/utils/formatting.py +148 -0
  14. {haiway-0.18.1 → haiway-0.19.0}/uv.lock +1 -1
  15. {haiway-0.18.1 → haiway-0.19.0}/.github/workflows/ci.yml +0 -0
  16. {haiway-0.18.1 → haiway-0.19.0}/.github/workflows/publish.yml +0 -0
  17. {haiway-0.18.1 → haiway-0.19.0}/.gitignore +0 -0
  18. {haiway-0.18.1 → haiway-0.19.0}/LICENSE +0 -0
  19. {haiway-0.18.1 → haiway-0.19.0}/Makefile +0 -0
  20. {haiway-0.18.1 → haiway-0.19.0}/README.md +0 -0
  21. {haiway-0.18.1 → haiway-0.19.0}/config/pre-push +0 -0
  22. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/.dockerignore +0 -0
  23. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/Dockerfile +0 -0
  24. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/Makefile +0 -0
  25. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/README.md +0 -0
  26. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/config/.env.example +0 -0
  27. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/config/unit.json +0 -0
  28. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/docker-compose.yml +0 -0
  29. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/pyproject.toml +0 -0
  30. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/__int__.py +0 -0
  31. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/__init__.py +0 -0
  32. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/config.py +0 -0
  33. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/state.py +0 -0
  34. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/types.py +0 -0
  35. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/user_tasks.py +0 -0
  36. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/__init__.py +0 -0
  37. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/__init__.py +0 -0
  38. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/client.py +0 -0
  39. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/config.py +0 -0
  40. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/state.py +0 -0
  41. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/types.py +0 -0
  42. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/__init__.py +0 -0
  43. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/__main__.py +0 -0
  44. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/__init__.py +0 -0
  45. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/execution.py +0 -0
  46. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/migration_0.py +0 -0
  47. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/types.py +0 -0
  48. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/__init__.py +0 -0
  49. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/__main__.py +0 -0
  50. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/application.py +0 -0
  51. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/config.py +0 -0
  52. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/__init__.py +0 -0
  53. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/context.py +0 -0
  54. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/__init__.py +0 -0
  55. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/technical.py +0 -0
  56. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/todos.py +0 -0
  57. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/__init__.py +0 -0
  58. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/__init__.py +0 -0
  59. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/config.py +0 -0
  60. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/postgres.py +0 -0
  61. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/state.py +0 -0
  62. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/types.py +0 -0
  63. {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/uv.lock +0 -0
  64. {haiway-0.18.1 → haiway-0.19.0}/guidelines/functionalities.md +0 -0
  65. {haiway-0.18.1 → haiway-0.19.0}/guidelines/packages.md +0 -0
  66. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/__init__.py +0 -0
  67. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/disposables.py +0 -0
  68. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/identifier.py +0 -0
  69. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/state.py +0 -0
  70. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/tasks.py +0 -0
  71. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/types.py +0 -0
  72. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/asynchrony.py +0 -0
  73. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/caching.py +0 -0
  74. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/retries.py +0 -0
  75. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/throttling.py +0 -0
  76. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/timeouted.py +0 -0
  77. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/opentelemetry/__init__.py +0 -0
  78. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/py.typed +0 -0
  79. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/__init__.py +0 -0
  80. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/attributes.py +0 -0
  81. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/path.py +0 -0
  82. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/requirement.py +0 -0
  83. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/validation.py +0 -0
  84. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/__init__.py +0 -0
  85. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/default.py +0 -0
  86. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/frozen.py +0 -0
  87. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/missing.py +0 -0
  88. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/always.py +0 -0
  89. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/collections.py +0 -0
  90. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/env.py +0 -0
  91. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/freezing.py +0 -0
  92. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/logs.py +0 -0
  93. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/mimic.py +0 -0
  94. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/noop.py +0 -0
  95. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/queue.py +0 -0
  96. {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/stream.py +0 -0
  97. {haiway-0.18.1 → haiway-0.19.0}/tests/__init__.py +0 -0
  98. {haiway-0.18.1 → haiway-0.19.0}/tests/test_async_queue.py +0 -0
  99. {haiway-0.18.1 → haiway-0.19.0}/tests/test_async_stream.py +0 -0
  100. {haiway-0.18.1 → haiway-0.19.0}/tests/test_attribute_path.py +0 -0
  101. {haiway-0.18.1 → haiway-0.19.0}/tests/test_auto_retry.py +0 -0
  102. {haiway-0.18.1 → haiway-0.19.0}/tests/test_cache.py +0 -0
  103. {haiway-0.18.1 → haiway-0.19.0}/tests/test_context.py +0 -0
  104. {haiway-0.18.1 → haiway-0.19.0}/tests/test_state.py +0 -0
  105. {haiway-0.18.1 → haiway-0.19.0}/tests/test_streaming.py +0 -0
  106. {haiway-0.18.1 → haiway-0.19.0}/tests/test_timeout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haiway
3
- Version: 0.18.1
3
+ Version: 0.19.0
4
4
  Summary: Framework for dependency injection and state management within structured concurrency model.
5
5
  Project-URL: Homepage, https://miquido.com
6
6
  Project-URL: Repository, https://github.com/miquido/haiway.git
@@ -1 +1 @@
1
- <?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="88" time="1.104" timestamp="2025-05-12T15:34:00.085428+00:00" hostname="pkrvmberfyhpb9w"><testcase classname="tests.test_async_queue" name="test_fails_when_stream_fails" time="0.001" /><testcase classname="tests.test_async_queue" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_queue" name="test_buffers_values_when_not_reading" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_buffer_when_streaming_fails" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_queue" name="test_fails_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_when_stream_fails" time="0.001" /><testcase classname="tests.test_async_stream" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_stream" name="test_finishes_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_failed" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_all_when_sending_async" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_id_path_points_to_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_points_to_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_id_path_set_updates_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_set_updates_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_auto_retry" name="test_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_logs_issue_with_errors" time="0.008" /><testcase classname="tests.test_auto_retry" name="test_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_when_cancelled" time="0.021" /><testcase classname="tests.test_auto_retry" name="test_async_uses_delay_with_errors" time="0.101" /><testcase classname="tests.test_auto_retry" name="test_async_uses_computed_delay_with_errors" time="0.106" /><testcase classname="tests.test_auto_retry" name="test_async_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_cache_value_with_same_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_different_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_limit_exceed" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_same_value_with_repeating_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_fails_with_error" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_different_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_limit_exceed" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_same_value_with_repeating_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_cancel_waiting_does_not_cancel_task" time="0.502" /><testcase classname="tests.test_cache" name="test_async_expiration_does_not_cancel_task" time="0.021" /><testcase classname="tests.test_cache" name="test_async_fails_with_error" time="0.001" /><testcase classname="tests.test_context" name="test_state_is_available_according_to_context" time="0.001" /><testcase classname="tests.test_context" name="test_state_update_updates_local_context" time="0.001" /><testcase classname="tests.test_context" name="test_exceptions_are_propagated" time="0.001" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments" time="0.002" /><testcase classname="tests.test_state" name="test_basic_initializes_with_defaults" time="0.001" /><testcase classname="tests.test_state" name="test_basic_equals_checks_properties" time="0.000" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments_and_defaults" time="0.000" /><testcase classname="tests.test_state" name="test_parametrized_initializes_with_proper_parameters" time="0.000" /><testcase classname="tests.test_state" name="test_nested_initializes_with_proper_arguments" time="0.001" /><testcase classname="tests.test_state" name="test_dict_skips_missing_properties" time="0.000" /><testcase classname="tests.test_state" name="test_initialization_allows_missing_properties" time="0.000" /><testcase classname="tests.test_state" name="test_generic_subtypes_validation" time="0.002" /><testcase classname="tests.test_state" name="test_copying_leaves_same_object" time="0.000" /><testcase classname="tests.test_streaming" name="test_fails_when_generator_fails" time="0.001" /><testcase classname="tests.test_streaming" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_streaming" name="test_ends_when_generator_ends" time="0.001" /><testcase classname="tests.test_streaming" name="test_delivers_updates_when_generating" time="0.001" /><testcase classname="tests.test_streaming" name="test_streaming_context_variables_access_is_preserved" time="0.001" /><testcase classname="tests.test_streaming" name="test_nested_streaming_streams_correctly" time="0.001" /><testcase classname="tests.test_timeout" name="test_returns_result_when_returning_value" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_error" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_cancel" time="0.011" /><testcase classname="tests.test_timeout" name="test_raises_with_timeout" time="0.011" /></testsuite></testsuites>
1
+ <?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="88" time="1.142" timestamp="2025-05-13T08:24:06.016960+00:00" hostname="pkrvmberfyhpb9w"><testcase classname="tests.test_async_queue" name="test_fails_when_stream_fails" time="0.002" /><testcase classname="tests.test_async_queue" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_queue" name="test_buffers_values_when_not_reading" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_buffer_when_streaming_fails" time="0.001" /><testcase classname="tests.test_async_queue" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_queue" name="test_fails_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_queue" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_when_stream_fails" time="0.001" /><testcase classname="tests.test_async_stream" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ends_when_stream_ends" time="0.001" /><testcase classname="tests.test_async_stream" name="test_finishes_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_fails_without_buffer" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_updates_when_sending" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_sending_to_failed" time="0.001" /><testcase classname="tests.test_async_stream" name="test_ignores_when_finishing_when_finished" time="0.001" /><testcase classname="tests.test_async_stream" name="test_delivers_all_when_sending_async" time="0.001" /><testcase classname="tests.test_attribute_path" name="test_id_path_points_to_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_points_to_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_path_points_to_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_points_to_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_id_path_set_updates_self" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_attribute_path_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_nested_attribute_path_set_updates_nested_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_recursive_attribute_set_updates_attribute" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_list_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_tuple_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_mixed_tuple_item_set_updates_item" time="0.000" /><testcase classname="tests.test_attribute_path" name="test_dict_item_path_set_updates_item" time="0.000" /><testcase classname="tests.test_auto_retry" name="test_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_logs_issue_with_errors" time="0.005" /><testcase classname="tests.test_auto_retry" name="test_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_returns_value_without_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_exceeding_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_cancellation" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_when_cancelled" time="0.021" /><testcase classname="tests.test_auto_retry" name="test_async_uses_delay_with_errors" time="0.102" /><testcase classname="tests.test_auto_retry" name="test_async_uses_computed_delay_with_errors" time="0.107" /><testcase classname="tests.test_auto_retry" name="test_async_logs_issue_with_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_retries_with_selected_errors" time="0.001" /><testcase classname="tests.test_auto_retry" name="test_async_fails_with_not_selected_errors" time="0.001" /><testcase classname="tests.test_cache" name="test_returns_cache_value_with_same_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_different_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_limit_exceed" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_same_value_with_repeating_argument" time="0.000" /><testcase classname="tests.test_cache" name="test_fails_with_error" time="0.000" /><testcase classname="tests.test_cache" name="test_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_returns_cache_value_with_same_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_different_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_limit_exceed" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_same_value_with_repeating_argument" time="0.001" /><testcase classname="tests.test_cache" name="test_async_returns_fresh_value_with_expiration_time_exceed" time="0.021" /><testcase classname="tests.test_cache" name="test_async_cancel_waiting_does_not_cancel_task" time="0.502" /><testcase classname="tests.test_cache" name="test_async_expiration_does_not_cancel_task" time="0.021" /><testcase classname="tests.test_cache" name="test_async_fails_with_error" time="0.001" /><testcase classname="tests.test_context" name="test_state_is_available_according_to_context" time="0.001" /><testcase classname="tests.test_context" name="test_state_update_updates_local_context" time="0.001" /><testcase classname="tests.test_context" name="test_exceptions_are_propagated" time="0.001" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments" time="0.002" /><testcase classname="tests.test_state" name="test_basic_initializes_with_defaults" time="0.001" /><testcase classname="tests.test_state" name="test_basic_equals_checks_properties" time="0.000" /><testcase classname="tests.test_state" name="test_basic_initializes_with_arguments_and_defaults" time="0.000" /><testcase classname="tests.test_state" name="test_parametrized_initializes_with_proper_parameters" time="0.000" /><testcase classname="tests.test_state" name="test_nested_initializes_with_proper_arguments" time="0.001" /><testcase classname="tests.test_state" name="test_dict_skips_missing_properties" time="0.000" /><testcase classname="tests.test_state" name="test_initialization_allows_missing_properties" time="0.000" /><testcase classname="tests.test_state" name="test_generic_subtypes_validation" time="0.002" /><testcase classname="tests.test_state" name="test_copying_leaves_same_object" time="0.001" /><testcase classname="tests.test_streaming" name="test_fails_when_generator_fails" time="0.001" /><testcase classname="tests.test_streaming" name="test_cancels_when_iteration_cancels" time="0.001" /><testcase classname="tests.test_streaming" name="test_ends_when_generator_ends" time="0.001" /><testcase classname="tests.test_streaming" name="test_delivers_updates_when_generating" time="0.001" /><testcase classname="tests.test_streaming" name="test_streaming_context_variables_access_is_preserved" time="0.001" /><testcase classname="tests.test_streaming" name="test_nested_streaming_streams_correctly" time="0.001" /><testcase classname="tests.test_timeout" name="test_returns_result_when_returning_value" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_error" time="0.001" /><testcase classname="tests.test_timeout" name="test_raises_with_cancel" time="0.011" /><testcase classname="tests.test_timeout" name="test_raises_with_timeout" time="0.011" /></testsuite></testsuites>
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
  [project]
6
6
  name = "haiway"
7
7
  description = "Framework for dependency injection and state management within structured concurrency model."
8
- version = "0.18.1"
8
+ version = "0.19.0"
9
9
  readme = "README.md"
10
10
  maintainers = [
11
11
  { name = "Kacper Kaliński", email = "kacper.kalinski@miquido.com" },
@@ -20,7 +20,6 @@ from haiway.context import (
20
20
  )
21
21
  from haiway.helpers import (
22
22
  LoggerObservability,
23
- ResultTrace,
24
23
  asynchronous,
25
24
  cache,
26
25
  retry,
@@ -87,7 +86,6 @@ __all__ = (
87
86
  "ObservabilityMetricRecording",
88
87
  "ObservabilityScopeEntering",
89
88
  "ObservabilityScopeExiting",
90
- "ResultTrace",
91
89
  "ScopeContext",
92
90
  "ScopeIdentifier",
93
91
  "State",
@@ -11,6 +11,7 @@ from collections.abc import (
11
11
  Callable,
12
12
  Coroutine,
13
13
  Iterable,
14
+ Mapping,
14
15
  )
15
16
  from logging import Logger
16
17
  from types import TracebackType
@@ -597,81 +598,69 @@ class ctx:
597
598
  ObservabilityLevel.DEBUG, message, *args, exception=exception, **extra
598
599
  )
599
600
 
601
+ @overload
600
602
  @staticmethod
601
- def event(
602
- event: State,
603
+ def record(
604
+ level: ObservabilityLevel = ObservabilityLevel.DEBUG,
603
605
  /,
604
606
  *,
605
- level: ObservabilityLevel = ObservabilityLevel.INFO,
606
- **extra: Any,
607
- ) -> None:
608
- """
609
- Record event within current scope context.
610
-
611
- Parameters
612
- ----------
613
- event: State
614
- contents of event to be recorded.
607
+ attributes: Mapping[str, ObservabilityAttribute],
608
+ ) -> None: ...
615
609
 
616
- Returns
617
- -------
618
- None
619
- """
620
-
621
- ObservabilityContext.record_event(
622
- event,
623
- level=level,
624
- **extra,
625
- )
610
+ @overload
611
+ @staticmethod
612
+ def record(
613
+ level: ObservabilityLevel = ObservabilityLevel.DEBUG,
614
+ /,
615
+ *,
616
+ event: str,
617
+ attributes: Mapping[str, ObservabilityAttribute] | None = None,
618
+ ) -> None: ...
626
619
 
620
+ @overload
627
621
  @staticmethod
628
- def metric(
629
- metric: str,
622
+ def record(
623
+ level: ObservabilityLevel = ObservabilityLevel.DEBUG,
630
624
  /,
631
625
  *,
626
+ metric: str,
632
627
  value: float | int,
633
628
  unit: str | None = None,
634
- **extra: Any,
635
- ) -> None:
636
- """
637
- Record metric within current scope context.
638
-
639
- Parameters
640
- ----------
641
- metric: State
642
- name of metric to be recorded.
643
- value: float | int
644
- value of metric to be recorded.
645
- unit: str | None = None
646
- unit of metric to be recorded.
647
-
648
- Returns
649
- -------
650
- None
651
- """
652
-
653
- ObservabilityContext.record_metric(
654
- metric,
655
- value=value,
656
- unit=unit,
657
- **extra,
658
- )
629
+ attributes: Mapping[str, ObservabilityAttribute] | None = None,
630
+ ) -> None: ...
659
631
 
660
632
  @staticmethod
661
- def attributes(**attributes: ObservabilityAttribute) -> None:
662
- """
663
- Record attributes within current scope context.
664
-
665
- Parameters
666
- ----------
667
- **attributes: ObservabilityAttribute,
668
- attributes to be recorded within current context.
633
+ def record(
634
+ level: ObservabilityLevel = ObservabilityLevel.DEBUG,
635
+ /,
636
+ *,
637
+ event: str | None = None,
638
+ metric: str | None = None,
639
+ value: float | int | None = None,
640
+ unit: str | None = None,
641
+ attributes: Mapping[str, ObservabilityAttribute] | None = None,
642
+ ) -> None:
643
+ if event is not None:
644
+ assert metric is None # nosec: B101
645
+ ObservabilityContext.record_event(
646
+ level,
647
+ event,
648
+ attributes=attributes or {},
649
+ )
669
650
 
670
- Returns
671
- -------
672
- None
673
- """
651
+ elif metric is not None:
652
+ assert event is None # nosec: B101
653
+ assert value is not None # nosec: B101
654
+ ObservabilityContext.record_metric(
655
+ level,
656
+ metric,
657
+ value=value,
658
+ unit=unit,
659
+ attributes=attributes or {},
660
+ )
674
661
 
675
- ObservabilityContext.record_attributes(
676
- **attributes,
677
- )
662
+ else:
663
+ ObservabilityContext.record_attributes(
664
+ level,
665
+ attributes=attributes or {},
666
+ )
@@ -1,4 +1,4 @@
1
- from collections.abc import Sequence
1
+ from collections.abc import Mapping, Sequence
2
2
  from contextvars import ContextVar, Token
3
3
  from enum import IntEnum
4
4
  from logging import DEBUG as DEBUG_LOGGING
@@ -10,9 +10,9 @@ from types import TracebackType
10
10
  from typing import Any, Final, Protocol, Self, final, runtime_checkable
11
11
 
12
12
  from haiway.context.identifier import ScopeIdentifier
13
-
14
- # from haiway.context.logging import LoggerContext
15
13
  from haiway.state import State
14
+ from haiway.types import Missing
15
+ from haiway.utils.formatting import format_str
16
16
 
17
17
  __all__ = (
18
18
  "DEBUG",
@@ -46,7 +46,16 @@ INFO: Final[int] = ObservabilityLevel.INFO
46
46
  DEBUG: Final[int] = ObservabilityLevel.DEBUG
47
47
 
48
48
  type ObservabilityAttribute = (
49
- Sequence[str] | Sequence[float] | Sequence[int] | Sequence[bool] | str | float | int | bool
49
+ Sequence[str]
50
+ | Sequence[float]
51
+ | Sequence[int]
52
+ | Sequence[bool]
53
+ | str
54
+ | float
55
+ | int
56
+ | bool
57
+ | None
58
+ | Missing
50
59
  )
51
60
 
52
61
 
@@ -60,7 +69,6 @@ class ObservabilityLogRecording(Protocol):
60
69
  message: str,
61
70
  *args: Any,
62
71
  exception: BaseException | None,
63
- **extra: Any,
64
72
  ) -> None: ...
65
73
 
66
74
 
@@ -70,10 +78,10 @@ class ObservabilityEventRecording(Protocol):
70
78
  self,
71
79
  scope: ScopeIdentifier,
72
80
  /,
73
- *,
74
81
  level: ObservabilityLevel,
75
- event: State,
76
- **extra: Any,
82
+ *,
83
+ event: str,
84
+ attributes: Mapping[str, ObservabilityAttribute],
77
85
  ) -> None: ...
78
86
 
79
87
 
@@ -83,11 +91,12 @@ class ObservabilityMetricRecording(Protocol):
83
91
  self,
84
92
  scope: ScopeIdentifier,
85
93
  /,
94
+ level: ObservabilityLevel,
86
95
  *,
87
96
  metric: str,
88
97
  value: float | int,
89
98
  unit: str | None,
90
- **extra: Any,
99
+ attributes: Mapping[str, ObservabilityAttribute],
91
100
  ) -> None: ...
92
101
 
93
102
 
@@ -97,7 +106,8 @@ class ObservabilityAttributesRecording(Protocol):
97
106
  self,
98
107
  scope: ScopeIdentifier,
99
108
  /,
100
- **attributes: ObservabilityAttribute,
109
+ level: ObservabilityLevel,
110
+ attributes: Mapping[str, ObservabilityAttribute],
101
111
  ) -> None: ...
102
112
 
103
113
 
@@ -209,7 +219,6 @@ def _logger_observability(
209
219
  message: str,
210
220
  *args: Any,
211
221
  exception: BaseException | None,
212
- **extra: Any,
213
222
  ) -> None:
214
223
  logger.log(
215
224
  level,
@@ -221,42 +230,51 @@ def _logger_observability(
221
230
  def event_recording(
222
231
  scope: ScopeIdentifier,
223
232
  /,
224
- *,
225
233
  level: ObservabilityLevel,
226
- event: State,
227
- **extra: Any,
234
+ *,
235
+ event: str,
236
+ attributes: Mapping[str, ObservabilityAttribute],
228
237
  ) -> None:
229
238
  logger.log(
230
239
  level,
231
- f"{scope.unique_name} Recorded event:\n{event.to_str(pretty=True)}",
240
+ f"{scope.unique_name} Recorded event: {event} {format_str(attributes)}",
232
241
  )
233
242
 
234
243
  def metric_recording(
235
244
  scope: ScopeIdentifier,
236
245
  /,
246
+ level: ObservabilityLevel,
237
247
  *,
238
248
  metric: str,
239
249
  value: float | int,
240
250
  unit: str | None,
241
- **extra: Any,
251
+ attributes: Mapping[str, ObservabilityAttribute],
242
252
  ) -> None:
243
- logger.log(
244
- INFO,
245
- f"{scope.unique_name} Recorded metric: {metric}={value}{unit or ''}",
246
- )
253
+ if attributes:
254
+ logger.log(
255
+ level,
256
+ f"{scope.unique_name} Recorded metric: {metric}={value}{unit or ''}"
257
+ f"\n{format_str(attributes)}",
258
+ )
259
+
260
+ else:
261
+ logger.log(
262
+ level,
263
+ f"{scope.unique_name} Recorded metric: {metric}={value}{unit or ''}",
264
+ )
247
265
 
248
266
  def attributes_recording(
249
267
  scope: ScopeIdentifier,
250
268
  /,
251
- **attributes: ObservabilityAttribute,
269
+ level: ObservabilityLevel,
270
+ attributes: Mapping[str, ObservabilityAttribute],
252
271
  ) -> None:
253
272
  if not attributes:
254
273
  return
255
274
 
256
275
  logger.log(
257
- INFO,
258
- f"{scope.unique_name} Recorded attributes:"
259
- f"\n{'\n'.join([f'{k}: {v}' for k, v in attributes.items()])}",
276
+ level,
277
+ f"{scope.unique_name} Recorded attributes: {format_str(attributes)}",
260
278
  )
261
279
 
262
280
  def scope_entering[Metric: State](
@@ -349,7 +367,6 @@ class ObservabilityContext:
349
367
  /,
350
368
  *args: Any,
351
369
  exception: BaseException | None,
352
- **extra: Any,
353
370
  ) -> None:
354
371
  try: # catch exceptions - we don't wan't to blow up on observability
355
372
  context: Self = cls._context.get()
@@ -361,7 +378,6 @@ class ObservabilityContext:
361
378
  message,
362
379
  *args,
363
380
  exception=exception,
364
- **extra,
365
381
  )
366
382
 
367
383
  except LookupError:
@@ -375,11 +391,11 @@ class ObservabilityContext:
375
391
  @classmethod
376
392
  def record_event(
377
393
  cls,
378
- event: State,
394
+ level: ObservabilityLevel,
395
+ event: str,
379
396
  /,
380
397
  *,
381
- level: ObservabilityLevel,
382
- **extra: Any,
398
+ attributes: Mapping[str, ObservabilityAttribute],
383
399
  ) -> None:
384
400
  try: # catch exceptions - we don't wan't to blow up on observability
385
401
  context: Self = cls._context.get()
@@ -389,7 +405,7 @@ class ObservabilityContext:
389
405
  context._scope,
390
406
  level=level,
391
407
  event=event,
392
- **extra,
408
+ attributes=attributes,
393
409
  )
394
410
 
395
411
  except Exception as exc:
@@ -402,12 +418,13 @@ class ObservabilityContext:
402
418
  @classmethod
403
419
  def record_metric(
404
420
  cls,
421
+ level: ObservabilityLevel,
405
422
  metric: str,
406
423
  /,
407
424
  *,
408
425
  value: float | int,
409
426
  unit: str | None,
410
- **extra: Any,
427
+ attributes: Mapping[str, ObservabilityAttribute],
411
428
  ) -> None:
412
429
  try: # catch exceptions - we don't wan't to blow up on observability
413
430
  context: Self = cls._context.get()
@@ -415,10 +432,11 @@ class ObservabilityContext:
415
432
  if context.observability is not None:
416
433
  context.observability.metric_recording(
417
434
  context._scope,
435
+ level=level,
418
436
  metric=metric,
419
437
  value=value,
420
438
  unit=unit,
421
- **extra,
439
+ attributes=attributes,
422
440
  )
423
441
 
424
442
  except Exception as exc:
@@ -431,7 +449,10 @@ class ObservabilityContext:
431
449
  @classmethod
432
450
  def record_attributes(
433
451
  cls,
434
- **attributes: ObservabilityAttribute,
452
+ level: ObservabilityLevel,
453
+ /,
454
+ *,
455
+ attributes: Mapping[str, ObservabilityAttribute],
435
456
  ) -> None:
436
457
  try: # catch exceptions - we don't wan't to blow up on observability
437
458
  context: Self = cls._context.get()
@@ -439,13 +460,14 @@ class ObservabilityContext:
439
460
  if context.observability is not None:
440
461
  context.observability.attributes_recording(
441
462
  context._scope,
442
- **attributes,
463
+ level=level,
464
+ attributes=attributes,
443
465
  )
444
466
 
445
467
  except Exception as exc:
446
468
  cls.record_log(
447
469
  ERROR,
448
- f"Failed to record attributes: {attributes}",
470
+ "Failed to record attributes",
449
471
  exception=exc,
450
472
  )
451
473
 
@@ -4,14 +4,13 @@ from haiway.helpers.observability import LoggerObservability
4
4
  from haiway.helpers.retries import retry
5
5
  from haiway.helpers.throttling import throttle
6
6
  from haiway.helpers.timeouted import timeout
7
- from haiway.helpers.tracing import ResultTrace, traced
7
+ from haiway.helpers.tracing import traced
8
8
 
9
9
  __all__ = (
10
10
  "CacheMakeKey",
11
11
  "CacheRead",
12
12
  "CacheWrite",
13
13
  "LoggerObservability",
14
- "ResultTrace",
15
14
  "asynchronous",
16
15
  "cache",
17
16
  "retry",