rebrandly-otel 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.

Potentially problematic release.


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

@@ -0,0 +1,19 @@
1
+ Copyright (C) 2025 RadiateCapital Ltd (dba Rebrandly). (https://rebrandly.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.4
2
+ Name: rebrandly_otel
3
+ Version: 0.1.1
4
+ Summary: Python OTEL wrapper by Rebrandly
5
+ Home-page: https://github.com/pypa/sampleproject
6
+ Author: Antonio Romano
7
+ Author-email: antobio@rebrandly.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: author
14
+ Dynamic: author-email
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: home-page
19
+ Dynamic: license-file
20
+ Dynamic: summary
21
+
22
+ # Rebrandly OpenTelemetry SDK for Python
23
+
24
+ A comprehensive OpenTelemetry instrumentation SDK designed specifically for Rebrandly services, with built-in support for AWS Lambda functions and message processing.
25
+
26
+ ## Overview
27
+
28
+ The Rebrandly OpenTelemetry SDK provides a unified interface for distributed tracing, metrics collection, and structured logging across Python applications. It offers automatic instrumentation for AWS Lambda functions, simplified span management, and seamless integration with OTLP-compatible backends.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install rebrandly-otel-sdk
34
+ ```
35
+
36
+ ### Dependencies
37
+
38
+ - `opentelemetry-api`
39
+ - `opentelemetry-sdk`
40
+ - `opentelemetry-exporter-otlp-proto-grpc`
41
+ - `opentelemetry-semantic-conventions`
42
+ - `psutil` (for system metrics)
43
+
44
+ ## Configuration
45
+
46
+ The SDK is configured through environment variables:
47
+
48
+ | Variable | Description | Default |
49
+ |------------------------------------|-------------|---------|
50
+ | `OTEL_SERVICE_NAME` | Service identifier | `default-service-python` |
51
+ | `OTEL_SERVICE_VERSION` | Service version | `1.0.0` |
52
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | `None` |
53
+ | `OTEL_DEBUG` | Enable console debugging | `false` |
54
+ | `BATCH_EXPORT_TIME_MILLIS` | Batch export interval | `100` |
55
+ | `ENV` or `ENVIRONMENT` or `NODE_ENV` | Deployment environment | `local` |
56
+
57
+ ## Core Components
58
+
59
+ ### RebrandlyOTEL Class
60
+
61
+ The main entry point for all telemetry operations. Implements a singleton pattern to ensure consistent instrumentation across your application.
62
+
63
+ #### Properties
64
+
65
+ - **`tracer`**: Returns the `RebrandlyTracer` instance for distributed tracing
66
+ - **`meter`**: Returns the `RebrandlyMeter` instance for metrics collection
67
+ - **`logger`**: Returns the configured Python logger with OpenTelemetry integration
68
+
69
+ #### Initialization
70
+
71
+ The SDK auto-initializes as soon as you embed it.
72
+
73
+ ### Key Methods
74
+
75
+ #### `span(name, attributes=None, kind=SpanKind.INTERNAL, message=None)`
76
+
77
+ Context manager for creating traced spans with automatic error handling and status management.
78
+
79
+ #### `lambda_handler(name=None, attributes=None, kind=SpanKind.CONSUMER, auto_flush=True, skip_aws_link=True)`
80
+
81
+ Decorator for AWS Lambda functions with automatic instrumentation, metrics collection, and telemetry flushing.
82
+
83
+ #### `aws_message_handler(name=None, attributes=None, kind=SpanKind.CONSUMER, auto_flush=True)`
84
+
85
+ Decorator for processing individual AWS messages (SQS/SNS) with context propagation.
86
+
87
+ #### `aws_message_span(name, message=None, attributes=None, kind=SpanKind.CONSUMER)`
88
+
89
+ Context manager for creating spans from AWS messages with automatic context extraction.
90
+
91
+ #### `force_flush(start_datetime=None, timeout_millis=1000)`
92
+
93
+ Forces all pending telemetry data to be exported. Critical for serverless environments.
94
+
95
+ #### `shutdown()`
96
+
97
+ Gracefully shuts down all OpenTelemetry components.
98
+
99
+ ## Built-in Metrics
100
+
101
+ The SDK automatically registers and tracks the following metrics:
102
+
103
+ ### Standard Metrics
104
+
105
+ - **`invocations`** (Counter): Total number of function invocations
106
+ - **`successful_invocations`** (Counter): Number of successful completions
107
+ - **`error_invocations`** (Counter): Number of failed invocations
108
+ - **`duration`** (Histogram): Execution duration in milliseconds
109
+ - **`cpu_usage_percentage`** (Gauge): CPU utilization percentage
110
+ - **`memory_usage_bytes`** (Gauge): Memory usage in bytes
111
+
112
+ ### Global Metrics Access
113
+
114
+ ```python
115
+ from rebrandly_otel import meter
116
+
117
+ # Access pre-configured metrics
118
+ meter.GlobalMetrics.invocations.add(1, {'function': 'my_function'})
119
+ meter.GlobalMetrics.duration.record(150.5, {'source': 'api'})
120
+ ```
121
+
122
+ ## Tracing Features
123
+
124
+ ### Automatic Context Propagation
125
+
126
+ The SDK automatically extracts and propagates trace context from:
127
+ - AWS SQS message attributes
128
+ - AWS SNS message attributes
129
+ - HTTP headers
130
+ - Custom carriers
131
+
132
+ ### Span Attributes
133
+
134
+ Lambda spans automatically include:
135
+ - `faas.trigger`: Detected trigger type (sqs, sns, api_gateway, etc.)
136
+ - `faas.execution`: AWS request ID
137
+ - `faas.id`: Function ARN
138
+ - `cloud.provider`: Always "aws" for Lambda
139
+ - `cloud.platform`: Always "aws_lambda" for Lambda
140
+
141
+ ### Exception Handling
142
+
143
+ Spans automatically capture exceptions with:
144
+ - Full exception details and stack traces
145
+ - Automatic status code setting
146
+ - Exception events in the span timeline
147
+
148
+ ## Logging Integration
149
+
150
+ The SDK integrates with Python's standard logging module:
151
+
152
+ ```python
153
+ from rebrandly_otel import logger
154
+
155
+ # Use as a standard Python logger
156
+ logger.info("Processing started", extra={"request_id": "123"})
157
+ logger.error("Processing failed", exc_info=True)
158
+ ```
159
+
160
+ Features:
161
+ - Automatic trace context injection
162
+ - Structured logging support
163
+ - Console and OTLP export
164
+ - Log level configuration via environment
165
+
166
+ ## AWS Lambda Support
167
+
168
+ ### Trigger Detection
169
+
170
+ Automatically detects and labels Lambda triggers:
171
+ - API Gateway (v1 and v2)
172
+ - SQS
173
+ - SNS
174
+ - S3
175
+ - Kinesis
176
+ - DynamoDB
177
+ - EventBridge
178
+ - Batch
179
+
180
+ ### Automatic Metrics
181
+
182
+ For Lambda functions, the SDK automatically captures:
183
+ - Function duration
184
+ - Memory usage
185
+ - CPU utilization
186
+ - Invocation counts by status
187
+
188
+ ### Context Extraction
189
+
190
+ Automatically extracts trace context from:
191
+ - SQS MessageAttributes
192
+ - SNS MessageAttributes (including nested format)
193
+ - Custom message attributes
194
+
195
+ ## Performance Considerations
196
+
197
+ ### Batch Processing
198
+
199
+ - Configurable batch sizes and intervals
200
+ - Automatic batching for traces, metrics, and logs
201
+ - Optimized for high-throughput scenarios
202
+
203
+ ### Lambda Optimization
204
+
205
+ - Automatic flushing before function freeze
206
+ - Minimal cold start impact
207
+ - Efficient memory usage
208
+ - Configurable timeout handling
209
+
210
+ ## Export Formats
211
+
212
+ ### Supported Exporters
213
+
214
+ - **OTLP/gRPC**: Primary export format for production
215
+ - **Console**: Available for local development and debugging
216
+
217
+ ## Thread Safety
218
+
219
+ All components are thread-safe and can be used in multi-threaded applications:
220
+ - Singleton pattern ensures single initialization
221
+ - Thread-safe metric recording
222
+ - Concurrent span creation support
223
+
224
+ ## Resource Attributes
225
+
226
+ Automatically includes:
227
+ - Service name and version
228
+ - Python runtime version
229
+ - Deployment environment
230
+ - Custom resource attributes via environment
231
+
232
+ ## Error Handling
233
+
234
+ - Graceful degradation when OTLP endpoint unavailable
235
+ - Non-blocking telemetry operations
236
+ - Automatic retry with exponential backoff
237
+ - Comprehensive error logging
238
+
239
+ ## Compatibility
240
+
241
+ - Python 3.7+
242
+ - AWS Lambda runtime support
243
+ - Compatible with OpenTelemetry Collector
244
+ - Works with any OTLP-compatible backend
245
+
246
+ ## Examples
247
+
248
+ ### Lambda - Send SNS / SQS message
249
+ ```python
250
+ import os
251
+ import json
252
+ import boto3
253
+ from rebrandly_otel import otel, lambda_handler, logger
254
+
255
+ sqs = boto3.client('sqs')
256
+ QUEUE_URL = os.environ.get('SQS_URL')
257
+
258
+ @lambda_handler("sqs_sender")
259
+ def handler(event, context):
260
+ logger.info("Starting SQS message send")
261
+
262
+ # Get trace context for propagation
263
+ trace_attrs = otel.tracer.get_attributes_for_aws_from_context()
264
+
265
+ # Send message with trace context
266
+ response = sqs.send_message(
267
+ QueueUrl=QUEUE_URL,
268
+ MessageBody=json.dumps({"data": "test message"}),
269
+ MessageAttributes=trace_attrs
270
+ )
271
+
272
+ logger.info(f"Sent SQS message: {response['MessageId']}")
273
+
274
+ return {
275
+ 'statusCode': 200,
276
+ 'body': json.dumps({'messageId': response['MessageId']})
277
+ }
278
+ ```
279
+
280
+ ### Lambda Receive SQS message
281
+ ```python
282
+ import json
283
+ from rebrandly_otel import lambda_handler, logger, aws_message_span
284
+
285
+ @lambda_handler(name="sqs_receiver")
286
+ def handler(event, context):
287
+ for record in event['Records']:
288
+ # Process each message with trace context
289
+ process_message(record)
290
+
291
+ def process_message(record):
292
+ with aws_message_span("process_message_sqs_receiver", message=record) as s:
293
+ logger.info(f"Processing message: {record['messageId']}")
294
+
295
+ # Parse message body
296
+ body = json.loads(record['body'])
297
+ logger.info(f"Message data: {body}")
298
+ ```
299
+
300
+ ### Lambda Receive SNS message (record specific event)
301
+ ```python
302
+ import json
303
+ from rebrandly_otel import lambda_handler, logger, aws_message_span
304
+
305
+ @lambda_handler(name="sns_receiver")
306
+ def handler(event, context):
307
+ for record in event['Records']:
308
+ # Process each message with trace context
309
+ process_message(record)
310
+
311
+ def process_message(record):
312
+ message = json.loads(record['Sns']['Message'])
313
+ if message['event'] == 'whitelisted-event':
314
+ with aws_message_span("process_message_sns_receiver", message=record) as s:
315
+ logger.info(f"Processing message: {record['messageId']}")
316
+
317
+ # Parse message body
318
+ body = json.loads(record['body'])
319
+ logger.info(f"Message data: {body}")
320
+ ```
321
+
322
+ ### More examples
323
+ You can find More examples [here](examples)
324
+
325
+ ## License
326
+
327
+ Rebrandly Python SDK is released under the MIT License.
@@ -0,0 +1,306 @@
1
+ # Rebrandly OpenTelemetry SDK for Python
2
+
3
+ A comprehensive OpenTelemetry instrumentation SDK designed specifically for Rebrandly services, with built-in support for AWS Lambda functions and message processing.
4
+
5
+ ## Overview
6
+
7
+ The Rebrandly OpenTelemetry SDK provides a unified interface for distributed tracing, metrics collection, and structured logging across Python applications. It offers automatic instrumentation for AWS Lambda functions, simplified span management, and seamless integration with OTLP-compatible backends.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install rebrandly-otel-sdk
13
+ ```
14
+
15
+ ### Dependencies
16
+
17
+ - `opentelemetry-api`
18
+ - `opentelemetry-sdk`
19
+ - `opentelemetry-exporter-otlp-proto-grpc`
20
+ - `opentelemetry-semantic-conventions`
21
+ - `psutil` (for system metrics)
22
+
23
+ ## Configuration
24
+
25
+ The SDK is configured through environment variables:
26
+
27
+ | Variable | Description | Default |
28
+ |------------------------------------|-------------|---------|
29
+ | `OTEL_SERVICE_NAME` | Service identifier | `default-service-python` |
30
+ | `OTEL_SERVICE_VERSION` | Service version | `1.0.0` |
31
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | `None` |
32
+ | `OTEL_DEBUG` | Enable console debugging | `false` |
33
+ | `BATCH_EXPORT_TIME_MILLIS` | Batch export interval | `100` |
34
+ | `ENV` or `ENVIRONMENT` or `NODE_ENV` | Deployment environment | `local` |
35
+
36
+ ## Core Components
37
+
38
+ ### RebrandlyOTEL Class
39
+
40
+ The main entry point for all telemetry operations. Implements a singleton pattern to ensure consistent instrumentation across your application.
41
+
42
+ #### Properties
43
+
44
+ - **`tracer`**: Returns the `RebrandlyTracer` instance for distributed tracing
45
+ - **`meter`**: Returns the `RebrandlyMeter` instance for metrics collection
46
+ - **`logger`**: Returns the configured Python logger with OpenTelemetry integration
47
+
48
+ #### Initialization
49
+
50
+ The SDK auto-initializes as soon as you embed it.
51
+
52
+ ### Key Methods
53
+
54
+ #### `span(name, attributes=None, kind=SpanKind.INTERNAL, message=None)`
55
+
56
+ Context manager for creating traced spans with automatic error handling and status management.
57
+
58
+ #### `lambda_handler(name=None, attributes=None, kind=SpanKind.CONSUMER, auto_flush=True, skip_aws_link=True)`
59
+
60
+ Decorator for AWS Lambda functions with automatic instrumentation, metrics collection, and telemetry flushing.
61
+
62
+ #### `aws_message_handler(name=None, attributes=None, kind=SpanKind.CONSUMER, auto_flush=True)`
63
+
64
+ Decorator for processing individual AWS messages (SQS/SNS) with context propagation.
65
+
66
+ #### `aws_message_span(name, message=None, attributes=None, kind=SpanKind.CONSUMER)`
67
+
68
+ Context manager for creating spans from AWS messages with automatic context extraction.
69
+
70
+ #### `force_flush(start_datetime=None, timeout_millis=1000)`
71
+
72
+ Forces all pending telemetry data to be exported. Critical for serverless environments.
73
+
74
+ #### `shutdown()`
75
+
76
+ Gracefully shuts down all OpenTelemetry components.
77
+
78
+ ## Built-in Metrics
79
+
80
+ The SDK automatically registers and tracks the following metrics:
81
+
82
+ ### Standard Metrics
83
+
84
+ - **`invocations`** (Counter): Total number of function invocations
85
+ - **`successful_invocations`** (Counter): Number of successful completions
86
+ - **`error_invocations`** (Counter): Number of failed invocations
87
+ - **`duration`** (Histogram): Execution duration in milliseconds
88
+ - **`cpu_usage_percentage`** (Gauge): CPU utilization percentage
89
+ - **`memory_usage_bytes`** (Gauge): Memory usage in bytes
90
+
91
+ ### Global Metrics Access
92
+
93
+ ```python
94
+ from rebrandly_otel import meter
95
+
96
+ # Access pre-configured metrics
97
+ meter.GlobalMetrics.invocations.add(1, {'function': 'my_function'})
98
+ meter.GlobalMetrics.duration.record(150.5, {'source': 'api'})
99
+ ```
100
+
101
+ ## Tracing Features
102
+
103
+ ### Automatic Context Propagation
104
+
105
+ The SDK automatically extracts and propagates trace context from:
106
+ - AWS SQS message attributes
107
+ - AWS SNS message attributes
108
+ - HTTP headers
109
+ - Custom carriers
110
+
111
+ ### Span Attributes
112
+
113
+ Lambda spans automatically include:
114
+ - `faas.trigger`: Detected trigger type (sqs, sns, api_gateway, etc.)
115
+ - `faas.execution`: AWS request ID
116
+ - `faas.id`: Function ARN
117
+ - `cloud.provider`: Always "aws" for Lambda
118
+ - `cloud.platform`: Always "aws_lambda" for Lambda
119
+
120
+ ### Exception Handling
121
+
122
+ Spans automatically capture exceptions with:
123
+ - Full exception details and stack traces
124
+ - Automatic status code setting
125
+ - Exception events in the span timeline
126
+
127
+ ## Logging Integration
128
+
129
+ The SDK integrates with Python's standard logging module:
130
+
131
+ ```python
132
+ from rebrandly_otel import logger
133
+
134
+ # Use as a standard Python logger
135
+ logger.info("Processing started", extra={"request_id": "123"})
136
+ logger.error("Processing failed", exc_info=True)
137
+ ```
138
+
139
+ Features:
140
+ - Automatic trace context injection
141
+ - Structured logging support
142
+ - Console and OTLP export
143
+ - Log level configuration via environment
144
+
145
+ ## AWS Lambda Support
146
+
147
+ ### Trigger Detection
148
+
149
+ Automatically detects and labels Lambda triggers:
150
+ - API Gateway (v1 and v2)
151
+ - SQS
152
+ - SNS
153
+ - S3
154
+ - Kinesis
155
+ - DynamoDB
156
+ - EventBridge
157
+ - Batch
158
+
159
+ ### Automatic Metrics
160
+
161
+ For Lambda functions, the SDK automatically captures:
162
+ - Function duration
163
+ - Memory usage
164
+ - CPU utilization
165
+ - Invocation counts by status
166
+
167
+ ### Context Extraction
168
+
169
+ Automatically extracts trace context from:
170
+ - SQS MessageAttributes
171
+ - SNS MessageAttributes (including nested format)
172
+ - Custom message attributes
173
+
174
+ ## Performance Considerations
175
+
176
+ ### Batch Processing
177
+
178
+ - Configurable batch sizes and intervals
179
+ - Automatic batching for traces, metrics, and logs
180
+ - Optimized for high-throughput scenarios
181
+
182
+ ### Lambda Optimization
183
+
184
+ - Automatic flushing before function freeze
185
+ - Minimal cold start impact
186
+ - Efficient memory usage
187
+ - Configurable timeout handling
188
+
189
+ ## Export Formats
190
+
191
+ ### Supported Exporters
192
+
193
+ - **OTLP/gRPC**: Primary export format for production
194
+ - **Console**: Available for local development and debugging
195
+
196
+ ## Thread Safety
197
+
198
+ All components are thread-safe and can be used in multi-threaded applications:
199
+ - Singleton pattern ensures single initialization
200
+ - Thread-safe metric recording
201
+ - Concurrent span creation support
202
+
203
+ ## Resource Attributes
204
+
205
+ Automatically includes:
206
+ - Service name and version
207
+ - Python runtime version
208
+ - Deployment environment
209
+ - Custom resource attributes via environment
210
+
211
+ ## Error Handling
212
+
213
+ - Graceful degradation when OTLP endpoint unavailable
214
+ - Non-blocking telemetry operations
215
+ - Automatic retry with exponential backoff
216
+ - Comprehensive error logging
217
+
218
+ ## Compatibility
219
+
220
+ - Python 3.7+
221
+ - AWS Lambda runtime support
222
+ - Compatible with OpenTelemetry Collector
223
+ - Works with any OTLP-compatible backend
224
+
225
+ ## Examples
226
+
227
+ ### Lambda - Send SNS / SQS message
228
+ ```python
229
+ import os
230
+ import json
231
+ import boto3
232
+ from rebrandly_otel import otel, lambda_handler, logger
233
+
234
+ sqs = boto3.client('sqs')
235
+ QUEUE_URL = os.environ.get('SQS_URL')
236
+
237
+ @lambda_handler("sqs_sender")
238
+ def handler(event, context):
239
+ logger.info("Starting SQS message send")
240
+
241
+ # Get trace context for propagation
242
+ trace_attrs = otel.tracer.get_attributes_for_aws_from_context()
243
+
244
+ # Send message with trace context
245
+ response = sqs.send_message(
246
+ QueueUrl=QUEUE_URL,
247
+ MessageBody=json.dumps({"data": "test message"}),
248
+ MessageAttributes=trace_attrs
249
+ )
250
+
251
+ logger.info(f"Sent SQS message: {response['MessageId']}")
252
+
253
+ return {
254
+ 'statusCode': 200,
255
+ 'body': json.dumps({'messageId': response['MessageId']})
256
+ }
257
+ ```
258
+
259
+ ### Lambda Receive SQS message
260
+ ```python
261
+ import json
262
+ from rebrandly_otel import lambda_handler, logger, aws_message_span
263
+
264
+ @lambda_handler(name="sqs_receiver")
265
+ def handler(event, context):
266
+ for record in event['Records']:
267
+ # Process each message with trace context
268
+ process_message(record)
269
+
270
+ def process_message(record):
271
+ with aws_message_span("process_message_sqs_receiver", message=record) as s:
272
+ logger.info(f"Processing message: {record['messageId']}")
273
+
274
+ # Parse message body
275
+ body = json.loads(record['body'])
276
+ logger.info(f"Message data: {body}")
277
+ ```
278
+
279
+ ### Lambda Receive SNS message (record specific event)
280
+ ```python
281
+ import json
282
+ from rebrandly_otel import lambda_handler, logger, aws_message_span
283
+
284
+ @lambda_handler(name="sns_receiver")
285
+ def handler(event, context):
286
+ for record in event['Records']:
287
+ # Process each message with trace context
288
+ process_message(record)
289
+
290
+ def process_message(record):
291
+ message = json.loads(record['Sns']['Message'])
292
+ if message['event'] == 'whitelisted-event':
293
+ with aws_message_span("process_message_sns_receiver", message=record) as s:
294
+ logger.info(f"Processing message: {record['messageId']}")
295
+
296
+ # Parse message body
297
+ body = json.loads(record['body'])
298
+ logger.info(f"Message data: {body}")
299
+ ```
300
+
301
+ ### More examples
302
+ You can find More examples [here](examples)
303
+
304
+ ## License
305
+
306
+ Rebrandly Python SDK is released under the MIT License.