Skip to content
Sign In Get Started

Python SDK (floopy-sdk)

floopy-sdk is the official Floopy SDK for Python. It wraps the official openai package and points it at the Floopy gateway, so chat.completions and embeddings stay a 1:1 drop-in while Floopy-only features (audit, experiments, constraints, decision export, feedback, routing dry-run, sessions) get first-class typed methods.

Prefer the zero-SDK approach? The Python page shows how to use the raw OpenAI SDK with Floopy headers. Use floopy-sdk when you also want the typed Floopy resources and a single client for both.

Both a synchronous Floopy and an asynchronous AsyncFloopy client are provided. Requires Python >= 3.10.

Terminal window
pip install floopy-sdk
import os
from floopy import Floopy
with Floopy(api_key=os.environ["FLOOPY_API_KEY"]) as floopy:
response = floopy.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello from Floopy!"}],
)
print(response.choices[0].message.content)

Set FLOOPY_API_KEY in your environment. You can create one in the dashboard.

from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
from floopy import Floopy
client = Floopy(api_key=os.environ["FLOOPY_API_KEY"])
r = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "..."}],
)

client.chat, client.embeddings, and client.models return the underlying openai resources, so types and runtime behaviour are identical. Security updates to the OpenAI SDK reach you on pip install -U without forks or parity drift.

FloopyOptions map to Floopy-* headers and are forwarded to every request (both OpenAI-compat calls and Floopy-only ones). Per-call overrides are available via request_options=RequestOptions(...) on every resource.

from floopy import Floopy, FloopyOptions, CacheOptions
floopy = Floopy(
api_key="fl_...",
options=FloopyOptions(
cache=CacheOptions(enabled=True, bucket_max_size=3),
prompt_id="cd4249d5-44d5-46c8-8961-9eb3861e1f7e",
prompt_version="1",
llm_security_enabled=True,
),
)
OptionHeaderPurpose
cache.enabledFloopy-Cache-EnabledToggle exact + semantic cache
cache.bucket_max_sizeFloopy-Cache-Bucket-Max-SizeMax entries per semantic bucket
prompt_idFloopy-Prompt-IdStored prompt to resolve
prompt_versionFloopy-Prompt-VersionPinned version for prompt_id
llm_security_enabledfloopy-llm-security-enabledLLM firewall pre-check

See the Headers Reference for the full list.

Each resource maps to a public /v1/* gateway endpoint and is typed end-to-end. Every method exists on both Floopy (sync) and AsyncFloopy (await it).

# Feedback
floopy.feedback.submit(score=9, useful=True, session_id=r.id)
# Decisions (paginated iterators)
decision = floopy.decisions.get(request_id)
for d in floopy.decisions.iterate(from_=since, limit=50):
...
# Experiments (auto X-Floopy-Confirm: experiments header)
exp = floopy.experiments.create(
name="cost-vs-quality",
variant_a_routing_rule_id=rule_a,
variant_b_routing_rule_id=rule_b,
)
floopy.experiments.rollback(exp.id)
# Constraints (full-replace PUT)
from floopy import OrgConstraints
floopy.constraints.put(OrgConstraints(cost_limit_monthly_usd=100))
# Export (streamed JSONL + trailer)
stream = floopy.export.decisions_with_trailer(from_=start, to=end)
for row in stream:
...
print(stream.trailer)
# Evaluations
run = floopy.evaluations.create(dataset_id=ds_id, model="gpt-4o")
results = floopy.evaluations.results(run.id, limit=100)
# Routing dry-run (Pro plan)
explain = floopy.routing.explain(model="gpt-4o", messages=messages)
# Sessions — restore a stored conversation
session = floopy.sessions.get(session_id)
floopy.chat.completions.create(model="gpt-4o", messages=session.messages)

Every Floopy-only call raises a FloopyError subclass:

from floopy import FloopyRateLimitError, FloopyPlanError
try:
for row in floopy.export.decisions(from_=start, to=end):
...
except FloopyRateLimitError as err:
time.sleep(err.retry_after_seconds or 1)
except FloopyPlanError as err:
print(f"Upgrade plan: feature {err.feature} not in current plan")

Errors from chat.completions / embeddings are emitted by the OpenAI SDK (openai.APIError and friends).

  • The API key is only ever sent in the Authorization header and is masked in repr(); the SDK never logs request or response bodies.
  • TLS certificate verification is on by default.
  • Releases are published to PyPI via Trusted Publishing (OIDC) with PEP 740 attestations — no long-lived tokens, and consumers can verify the artifact was built by the release workflow.

See the Security guide for gateway-side controls.