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.
- {haiway-0.18.1 → haiway-0.19.0}/PKG-INFO +1 -1
- {haiway-0.18.1 → haiway-0.19.0}/junit/test-results.xml +1 -1
- {haiway-0.18.1 → haiway-0.19.0}/pyproject.toml +1 -1
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/__init__.py +0 -2
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/access.py +53 -64
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/observability.py +57 -35
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/__init__.py +1 -2
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/observability.py +54 -35
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/tracing.py +36 -45
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/opentelemetry/observability.py +60 -38
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/structure.py +3 -151
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/__init__.py +2 -0
- haiway-0.19.0/src/haiway/utils/formatting.py +148 -0
- {haiway-0.18.1 → haiway-0.19.0}/uv.lock +1 -1
- {haiway-0.18.1 → haiway-0.19.0}/.github/workflows/ci.yml +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/.github/workflows/publish.yml +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/.gitignore +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/LICENSE +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/Makefile +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/README.md +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/config/pre-push +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/.dockerignore +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/Dockerfile +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/Makefile +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/README.md +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/config/.env.example +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/config/unit.json +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/docker-compose.yml +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/pyproject.toml +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/__int__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/config.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/state.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/types.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/features/todos/user_tasks.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/client.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/config.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/state.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/integrations/postgres/types.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/__main__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/execution.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/migration_0.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/migrations/postgres/types.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/__main__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/application.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/config.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/middlewares/context.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/technical.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/server/routes/todos.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/config.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/postgres.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/state.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/src/solutions/user_tasks/types.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/examples/fastAPI/uv.lock +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/guidelines/functionalities.md +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/guidelines/packages.md +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/disposables.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/identifier.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/state.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/tasks.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/context/types.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/asynchrony.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/caching.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/retries.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/throttling.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/helpers/timeouted.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/opentelemetry/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/py.typed +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/attributes.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/path.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/requirement.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/state/validation.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/default.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/frozen.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/types/missing.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/always.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/collections.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/env.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/freezing.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/logs.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/mimic.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/noop.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/queue.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/src/haiway/utils/stream.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/__init__.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_async_queue.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_async_stream.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_attribute_path.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_auto_retry.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_cache.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_context.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_state.py +0 -0
- {haiway-0.18.1 → haiway-0.19.0}/tests/test_streaming.py +0 -0
- {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.
|
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.
|
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.
|
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
|
602
|
-
|
603
|
+
def record(
|
604
|
+
level: ObservabilityLevel = ObservabilityLevel.DEBUG,
|
603
605
|
/,
|
604
606
|
*,
|
605
|
-
|
606
|
-
|
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
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
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
|
629
|
-
|
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
|
-
|
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
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
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
|
-
|
671
|
-
|
672
|
-
|
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
|
-
|
676
|
-
|
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]
|
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
|
-
|
76
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
227
|
-
|
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
|
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
|
-
|
251
|
+
attributes: Mapping[str, ObservabilityAttribute],
|
242
252
|
) -> None:
|
243
|
-
|
244
|
-
|
245
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
394
|
+
level: ObservabilityLevel,
|
395
|
+
event: str,
|
379
396
|
/,
|
380
397
|
*,
|
381
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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",
|