beamlit 0.0.26rc22__py3-none-any.whl → 0.0.27rc23__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ from typing import Any
2
+
3
+ from fastapi import FastAPI
4
+ from opentelemetry import metrics, trace
5
+ from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
6
+ OTLPMetricExporter,
7
+ )
8
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
9
+ OTLPSpanExporter,
10
+ )
11
+ from opentelemetry.instrumentation.fastapi import ( # type: ignore
12
+ FastAPIInstrumentor,
13
+ )
14
+ from opentelemetry.instrumentation.httpx import ( # type: ignore
15
+ HTTPXClientInstrumentor,
16
+ )
17
+ from opentelemetry.instrumentation.logging import ( # type: ignore
18
+ LoggingInstrumentor,
19
+ )
20
+ from opentelemetry.sdk.metrics import MeterProvider
21
+ from opentelemetry.sdk.metrics.export import (
22
+ PeriodicExportingMetricReader,
23
+ )
24
+ from opentelemetry.sdk.resources import Resource
25
+ from opentelemetry.sdk.trace import TracerProvider
26
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
27
+ from typing_extensions import Dict
28
+
29
+ from .settings import get_settings
30
+
31
+ tracer: trace.Tracer | None = None
32
+ meter: metrics.Meter | None = None
33
+
34
+
35
+ def get_tracer() -> trace.Tracer:
36
+ if tracer is None:
37
+ raise Exception("Tracer is not initialized")
38
+ return tracer
39
+
40
+
41
+ def get_meter() -> metrics.Meter:
42
+ if meter is None:
43
+ raise Exception("Meter is not initialized")
44
+ return meter
45
+
46
+
47
+ def get_resource_attributes() -> Dict[str, Any]:
48
+ resources = Resource.create()
49
+ resources_dict: Dict[str, Any] = {}
50
+ for key in resources.attributes:
51
+ resources_dict[key] = resources.attributes[key]
52
+ settings = get_settings()
53
+ if settings is None:
54
+ raise Exception("Settings are not initialized")
55
+ resources_dict["workspace"] = settings.workspace
56
+ resources_dict["service.name"] = settings.name
57
+ return resources_dict
58
+
59
+
60
+ def get_metrics_exporter() -> OTLPMetricExporter:
61
+ return OTLPMetricExporter()
62
+
63
+
64
+ def get_span_exporter() -> OTLPSpanExporter:
65
+ return OTLPSpanExporter()
66
+
67
+
68
+ def instrument_app(app: FastAPI):
69
+ global tracer
70
+ global meter
71
+ settings = get_settings()
72
+ if settings is None:
73
+ raise Exception("Settings are not initialized")
74
+ resource = Resource.create(
75
+ {
76
+ "service.name": settings.name,
77
+ "service.namespace": settings.workspace,
78
+ "service.workspace": settings.workspace,
79
+ }
80
+ )
81
+ # Set up the TracerProvider
82
+ trace_provider = TracerProvider(resource=resource)
83
+ span_processor = BatchSpanProcessor(get_span_exporter())
84
+ trace_provider.add_span_processor(span_processor)
85
+ trace.set_tracer_provider(trace_provider)
86
+ tracer = trace_provider.get_tracer(__name__)
87
+
88
+ metrics_exporter = PeriodicExportingMetricReader(get_metrics_exporter())
89
+ meter_provider = MeterProvider(
90
+ resource=resource, metric_readers=[metrics_exporter]
91
+ )
92
+ metrics.set_meter_provider(meter_provider)
93
+ meter = meter_provider.get_meter(__name__)
94
+
95
+ FastAPIInstrumentor.instrument_app( # type: ignore
96
+ app=app, tracer_provider=trace_provider, meter_provider=meter_provider
97
+ )
98
+ HTTPXClientInstrumentor().instrument(meter_provider=meter_provider) # type: ignore
99
+ LoggingInstrumentor(tracer_provider=trace_provider).instrument(
100
+ set_logging_format=True
101
+ )
beamlit/serve/app.py CHANGED
@@ -8,8 +8,15 @@ from uuid import uuid4
8
8
 
9
9
  from asgi_correlation_id import CorrelationIdMiddleware
10
10
  from beamlit.common.settings import get_settings, init
11
+ from beamlit.common.instrumentation import (
12
+ get_metrics_exporter,
13
+ get_resource_attributes,
14
+ get_span_exporter,
15
+ instrument_app,
16
+ )
11
17
  from fastapi import FastAPI, Request, Response
12
18
  from fastapi.responses import JSONResponse
19
+ from traceloop.sdk import Traceloop
13
20
 
14
21
  from .middlewares import AccessLogMiddleware, AddProcessTimeHeader
15
22
 
@@ -33,6 +40,14 @@ logger.info(
33
40
  f" on {settings.server.host}:{settings.server.port}"
34
41
  )
35
42
 
43
+ Traceloop.init(
44
+ app_name=settings.name,
45
+ exporter=get_span_exporter(),
46
+ metrics_exporter=get_metrics_exporter(),
47
+ resource_attributes=get_resource_attributes(),
48
+ should_enrich_metrics=os.getenv("ENRICHED_METRICS", "false") == "true",
49
+ )
50
+
36
51
  app = FastAPI(docs_url=None, redoc_url=None)
37
52
  app.add_middleware(
38
53
  CorrelationIdMiddleware,
@@ -41,7 +56,7 @@ app.add_middleware(
41
56
  )
42
57
  app.add_middleware(AddProcessTimeHeader)
43
58
  app.add_middleware(AccessLogMiddleware)
44
-
59
+ instrument_app(app)
45
60
 
46
61
  @app.get("/health")
47
62
  async def health():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beamlit
3
- Version: 0.0.26rc22
3
+ Version: 0.0.27rc23
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -13,11 +13,18 @@ Requires-Dist: langchain-core<0.4.0,>=0.3.13
13
13
  Requires-Dist: langchain-openai<0.3.0,>=0.2.4
14
14
  Requires-Dist: langgraph<0.3.0,>=0.2.40
15
15
  Requires-Dist: mcp>=1.1.2
16
+ Requires-Dist: opentelemetry-api>=1.28.2
17
+ Requires-Dist: opentelemetry-exporter-otlp>=1.28.2
18
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.49b2
19
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.49b2
20
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.49b2
21
+ Requires-Dist: opentelemetry-sdk>=1.28.2
16
22
  Requires-Dist: pydantic-settings<2.7.0,>=2.6.1
17
23
  Requires-Dist: pydantic<2.11.0,>=2.10.3
18
24
  Requires-Dist: python-dateutil>=2.8.0
19
25
  Requires-Dist: pyyaml<6.1.0,>=6.0.2
20
26
  Requires-Dist: requests<2.33.0,>=2.32.3
27
+ Requires-Dist: traceloop-sdk>=0.33.12
21
28
  Description-Content-Type: text/markdown
22
29
 
23
30
  # beamlit
@@ -122,6 +122,7 @@ beamlit/authentication/credentials.py,sha256=p_1xenabCbQuRz7BiFk7oTK4uCxAt_zoyku
122
122
  beamlit/authentication/device_mode.py,sha256=tmr22gllKOZwBRub_QjF5pYa425x-nE8tQNpZ_EGR6g,3644
123
123
  beamlit/common/__init__.py,sha256=yDoMJDKj-xjTGl7U1YI59KpWxiOV65HSiUulgO8xdTA,277
124
124
  beamlit/common/generate.py,sha256=LtdCju_QayRS4lZrrb_0VHqWWvTcv4Mbf-iV1TB_Qko,7522
125
+ beamlit/common/instrumentation.py,sha256=MsBDfFcMYqGDiHHj4j5hLHE4EWxZExkhmCeFS3SKzJY,3181
125
126
  beamlit/common/logger.py,sha256=VFRbaZh93n8ZGugeeYKe88IP2nI3g2JNa7XN4j8wVJE,1116
126
127
  beamlit/common/secrets.py,sha256=sid81bOe3LflkMKDHwBsBs9nIju8bp5-v9qU9gkyNMc,212
127
128
  beamlit/common/settings.py,sha256=igwhNY6DPm0tiSW-_2fCkllHdTyXVthVAT6p3kggJxo,5435
@@ -238,10 +239,10 @@ beamlit/models/websocket_channel.py,sha256=jg3vN7yS_oOIwGtndtIUr1LsyEA58RXLXahqS
238
239
  beamlit/models/workspace.py,sha256=l__bIpbA4oJvxXo7UbEoCcqkvu9MiNt5aXXpZ3bgwHg,4309
239
240
  beamlit/models/workspace_labels.py,sha256=WbnUY6eCTkUNdY7hhhSF-KQCl8fWFfkCf7hzCTiNp4A,1246
240
241
  beamlit/models/workspace_user.py,sha256=70CcifQWYbeWG7TDui4pblTzUe5sVK0AS19vNCzKE8g,3423
241
- beamlit/serve/app.py,sha256=4mtrrYW32ywFIapL26Uvsp3AnKcEpa8G-juJy_0A5Qo,2618
242
+ beamlit/serve/app.py,sha256=OpwPjRdyHZK6J-ziPwhiRDGGa2mvCrFVcBFE6alJVOM,3071
242
243
  beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
243
244
  beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
244
245
  beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
245
- beamlit-0.0.26rc22.dist-info/METADATA,sha256=k7j9e8a8SMtmeRn0f66x1fFVX3aGx62hDYQtLeCfu2c,2053
246
- beamlit-0.0.26rc22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
247
- beamlit-0.0.26rc22.dist-info/RECORD,,
246
+ beamlit-0.0.27rc23.dist-info/METADATA,sha256=wZtsDtJuxfbhkS9ATsx7Ed6Eowpg7I9AJGtHNwseexs,2405
247
+ beamlit-0.0.27rc23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
248
+ beamlit-0.0.27rc23.dist-info/RECORD,,