rebrandly-otel 0.1.25__tar.gz → 0.1.27__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.

Potentially problematic release.


This version of rebrandly-otel might be problematic. Click here for more details.

Files changed (20) hide show
  1. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/PKG-INFO +1 -2
  2. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/rebrandly_otel.egg-info/PKG-INFO +1 -2
  3. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/rebrandly_otel.egg-info/requires.txt +0 -1
  4. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/setup.py +1 -2
  5. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/fastapi_support.py +25 -16
  6. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/flask_support.py +25 -16
  7. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/otel_utils.py +2 -2
  8. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/LICENSE +0 -0
  9. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/README.md +0 -0
  10. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/rebrandly_otel.egg-info/SOURCES.txt +0 -0
  11. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/rebrandly_otel.egg-info/dependency_links.txt +0 -0
  12. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/rebrandly_otel.egg-info/top_level.txt +0 -0
  13. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/setup.cfg +0 -0
  14. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/__init__.py +0 -0
  15. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/logs.py +0 -0
  16. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/metrics.py +0 -0
  17. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/pymysql_instrumentation.py +0 -0
  18. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/rebrandly_otel.py +0 -0
  19. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/src/traces.py +0 -0
  20. {rebrandly_otel-0.1.25 → rebrandly_otel-0.1.27}/tests/test_usage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rebrandly_otel
3
- Version: 0.1.25
3
+ Version: 0.1.27
4
4
  Summary: Python OTEL wrapper by Rebrandly
5
5
  Home-page: https://github.com/rebrandly/rebrandly-otel-python
6
6
  Author: Antonio Romano
@@ -14,7 +14,6 @@ Requires-Dist: opentelemetry-api>=1.34.0
14
14
  Requires-Dist: opentelemetry-sdk>=1.34.0
15
15
  Requires-Dist: opentelemetry-exporter-otlp>=1.34.0
16
16
  Requires-Dist: psutil>=5.0.0
17
- Requires-Dist: flask>=3.1.2
18
17
  Requires-Dist: fastapi>=0.118.0
19
18
  Dynamic: author
20
19
  Dynamic: author-email
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rebrandly_otel
3
- Version: 0.1.25
3
+ Version: 0.1.27
4
4
  Summary: Python OTEL wrapper by Rebrandly
5
5
  Home-page: https://github.com/rebrandly/rebrandly-otel-python
6
6
  Author: Antonio Romano
@@ -14,7 +14,6 @@ Requires-Dist: opentelemetry-api>=1.34.0
14
14
  Requires-Dist: opentelemetry-sdk>=1.34.0
15
15
  Requires-Dist: opentelemetry-exporter-otlp>=1.34.0
16
16
  Requires-Dist: psutil>=5.0.0
17
- Requires-Dist: flask>=3.1.2
18
17
  Requires-Dist: fastapi>=0.118.0
19
18
  Dynamic: author
20
19
  Dynamic: author-email
@@ -2,5 +2,4 @@ opentelemetry-api>=1.34.0
2
2
  opentelemetry-sdk>=1.34.0
3
3
  opentelemetry-exporter-otlp>=1.34.0
4
4
  psutil>=5.0.0
5
- flask>=3.1.2
6
5
  fastapi>=0.118.0
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="rebrandly_otel",
8
- version="0.1.25",
8
+ version="0.1.27",
9
9
  author="Antonio Romano",
10
10
  author_email="antonio@rebrandly.com",
11
11
  description="Python OTEL wrapper by Rebrandly",
@@ -19,7 +19,6 @@ setuptools.setup(
19
19
  "opentelemetry-sdk>=1.34.0",
20
20
  "opentelemetry-exporter-otlp>=1.34.0",
21
21
  "psutil>=5.0.0",
22
- "flask>=3.1.2",
23
22
  "fastapi>=0.118.0"
24
23
  ],
25
24
  classifiers=[
@@ -49,25 +49,34 @@ def add_otel_middleware(otel, app):
49
49
  # Start span for request
50
50
  span_name = f"{request.method} {request.url.path}"
51
51
 
52
+ # Build attributes dict, excluding None values
53
+ attributes = {
54
+ # Required HTTP attributes per semantic conventions
55
+ "http.request.method": request.method,
56
+ "http.request.headers": json.dumps(request.headers, default=str),
57
+ "url.full": str(request.url),
58
+ "url.scheme": request.url.scheme,
59
+ "url.path": request.url.path,
60
+ "network.protocol.version": "1.1", # FastAPI/Starlette typically uses HTTP/1.1
61
+ "server.address": request.url.hostname,
62
+ "server.port": request.url.port or (443 if request.url.scheme == 'https' else 80),
63
+ }
64
+
65
+ # Add optional attributes only if they have values
66
+ if request.url.query:
67
+ attributes["url.query"] = request.url.query
68
+
69
+ user_agent = request.headers.get("user-agent")
70
+ if user_agent:
71
+ attributes["user_agent.original"] = user_agent
72
+
73
+ if request.client and request.client.host:
74
+ attributes["client.address"] = request.client.host
75
+
52
76
  # Use start_as_current_span for proper context propagation
53
77
  with self.otel.tracer.tracer.start_as_current_span(
54
78
  span_name,
55
- attributes={
56
- # Required HTTP attributes per semantic conventions
57
- "http.request.method": request.method,
58
- "http.request.headers": json.dumps(request.headers, default=str),
59
- "http.response.status_code": None, # Will be set after response
60
- "url.full": str(request.url),
61
- "url.scheme": request.url.scheme,
62
- "url.path": request.url.path,
63
- "url.query": request.url.query if request.url.query else None,
64
- "user_agent.original": request.headers.get("user-agent"),
65
- "http.route": None, # Will be set after routing
66
- "network.protocol.version": "1.1", # FastAPI/Starlette typically uses HTTP/1.1
67
- "server.address": request.url.hostname,
68
- "server.port": request.url.port or (443 if request.url.scheme == 'https' else 80),
69
- "client.address": request.client.host if request.client else None,
70
- },
79
+ attributes=attributes,
71
80
  kind=SpanKind.SERVER
72
81
  ) as span:
73
82
  # Log request start
@@ -40,25 +40,34 @@ def app_before_request(otel):
40
40
  # Route will be available after request routing is done
41
41
  span_name = f"{request.method} {request.path}"
42
42
 
43
+ # Build attributes dict, excluding None values
44
+ attributes = {
45
+ # Required HTTP attributes per semantic conventions
46
+ "http.request.method": request.method,
47
+ "http.request.headers": json.dumps(request.headers, default=str),
48
+ "url.full": request.url,
49
+ "url.scheme": request.scheme,
50
+ "url.path": request.path,
51
+ "http.route": request.path, # Flask doesn't expose route pattern easily
52
+ "network.protocol.version": request.environ.get('SERVER_PROTOCOL', 'HTTP/1.1').split('/')[-1],
53
+ "server.address": request.host.split(':')[0],
54
+ "server.port": request.host.split(':')[1] if ':' in request.host else (443 if request.scheme == 'https' else 80),
55
+ }
56
+
57
+ # Add optional attributes only if they have values
58
+ if request.query_string:
59
+ attributes["url.query"] = request.query_string.decode('utf-8')
60
+
61
+ if request.user_agent and request.user_agent.string:
62
+ attributes["user_agent.original"] = request.user_agent.string
63
+
64
+ if request.remote_addr:
65
+ attributes["client.address"] = request.remote_addr
66
+
43
67
  # Start span for request using start_as_current_span to make it the active span
44
68
  span = otel.tracer.tracer.start_as_current_span(
45
69
  span_name,
46
- attributes={
47
- # Required HTTP attributes per semantic conventions
48
- "http.request.method": request.method,
49
- "http.request.headers": json.dumps(request.headers, default=str),
50
- "http.response.status_code": None, # Will be set in after_request
51
- "url.full": request.url,
52
- "url.scheme": request.scheme,
53
- "url.path": request.path,
54
- "url.query": request.query_string.decode('utf-8') if request.query_string else None,
55
- "user_agent.original": request.user_agent.string if request.user_agent else None,
56
- "http.route": request.path, # Flask doesn't expose route pattern easily
57
- "network.protocol.version": request.environ.get('SERVER_PROTOCOL', 'HTTP/1.1').split('/')[-1],
58
- "server.address": request.host.split(':')[0],
59
- "server.port": request.host.split(':')[1] if ':' in request.host else (443 if request.scheme == 'https' else 80),
60
- "client.address": request.remote_addr,
61
- },
70
+ attributes=attributes,
62
71
  kind=SpanKind.SERVER
63
72
  )
64
73
  # Store both the span context manager and the span itself
@@ -6,7 +6,7 @@ import sys
6
6
  import grpc
7
7
  import json
8
8
 
9
- from opentelemetry.sdk.resources import Resource
9
+ from opentelemetry.sdk.resources import Resource, SERVICE_NAMESPACE
10
10
  from opentelemetry.semconv.attributes import service_attributes
11
11
  from opentelemetry.semconv._incubating.attributes import process_attributes, deployment_attributes
12
12
 
@@ -22,7 +22,7 @@ def create_resource(name: str = None, version: str = None) -> Resource:
22
22
  service_attributes.SERVICE_NAME: name,
23
23
  service_attributes.SERVICE_VERSION: version,
24
24
  process_attributes.PROCESS_RUNTIME_VERSION: f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
25
- deployment_attributes.DEPLOYMENT_ENVIRONMENT_NAME: os.environ.get('ENV', os.environ.get('ENVIRONMENT', os.environ.get('NODE_ENV', 'local')))
25
+ SERVICE_NAMESPACE: os.environ.get('ENV', os.environ.get('ENVIRONMENT', os.environ.get('NODE_ENV', 'local')))
26
26
  }
27
27
  )
28
28
  return resource
File without changes