DevCycle Python Server SDK
The DevCycle Python Server SDK provides real-time feature flag delivery and experimentation capabilities for Python applications. It allows developers to define, manage, and evaluate feature flags and A/B tests to deliver personalized experiences. The SDK fetches configurations, evaluates variables, and tracks events. The current version is 3.13.7, with frequent releases addressing bug fixes and minor feature enhancements.
Common errors
-
RuntimeError: DevCycleClient not initialized.
cause Attempting to evaluate variables or perform other operations before the SDK has finished its asynchronous initialization process (fetching initial configurations).fixEnsure you `await client.on_initialized()` before making any calls to `client.variable()` or other evaluation methods. Handle potential exceptions during initialization. -
AttributeError: 'DevCycle' object has no attribute 'variable'
cause This error often occurs when upgrading from pre-v3.0.0 SDK versions without updating client initialization and method calls. The `DevCycle` class no longer exists; it's `DevCycleClient`.fixRefactor your code to use `DevCycleClient` and its `async` methods. For example, replace `client.variable()` with `await client.variable()` on the new `DevCycleClient` instance. -
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
cause This warning, often accompanied by `ResourceWarning: unclosed client session`, indicates that SDK resources (like HTTP sessions or background tasks) were not properly shut down before the application exited.fixEnsure `await client.close()` is called before your application's `asyncio` event loop terminates. This cleans up internal resources and prevents warnings related to unclosed connections. -
TypeError: object DevCycleClient can't be used in 'await' expression
cause This occurs when you try to `await` the `DevCycleClient` instance itself, rather than one of its asynchronous methods (e.g., `on_initialized()`, `variable()`, `close()`).fixOnly `await` specific asynchronous methods of the `DevCycleClient` object, such as `await client.on_initialized()` or `await client.variable(user, 'key', default_value)`.
Warnings
- breaking Version 3.0.0 introduced significant breaking changes, including a complete rewrite of the SDK. The `DevCycle` class was replaced with `DevCycleClient`, and the SDK shifted to an asynchronous (`asyncio`) programming model. Method signatures for initialization and variable evaluation changed substantially.
- gotcha The SDK is built on `asyncio`. Attempting to use `DevCycleClient` methods without `await` or outside a running `asyncio` event loop will lead to `RuntimeError` or unexpected behavior (e.g., tasks not completing).
- gotcha Incorrect or expired DevCycle Server SDK keys can lead to the SDK failing to fetch configurations or stopping polling for updates. This often results in default variable values being used or evaluation errors, without clear immediate indication in variable calls.
- gotcha The SDK offers both local bucketing (WASM) and cloud bucketing modes, controlled by `DevCycleOptions`. The default behavior for `enable_cloud_bucketing` can affect performance, network usage, and consistency if not explicitly configured.
Install
-
pip install devcycle-python-server-sdk
Imports
- DevCycleClient
from devcycle_python_sdk import DevCycleClient
- DevCycleOptions
from devcycle_python_sdk import DevCycleOptions
- DevCycleUser
from devcycle_python_sdk import DevCycleUser
- DevCycleLocalBucketingOptions
from devcycle_python_sdk import DevCycleLocalBucketingOptions
Quickstart
import os
import asyncio
from devcycle_python_sdk import DevCycleClient, DevCycleOptions, DevCycleUser
DEVCYCLE_SERVER_SDK_KEY = os.environ.get('DEVCYCLE_SERVER_SDK_KEY', '')
async def main():
if not DEVCYCLE_SERVER_SDK_KEY:
print("Error: DEVCYCLE_SERVER_SDK_KEY environment variable not set.")
return
# Configure options, e.g., enable cloud bucketing for server-side evaluation
# By default, local bucketing (WASM) is used if not specified
options = DevCycleOptions(enable_cloud_bucketing=True)
client = DevCycleClient(DEVCYCLE_SERVER_SDK_KEY, options)
try:
# Wait for the client to be initialized and fetch configurations
await client.on_initialized()
print("DevCycle client initialized.")
# Define a user for feature evaluation
user = DevCycleUser(
user_id="example-user",
email="test@example.com",
country="US"
)
# Evaluate a boolean variable
feature_enabled = await client.variable(user, "my-feature", False)
if feature_enabled.value:
print("Feature 'my-feature' is ON for the user.")
else:
print("Feature 'my-feature' is OFF for the user.")
# Evaluate a string variable
welcome_message = await client.variable(user, "welcome-text", "Hello!")
print(f"Welcome message for user: {welcome_message.value}")
except Exception as e:
print(f"An error occurred during DevCycle operations: {e}")
finally:
# Ensure the client is closed to release resources
await client.close()
print("DevCycle client closed.")
if __name__ == '__main__':
asyncio.run(main())