Skip to main content

Python SDK for FOFF Feature Config service

Project description

FOFF Python SDK

This document covers how to integrate with the FOFF Feature Config Service using the Python SDK.

Installation

Please head over to foff.twospoon.ai and create your first feature config. Then integrate it in your codebase using the following steps.

Dependency Installation

Install the dependency using the following command:

pip install foff

Requires Python 3.10 or later.

Quick Start

Sync Client

Proceed to create the client:

from foff import Client, Config

# STEP 1: Create appropriate config
config = Config(
    api_key="your-api-key",
    base_url="https://foff.twospoon.ai/live",
    scope="name-of-your-scope",
    polling_interval=30,  # refresh configs every 30 seconds (0 to disable)
)

# STEP 2: Create the client with the config
with Client(config) as client:
    # STEP 3: Retrieve configs for your created features for given hierarchies
    value = client.get_feature_config("my-feature", ["org-1", "team-a", "user-123"])
    print(value)

Async Client

import asyncio
from foff import AsyncClient, Config

config = Config(
    api_key="your-api-key",
    base_url="https://foff.twospoon.ai/live",
    scope="name-of-your-scope",
    polling_interval=30,
)

async def main():
    async with AsyncClient(config) as client:
        value = client.get_feature_config("my-feature", ["org-1", "team-a", "user-123"])
        print(value)

asyncio.run(main())

Configuration

The SDK is configured via the foff.Config dataclass:

Field Type Required Default Description
api_key str Yes Your FOFF API key.
base_url str Yes Base URL of the FOFF API.
scope str Yes The scope to fetch configs for, such as production or staging.
polling_interval int No 30 How often, in seconds, to poll for config updates. Use 0 to disable polling.

Validation

Creating a Client or AsyncClient validates the config and raises ValueError if api_key, base_url, or scope is empty.

Creating a Client

Sync Client

with Client(config) as client:
    value = client.get_feature_config("dark-mode", ["org-1", "team-a", "user-123"])

Async Client

async with AsyncClient(config) as client:
    value = client.get_feature_config("dark-mode", ["org-1", "team-a", "user-123"])

Fetching Feature Configs

get_feature_config(feature_name: str, ordered_hierarchy: list[str]) -> Any

Returns the config value for a feature, resolved against a hierarchy.

value = client.get_feature_config("dark-mode", ["org-1", "team-a", "user-123"])

Hierarchy resolution works from most specific to least specific:

  1. The SDK looks up the most specific combination first.
  2. For the example above, it checks keys in this order:
    • org-1 + team-a + user-123
    • org-1 + team-a
    • org-1
  3. If none match, it falls back to the "default" value of the config for a feature.
  4. If the feature does not exist at all, it returns None.

This lets you define config overrides at any level of your hierarchy, such as organisation -> team -> user or environment -> region -> service, and the SDK resolves the most specific value automatically.

Polling

When polling_interval > 0, the client refreshes configs in the background.

  • Polling errors are silently ignored, and the SDK continues serving the last successfully fetched config.
  • Calling close() on Client, or await close() on AsyncClient, stops background polling and releases resources.

Recommended Intervals

Use Case Interval
Near-real-time 10s
Standard 30-60s
Low-traffic / batch 300-600s

Client Lifecycle

Sync

# Context manager (recommended)
with Client(config) as client:
    ...

# Manual
client = Client(config)
try:
    ...
finally:
    client.close()

Async

# Context manager (recommended)
async with AsyncClient(config) as client:
    ...

# Manual
client = AsyncClient(config)
await client.start()
try:
    ...
finally:
    await client.close()

Contributing

Issues and pull requests are tracked on GitHub.

License

See LICENSE.

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

foff-0.1.1.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

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

foff-0.1.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file foff-0.1.1.tar.gz.

File metadata

  • Download URL: foff-0.1.1.tar.gz
  • Upload date:
  • Size: 22.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for foff-0.1.1.tar.gz
Algorithm Hash digest
SHA256 833f5b118b99b147d4496e63d5084e86277ed30d9225d00c97da58626fb4d35c
MD5 a8c6f9187beb18491a94bf2ac9b78c73
BLAKE2b-256 281fd2706a38798807117f08bf01f6acbe28e0982d7fac14851167df45ed2cbf

See more details on using hashes here.

Provenance

The following attestation bundles were made for foff-0.1.1.tar.gz:

Publisher: release.yml on twospoon/foff-feature-config-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file foff-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: foff-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for foff-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a6f634c72ef33e12818ba6feb9577f663c169748a06608be4f0274eff3de14da
MD5 8847d06318c840d40a0eab345fe9a49b
BLAKE2b-256 b28bc99b46f4c8a7ebd823c35faca04b51a7b6c7bc7674cd625b96c9bf4ba834

See more details on using hashes here.

Provenance

The following attestation bundles were made for foff-0.1.1-py3-none-any.whl:

Publisher: release.yml on twospoon/foff-feature-config-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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