python-server-sdk

Server-side Python SDK for LaunchDarkly feature flags, real-time flag evaluation, and progressive feature rollouts.

SDK
PyPI
v9.17.0
44stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
74/100Good
Development Activity96
Maintenance96
Community32
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture85
Code Quality88
Innovation78
Learning Curve80

launchdarkly-server-sdk is the official server-side Python client for LaunchDarkly, a feature management platform used to control feature rollouts, run experiments, and kill switches without redeploying code. The client connects to LaunchDarkly’s streaming or polling endpoints, keeps an in-memory (or persisted) copy of flag rules, and evaluates flags locally in-process so calls to variation() don’t add network latency to the request path.

The SDK targets Python 3.10+ and covers the full server-side feature set: context-based targeting (LaunchDarkly’s successor to the older “user” model), big segments backed by Redis/DynamoDB/Consul, safe migration tooling for moving between two implementations of a system, hooks and plugins for instrumenting evaluations, and a TestData source for writing deterministic unit tests without hitting the network. An experimental AsyncLDClient built on aiohttp is available for asyncio-based applications, alongside the mature thread-based LDClient.

What You Get

  • An LDClient (and experimental AsyncLDClient) that streams or polls flag and segment data from LaunchDarkly and evaluates flags locally with no per-call network round-trip
  • Context-based targeting rules, including big segments support backed by Redis, DynamoDB, or Consul for large user/attribute segments
  • A safe-migration toolkit (Migrator, MigratorBuilder, stage tracking) for shifting traffic between an old and new implementation of a system behind a flag
  • Hooks and a plugin interface for instrumenting flag evaluations (e.g. tracing, logging) without modifying application code
  • A TestData integration for constructing flag states in unit tests without any network or LaunchDarkly account dependency
  • Persistent data store wrappers (Redis, DynamoDB, Consul) so flag state survives process restarts and can be shared across instances

Common Use Cases

  • Gating a new feature behind a flag and rolling it out to a percentage of production traffic without a redeploy
  • Running a kill switch that can instantly disable a misbehaving feature in production
  • Targeting specific users, accounts, or cohorts (via evaluation context attributes) with different application behavior
  • Migrating a service from a legacy system to a new one gradually, tracking correctness and latency at each stage with the Migrator
  • Writing deterministic unit tests against flag-dependent code using TestData instead of mocking HTTP calls

Under The Hood

Architecture The SDK centers on LDClient (ldclient/client.py), a thread-safe object constructed once at application startup that owns a DataSystem abstraction (ldclient/impl/datasystem) responsible for populating an in-memory FeatureStore from either a streaming (StreamingUpdateProcessor) or polling (PollingUpdateProcessor) data source, with a newer FDv2 data system (ldclient/impl/datasystem/fdv2.py) layered alongside the original FDv1 path for backward compatibility. Flag evaluation itself runs through ldclient/impl/evaluator.py, which walks a flag’s targeting rules against an evaluation Context entirely in-process, so variation() calls never block on network I/O. Big segments, event delivery (DefaultEventProcessor), and diagnostics run on separate background threads coordinated through a ReadWriteLock, and a parallel AsyncLDClient (ldclient/async_client.py) mirrors this structure on asyncio/aiohttp for single-event-loop applications. What breaks if the core evaluator changes: every persistent-store integration (Redis/DynamoDB/Consul), the migration tracker, and both sync and async clients all depend on its rule-matching semantics staying byte-for-byte compatible with LaunchDarkly’s other SDKs.

Tech Stack The package targets Python 3.10+ and is built with Hatchling. Core runtime dependencies are minimal and deliberately lightweight: urllib3 for HTTP, launchdarkly-eventsource for SSE streaming, pyRFC3339 and semver for parsing, and expiringdict for TTL caching; aiohttp is pulled in only via the optional async extra. Optional persistent-store integrations are isolated behind extras (redis, consul, boto3/aioboto3 for DynamoDB), keeping the base install free of heavyweight database clients. Documentation builds with Sphinx and ships to Read the Docs, and CI (GitHub Actions) runs the full matrix across Python 3.10 through 3.14 with Redis, Consul, and DynamoDB service containers.

Code Quality The ldclient/testing/ directory contains roughly 90 test modules covering the sync client, async client, feature stores (in-memory and per-backend), context handling, hooks, migrations, and file-based data sources — including an end-to-end test (test_ldclient_end_to_end.py). The project runs mypy for static typing, pycodestyle and isort for style, and pytest with coverage in CI (make test-all), and public modules carry docstrings (visible throughout client.py and config.py). Contract tests (contract-tests/) additionally verify the SDK’s evaluation behavior against LaunchDarkly’s cross-SDK test harness, which is a stronger correctness signal than unit tests alone for a library whose core promise is identical behavior across languages.

API Design The public surface is small and intentional: applications construct one Config, pass it to LDClient, and call variation()/variation_detail() with a Context built via Context.create() or Context.builder(). Optional capabilities (persistent stores, big segments, migrations, hooks, plugins) are opt-in through Config fields rather than separate top-level APIs, so a minimal integration stays a few lines while advanced use (multi-kind contexts, safe migrations) composes onto the same client. The AsyncLDClient deliberately mirrors the sync client’s method names and shapes, reducing the cost of learning both, though the README flags it as experimental and not yet covered by the same compatibility guarantees.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search