beamlit 0.0.26__py3-none-any.whl → 0.0.27__py3-none-any.whl

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.
@@ -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/deploy/deploy.py CHANGED
@@ -199,8 +199,8 @@ COPY pyproject.toml /beamlit/pyproject.toml
199
199
  COPY uv.lock /beamlit/uv.lock
200
200
  RUN uv sync --no-cache
201
201
 
202
- COPY README.md /beamlit/README.md
203
- COPY LICENSE /beamlit/LICENSE
202
+ COPY README.m[d] /beamlit/README.md
203
+ COPY LICENS[E] /beamlit/LICENSE
204
204
  COPY src /beamlit/src
205
205
 
206
206
  ENV PATH="/beamlit/.venv/bin:$PATH"
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.26
3
+ Version: 0.0.27
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,12 +122,13 @@ 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
128
129
  beamlit/common/utils.py,sha256=jouz5igBvT37Xn_e94-foCHyQczVim-UzVcoIF6RWJ4,657
129
130
  beamlit/deploy/__init__.py,sha256=GS7l7Jtm2yKs7iNLKcfjYO-rAhUzggQ3xiYSf3oxLBY,91
130
- beamlit/deploy/deploy.py,sha256=0XQKyilODoWQchaO3B93vpoT5-gAjJ28nXNVvOTW-nE,9179
131
+ beamlit/deploy/deploy.py,sha256=rXpiAqlO36Ul1eadBEiwiil-6R2DkbaYHzw-qcqZ0g4,9183
131
132
  beamlit/deploy/format.py,sha256=78tOoeNPJ8969AhQTeFlIwZgQ3un8gmTSMmrYbRQSds,1818
132
133
  beamlit/deploy/parser.py,sha256=uT-bezLX6yjyxr1ogm1GXIT_MeREqHDUBlKiyav5qg0,6912
133
134
  beamlit/functions/__init__.py,sha256=_RPG1Bfg54JGdIPnViAU6n9zD7E1cDNsdXi8oYGskzE,138
@@ -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.26.dist-info/METADATA,sha256=Wu_SX7BK-xYsf_9XTFxZEQcC46vQNupG8YsXviNNEoQ,2049
246
- beamlit-0.0.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
247
- beamlit-0.0.26.dist-info/RECORD,,
246
+ beamlit-0.0.27.dist-info/METADATA,sha256=qXtSoaL19EpudttIjKmrB795nRP2ud-Y2-vlDeWXfgs,2401
247
+ beamlit-0.0.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
248
+ beamlit-0.0.27.dist-info/RECORD,,