microbootstrap 1.5.3__tar.gz → 1.5.5__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 (39) hide show
  1. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/PKG-INFO +17 -1
  2. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/README.md +16 -0
  3. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/faststream.py +6 -0
  4. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/opentelemetry_instrument.py +7 -1
  5. microbootstrap-1.5.5/microbootstrap/middlewares/faststream.py +66 -0
  6. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/pyproject.toml +1 -1
  7. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/pyproject.toml.orig +1 -1
  8. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/__init__.py +0 -0
  9. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/__init__.py +0 -0
  10. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/base.py +0 -0
  11. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/fastapi.py +0 -0
  12. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/fastmcp.py +0 -0
  13. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/bootstrappers/litestar.py +0 -0
  14. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/config/__init__.py +0 -0
  15. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/config/fastapi.py +0 -0
  16. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/config/fastmcp.py +0 -0
  17. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/config/faststream.py +0 -0
  18. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/config/litestar.py +0 -0
  19. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/console_writer.py +0 -0
  20. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/exceptions.py +0 -0
  21. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/granian_server.py +0 -0
  22. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/helpers.py +0 -0
  23. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/__init__.py +0 -0
  24. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/base.py +0 -0
  25. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/cors_instrument.py +0 -0
  26. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/health_checks_instrument.py +0 -0
  27. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/instrument_box.py +0 -0
  28. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/logging_instrument.py +0 -0
  29. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/prometheus_instrument.py +0 -0
  30. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/pyroscope_instrument.py +0 -0
  31. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/sentry_instrument.py +0 -0
  32. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments/swagger_instrument.py +0 -0
  33. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/instruments_setupper.py +0 -0
  34. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/middlewares/__init__.py +0 -0
  35. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/middlewares/fastapi.py +0 -0
  36. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/middlewares/fastmcp.py +0 -0
  37. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/middlewares/litestar.py +0 -0
  38. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/py.typed +0 -0
  39. {microbootstrap-1.5.3 → microbootstrap-1.5.5}/microbootstrap/settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: microbootstrap
3
- Version: 1.5.3
3
+ Version: 1.5.5
4
4
  Summary: Package for bootstrapping new micro-services
5
5
  Keywords: python,microservice,bootstrap,opentelemetry,logging,error-tracing,litestar,fastapi,fastmcp,mcp
6
6
  Author: community-of-python
@@ -528,6 +528,22 @@ Parameters description:
528
528
 
529
529
  These settings are subsequently passed to [opentelemetry](https://opentelemetry.io/), finalizing your Opentelemetry integration.
530
530
 
531
+ If an authoritative baggage value becomes available only after the current span has started, pass the same mapping to
532
+ `opentelemetry_baggage_scope` to also materialize that value on the already-started span:
533
+
534
+ ```python
535
+ from microbootstrap import opentelemetry_baggage_scope
536
+
537
+
538
+ with opentelemetry_baggage_scope(
539
+ {"conversation_id": conversation_id},
540
+ current_span_attributes=settings.opentelemetry_baggage_span_attributes,
541
+ ):
542
+ ...
543
+ ```
544
+
545
+ Only non-`None` baggage values supplied to the scope and present in the mapping are added to a recording current span.
546
+
531
547
  #### FastStream
532
548
 
533
549
  For FastStream you also should pass `opentelemetry_middleware_cls` - OpenTelemetry middleware for your broker
@@ -463,6 +463,22 @@ Parameters description:
463
463
 
464
464
  These settings are subsequently passed to [opentelemetry](https://opentelemetry.io/), finalizing your Opentelemetry integration.
465
465
 
466
+ If an authoritative baggage value becomes available only after the current span has started, pass the same mapping to
467
+ `opentelemetry_baggage_scope` to also materialize that value on the already-started span:
468
+
469
+ ```python
470
+ from microbootstrap import opentelemetry_baggage_scope
471
+
472
+
473
+ with opentelemetry_baggage_scope(
474
+ {"conversation_id": conversation_id},
475
+ current_span_attributes=settings.opentelemetry_baggage_span_attributes,
476
+ ):
477
+ ...
478
+ ```
479
+
480
+ Only non-`None` baggage values supplied to the scope and present in the mapping are added to a recording current span.
481
+
466
482
  #### FastStream
467
483
 
468
484
  For FastStream you also should pass `opentelemetry_middleware_cls` - OpenTelemetry middleware for your broker
@@ -24,6 +24,7 @@ from microbootstrap.instruments.opentelemetry_instrument import (
24
24
  from microbootstrap.instruments.prometheus_instrument import FastStreamPrometheusConfig, PrometheusInstrument
25
25
  from microbootstrap.instruments.pyroscope_instrument import PyroscopeInstrument
26
26
  from microbootstrap.instruments.sentry_instrument import SentryInstrument
27
+ from microbootstrap.middlewares.faststream import FastStreamOpenTelemetryBaggageMiddleware
27
28
  from microbootstrap.settings import FastStreamSettings
28
29
 
29
30
 
@@ -101,6 +102,11 @@ class FastStreamOpentelemetryInstrument(BaseOpentelemetryInstrument[FastStreamOp
101
102
  application.broker.add_middleware(
102
103
  self.instrument_config.opentelemetry_middleware_cls(tracer_provider=self.tracer_provider),
103
104
  )
105
+ application.broker.add_middleware(
106
+ FastStreamOpenTelemetryBaggageMiddleware(
107
+ baggage_span_attributes=self.instrument_config.opentelemetry_baggage_span_attributes,
108
+ ),
109
+ )
104
110
  return application
105
111
 
106
112
  @classmethod
@@ -17,7 +17,7 @@ from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor
17
17
  from opentelemetry.sdk.trace import TracerProvider as SdkTracerProvider
18
18
  from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor
19
19
  from opentelemetry.semconv.resource import ResourceAttributes
20
- from opentelemetry.trace import SpanKind, format_span_id, set_tracer_provider
20
+ from opentelemetry.trace import SpanKind, format_span_id, get_current_span, set_tracer_provider
21
21
  from opentelemetry.util._importlib_metadata import entry_points
22
22
 
23
23
  from microbootstrap.instruments.base import BaseInstrumentConfig, Instrument
@@ -44,6 +44,8 @@ OpentelemetryConfigT = typing.TypeVar("OpentelemetryConfigT", bound="Opentelemet
44
44
  @contextlib.contextmanager
45
45
  def opentelemetry_baggage_scope(
46
46
  baggage_values: typing.Mapping[str, object | None],
47
+ *,
48
+ current_span_attributes: typing.Mapping[str, str] | None = None,
47
49
  ) -> typing.Iterator[None]:
48
50
  baggage_context = context.get_current()
49
51
  for key, value in baggage_values.items():
@@ -55,6 +57,10 @@ def opentelemetry_baggage_scope(
55
57
 
56
58
  token: typing.Final = context.attach(baggage_context)
57
59
  try:
60
+ if current_span_attributes and (current_span := get_current_span()).is_recording():
61
+ for baggage_key, span_attribute in current_span_attributes.items():
62
+ if baggage_key in baggage_values and (value := baggage_values[baggage_key]) is not None:
63
+ current_span.set_attribute(span_attribute, str(value))
58
64
  yield
59
65
  except Exception as exc:
60
66
  with contextlib.suppress(Exception):
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+ import typing
3
+
4
+ from faststream._internal.middlewares import BaseMiddleware
5
+ from opentelemetry import baggage, propagate
6
+
7
+ from microbootstrap.instruments.opentelemetry_instrument import opentelemetry_baggage_scope
8
+
9
+
10
+ if typing.TYPE_CHECKING:
11
+ from faststream._internal.basic_types import AsyncFuncAny
12
+ from faststream._internal.context import ContextRepo
13
+ from faststream.message import StreamMessage
14
+
15
+
16
+ class FastStreamOpenTelemetryBaggageMiddleware:
17
+ def __init__(self, *, baggage_span_attributes: typing.Mapping[str, str]) -> None:
18
+ self.baggage_span_attributes = baggage_span_attributes
19
+
20
+ def __call__(
21
+ self,
22
+ msg: typing.Any, # noqa: ANN401
23
+ /,
24
+ *,
25
+ context: ContextRepo,
26
+ ) -> _FastStreamOpenTelemetryBaggageMiddleware:
27
+ return _FastStreamOpenTelemetryBaggageMiddleware(
28
+ msg,
29
+ context=context,
30
+ baggage_span_attributes=self.baggage_span_attributes,
31
+ )
32
+
33
+
34
+ class _FastStreamOpenTelemetryBaggageMiddleware(BaseMiddleware[typing.Any, typing.Any]):
35
+ def __init__(
36
+ self,
37
+ msg: typing.Any, # noqa: ANN401
38
+ /,
39
+ *,
40
+ context: ContextRepo,
41
+ baggage_span_attributes: typing.Mapping[str, str],
42
+ ) -> None:
43
+ super().__init__(msg, context=context)
44
+ self.baggage_span_attributes = baggage_span_attributes
45
+
46
+ async def consume_scope(
47
+ self,
48
+ call_next: AsyncFuncAny,
49
+ msg: StreamMessage[typing.Any],
50
+ ) -> typing.Any: # noqa: ANN401
51
+ extracted_baggage: typing.Final = baggage.get_all(propagate.extract(msg.headers))
52
+ with opentelemetry_baggage_scope(
53
+ extracted_baggage,
54
+ current_span_attributes=self.baggage_span_attributes,
55
+ ):
56
+ return await call_next(msg)
57
+
58
+ async def publish_scope(
59
+ self,
60
+ call_next: typing.Callable[[typing.Any], typing.Awaitable[typing.Any]],
61
+ cmd: typing.Any, # noqa: ANN401
62
+ ) -> typing.Any: # noqa: ANN401
63
+ for field in propagate.get_global_textmap().fields:
64
+ cmd.headers.pop(field, None)
65
+ propagate.inject(cmd.headers)
66
+ return await call_next(cmd)
@@ -58,7 +58,7 @@ dependencies = [
58
58
  "opentelemetry-instrumentation-asgi>=0.46b0",
59
59
  "orjson>=3.10.18",
60
60
  ]
61
- version = "1.5.3"
61
+ version = "1.5.5"
62
62
 
63
63
  [[project.authors]]
64
64
  name = "community-of-python"
@@ -58,7 +58,7 @@ dependencies = [
58
58
  "opentelemetry-instrumentation-asgi>=0.46b0",
59
59
  "orjson>=3.10.18",
60
60
  ]
61
- version = "1.5.3"
61
+ version = "1.5.5"
62
62
  authors = [{ name = "community-of-python" }]
63
63
 
64
64
  [project.optional-dependencies]