Skip to main content

FoxNose Python SDK

PyPI version Python versions CI codecov Docs License

FoxNose is a managed knowledge layer for RAG and AI agents — auto-embeddings, hybrid search, and zero ETL pipelines to maintain.

This is the official Python SDK for FoxNose Management and Flux APIs.

Features

  • Type-safe clients - Full type hints and Pydantic models
  • Sync and async - Both synchronous and asynchronous clients
  • Automatic retries - Configurable retry with exponential backoff
  • JWT authentication - Built-in token refresh support
  • Flux introspection - Discover routes and live schema via /_router and /_schema

Documentation

SDK Documentation: foxnose-python.readthedocs.io

FoxNose Platform:

Installation

pip install foxnose-sdk

Quick Start

To get started, you'll need a FoxNose account. Create one here.

from foxnose_sdk.management import ManagementClient
from foxnose_sdk.auth import JWTAuth

client = ManagementClient(
    base_url="https://api.foxnose.net",
    environment_key="your-environment-key",
    auth=JWTAuth.from_static_token("YOUR_ACCESS_TOKEN"),
)

# List collections
collections = client.list_collections()
for collection in collections.results:
    print(f"{collection.name} ({collection.key})")

client.close()

Note (0.6.0): Folder-named methods (list_folders, create_folder, add_api_folder, list_folder_versions, list_folder_fields, etc.) remain as deprecated aliases that emit a one-shot DeprecationWarning on first use per process. They keep their original wire behaviour (hitting the legacy /folders/... URL alias on the server) and will be removed in 1.0. Prefer the *_collection* names in new code.

Async Client

from foxnose_sdk.management import AsyncManagementClient

async def main():
    client = AsyncManagementClient(
        base_url="https://api.foxnose.net",
        environment_key="your-environment-key",
        auth=JWTAuth.from_static_token("YOUR_ACCESS_TOKEN"),
    )

    collections = await client.list_collections()
    await client.aclose()

Components on Collections

Collections can embed Components as nested fields with explicit pin semantics (component, component_version, auto_update). The NestedFieldMeta helper builds the meta block for you, and sync_collection_component advances pinned fields to a target Component version on demand.

from foxnose_sdk import (
    ManagementClient,
    FoxnoseConfig,
    NestedFieldMeta,
)
from foxnose_sdk.auth import JWTAuth

client = ManagementClient(
    FoxnoseConfig(base_url="https://api.foxnose.com"),
    environment_key="prod",
    auth=JWTAuth("ACCESS_TOKEN"),
)

# Embed a Component as a pinned nested field on a Collection draft.
client.create_collection_field(
    "articles",
    "v2-draft",
    {
        "key": "seo",
        "name": "SEO",
        "type": "nested",
        "required": True,
        "meta": NestedFieldMeta(
            component="cmp-seo-metadata",
            component_version="ver-abc12345",
            auto_update=False,  # default — pin until explicit sync
        ).to_meta(),
    },
)

# Later, advance every pinned nested field to its Component's current
# version (empty body = sync all pinned).
result = client.sync_collection_component("articles")
print(result.synced_paths, result.schema_version)

# Advance specific paths to a chosen Component version.
result = client.sync_collection_component(
    "articles",
    field_paths=["seo"],
    to_versions={"seo": "ver-def67890"},
)

sync_collection_component returns a SyncComponentResponse with synced_paths, skipped (per-path reasons), and schema_version (UID of the newly published Collection schema version, or None if no field needed advancing). On compatibility conflict the server returns 409 component_sync_conflict; quota exhaustion returns 422 too_many_versions. Both surface as FoxnoseAPIError.

Handling billing errors

Billing and quota responses raise typed subclasses of FoxnoseAPIError, so existing except FoxnoseAPIError handlers keep working while new code can read the typed attributes:

from foxnose_sdk import (
    SpendCapExceeded,
    PlanExhausted,
    PlanLimitExceeded,
    RateLimitExceeded,
)

try:
    client.create_collection({"name": "Blog"})
except SpendCapExceeded as e:  # HTTP 402
    print(f"Spend cap {e.cap_usd}; resets at {e.cycle_resets_at}: {e.raise_cap_url}")
except PlanExhausted as e:  # HTTP 402
    print(f"Allowance for {e.axis} exhausted; resets at {e.window_resets_at}")
except PlanLimitExceeded as e:  # HTTP 403
    print(f"{e.entity}: {e.current}/{e.limit}. Upgrade: {e.upgrade_url}")
except RateLimitExceeded as e:  # HTTP 429
    print(f"Rate limited; retry after {e.retry_after}s")

All four subclass FoxnoseAPIError, so a single except FoxnoseAPIError still catches them if you don't need the typed fields.

Flux Client

from foxnose_sdk.flux import FluxClient
from foxnose_sdk.auth import SimpleKeyAuth

client = FluxClient(
    base_url="https://<env_key>.fxns.io",
    api_prefix="v1",
    auth=SimpleKeyAuth("PUBLIC_KEY", "SECRET_KEY"),
)

resources = client.list_resources("blog-posts")

# Writes require a write-capable key. Create publishes immediately; `key` is an
# optional external id used to deduplicate. update_resource is a full replace.
created = client.create_resource("blog-posts", {"title": "Hello"}, key="my-id")
client.update_resource("blog-posts", created["resource_key"], {"title": "Hello (edited)"})

client.close()

Development

# Install with dev dependencies
pip install -e .[test,docs]

# Run tests
pytest

# Run tests with coverage
pytest --cov=foxnose_sdk --cov-report=term-missing

# Build docs
mkdocs serve

License

Apache 2.0 - see LICENSE for details.

Download files

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

Source Distribution

foxnose_sdk-0.7.1.tar.gz (103.3 kB view details)

Uploaded Source

Built Distribution

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

foxnose_sdk-0.7.1-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

Details for the file foxnose_sdk-0.7.1.tar.gz.

File metadata

  • Download URL: foxnose_sdk-0.7.1.tar.gz
  • Upload date:
  • Size: 103.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for foxnose_sdk-0.7.1.tar.gz
Algorithm Hash digest
SHA256 d4a008df7f0a61814e0108df1c4abdcf8a9ae1f075e46b2649a18363dc3c8b4b
MD5 b1ad0019239535b1d6f20346a2ae9a97
BLAKE2b-256 07b46893f92259e4328907099ae1a1cbc8129476f8bdcd1bb7bd3d2e1f86ccf3

See more details on using hashes here.

File details

Details for the file foxnose_sdk-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: foxnose_sdk-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 47.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for foxnose_sdk-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0aaf4103320f51ce0b0f281b8d51fd1657e88cb9b7a47d60e32afe88ccdd3a95
MD5 3585f0ff0c588dccbbdd06ecd986fcd5
BLAKE2b-256 8881ae5b92e1fe06286c6b3a9c30b3af4f3c6746708ace36380171be91d7ba7b

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