haiway 0.18.2__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.2 → haiway-0.19.0}/PKG-INFO +1 -1
  2. {haiway-0.18.2 → haiway-0.19.0}/junit/test-results.xml +1 -1
  3. {haiway-0.18.2 → haiway-0.19.0}/pyproject.toml +1 -1
  4. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/__init__.py +0 -2
  5. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/access.py +53 -64
  6. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/observability.py +47 -33
  7. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/__init__.py +1 -2
  8. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/observability.py +53 -35
  9. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/tracing.py +35 -43
  10. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/opentelemetry/observability.py +53 -31
  11. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/structure.py +3 -151
  12. {haiway-0.18.2 → 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.2 → haiway-0.19.0}/uv.lock +1 -1
  15. {haiway-0.18.2 → haiway-0.19.0}/.github/workflows/ci.yml +0 -0
  16. {haiway-0.18.2 → haiway-0.19.0}/.github/workflows/publish.yml +0 -0
  17. {haiway-0.18.2 → haiway-0.19.0}/.gitignore +0 -0
  18. {haiway-0.18.2 → haiway-0.19.0}/LICENSE +0 -0
  19. {haiway-0.18.2 → haiway-0.19.0}/Makefile +0 -0
  20. {haiway-0.18.2 → haiway-0.19.0}/README.md +0 -0
  21. {haiway-0.18.2 → haiway-0.19.0}/config/pre-push +0 -0
  22. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/.dockerignore +0 -0
  23. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/Dockerfile +0 -0
  24. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/Makefile +0 -0
  25. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/README.md +0 -0
  26. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/config/.env.example +0 -0
  27. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/config/unit.json +0 -0
  28. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/docker-compose.yml +0 -0
  29. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/pyproject.toml +0 -0
  30. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/__int__.py +0 -0
  31. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/todos/__init__.py +0 -0
  32. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/todos/config.py +0 -0
  33. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/todos/state.py +0 -0
  34. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/todos/types.py +0 -0
  35. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/features/todos/user_tasks.py +0 -0
  36. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/__init__.py +0 -0
  37. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/__init__.py +0 -0
  38. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/client.py +0 -0
  39. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/config.py +0 -0
  40. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/state.py +0 -0
  41. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/types.py +0 -0
  42. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/__init__.py +0 -0
  43. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/__main__.py +0 -0
  44. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/__init__.py +0 -0
  45. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/execution.py +0 -0
  46. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/migration_0.py +0 -0
  47. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/types.py +0 -0
  48. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/__init__.py +0 -0
  49. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/__main__.py +0 -0
  50. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/application.py +0 -0
  51. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/config.py +0 -0
  52. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/__init__.py +0 -0
  53. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/context.py +0 -0
  54. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/routes/__init__.py +0 -0
  55. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/routes/technical.py +0 -0
  56. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/server/routes/todos.py +0 -0
  57. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/__init__.py +0 -0
  58. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/__init__.py +0 -0
  59. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/config.py +0 -0
  60. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/postgres.py +0 -0
  61. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/state.py +0 -0
  62. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/types.py +0 -0
  63. {haiway-0.18.2 → haiway-0.19.0}/examples/fastAPI/uv.lock +0 -0
  64. {haiway-0.18.2 → haiway-0.19.0}/guidelines/functionalities.md +0 -0
  65. {haiway-0.18.2 → haiway-0.19.0}/guidelines/packages.md +0 -0
  66. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/__init__.py +0 -0
  67. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/disposables.py +0 -0
  68. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/identifier.py +0 -0
  69. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/state.py +0 -0
  70. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/tasks.py +0 -0
  71. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/context/types.py +0 -0
  72. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/asynchrony.py +0 -0
  73. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/caching.py +0 -0
  74. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/retries.py +0 -0
  75. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/throttling.py +0 -0
  76. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/helpers/timeouted.py +0 -0
  77. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/opentelemetry/__init__.py +0 -0
  78. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/py.typed +0 -0
  79. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/__init__.py +0 -0
  80. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/attributes.py +0 -0
  81. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/path.py +0 -0
  82. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/requirement.py +0 -0
  83. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/state/validation.py +0 -0
  84. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/types/__init__.py +0 -0
  85. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/types/default.py +0 -0
  86. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/types/frozen.py +0 -0
  87. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/types/missing.py +0 -0
  88. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/always.py +0 -0
  89. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/collections.py +0 -0
  90. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/env.py +0 -0
  91. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/freezing.py +0 -0
  92. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/logs.py +0 -0
  93. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/mimic.py +0 -0
  94. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/noop.py +0 -0
  95. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/queue.py +0 -0
  96. {haiway-0.18.2 → haiway-0.19.0}/src/haiway/utils/stream.py +0 -0
  97. {haiway-0.18.2 → haiway-0.19.0}/tests/__init__.py +0 -0
  98. {haiway-0.18.2 → haiway-0.19.0}/tests/test_async_queue.py +0 -0
  99. {haiway-0.18.2 → haiway-0.19.0}/tests/test_async_stream.py +0 -0
  100. {haiway-0.18.2 → haiway-0.19.0}/tests/test_attribute_path.py +0 -0
  101. {haiway-0.18.2 → haiway-0.19.0}/tests/test_auto_retry.py +0 -0
  102. {haiway-0.18.2 → haiway-0.19.0}/tests/test_cache.py +0 -0
  103. {haiway-0.18.2 → haiway-0.19.0}/tests/test_context.py +0 -0
  104. {haiway-0.18.2 → haiway-0.19.0}/tests/test_state.py +0 -0
  105. {haiway-0.18.2 → haiway-0.19.0}/tests/test_streaming.py +0 -0
  106. {haiway-0.18.2 → 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.2
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.116" timestamp="2025-05-12T15:57:41.113378+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.007" /><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.001" /><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.001" /><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>
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.2"
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
@@ -11,7 +11,8 @@ from typing import Any, Final, Protocol, Self, final, runtime_checkable
11
11
 
12
12
  from haiway.context.identifier import ScopeIdentifier
13
13
  from haiway.state import State
14
- from haiway.types import MISSING, Missing
14
+ from haiway.types import Missing
15
+ from haiway.utils.formatting import format_str
15
16
 
16
17
  __all__ = (
17
18
  "DEBUG",
@@ -68,7 +69,6 @@ class ObservabilityLogRecording(Protocol):
68
69
  message: str,
69
70
  *args: Any,
70
71
  exception: BaseException | None,
71
- **extra: Any,
72
72
  ) -> None: ...
73
73
 
74
74
 
@@ -78,10 +78,10 @@ class ObservabilityEventRecording(Protocol):
78
78
  self,
79
79
  scope: ScopeIdentifier,
80
80
  /,
81
- *,
82
81
  level: ObservabilityLevel,
83
- event: State,
84
- **extra: Any,
82
+ *,
83
+ event: str,
84
+ attributes: Mapping[str, ObservabilityAttribute],
85
85
  ) -> None: ...
86
86
 
87
87
 
@@ -91,11 +91,12 @@ class ObservabilityMetricRecording(Protocol):
91
91
  self,
92
92
  scope: ScopeIdentifier,
93
93
  /,
94
+ level: ObservabilityLevel,
94
95
  *,
95
96
  metric: str,
96
97
  value: float | int,
97
98
  unit: str | None,
98
- **extra: Any,
99
+ attributes: Mapping[str, ObservabilityAttribute],
99
100
  ) -> None: ...
100
101
 
101
102
 
@@ -105,7 +106,8 @@ class ObservabilityAttributesRecording(Protocol):
105
106
  self,
106
107
  scope: ScopeIdentifier,
107
108
  /,
108
- **attributes: ObservabilityAttribute,
109
+ level: ObservabilityLevel,
110
+ attributes: Mapping[str, ObservabilityAttribute],
109
111
  ) -> None: ...
110
112
 
111
113
 
@@ -217,7 +219,6 @@ def _logger_observability(
217
219
  message: str,
218
220
  *args: Any,
219
221
  exception: BaseException | None,
220
- **extra: Any,
221
222
  ) -> None:
222
223
  logger.log(
223
224
  level,
@@ -229,42 +230,51 @@ def _logger_observability(
229
230
  def event_recording(
230
231
  scope: ScopeIdentifier,
231
232
  /,
232
- *,
233
233
  level: ObservabilityLevel,
234
- event: State,
235
- **extra: Any,
234
+ *,
235
+ event: str,
236
+ attributes: Mapping[str, ObservabilityAttribute],
236
237
  ) -> None:
237
238
  logger.log(
238
239
  level,
239
- f"{scope.unique_name} Recorded event:\n{event.to_str(pretty=True)}",
240
+ f"{scope.unique_name} Recorded event: {event} {format_str(attributes)}",
240
241
  )
241
242
 
242
243
  def metric_recording(
243
244
  scope: ScopeIdentifier,
244
245
  /,
246
+ level: ObservabilityLevel,
245
247
  *,
246
248
  metric: str,
247
249
  value: float | int,
248
250
  unit: str | None,
249
- **extra: Any,
251
+ attributes: Mapping[str, ObservabilityAttribute],
250
252
  ) -> None:
251
- logger.log(
252
- INFO,
253
- f"{scope.unique_name} Recorded metric: {metric}={value}{unit or ''}",
254
- )
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
+ )
255
265
 
256
266
  def attributes_recording(
257
267
  scope: ScopeIdentifier,
258
268
  /,
259
- **attributes: ObservabilityAttribute,
269
+ level: ObservabilityLevel,
270
+ attributes: Mapping[str, ObservabilityAttribute],
260
271
  ) -> None:
261
272
  if not attributes:
262
273
  return
263
274
 
264
275
  logger.log(
265
- INFO,
266
- f"{scope.unique_name} Recorded attributes:"
267
- f"\n{'\n'.join(f'{k}: {v}' for k, v in attributes.items() if v is not None and v is not MISSING)}", # noqa: E501
276
+ level,
277
+ f"{scope.unique_name} Recorded attributes: {format_str(attributes)}",
268
278
  )
269
279
 
270
280
  def scope_entering[Metric: State](
@@ -357,7 +367,6 @@ class ObservabilityContext:
357
367
  /,
358
368
  *args: Any,
359
369
  exception: BaseException | None,
360
- **extra: Any,
361
370
  ) -> None:
362
371
  try: # catch exceptions - we don't wan't to blow up on observability
363
372
  context: Self = cls._context.get()
@@ -369,7 +378,6 @@ class ObservabilityContext:
369
378
  message,
370
379
  *args,
371
380
  exception=exception,
372
- **extra,
373
381
  )
374
382
 
375
383
  except LookupError:
@@ -383,11 +391,11 @@ class ObservabilityContext:
383
391
  @classmethod
384
392
  def record_event(
385
393
  cls,
386
- event: State,
394
+ level: ObservabilityLevel,
395
+ event: str,
387
396
  /,
388
397
  *,
389
- level: ObservabilityLevel,
390
- **extra: Any,
398
+ attributes: Mapping[str, ObservabilityAttribute],
391
399
  ) -> None:
392
400
  try: # catch exceptions - we don't wan't to blow up on observability
393
401
  context: Self = cls._context.get()
@@ -397,7 +405,7 @@ class ObservabilityContext:
397
405
  context._scope,
398
406
  level=level,
399
407
  event=event,
400
- **extra,
408
+ attributes=attributes,
401
409
  )
402
410
 
403
411
  except Exception as exc:
@@ -410,12 +418,13 @@ class ObservabilityContext:
410
418
  @classmethod
411
419
  def record_metric(
412
420
  cls,
421
+ level: ObservabilityLevel,
413
422
  metric: str,
414
423
  /,
415
424
  *,
416
425
  value: float | int,
417
426
  unit: str | None,
418
- **extra: Any,
427
+ attributes: Mapping[str, ObservabilityAttribute],
419
428
  ) -> None:
420
429
  try: # catch exceptions - we don't wan't to blow up on observability
421
430
  context: Self = cls._context.get()
@@ -423,10 +432,11 @@ class ObservabilityContext:
423
432
  if context.observability is not None:
424
433
  context.observability.metric_recording(
425
434
  context._scope,
435
+ level=level,
426
436
  metric=metric,
427
437
  value=value,
428
438
  unit=unit,
429
- **extra,
439
+ attributes=attributes,
430
440
  )
431
441
 
432
442
  except Exception as exc:
@@ -439,7 +449,10 @@ class ObservabilityContext:
439
449
  @classmethod
440
450
  def record_attributes(
441
451
  cls,
442
- **attributes: ObservabilityAttribute,
452
+ level: ObservabilityLevel,
453
+ /,
454
+ *,
455
+ attributes: Mapping[str, ObservabilityAttribute],
443
456
  ) -> None:
444
457
  try: # catch exceptions - we don't wan't to blow up on observability
445
458
  context: Self = cls._context.get()
@@ -447,13 +460,14 @@ class ObservabilityContext:
447
460
  if context.observability is not None:
448
461
  context.observability.attributes_recording(
449
462
  context._scope,
450
- **attributes,
463
+ level=level,
464
+ attributes=attributes,
451
465
  )
452
466
 
453
467
  except Exception as exc:
454
468
  cls.record_log(
455
469
  ERROR,
456
- f"Failed to record attributes: {attributes}",
470
+ "Failed to record attributes",
457
471
  exception=exc,
458
472
  )
459
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",