owlpane 0.1.1__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.
owlpane-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: owlpane
3
+ Version: 0.1.1
4
+ Summary: Thin OpenTelemetry bootstrap for Owlpane ingest
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: opentelemetry-api>=1.28.0
8
+ Requires-Dist: opentelemetry-sdk>=1.28.0
9
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.28.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
12
+
13
+ # owlpane (Python)
14
+
15
+ Thin SDK: resolves env like `@owlpane/node`, exports traces via OpenTelemetry.
16
+
17
+ ```bash
18
+ pip install -e .
19
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.example.com
20
+ export OWLPANE_INGEST_KEY=owl_ing_…
21
+ export OTEL_SERVICE_NAME=my-api
22
+ ```
23
+
24
+ ```python
25
+ from owlpane import shutdown, start
26
+
27
+ start()
28
+ # … application …
29
+ shutdown()
30
+ ```
@@ -0,0 +1,18 @@
1
+ # owlpane (Python)
2
+
3
+ Thin SDK: resolves env like `@owlpane/node`, exports traces via OpenTelemetry.
4
+
5
+ ```bash
6
+ pip install -e .
7
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.example.com
8
+ export OWLPANE_INGEST_KEY=owl_ing_…
9
+ export OTEL_SERVICE_NAME=my-api
10
+ ```
11
+
12
+ ```python
13
+ from owlpane import shutdown, start
14
+
15
+ start()
16
+ # … application …
17
+ shutdown()
18
+ ```
@@ -0,0 +1,70 @@
1
+ """Owlpane thin Python SDK — configures OpenTelemetry export from environment."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Callable, Optional
6
+
7
+ from opentelemetry import trace
8
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
9
+ from opentelemetry.sdk.resources import Resource
10
+ from opentelemetry.sdk.trace import TracerProvider
11
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
12
+ from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio
13
+
14
+ from owlpane._generated_config import Config, resolve_config_from_env
15
+
16
+ _provider: Optional[TracerProvider] = None
17
+ _enabled = False
18
+
19
+
20
+ def start(cfg: Optional[Config] = None) -> Optional[Callable[[], None]]:
21
+ """Start OTLP export. Returns shutdown callable, or None when unconfigured."""
22
+ global _provider, _enabled
23
+ if cfg is None:
24
+ cfg = resolve_config_from_env()
25
+ if cfg is None:
26
+ return None
27
+ if _provider is not None:
28
+ return shutdown
29
+
30
+ headers = {}
31
+ if cfg.authorization:
32
+ headers["Authorization"] = cfg.authorization
33
+
34
+ exporter = OTLPSpanExporter(
35
+ endpoint=f"{cfg.base_url}/v1/traces",
36
+ headers=headers,
37
+ )
38
+ resource = Resource.create(
39
+ {
40
+ "service.name": cfg.service_name,
41
+ "service.version": cfg.version,
42
+ "deployment.environment.name": cfg.environment,
43
+ }
44
+ )
45
+ sampler = ParentBasedTraceIdRatio(cfg.sample_ratio)
46
+ _provider = TracerProvider(resource=resource, sampler=sampler)
47
+ _provider.add_span_processor(BatchSpanProcessor(exporter))
48
+ trace.set_tracer_provider(_provider)
49
+ _enabled = True
50
+ return shutdown
51
+
52
+
53
+ def shutdown() -> None:
54
+ global _provider, _enabled
55
+ if _provider is not None:
56
+ _provider.shutdown()
57
+ _provider = None
58
+ _enabled = False
59
+
60
+
61
+ def is_enabled() -> bool:
62
+ return _enabled
63
+
64
+
65
+ def emit_test_span(name: str) -> None:
66
+ if not _enabled:
67
+ raise RuntimeError("owlpane not enabled")
68
+ tracer = trace.get_tracer("owlpane")
69
+ with tracer.start_as_current_span(name):
70
+ pass
@@ -0,0 +1,55 @@
1
+ # Code generated by codegen/generate.ts; DO NOT EDIT.
2
+ from __future__ import annotations
3
+
4
+ import os
5
+ from dataclasses import dataclass
6
+ from typing import Optional
7
+
8
+
9
+ @dataclass
10
+ class Config:
11
+ base_url: str
12
+ authorization: str
13
+ service_name: str
14
+ version: str
15
+ environment: str
16
+ sample_ratio: float
17
+ trace_user_profile: bool
18
+
19
+
20
+ def _env(k: str) -> str:
21
+ return (os.environ.get(k) or "").strip()
22
+
23
+
24
+ def resolve_config_from_env() -> Optional[Config]:
25
+ if _env("OTEL_SDK_DISABLED") == "true":
26
+ return None
27
+ endpoint = _env("OTEL_EXPORTER_OTLP_ENDPOINT") or _env("OWLPANE_INGEST_URL")
28
+ if not endpoint:
29
+ return None
30
+ endpoint = endpoint.rstrip("/")
31
+ service = _env("OTEL_SERVICE_NAME") or "python-app"
32
+ version = _env("OWLPANE_RELEASE") or "0.0.0"
33
+ environment = _env("OWLPANE_ENVIRONMENT") or _env("NODE_ENV") or "development"
34
+ key = _env("OWLPANE_INGEST_KEY")
35
+ auth = f"Bearer {key}" if key else ""
36
+ ratio = 1.0
37
+ if _env("NODE_ENV") == "production":
38
+ ratio = 0.1
39
+ raw = _env("OTEL_TRACES_SAMPLER_ARG")
40
+ if raw:
41
+ try:
42
+ f = float(raw)
43
+ ratio = f if 0 <= f <= 1 else 0.1
44
+ except ValueError:
45
+ ratio = 0.1
46
+ tup = _env("OWLPANE_TRACE_USER_PROFILE").lower() in ("1", "true", "yes")
47
+ return Config(
48
+ base_url=endpoint,
49
+ authorization=auth,
50
+ service_name=service,
51
+ version=version,
52
+ environment=environment,
53
+ sample_ratio=ratio,
54
+ trace_user_profile=tup,
55
+ )
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: owlpane
3
+ Version: 0.1.1
4
+ Summary: Thin OpenTelemetry bootstrap for Owlpane ingest
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: opentelemetry-api>=1.28.0
8
+ Requires-Dist: opentelemetry-sdk>=1.28.0
9
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.28.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
12
+
13
+ # owlpane (Python)
14
+
15
+ Thin SDK: resolves env like `@owlpane/node`, exports traces via OpenTelemetry.
16
+
17
+ ```bash
18
+ pip install -e .
19
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.example.com
20
+ export OWLPANE_INGEST_KEY=owl_ing_…
21
+ export OTEL_SERVICE_NAME=my-api
22
+ ```
23
+
24
+ ```python
25
+ from owlpane import shutdown, start
26
+
27
+ start()
28
+ # … application …
29
+ shutdown()
30
+ ```
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ owlpane/__init__.py
4
+ owlpane/_generated_config.py
5
+ owlpane.egg-info/PKG-INFO
6
+ owlpane.egg-info/SOURCES.txt
7
+ owlpane.egg-info/dependency_links.txt
8
+ owlpane.egg-info/requires.txt
9
+ owlpane.egg-info/top_level.txt
10
+ tests/test_config.py
@@ -0,0 +1,6 @@
1
+ opentelemetry-api>=1.28.0
2
+ opentelemetry-sdk>=1.28.0
3
+ opentelemetry-exporter-otlp-proto-http>=1.28.0
4
+
5
+ [dev]
6
+ pytest>=8.0.0
@@ -0,0 +1 @@
1
+ owlpane
@@ -0,0 +1,22 @@
1
+ [project]
2
+ name = "owlpane"
3
+ version = "0.1.1"
4
+ description = "Thin OpenTelemetry bootstrap for Owlpane ingest"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "opentelemetry-api>=1.28.0",
9
+ "opentelemetry-sdk>=1.28.0",
10
+ "opentelemetry-exporter-otlp-proto-http>=1.28.0",
11
+ ]
12
+
13
+ [project.optional-dependencies]
14
+ dev = ["pytest>=8.0.0"]
15
+
16
+ [build-system]
17
+ requires = ["setuptools>=68"]
18
+ build-backend = "setuptools.build_meta"
19
+
20
+ [tool.setuptools.packages.find]
21
+ where = ["."]
22
+ include = ["owlpane*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ import os
2
+
3
+ from owlpane._generated_config import resolve_config_from_env
4
+
5
+
6
+ def test_missing_endpoint():
7
+ os.environ.clear()
8
+ assert resolve_config_from_env() is None
9
+
10
+
11
+ def test_basic():
12
+ os.environ.clear()
13
+ os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://ingest.test"
14
+ os.environ["OWLPANE_INGEST_KEY"] = "owl_ing_" + "a" * 48
15
+ os.environ["OTEL_SERVICE_NAME"] = "api"
16
+ cfg = resolve_config_from_env()
17
+ assert cfg is not None
18
+ assert cfg.base_url == "https://ingest.test"
19
+ assert cfg.service_name == "api"
20
+ assert cfg.authorization.startswith("Bearer ")