Skip to main content

Astrolabe Python SDK

A Python SDK for the Astrolabe feature flag system, supporting number, string, boolean, and JSON flags with environment-based configuration.

Installation

pip install astrolabe-python-sdk

Quick Start

from astrolabe import AstrolabeClient

# Initialize the client with your environment
client = AstrolabeClient(env="development")  # or "staging", "production"

# Evaluate different types of flags
boolean_flag = client.get_boolean_flag("feature_enabled", default=False)
string_flag = client.get_string_flag("welcome_message", default="Hello!")
number_flag = client.get_number_flag("max_items", default=10)
json_flag = client.get_json_flag("config", default={"theme": "light"})

# Generic flag evaluation (type inferred from default)
flag_value = client.get_flag("any_flag", default="default_value")

Usage

Initialization

from astrolabe import AstrolabeClient
from astrolabe.client import Environment

# Using string
client = AstrolabeClient("production")

# Using enum
client = AstrolabeClient(Environment.PRODUCTION)

Flag Evaluation with Attributes

# Pass attributes for context-aware flag evaluation
attributes = {
    "user_id": "12345",
    "region": "us-east-1",
    "plan": "premium"
}

result = client.get_boolean_flag(
    key="premium_feature", 
    default=False, 
    attributes=attributes
)

Supported Flag Types

  • Boolean flags: get_boolean_flag(key, default, attributes=None)
  • String flags: get_string_flag(key, default, attributes=None)
  • Number flags: get_number_flag(key, default, attributes=None) (supports int and float)
  • JSON flags: get_json_flag(key, default, attributes=None) (returns dict)
  • Generic flags: get_flag(key, default, attributes=None) (type inferred from default)

Environments

Supported environments:

  • development
  • staging
  • production

Async Support

For use in async frameworks (FastAPI, Starlette, aiohttp, etc.), install the async extra:

pip install astrolabe-python-sdk[async]

Then use AsyncAstrolabeClient, which uses httpx.AsyncClient under the hood and an asyncio.Task for background polling — it never blocks the event loop.

Basic async usage

import os
from astrolabe import AsyncAstrolabeClient

os.environ["ASTROLABE_API_URL"] = "https://your-astrolabe-api.com"

async def main():
    async with AsyncAstrolabeClient(
        env="production",
        subscribed_projects=["my-project"],
    ) as client:
        # Evaluate flags (sync — pure in-memory cache reads, no I/O)
        enabled = client.get_bool("my-project/dark-mode", default=False)
        limit  = client.get_number("my-project/rate-limit", default=100)
        banner = client.get_string("my-project/banner-text", default="Welcome!")
        config = client.get_json("my-project/ui-config", default={"theme": "light"})

        # With user attributes for rule-based targeting
        premium = client.get_bool(
            "my-project/premium-feature",
            default=False,
            attributes={"user_id": "u-42", "plan": "enterprise"},
        )

        # Manual refresh (non-blocking)
        await client.refresh_flags()

FastAPI example

from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from astrolabe import AsyncAstrolabeClient

astrolabe: AsyncAstrolabeClient | None = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global astrolabe
    astrolabe = await AsyncAstrolabeClient(
        env="production",
        subscribed_projects=["backend"],
    ).start()
    yield
    await astrolabe.close()

app = FastAPI(lifespan=lifespan)

@app.get("/feature")
async def feature(request: Request):
    enabled = astrolabe.get_bool("backend/new-checkout", default=False)
    return {"new_checkout_enabled": enabled}

FastAPI with Depends()

You can inject the client through FastAPI's dependency injection system:

from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from astrolabe import AsyncAstrolabeClient

@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.astrolabe = await AsyncAstrolabeClient(
        env="production",
        subscribed_projects=["backend"],
    ).start()
    yield
    await app.state.astrolabe.close()

app = FastAPI(lifespan=lifespan)


def get_astrolabe(request) -> AsyncAstrolabeClient:
    """Dependency that provides the shared AsyncAstrolabeClient."""
    return request.app.state.astrolabe


@app.get("/feature")
async def feature(flags: AsyncAstrolabeClient = Depends(get_astrolabe)):
    enabled = flags.get_bool("backend/new-checkout", default=False)
    limit = flags.get_number("backend/rate-limit", default=100)
    return {"new_checkout_enabled": enabled, "rate_limit": limit}


@app.get("/dashboard")
async def dashboard(flags: AsyncAstrolabeClient = Depends(get_astrolabe)):
    theme = flags.get_string("backend/theme", default="light")
    config = flags.get_json(
        "backend/dashboard-config",
        default={"widgets": []},
        attributes={"role": "admin"},
    )
    return {"theme": theme, "config": config}

This pattern stores the client on app.state and injects it via Depends(), so your route handlers stay testable — just override the dependency in tests.

Explicit lifecycle (without context manager)

client = AsyncAstrolabeClient("staging", subscribed_projects=["svc"])
await client.start()       # creates httpx client, fetches flags, starts polling

try:
    value = client.get_flag("svc/experiment", default="control")
finally:
    await client.close()   # stops polling, closes httpx client

Development

This SDK is currently in development. Flag evaluation logic is stubbed and will be implemented in future versions.

License

MIT License

Metadata

Release files for astrolabe-python-sdk 1.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for astrolabe-python-sdk 1.1.3
File Size Uploaded
astrolabe_python_sdk-1.1.3.tar.gz 37.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for astrolabe-python-sdk 1.1.3
File Interpreter ABI Platform
astrolabe_python_sdk-1.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 53.4 kB

Release files / astrolabe_python_sdk-1.1.3.tar.gz

Download URL astrolabe_python_sdk-1.1.3.tar.gz
Size 37.3 kB
Tags Source
SHA-256 checksum
How to use checksums
d27767ed6bd2eae6ba4554355d8c0198dcc8f986d233a6d94a30343d8b757cae
BLAKE2b-256 checksum
How to use checksums
662cfd787593b54302837df845cc715bc9b22ea89eb99881eba05810b337ab6e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / astrolabe_python_sdk-1.1.3-py3-none-any.whl

Download URL astrolabe_python_sdk-1.1.3-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4ebcf2476e97c18c311629a1abc090c60ba3a93336d95926ca625ffc0249687
BLAKE2b-256 checksum
How to use checksums
40402cd8c975181cf1a12e32d6d831962abc364758c015f0bd2545399d53741f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

1.1.3 This release

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page