Skip to main content

OpenFeature provider for Cloudflare Flagship feature flags.

Project description

cloudflare-flagship

PyPI version Python versions license

Flagship is a globally distributed, low-latency feature flag platform built entirely on Cloudflare. This package is the Python SDK — an OpenFeature-compliant provider for evaluating feature flags from Python server environments.

Note: The Python SDK supports HTTP mode only. The Cloudflare Workers binding mode (env.FLAGS) is exclusive to the TypeScript SDK and is not available in Python.

Installation

# uv
uv add cloudflare-flagship

# pip
pip install cloudflare-flagship

Quick start

from openfeature import api
from openfeature.evaluation_context import EvaluationContext
from flagship import FlagshipServerProvider

api.set_provider(
    FlagshipServerProvider(
        app_id="your-app-id",
        account_id="your-account-id",
        auth_token="your-token",
    )
)

client = api.get_client()
enabled = client.get_boolean_value(
    "dark-mode",
    False,
    EvaluationContext(targeting_key="user-123", attributes={"plan": "premium"}),
)

See examples/server.py for a full synchronous example and examples/async_server.py for async usage with asyncio.

Flag types

All four OpenFeature flag types are supported. Python's OpenFeature SDK splits the TypeScript number type into integer and float.

enabled = client.get_boolean_value("new-checkout", False, context)
variant = client.get_string_value("homepage-hero", "control", context)
limit   = client.get_integer_value("upload-limit", 10, context)
rate    = client.get_float_value("sample-rate", 0.1, context)
config  = client.get_object_value("ui-config", {"theme": "light"}, context)

Use the *_details variants when you need the full resolution result:

details = client.get_boolean_details("my-flag", False, context)

print(details.value)          # resolved value (or default on error)
print(details.reason)         # TARGETING_MATCH | SPLIT | DEFAULT | DISABLED | ERROR
print(details.variant)        # variation key, e.g. "on", "off", "v2"
print(details.error_code)     # set on error, e.g. FLAG_NOT_FOUND, TYPE_MISMATCH
print(details.error_message)

Configuration

FlagshipServerProvider accepts either app_id + account_id (recommended) or a full endpoint URL — not both.

FlagshipServerProvider(
    # Option A (recommended)
    app_id="your-app-id",
    account_id="your-account-id",

    # Option B: full URL (mutually exclusive with app_id)
    # endpoint="http://localhost:8787/v1/acct/apps/app-id/evaluate",

    # Static bearer token
    auth_token="your-token",

    # Dynamic credentials — called once per request, takes precedence over auth_token
    # headers_factory=lambda: {"Authorization": f"Bearer {get_token()}"},

    # Override the base URL for local dev
    # base_url="http://localhost:8787",

    timeout=5.0,      # seconds (default: 5.0)
    retries=1,        # retry attempts on transient errors, capped at 10 (default: 1)
    retry_delay=1.0,  # seconds between retries, capped at 30.0 (default: 1.0)
    logging=False,    # set True to enable SDK debug output (default: False)
)
Option Type Default Description
app_id str Flagship app ID (mutually exclusive with endpoint)
account_id str Required with app_id
base_url str https://api.cloudflare.com Base URL override (only used with app_id)
endpoint str Full evaluation URL (mutually exclusive with app_id)
auth_token str Bearer token added to every request
headers_factory Callable[[], dict[str, str]] Called per request; takes precedence over auth_token
timeout float 5.0 Request timeout in seconds
retries int 1 Retry attempts on transient errors; capped at 10
retry_delay float 1.0 Delay between retries in seconds; capped at 30.0
logging bool False Enable SDK-level debug output via the flagship logger

Evaluation context

Context attributes are sent as URL query parameters. Supported types:

Type Serialisation
str, int, float Passed as a string
bool "true" or "false"
datetime ISO 8601
dict, list, other Not supported — raises InvalidContextError

Async

The async API mirrors the sync API — just await the *_async variants:

enabled = await client.get_boolean_value_async("dark-mode", False, context)
details = await client.get_boolean_details_async("dark-mode", False, context)

# Evaluate multiple flags concurrently
import asyncio
dark_mode, beta_access = await asyncio.gather(
    client.get_boolean_value_async("dark-mode", False, context),
    client.get_boolean_value_async("beta-access", False, context),
)

When shutting down in an async context, use shutdown_async() to properly close the HTTP client:

await api.shutdown_async()

Error handling

The provider never throws from a resolution method. On error the OpenFeature SDK returns the default value with an error_code and error_message.

Error code Cause
FLAG_NOT_FOUND Flag key does not exist (HTTP 404)
TYPE_MISMATCH The flag's resolved type does not match the requested type
INVALID_CONTEXT The evaluation context contains unsupported types (dict, list)
PARSE_ERROR The API response was not a valid evaluation response
GENERAL Network error, timeout, or any other transient failure

404 and 400 responses are never retried. All other failures are retried up to retries times.

Hooks

from flagship import LoggingHook, TelemetryHook

# Logs evaluation lifecycle events via the flagship logger (INFO level)
api.add_hooks([LoggingHook()])

# Emits a TelemetryEvent after every evaluation
api.add_hooks([TelemetryHook(lambda event: analytics.track("flag_evaluated", event))])

TelemetryEvent fields: type, flag_key, timestamp, duration_ms, value, reason, variant, error_code, error_message, context, hints.

Provider events

from openfeature.event import ProviderEvent

api.add_handler(ProviderEvent.PROVIDER_READY, lambda _: print("ready"))
api.add_handler(ProviderEvent.PROVIDER_ERROR, lambda d: print("error:", d.message))

During initialisation the provider probes the endpoint with a health-check request. A 404 is treated as success. Any other error transitions the provider to ERROR status and emits PROVIDER_ERROR.

Development

uv sync --group dev        # install dependencies
uv run pytest              # run tests
uv run mypy src            # type check
uv build                   # build wheel and sdist

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cloudflare_flagship-0.3.1.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloudflare_flagship-0.3.1-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file cloudflare_flagship-0.3.1.tar.gz.

File metadata

  • Download URL: cloudflare_flagship-0.3.1.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cloudflare_flagship-0.3.1.tar.gz
Algorithm Hash digest
SHA256 0fb080069e10027aa094e66060aa72f677331f4c7f7a49d96813734dc1417894
MD5 1f5dd9bf80a1da4d5b880a36bc9f15a4
BLAKE2b-256 1afc0d2c24e8973da8e7c5feb6b7937fad87d76ea2d4a8c6422598f12eacf813

See more details on using hashes here.

File details

Details for the file cloudflare_flagship-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: cloudflare_flagship-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 17.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cloudflare_flagship-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7a97bff45106dee56d94e331b41c5dce088a630375b0afd1c4607d8e9dddae68
MD5 8d6d5529db3717ee95cf18094c281a18
BLAKE2b-256 32830f6ad6f2e375ed0587975587786bcda8669084dd9a9345771e4f18b1053a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page